mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 02:27:36 +03:00
Add JSON output support to channel programs
The changes piggyback JSON output support on top of channel programs (#6558). This way the JSON output support is targeted to scripting use cases and is easily maintainable since it really only touches one function (zfs_do_channel_program()). This patch ports Joyent's JSON nvlist library from illumos to enable easy JSON printing of channel program output nvlist. To keep the delta small I also took advantage of the fact that printing in zfs_do_channel_program() was almost always done before exiting the program. Reviewed by: Matt Ahrens <mahrens@delphix.com> Reviewed-by: Tony Hutter <hutter2@llnl.gov> Reviewed-by: Richard Elling <Richard.Elling@RichardElling.com> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Alek Pinchuk <apinchuk@datto.com> Closes #7281
This commit is contained in:
@@ -16,6 +16,7 @@ SUBDIRS = \
|
||||
zfs_inherit \
|
||||
zfs_load-key \
|
||||
zfs_mount \
|
||||
zfs_program \
|
||||
zfs_promote \
|
||||
zfs_property \
|
||||
zfs_receive \
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
pkgdatadir = $(datadir)/@PACKAGE@/zfs-tests/tests/functional/cli_root/zfs_program
|
||||
dist_pkgdata_SCRIPTS = \
|
||||
setup.ksh \
|
||||
cleanup.ksh \
|
||||
zfs_program_json.ksh
|
||||
@@ -0,0 +1,30 @@
|
||||
#!/bin/ksh -p
|
||||
#
|
||||
# CDDL HEADER START
|
||||
#
|
||||
# The contents of this file are subject to the terms of the
|
||||
# Common Development and Distribution License (the "License").
|
||||
# You may not use this file except in compliance with the License.
|
||||
#
|
||||
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
# or http://www.opensolaris.org/os/licensing.
|
||||
# See the License for the specific language governing permissions
|
||||
# and limitations under the License.
|
||||
#
|
||||
# When distributing Covered Code, include this CDDL HEADER in each
|
||||
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
# If applicable, add the following below this CDDL HEADER, with the
|
||||
# fields enclosed by brackets "[]" replaced with your own identifying
|
||||
# information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
#
|
||||
# CDDL HEADER END
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
|
||||
# Use is subject to license terms.
|
||||
#
|
||||
|
||||
. $STF_SUITE/include/libtest.shlib
|
||||
|
||||
default_cleanup
|
||||
@@ -0,0 +1,32 @@
|
||||
#!/bin/ksh -p
|
||||
#
|
||||
# CDDL HEADER START
|
||||
#
|
||||
# The contents of this file are subject to the terms of the
|
||||
# Common Development and Distribution License (the "License").
|
||||
# You may not use this file except in compliance with the License.
|
||||
#
|
||||
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
# or http://www.opensolaris.org/os/licensing.
|
||||
# See the License for the specific language governing permissions
|
||||
# and limitations under the License.
|
||||
#
|
||||
# When distributing Covered Code, include this CDDL HEADER in each
|
||||
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
# If applicable, add the following below this CDDL HEADER, with the
|
||||
# fields enclosed by brackets "[]" replaced with your own identifying
|
||||
# information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
#
|
||||
# CDDL HEADER END
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
|
||||
# Use is subject to license terms.
|
||||
#
|
||||
|
||||
. $STF_SUITE/include/libtest.shlib
|
||||
|
||||
DISK=${DISKS%% *}
|
||||
|
||||
default_setup $DISK
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
#!/bin/ksh -p
|
||||
#
|
||||
# CDDL HEADER START
|
||||
#
|
||||
# This file and its contents are supplied under the terms of the
|
||||
# Common Development and Distribution License ("CDDL"), version 1.0.
|
||||
# You may only use this file in accordance with the terms of version
|
||||
# 1.0 of the CDDL.
|
||||
#
|
||||
# A full copy of the text of the CDDL should have accompanied this
|
||||
# source. A copy is of the CDDL is also available via the Internet
|
||||
# at http://www.illumos.org/license/CDDL.
|
||||
#
|
||||
# CDDL HEADER END
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright (c) 2018 Datto Inc.
|
||||
#
|
||||
|
||||
. $STF_SUITE/include/libtest.shlib
|
||||
|
||||
#
|
||||
# DESCRIPTION:
|
||||
#
|
||||
# STRATEGY:
|
||||
# 1. Compare JSON output formatting for a channel program to template
|
||||
# 2. Using bad command line option (-Z) gives correct error output
|
||||
#
|
||||
|
||||
verify_runnable "both"
|
||||
|
||||
function cleanup
|
||||
{
|
||||
log_must zfs destroy $TESTDS
|
||||
return 0
|
||||
}
|
||||
log_onexit cleanup
|
||||
|
||||
log_assert "Channel programs output valid JSON"
|
||||
|
||||
TESTDS="$TESTPOOL/zcp-json"
|
||||
log_must zfs create $TESTDS
|
||||
|
||||
TESTZCP="/$TESTDS/zfs_rlist.zcp"
|
||||
cat > "$TESTZCP" << EOF
|
||||
succeeded = {}
|
||||
failed = {}
|
||||
|
||||
function list_recursive(root, prop)
|
||||
for child in zfs.list.children(root) do
|
||||
list_recursive(child, prop)
|
||||
end
|
||||
val, src = zfs.get_prop(root, prop)
|
||||
if (val == nil) then
|
||||
failed[root] = val
|
||||
else
|
||||
succeeded[root] = val
|
||||
end
|
||||
end
|
||||
|
||||
args = ...
|
||||
|
||||
argv = args["argv"]
|
||||
|
||||
list_recursive(argv[1], argv[2])
|
||||
|
||||
results = {}
|
||||
results["succeeded"] = succeeded
|
||||
results["failed"] = failed
|
||||
return results
|
||||
EOF
|
||||
|
||||
# 1. Compare JSON output formatting for a channel program to template
|
||||
typeset -a pos_cmds=("recordsize" "type")
|
||||
typeset -a pos_cmds_out=(
|
||||
"{
|
||||
\"return\": {
|
||||
\"failed\": {},
|
||||
\"succeeded\": {
|
||||
\"$TESTDS\": 131072
|
||||
}
|
||||
}
|
||||
}"
|
||||
"{
|
||||
\"return\": {
|
||||
\"failed\": {},
|
||||
\"succeeded\": {
|
||||
\"$TESTDS\": \"filesystem\"
|
||||
}
|
||||
}
|
||||
}")
|
||||
typeset -i cnt=0
|
||||
typeset cmd
|
||||
for cmd in ${pos_cmds[@]}; do
|
||||
log_must zfs program $TESTPOOL $TESTZCP $TESTDS $cmd 2>&1
|
||||
log_must zfs program $TESTPOOL -j $TESTZCP $TESTDS $cmd 2>&1
|
||||
# json.tool is needed to guarantee consistent ordering of fields
|
||||
# sed is needed to trim trailing space in CentOS 6's json.tool output
|
||||
OUTPUT=$(zfs program $TESTPOOL -j $TESTZCP $TESTDS $cmd 2>&1 | python -m json.tool | sed 's/[[:space:]]*$//')
|
||||
if [ "$OUTPUT" != "${pos_cmds_out[$cnt]}" ]; then
|
||||
log_note "Got :$OUTPUT"
|
||||
log_note "Expected:${pos_cmds_out[$cnt]}"
|
||||
log_fail "Unexpected channel program output";
|
||||
fi
|
||||
cnt=$((cnt + 1))
|
||||
done
|
||||
|
||||
# 2. Using bad command line option (-Z) gives correct error output
|
||||
typeset -a neg_cmds=("-Z")
|
||||
typeset -a neg_cmds_out=(
|
||||
"invalid option 'Z'
|
||||
usage:
|
||||
program [-jn] [-t <instruction limit>] [-m <memory limit (b)>] <pool> <program file> [lua args...]
|
||||
|
||||
For the property list, run: zfs set|get
|
||||
|
||||
For the delegated permission list, run: zfs allow|unallow")
|
||||
cnt=0
|
||||
for cmd in ${neg_cmds[@]}; do
|
||||
log_mustnot zfs program $TESTPOOL $TESTZCP $TESTDS $cmd 2>&1
|
||||
log_mustnot zfs program $TESTPOOL -j $TESTZCP $TESTDS $cmd 2>&1
|
||||
OUTPUT=$(zfs program $TESTPOOL -j $TESTZCP $TESTDS $cmd 2>&1)
|
||||
if [ "$OUTPUT" != "${neg_cmds_out[$cnt]}" ]; then
|
||||
log_note "Got :$OUTPUT"
|
||||
log_note "Expected:${neg_cmds_out[$cnt]}"
|
||||
log_fail "Unexpected channel program error output";
|
||||
fi
|
||||
cnt=$((cnt + 1))
|
||||
done
|
||||
|
||||
log_pass "Channel programs output valid JSON"
|
||||
Reference in New Issue
Block a user