]> xenbits.xensource.com Git - libvirt.git/commitdiff
vsh: Annotate 'required' and 'positional' arguments explicitly
authorPeter Krempa <pkrempa@redhat.com>
Tue, 5 Mar 2024 14:07:47 +0000 (15:07 +0100)
committerPeter Krempa <pkrempa@redhat.com>
Wed, 13 Mar 2024 14:02:52 +0000 (15:02 +0100)
Add 'positional' and 'required' fields to vshCmdOptDef, which will
explicitly track the two properties of arguments.

To ensure that we have proper coverage, add checks to
vshCmddefCheckInternals validating the state of the above flags by
infering it from existing data.

This conversion will allow us:
 - remove VSH_OT_DATA in favor of VSH_OT_STRING
 - use VSH_OT_INT when required both as positional and non-positional
 - properly annotate which VSH_OT_ARGV are positional and which are not
   (currently inferred by whether an previous positional option exists)

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
15 files changed:
tools/virsh-domain-monitor.c
tools/virsh-domain.c
tools/virsh-host.c
tools/virsh-interface.c
tools/virsh-network.c
tools/virsh-nodedev.c
tools/virsh-nwfilter.c
tools/virsh-pool.c
tools/virsh-secret.c
tools/virsh-snapshot.c
tools/virsh-volume.c
tools/virsh.h
tools/virt-admin.c
tools/vsh.c
tools/vsh.h

