From: Peter Krempa <pkrempa@redhat.com> Add users possibility to discover presence of arguments safely. The new global argument '--probe-arguments' which runs the argument parser but doesn't run the actual function and returning success if it gets to the point of actually trying to runt he parser. This will allow users to probe for new arguments (which were added after this patch: - virsh prior to this patch: $ virsh --probe-arguments blockresize cd vda 1 --extend ; echo $? error: unsupported option '--probe-arguments'. See --help. 1 - virsh with this patch but checking for something that doesn't yet exist: $ virsh --probe-arguments blockresize cd vda 1 --allow-shrink ; echo $? error: command 'blockresize' doesn't support option --allow-shrink 1 - virsh with this patch with the argument present: $ virsh --probe-arguments blockresize cd vda 1 --allow-shrink ; echo $? 0 Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- docs/manpages/virsh.rst | 17 ++++++++++++++++- tools/virsh.c | 4 ++++ tools/virt-admin.c | 9 +++++++++ tools/vsh.c | 3 +++ tools/vsh.h | 1 + 5 files changed, 33 insertions(+), 1 deletion(-) diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst index 80b0ea14a8..9ede859aaf 100644 --- a/docs/manpages/virsh.rst +++ b/docs/manpages/virsh.rst @@ -161,7 +161,22 @@ Ignore all other arguments, and prints the version of the libvirt library virsh is coming from and which options and driver are compiled in. - +- ``--probe-arguments`` + +Parse all incomming commands and their arguments. Return without actually +executing the command. This gives the caller the possibility to probe if given +command or argument exists in this version of virsh without executing the +command. Mandatory arguments need to be provided albeit with dummy values if +checking existence of optional features. +(Introduced in libvirt-12.3.0) + +Example:: + + if virsh --probe-arguments blockresize --domain dummy --path dummy --size 1 --allow-shrink 2>/dev/null; then + echo "supported" + else + echo "unsupported" + fi NOTES ===== diff --git a/tools/virsh.c b/tools/virsh.c index fdce3220b3..57e2b9c1a9 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -646,6 +646,7 @@ virshParseArgv(vshControl *ctl, int argc, char **argv) { "timing", no_argument, NULL, 't' }, { "no-pkttyagent", no_argument, NULL, 0 }, { "version", optional_argument, NULL, 'v' }, + { "probe-arguments", no_argument, NULL, 0 }, { NULL, 0, NULL, 0 }, }; @@ -746,6 +747,9 @@ virshParseArgv(vshControl *ctl, int argc, char **argv) if (STREQ(opt[longindex].name, "no-pkttyagent")) { ctl->no_pkttyagent = true; break; + } else if (STREQ(opt[longindex].name, "probe-arguments")) { + ctl->probe_arguments = true; + break; } else { vshError(ctl, "%s", _("unknown option")); exit(EXIT_FAILURE); diff --git a/tools/virt-admin.c b/tools/virt-admin.c index ac8f3202b6..ff6f3856aa 100644 --- a/tools/virt-admin.c +++ b/tools/virt-admin.c @@ -1292,6 +1292,7 @@ vshAdmParseArgv(vshControl *ctl, int argc, char **argv) { "log", required_argument, NULL, 'l' }, { "quiet", no_argument, NULL, 'q' }, { "version", optional_argument, NULL, 'v' }, + { "probe-arguments", no_argument, NULL, 0 }, { NULL, 0, NULL, 0 }, }; @@ -1337,6 +1338,14 @@ vshAdmParseArgv(vshControl *ctl, int argc, char **argv) case 'V': vshAdmShowVersion(ctl); exit(EXIT_SUCCESS); + case 0: + if (STREQ(opt[longindex].name, "probe-arguments")) { + ctl->probe_arguments = true; + break; + } else { + vshError(ctl, "%s", _("unknown option")); + exit(EXIT_FAILURE); + } case ':': for (i = 0; opt[i].name != NULL; i++) { if (opt[i].val == optopt) diff --git a/tools/vsh.c b/tools/vsh.c index 74016c0043..e85d8b5001 100644 --- a/tools/vsh.c +++ b/tools/vsh.c @@ -1366,6 +1366,9 @@ vshCommandRun(vshControl *ctl, const vshClientHooks *hooks = ctl->hooks; int ret = EXIT_SUCCESS; + if (ctl->probe_arguments) + return EXIT_SUCCESS; + while (cmd) { gint64 before, after; bool enable_timing = ctl->timing; diff --git a/tools/vsh.h b/tools/vsh.h index bd2494e899..18fa7ad594 100644 --- a/tools/vsh.h +++ b/tools/vsh.h @@ -203,6 +203,7 @@ struct _vshControl { bool timing; /* print timing info? */ bool no_pkttyagent; /* suppress registration of pkttyagent? */ int debug; /* print debug messages? */ + bool probe_arguments; /* process arguments but don't run command */ char *logfile; /* log file name */ int log_fd; /* log file descriptor */ char *historydir; /* readline history directory name */ -- 2.53.0