index 7a25318bbdeb2580cc9b600503c44af2dfa69f58..573451c678474e2ad7cba679fd90d6611a639f84 100644 (file)
@@ -738,6 +738,8 @@ static const vshCmdOptDef opts_domif_getlink[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(0),
     {.name = "interface",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshDomainInterfaceCompleter,
      .help = N_("interface device (MAC Address)")
@@ -1038,6 +1040,8 @@ static const vshCmdOptDef opts_domifstat[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE),
     {.name = "interface",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshDomainInterfaceCompleter,
      .help = N_("interface device specified by name or MAC Address")
@@ -2050,6 +2054,7 @@ static const vshCmdOptDef opts_domstats[] = {
     },
     {.name = "domain",
      .type = VSH_OT_ARGV,
+     .positional = true,
      .help = N_("list of domains to get stats for"),
      .completer = virshDomainNameCompleter,
     },
index bbad264053941eb1d49c54b93430046f08f4a3a1..063a5145214e13522eb120c962c42fc72da4e9d6 100644 (file)
@@ -420,11 +420,15 @@ static const vshCmdOptDef opts_attach_disk[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(0),
     {.name = "source",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ | VSH_OFLAG_EMPTY_OK,
      .help = N_("source of disk device or name of network disk")
     },
     {.name = "target",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshCompleteEmpty,
      .help = N_("target of disk device")
@@ -812,11 +816,15 @@ static const vshCmdOptDef opts_attach_interface[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(0),
     {.name = "type",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("network interface type")
     },
     {.name = "source",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("source of network interface")
     },
@@ -1188,6 +1196,8 @@ static const vshCmdOptDef opts_blkdeviotune[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(0),
     {.name = "device",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshDomainDiskTargetCompleter,
      .help = N_("block device")
@@ -1981,6 +1991,8 @@ static const vshCmdOptDef opts_blockcommit[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE),
     {.name = "path",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshDomainDiskTargetCompleter,
      .help = N_("fully-qualified path of disk")
@@ -2200,6 +2212,8 @@ static const vshCmdOptDef opts_blockcopy[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE),
     {.name = "path",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshDomainDiskTargetCompleter,
      .help = N_("fully-qualified path of source disk")
@@ -2532,6 +2546,8 @@ static const vshCmdOptDef opts_blockjob[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE),
     {.name = "path",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshDomainDiskTargetCompleter,
      .help = N_("fully-qualified path of disk")
@@ -2743,6 +2759,8 @@ static const vshCmdOptDef opts_blockpull[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE),
     {.name = "path",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshDomainDiskTargetCompleter,
      .help = N_("fully-qualified path of disk")
@@ -2885,6 +2903,8 @@ static const vshCmdOptDef opts_blockresize[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE),
     {.name = "path",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshDomainDiskTargetCompleter,
      .help = N_("Fully-qualified path of block device")
@@ -3042,12 +3062,16 @@ static const vshCmdOptDef opts_domif_setlink[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(0),
     {.name = "interface",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshDomainInterfaceCompleter,
      .help = N_("interface device (MAC Address)")
     },
     {.name = "state",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshDomainInterfaceStateCompleter,
      .help = N_("new state of the device")
@@ -3188,6 +3212,8 @@ static const vshCmdOptDef opts_domiftune[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(0),
     {.name = "interface",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshDomainInterfaceCompleter,
      .help = N_("interface device (MAC Address)")
@@ -3413,6 +3439,8 @@ static const vshCmdOptDef opts_dom_pm_suspend[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_RUNNING),
     {.name = "target",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshNodeSuspendTargetCompleter,
      .help = N_("mem(Suspend-to-RAM), "
@@ -4096,6 +4124,8 @@ static const vshCmdOptDef opts_save[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE),
     {.name = "file",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("where to save the data")
     },
@@ -4445,6 +4475,8 @@ static const vshCmdInfo info_save_image_dumpxml = {
 static const vshCmdOptDef opts_save_image_dumpxml[] = {
     {.name = "file",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("saved state file to read")
     },
@@ -4502,11 +4534,15 @@ static const vshCmdInfo info_save_image_define = {
 static const vshCmdOptDef opts_save_image_define[] = {
     {.name = "file",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("saved state file to modify")
     },
     {.name = "xml",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshCompletePathLocalExisting,
      .help = N_("filename containing updated XML for the target")
@@ -4565,6 +4601,8 @@ static const vshCmdInfo info_save_image_edit = {
 static const vshCmdOptDef opts_save_image_edit[] = {
     {.name = "file",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("saved state file to edit")
     },
@@ -4904,6 +4942,8 @@ static const vshCmdOptDef opts_managed_save_define[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_MANAGEDSAVE),
     {.name = "xml",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshCompletePathLocalExisting,
      .help = N_("filename containing updated XML for the target")
@@ -5180,6 +5220,8 @@ static const vshCmdInfo info_restore = {
 static const vshCmdOptDef opts_restore[] = {
     {.name = "file",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("the state to restore")
     },
@@ -5263,6 +5305,8 @@ static const vshCmdOptDef opts_dump[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE),
     {.name = "file",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("where to dump the core")
     },
@@ -5562,12 +5606,16 @@ static const vshCmdOptDef opts_setLifecycleAction[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(0),
     {.name = "type",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshDomainLifecycleCompleter,
      .help = N_("lifecycle type to modify")
     },
     {.name = "action",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshDomainLifecycleActionCompleter,
      .help = N_("lifecycle action to set")
@@ -5654,11 +5702,15 @@ static const vshCmdOptDef opts_set_user_password[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE),
     {.name = "user",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("the username")
     },
     {.name = "password",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshCompleteEmpty,
      .help = N_("the new password")
@@ -7074,6 +7126,8 @@ static const vshCmdOptDef opts_setvcpus[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(0),
     {.name = "count",
      .type = VSH_OT_INT,
+     .required = true,
+     .positional = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("number of virtual CPUs")
     },
@@ -7240,6 +7294,8 @@ static const vshCmdOptDef opts_setvcpu[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(0),
     {.name = "vcpulist",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshDomainVcpulistCompleter,
      .help = N_("ids of vcpus to manipulate")
@@ -7314,12 +7370,16 @@ static const vshCmdOptDef opts_domblkthreshold[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE),
     {.name = "dev",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshDomainDiskTargetCompleter,
      .help = N_("device to set threshold for")
     },
     {.name = "threshold",
      .type = VSH_OT_INT,
+     .required = true,
+     .positional = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("threshold as a scaled number (by default bytes)")
     },
@@ -7442,12 +7502,16 @@ static const vshCmdOptDef opts_iothreadpin[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(0),
     {.name = "iothread",
      .type = VSH_OT_INT,
+     .required = true,
+     .positional = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshDomainIOThreadIdCompleter,
      .help = N_("IOThread ID number")
     },
     {.name = "cpulist",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshDomainCpulistCompleter,
      .help = N_("host cpu number(s) to set")
@@ -7515,6 +7579,8 @@ static const vshCmdOptDef opts_iothreadadd[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(0),
     {.name = "id",
      .type = VSH_OT_INT,
+     .required = true,
+     .positional = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("iothread for the new IOThread")
     },
@@ -7571,6 +7637,8 @@ static const vshCmdOptDef opts_iothreadset[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(0),
     {.name = "id",
      .type = VSH_OT_INT,
+     .required = true,
+     .positional = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshDomainIOThreadIdCompleter,
      .help = N_("iothread id of existing IOThread")
@@ -7687,6 +7755,8 @@ static const vshCmdOptDef opts_iothreaddel[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(0),
     {.name = "id",
      .type = VSH_OT_INT,
+     .required = true,
+     .positional = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshDomainIOThreadIdCompleter,
      .help = N_("iothread_id for the IOThread to delete")
@@ -8277,6 +8347,8 @@ static const vshCmdOptDef opts_metadata[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(0),
     {.name = "uri",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("URI of the namespace")
     },
@@ -8455,6 +8527,7 @@ static const vshCmdOptDef opts_send_key[] = {
     },
     {.name = "keycode",
      .type = VSH_OT_ARGV,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshKeycodeNameCompleter,
      .help = N_("the key code")
@@ -8539,12 +8612,16 @@ static const vshCmdOptDef opts_send_process_signal[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE),
     {.name = "pid",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshCompleteEmpty,
      .help = N_("the process ID")
     },
     {.name = "signame",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshDomainSignalCompleter,
      .help = N_("the signal number or name")
@@ -8633,6 +8710,8 @@ static const vshCmdOptDef opts_setmem[] = {
     },
     {.name = "size",
      .type = VSH_OT_INT,
+     .required = true,
+     .positional = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("new memory size, as scaled integer (default KiB)")
     },
@@ -8702,6 +8781,8 @@ static const vshCmdOptDef opts_setmaxmem[] = {
     },
     {.name = "size",
      .type = VSH_OT_INT,
+     .required = true,
+     .positional = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("new maximum memory size, as scaled integer (default KiB)")
     },
@@ -9475,12 +9556,16 @@ static const vshCmdOptDef opts_dom_fd_associate[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(0),
     {.name = "name",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshCompleteEmpty,
      .help = N_("name of the FD group")
     },
     {.name = "pass-fds",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshCompleteEmpty,
      .help = N_("file descriptors N,M,... to associate")
@@ -9557,6 +9642,7 @@ static const vshCmdOptDef opts_qemu_monitor_command[] = {
     },
     {.name = "cmd",
      .type = VSH_OT_ARGV,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("command")
     },
@@ -9892,6 +9978,8 @@ static const vshCmdInfo info_qemu_attach = {
 static const vshCmdOptDef opts_qemu_attach[] = {
     {.name = "pid",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshCompleteEmpty,
      .help = N_("pid")
@@ -9949,6 +10037,7 @@ static const vshCmdOptDef opts_qemu_agent_command[] = {
     },
     {.name = "cmd",
      .type = VSH_OT_ARGV,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("command")
     },
@@ -10045,6 +10134,7 @@ static const vshCmdOptDef opts_lxc_enter_namespace[] = {
     },
     {.name = "cmd",
      .type = VSH_OT_ARGV,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("command to run")
     },
@@ -10224,11 +10314,15 @@ static const vshCmdInfo info_domxmlfromnative = {
 static const vshCmdOptDef opts_domxmlfromnative[] = {
     {.name = "format",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("source config data format")
     },
     {.name = "config",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshCompletePathLocalExisting,
      .help = N_("config data file to import from")
@@ -10272,6 +10366,8 @@ static const vshCmdInfo info_domxmltonative = {
 static const vshCmdOptDef opts_domxmltonative[] = {
     {.name = "format",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("target config data type format")
     },
@@ -10339,6 +10435,8 @@ static const vshCmdInfo info_domname = {
 static const vshCmdOptDef opts_domname[] = {
     {.name = "domain",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshDomainUUIDCompleter,
      .help = N_("domain id or uuid")
@@ -10372,6 +10470,8 @@ static const vshCmdOptDef opts_domrename[] = {
                             VIR_CONNECT_LIST_DOMAINS_INACTIVE),
     {.name = "new-name",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshCompleteEmpty,
      .help = N_("new domain name")
@@ -10474,6 +10574,8 @@ static const vshCmdOptDef opts_migrate[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(0),
     {.name = "desturi",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshCompleteEmpty,
      .help = N_("connection URI of the destination host as seen from the client(normal migration) or source(p2p migration)")
@@ -11171,6 +11273,8 @@ static const vshCmdOptDef opts_migrate_setmaxdowntime[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE),
     {.name = "downtime",
      .type = VSH_OT_INT,
+     .required = true,
+     .positional = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("maximum tolerable downtime (in milliseconds) for migration")
     },
@@ -11289,6 +11393,8 @@ static const vshCmdOptDef opts_migrate_setspeed[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE),
     {.name = "bandwidth",
      .type = VSH_OT_INT,
+     .required = true,
+     .positional = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("migration bandwidth limit in MiB/s")
     },
@@ -11878,6 +11984,8 @@ static const vshCmdOptDef opts_detach_device_alias[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(0),
     {.name = "alias",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshDomainDeviceAliasCompleter,
      .help = N_("device alias")
@@ -12006,6 +12114,8 @@ static const vshCmdOptDef opts_detach_interface[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(0),
     {.name = "type",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("network interface type")
     },
@@ -12378,6 +12488,8 @@ static const vshCmdOptDef opts_detach_disk[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(0),
     {.name = "target",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshDomainDiskTargetCompleter,
      .help = N_("target of disk device")
@@ -12538,6 +12650,8 @@ static const vshCmdOptDef opts_change_media[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(0),
     {.name = "path",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshDomainDiskTargetCompleter,
      .help = N_("Fully-qualified path or target of disk device")
@@ -13012,6 +13126,8 @@ static const vshCmdOptDef opts_get_user_sshkeys[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE),
     {.name = "user",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("user to list authorized keys for"),
     },
@@ -13059,6 +13175,8 @@ static const vshCmdOptDef opts_set_user_sshkeys[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE),
     {.name = "user",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("user to set authorized keys for"),
     },
index 1a97f4926bb2c1b630825390f0711b884cbdd077..368e6565504a813288430290f1ab86d9d91472d6 100644 (file)
@@ -468,12 +468,16 @@ static const vshCmdInfo info_allocpages = {
 static const vshCmdOptDef opts_allocpages[] = {
     {.name = "pagesize",
      .type = VSH_OT_INT,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshAllocpagesPagesizeCompleter,
      .help = N_("page size (in kibibytes)")
     },
     {.name = "pagecount",
      .type = VSH_OT_INT,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("page count")
     },
@@ -943,6 +947,8 @@ static const vshCmdInfo info_nodesuspend = {
 static const vshCmdOptDef opts_node_suspend[] = {
     {.name = "target",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshNodeSuspendTargetCompleter,
      .help = N_("mem(Suspend-to-RAM), disk(Suspend-to-Disk), "
@@ -950,6 +956,8 @@ static const vshCmdOptDef opts_node_suspend[] = {
     },
     {.name = "duration",
      .type = VSH_OT_INT,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("Suspend duration in seconds, at least 60")
     },
@@ -1270,6 +1278,8 @@ static const vshCmdInfo info_cpu_models = {
 static const vshCmdOptDef opts_cpu_models[] = {
     {.name = "arch",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .completer = virshArchCompleter,
      .flags = VSH_OFLAG_REQ,
      .help = N_("architecture")
index 5dde4f9d46c9a508468bde9dea3dd6f74806e835..52dce97462e5c3ce21ff8e08ccb85d9dab6310da 100644 (file)
@@ -21,6 +21,8 @@
 #define VIRSH_COMMON_OPT_INTERFACE(cflags) \
     {.name = "interface", \
      .type = VSH_OT_DATA, \
+     .positional = true, \
+     .required = true, \
      .flags = VSH_OFLAG_REQ, \
      .help = N_("interface name or MAC address"), \
      .completer = virshInterfaceNameCompleter, \
@@ -383,6 +385,8 @@ static const vshCmdInfo info_interface_name = {
 static const vshCmdOptDef opts_interface_name[] = {
     {.name = "interface",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshInterfaceMacCompleter,
      .help = N_("interface mac")
@@ -414,6 +418,8 @@ static const vshCmdInfo info_interface_mac = {
 static const vshCmdOptDef opts_interface_mac[] = {
     {.name = "interface",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshInterfaceNameCompleter,
      .help = N_("interface name")
@@ -716,12 +722,16 @@ static const vshCmdInfo info_interface_bridge = {
 static const vshCmdOptDef opts_interface_bridge[] = {
     {.name = "interface",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshInterfaceNameCompleter,
      .help = N_("existing interface name")
     },
     {.name = "bridge",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("new bridge device name")
     },
@@ -943,6 +953,8 @@ static const vshCmdInfo info_interface_unbridge = {
 static const vshCmdOptDef opts_interface_unbridge[] = {
     {.name = "bridge",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("current bridge device name")
     },
index 8eca6e866cfae377dafae5c9e53407509d0a78f4..b12efdce36e761524892603ed8c08c6cd416c363 100644 (file)
@@ -33,6 +33,8 @@
 #define VIRSH_COMMON_OPT_NETWORK(_helpstr, cflags) \
     {.name = "network", \
      .type = VSH_OT_DATA, \
+     .positional = true, \
+     .required = true, \
      .flags = VSH_OFLAG_REQ, \
      .help = _helpstr, \
      .completer = virshNetworkNameCompleter, \
@@ -56,6 +58,8 @@
 #define VIRSH_COMMON_OPT_NETWORK_PORT(cflags) \
     {.name = "port", \
      .type = VSH_OT_DATA, \
+     .positional = true, \
+     .required = true, \
      .flags = VSH_OFLAG_REQ, \
      .help = N_("port UUID"), \
      .completer = virshNetworkPortUUIDCompleter, \
@@ -502,6 +506,8 @@ static const vshCmdOptDef opts_network_metadata[] = {
     VIRSH_COMMON_OPT_NETWORK_FULL(0),
     {.name = "uri",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("URI of the namespace")
     },
@@ -1127,6 +1133,8 @@ static const vshCmdInfo info_network_name = {
 static const vshCmdOptDef opts_network_name[] = {
     {.name = "network",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshNetworkUUIDCompleter,
      .help = N_("network uuid")
@@ -1224,18 +1232,24 @@ static const vshCmdOptDef opts_network_update[] = {
     VIRSH_COMMON_OPT_NETWORK_FULL(0),
     {.name = "command",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshNetworkUpdateCommandCompleter,
      .help = N_("type of update (add-first, add-last (add), delete, or modify)")
     },
     {.name = "section",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshNetworkUpdateSectionCompleter,
      .help = N_("which section of network configuration to update")
     },
     {.name = "xml",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshCompletePathLocalExisting,
      .help = N_("name of file containing xml (or, if it starts with '<', the complete "
index c0fb319fa79b108e556ef9dc72ec5e185caeb15b..0081e3cbb727aeb894f551f2461386945b052cb3 100644 (file)
@@ -97,6 +97,8 @@ static const vshCmdOptDef opts_node_device_destroy[] = {
     },
     {.name = "device",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("device name or wwn pair in 'wwnn,wwpn' format"),
      .completer = virshNodeDeviceNameCompleter,
@@ -571,6 +573,8 @@ static const vshCmdInfo info_node_device_dumpxml = {
 static const vshCmdOptDef opts_node_device_dumpxml[] = {
     {.name = "device",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("device name or wwn pair in 'wwnn,wwpn' format"),
      .completer = virshNodeDeviceNameCompleter,
@@ -634,6 +638,8 @@ static const vshCmdInfo info_node_device_detach = {
 static const vshCmdOptDef opts_node_device_detach[] = {
     {.name = "device",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("device key"),
      .completer = virshNodeDeviceNameCompleter,
@@ -696,6 +702,8 @@ static const vshCmdInfo info_node_device_reattach = {
 static const vshCmdOptDef opts_node_device_reattach[] = {
     {.name = "device",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("device key"),
      .completer = virshNodeDeviceNameCompleter,
@@ -741,6 +749,8 @@ static const vshCmdInfo info_node_device_reset = {
 static const vshCmdOptDef opts_node_device_reset[] = {
     {.name = "device",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("device key"),
      .completer = virshNodeDeviceNameCompleter,
@@ -1002,6 +1012,8 @@ static const vshCmdInfo info_node_device_undefine = {
 static const vshCmdOptDef opts_node_device_undefine[] = {
     {.name = "device",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("device name or wwn pair in 'wwnn,wwpn' format"),
      .completer = virshNodeDeviceNameCompleter,
@@ -1093,6 +1105,8 @@ static const vshCmdInfo info_node_device_start = {
 static const vshCmdOptDef opts_node_device_start[] = {
     {.name = "device",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("device name"),
      .completer = virshNodeDeviceNameCompleter,
@@ -1138,6 +1152,8 @@ static const vshCmdInfo info_node_device_autostart = {
 static const vshCmdOptDef opts_node_device_autostart[] = {
     {.name = "device",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("device name or wwn pair in 'wwnn,wwpn' format"),
      .completer = virshNodeDeviceNameCompleter,
@@ -1195,6 +1211,8 @@ static const vshCmdInfo info_node_device_info = {
 static const vshCmdOptDef opts_node_device_info[] = {
     {.name = "device",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("device name or wwn pair in 'wwnn,wwpn' format"),
      .completer = virshNodeDeviceNameCompleter,
@@ -1245,6 +1263,8 @@ static const vshCmdInfo info_node_device_update = {
 static const vshCmdOptDef opts_node_device_update[] = {
     {.name = "device",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("device name or wwn pair in 'wwnn,wwpn' format"),
      .completer = virshNodeDeviceNameCompleter,
index 7a578f3f7c983d27446a1a8b14b7beb183e53162..993539d368e9f453ebc9e342902369829ded1899 100644 (file)
@@ -129,6 +129,8 @@ static const vshCmdInfo info_nwfilter_undefine = {
 static const vshCmdOptDef opts_nwfilter_undefine[] = {
     {.name = "nwfilter",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("network filter name or uuid"),
      .completer = virshNWFilterNameCompleter,
@@ -167,6 +169,8 @@ static const vshCmdInfo info_nwfilter_dumpxml = {
 static const vshCmdOptDef opts_nwfilter_dumpxml[] = {
     {.name = "nwfilter",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("network filter name or uuid"),
      .completer = virshNWFilterNameCompleter,
@@ -391,6 +395,8 @@ static const vshCmdInfo info_nwfilter_edit = {
 static const vshCmdOptDef opts_nwfilter_edit[] = {
     {.name = "nwfilter",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("network filter name or uuid"),
      .completer = virshNWFilterNameCompleter,
@@ -526,6 +532,8 @@ static const vshCmdInfo info_nwfilter_binding_delete = {
 static const vshCmdOptDef opts_nwfilter_binding_delete[] = {
     {.name = "binding",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("network filter binding port dev"),
      .completer = virshNWFilterBindingNameCompleter,
@@ -566,6 +574,8 @@ static const vshCmdInfo info_nwfilter_binding_dumpxml = {
 static const vshCmdOptDef opts_nwfilter_binding_dumpxml[] = {
     {.name = "binding",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("network filter binding portdev"),
      .completer = virshNWFilterBindingNameCompleter,
index a7b82de9be358185806074859573a84057612ede..46069908361d88d804dda1f43006e599d14ce148 100644 (file)
 #define VIRSH_COMMON_OPT_POOL_X_AS \
     {.name = "name", \
      .type = VSH_OT_DATA, \
+     .positional = true, \
+     .required = true, \
      .flags = VSH_OFLAG_REQ, \
      .completer = virshCompleteEmpty, \
      .help = N_("name of the pool") \
     }, \
     {.name = "type", \
      .type = VSH_OT_DATA, \
+     .positional = true, \
+     .required = true, \
      .flags = VSH_OFLAG_REQ, \
      .completer = virshPoolTypeCompleter, \
      .help = N_("type of the pool") \
@@ -1354,6 +1358,8 @@ static const vshCmdInfo info_find_storage_pool_sources_as = {
 static const vshCmdOptDef opts_find_storage_pool_sources_as[] = {
     {.name = "type",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshPoolTypeCompleter,
      .help = N_("type of storage pool sources to find")
@@ -1437,6 +1443,8 @@ static const vshCmdInfo info_find_storage_pool_sources = {
 static const vshCmdOptDef opts_find_storage_pool_sources[] = {
     {.name = "type",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshPoolTypeCompleter,
      .help = N_("type of storage pool sources to discover")
index a88980ef9ea044d61bdc98dd53f538e0737ef84d..d7e60de4cad22870d6fb78d59776522d19108d22 100644 (file)
@@ -124,6 +124,8 @@ static const vshCmdInfo info_secret_dumpxml = {
 static const vshCmdOptDef opts_secret_dumpxml[] = {
     {.name = "secret",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("secret UUID"),
      .completer = virshSecretUUIDCompleter,
@@ -179,6 +181,8 @@ static const vshCmdInfo info_secret_set_value = {
 static const vshCmdOptDef opts_secret_set_value[] = {
     {.name = "secret",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("secret UUID"),
      .completer = virshSecretUUIDCompleter,
@@ -290,6 +294,8 @@ static const vshCmdInfo info_secret_get_value = {
 static const vshCmdOptDef opts_secret_get_value[] = {
     {.name = "secret",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("secret UUID"),
      .completer = virshSecretUUIDCompleter,
@@ -343,6 +349,8 @@ static const vshCmdInfo info_secret_undefine = {
 static const vshCmdOptDef opts_secret_undefine[] = {
     {.name = "secret",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("secret UUID"),
      .completer = virshSecretUUIDCompleter,
index 31ab27b112acb1ce7d0d25c50d7ee4433ebd2db8..9ad33c4252dc8e655dcb86e9287cfa40d1eba3ad 100644 (file)
@@ -1568,6 +1568,8 @@ static const vshCmdOptDef opts_snapshot_dumpxml[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_HAS_SNAPSHOT),
     {.name = "snapshotname",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("snapshot name"),
      .completer = virshSnapshotNameCompleter,
index 0cb7262b67d160d41a08cdbdcd4ef74afe2652ec..ecf89345c35afd590337b2f62545997e839d057e 100644 (file)
@@ -57,6 +57,8 @@
 #define VIRSH_COMMON_OPT_VOL_NAME(_helpstr) \
     {.name = "vol", \
      .type = VSH_OT_DATA, \
+     .positional = true, \
+     .required = true, \
      .flags = VSH_OFLAG_REQ, \
      .help = _helpstr, \
      .completer = virshStorageVolNameCompleter, \
@@ -65,6 +67,8 @@
 #define VIRSH_COMMON_OPT_VOL_KEY(_helpstr) \
     {.name = "vol", \
      .type = VSH_OT_DATA, \
+     .positional = true, \
+     .required = true, \
      .flags = VSH_OFLAG_REQ, \
      .help = _helpstr, \
      .completer = virshStorageVolKeyCompleter, \
@@ -173,12 +177,16 @@ static const vshCmdOptDef opts_vol_create_as[] = {
     VIRSH_COMMON_OPT_POOL_NAME,
     {.name = "name",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshCompleteEmpty,
      .help = N_("name of the volume")
     },
     {.name = "capacity",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshCompleteEmpty,
      .help = N_("size of the vol, as scaled integer (default bytes)")
@@ -520,6 +528,8 @@ static const vshCmdOptDef opts_vol_clone[] = {
     VIRSH_COMMON_OPT_VOL_FULL,
     {.name = "newname",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshCompleteEmpty,
      .help = N_("clone name")
@@ -1024,6 +1034,8 @@ static const vshCmdOptDef opts_vol_resize[] = {
     VIRSH_COMMON_OPT_VOL_FULL,
     {.name = "capacity",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = virshCompleteEmpty,
      .help = N_("new capacity for the vol, as scaled integer (default bytes)")
index 877b290e3ad120c17b3fdf7a3b08c676e1ec9f38..451683769de3b381a1074b9f53d94e9274efa1c4 100644 (file)
@@ -58,6 +58,8 @@
 #define VIRSH_COMMON_OPT_POOL(_helpstr, cflags) \
     {.name = "pool", \
      .type = VSH_OT_DATA, \
+     .positional = true, \
+     .required = true, \
      .flags = VSH_OFLAG_REQ, \
      .help = _helpstr, \
      .completer = virshStoragePoolNameCompleter, \
@@ -67,6 +69,8 @@
 #define VIRSH_COMMON_OPT_DOMAIN(_helpstr, cflags) \
     {.name = "domain", \
      .type = VSH_OT_DATA, \
+     .positional = true, \
+     .required = true, \
      .flags = VSH_OFLAG_REQ, \
      .help = _helpstr, \
      .completer = virshDomainNameCompleter, \
 #define VIRSH_COMMON_OPT_FILE(_helpstr) \
     VIRSH_COMMON_OPT_FILE_FULL(_helpstr, true)
 
-#define VIRSH_COMMON_OPT_FILE_FULL(_helpstr, required) \
+#define VIRSH_COMMON_OPT_FILE_FULL(_helpstr, required_) \
     {.name = "file", \
-     .type = required ? VSH_OT_DATA : VSH_OT_STRING, \
-     .flags = required ? VSH_OFLAG_REQ : VSH_OFLAG_NONE, \
+     .type = required_ ? VSH_OT_DATA : VSH_OT_STRING, \
+     .required = required_, \
+     .positional = required_, \
+     .flags = required_ ? VSH_OFLAG_REQ : VSH_OFLAG_NONE, \
      .completer = virshCompletePathLocalExisting, \
      .help = _helpstr \
     }
index 114ec2e8e7164f08d8f66becf463211c56078692..d266d824cb4f2f4b70941057c70aadd79978af15 100644 (file)
@@ -359,6 +359,8 @@ static const vshCmdInfo info_srv_threadpool_info = {
 static const vshCmdOptDef opts_srv_threadpool_info[] = {
     {.name = "server",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = vshAdmServerCompleter,
      .help = N_("Server to retrieve threadpool attributes from."),
@@ -416,6 +418,8 @@ static const vshCmdInfo info_srv_threadpool_set = {
 static const vshCmdOptDef opts_srv_threadpool_set[] = {
     {.name = "server",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = vshAdmServerCompleter,
      .help = N_("Server to alter threadpool attributes on."),
@@ -517,6 +521,8 @@ static const vshCmdInfo info_srv_clients_list = {
 static const vshCmdOptDef opts_srv_clients_list[] = {
     {.name = "server",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = vshAdmServerCompleter,
      .help = N_("server which to list connected clients from"),
@@ -599,12 +605,16 @@ static const vshCmdInfo info_client_info = {
 static const vshCmdOptDef opts_client_info[] = {
     {.name = "server",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = vshAdmServerCompleter,
      .help = N_("server to which <client> is connected to"),
     },
     {.name = "client",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("client which to retrieve identity information for"),
     },
@@ -681,12 +691,16 @@ static const vshCmdInfo info_client_disconnect = {
 static const vshCmdOptDef opts_client_disconnect[] = {
     {.name = "server",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = vshAdmServerCompleter,
      .help = N_("server which the client is currently connected to"),
     },
     {.name = "client",
      .type = VSH_OT_INT,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("client which to disconnect, specified by ID"),
     },
@@ -742,6 +756,8 @@ static const vshCmdInfo info_srv_clients_info = {
 static const vshCmdOptDef opts_srv_clients_info[] = {
     {.name = "server",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = vshAdmServerCompleter,
      .help = N_("Server to retrieve the client limits from."),
@@ -796,6 +812,8 @@ static const vshCmdInfo info_srv_clients_set = {
 static const vshCmdOptDef opts_srv_clients_set[] = {
     {.name = "server",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .completer = vshAdmServerCompleter,
      .help = N_("Server to alter the client-related configuration limits on."),
@@ -893,6 +911,8 @@ static const vshCmdInfo info_srv_update_tls_file = {
 static const vshCmdOptDef opts_srv_update_tls_file[] = {
     {.name = "server",
      .type = VSH_OT_DATA,
+     .positional = true,
+     .required = true,
      .flags = VSH_OFLAG_REQ,
      .help = N_("Available servers on a daemon. "
                 "Currently only supports 'libvirtd' or 'virtproxyd'.")
@@ -991,6 +1011,8 @@ static const vshCmdInfo info_daemon_log_outputs = {
 static const vshCmdOptDef opts_daemon_timeout[] = {
     {.name = "timeout",
      .type = VSH_OT_INT,
+     .positional = true,
+     .required = true,
      .help = N_("number of seconds the daemon will run without any active connection"),
      .flags = VSH_OFLAG_REQ | VSH_OFLAG_REQ_OPT
     },
index c4099bb725f7254a4aa53f493da8b0fe5095d665..f059434b1a2a6951c178e32c73664374682818bb 100644 (file)
@@ -248,6 +248,7 @@ vshCmddefCheckInternals(vshControl *ctl,
 {
     size_t i;
     bool seenOptionalOption = false;
+    bool seenPositionalOption = false;
     g_auto(virBuffer) complbuf = VIR_BUFFER_INITIALIZER;
 
     /* in order to perform the validation resolve the alias first */
@@ -301,6 +302,8 @@ vshCmddefCheckInternals(vshControl *ctl,
 
     for (i = 0; cmd->opts[i].name; i++) {
         const vshCmdOptDef *opt = &cmd->opts[i];
+        bool isPositional = false;
+        bool isRequired = false;
 
         if (i > 63) {
             vshError(ctl, "command '%s' has too many options", cmd->name);
@@ -385,12 +388,17 @@ vshCmddefCheckInternals(vshControl *ctl,
             }
         }
             break;
+
         case VSH_OT_ARGV:
             if (cmd->opts[i + 1].name) {
                 vshError(ctl, "parameter '%s' of command '%s' must be listed last",
                          opt->name, cmd->name);
                 return -1;
             }
+
+            isRequired = opt->flags & VSH_OFLAG_REQ;
+            /* ARGV argument is positional if there are no positional options */
+            isPositional = !seenPositionalOption;
             break;
 
         case VSH_OT_DATA:
@@ -400,6 +408,10 @@ vshCmddefCheckInternals(vshControl *ctl,
                 return -1;
             }
 
+            isRequired = true;
+            isPositional = true;
+            seenPositionalOption = true;
+
             if (seenOptionalOption) {
                 vshError(ctl, "parameter '%s' of command '%s' must be listed before optional parameters",
                          opt->name, cmd->name);
@@ -414,12 +426,28 @@ vshCmddefCheckInternals(vshControl *ctl,
                              opt->name, cmd->name);
                     return -1;
                 }
+                seenPositionalOption = true;
+                isPositional = true;
+                isRequired = true;
             } else {
-                seenOptionalOption = true;
+                isPositional = false;
+                isRequired = false;
             }
 
             break;
         }
+
+        if (opt->required != isRequired) {
+            vshError(ctl, "parameter '%s' of command '%s' 'required' state mismatch",
+                     opt->name, cmd->name);
+            return -1;
+        }
+
+        if (opt->positional != isPositional) {
+            vshError(ctl, "parameter '%s' of command '%s' 'positional' state mismatch",
+                     opt->name, cmd->name);
+            return -1;
+        }
     }
 
     virBufferTrim(&complbuf, ", ");
@@ -3241,6 +3269,7 @@ const vshCmdOptDef opts_echo[] = {
     },
     {.name = "string",
      .type = VSH_OT_ARGV,
+     .positional = true,
      .help = N_("arguments to echo")
     },
     {.name = NULL}
@@ -3379,6 +3408,7 @@ cmdSelfTest(vshControl *ctl, const vshCmd *cmd)
 const vshCmdOptDef opts_complete[] = {
     {.name = "string",
      .type = VSH_OT_ARGV,
+     .positional = true,
      .flags = VSH_OFLAG_EMPTY_OK,
      .help = N_("partial string to autocomplete")
     },
index 6007df2b7ebaef428b0392ad38653e241a42d49f..53384dbb55a9b11bceeeaaa535d33d5a475ba0bd 100644 (file)
@@ -133,6 +133,8 @@ struct _vshCmdInfo {
 struct _vshCmdOptDef {
     const char *name;           /* the name of option, or NULL for list end */
     vshCmdOptType type;         /* option type */
+    bool required;              /* option is required */
+    bool positional;            /* option is a positional option (not requiring '--optionname') */
     unsigned int flags;         /* flags */
     const char *help;           /* non-NULL help string; or for VSH_OT_ALIAS
                                  * the name of a later public option */