[PATCH 13/14] virsh: Introduce virshCompleteEmpty and use it for places where we can't suggest anything

Peter Krempa pkrempa at redhat.com
Thu Sep 16 17:10:44 UTC 2021


For now this serves just as an annotation because readline and also the
bash completion script insist on completing local paths when an empty
list is returned.

This will serve for future reference once we'll be able to properly
refuse to suggest anything.

The completer is used for fields such as names for new objects,
description strings, password strings etc, URIs and hostnames which we
can't feasibly autocomplete.

Signed-off-by: Peter Krempa <pkrempa at redhat.com>
---
 tools/virsh-checkpoint.c |  2 ++
 tools/virsh-completer.c  | 18 ++++++++++++++++++
 tools/virsh-completer.h  |  5 +++++
 tools/virsh-domain.c     | 33 +++++++++++++++++++++++++++++++++
 tools/virsh-pool.c       |  7 +++++++
 tools/virsh-secret.c     |  1 +
 tools/virsh-snapshot.c   |  2 ++
 tools/virsh-volume.c     |  5 +++++
 tools/virsh.c            |  1 +
 9 files changed, 74 insertions(+)

diff --git a/tools/virsh-checkpoint.c b/tools/virsh-checkpoint.c
index 78272b43c4..8ad37ece69 100644
--- a/tools/virsh-checkpoint.c
+++ b/tools/virsh-checkpoint.c
@@ -200,10 +200,12 @@ static const vshCmdOptDef opts_checkpoint_create_as[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE),
     {.name = "name",
      .type = VSH_OT_STRING,
+     .completer = virshCompleteEmpty,
      .help = N_("name of checkpoint")
     },
     {.name = "description",
      .type = VSH_OT_STRING,
+     .completer = virshCompleteEmpty,
      .help = N_("description of checkpoint")
     },
     {.name = "print-xml",
diff --git a/tools/virsh-completer.c b/tools/virsh-completer.c
index 100f206598..3d77be3121 100644
--- a/tools/virsh-completer.c
+++ b/tools/virsh-completer.c
@@ -145,3 +145,21 @@ virshCompletePathLocalExisting(vshControl *ctl G_GNUC_UNUSED,
 {
     return NULL;
 }
+
+
+/**
+ * virshCompleteEmpty:
+ *
+ * Complete nothing. For cases where an user input is required and we can't
+ * suggest anything.
+ *
+ * TODO: This is currently just an annotation, readline still completes local
+ * file list.
+ */
+char **
+virshCompleteEmpty(vshControl *ctl G_GNUC_UNUSED,
+                   const vshCmd *cmd G_GNUC_UNUSED,
+                   unsigned int completerflags G_GNUC_UNUSED)
+{
+    return NULL;
+}
diff --git a/tools/virsh-completer.h b/tools/virsh-completer.h
index 9a77aa117f..1d7affbb23 100644
--- a/tools/virsh-completer.h
+++ b/tools/virsh-completer.h
@@ -40,3 +40,8 @@ char **
 virshCompletePathLocalExisting(vshControl *ctl,
                                const vshCmd *cmd,
                                unsigned int completerflags);
+
+char **
+virshCompleteEmpty(vshControl *ctl,
+                   const vshCmd *cmd,
+                   unsigned int completerflags);
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 25e50064bd..d2e604f5dd 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -395,6 +395,7 @@ static const vshCmdOptDef opts_attach_disk[] = {
     {.name = "target",
      .type = VSH_OT_DATA,
      .flags = VSH_OFLAG_REQ,
+     .completer = virshCompleteEmpty,
      .help = N_("target of disk device")
     },
     {.name = "targetbus",
@@ -440,14 +441,17 @@ static const vshCmdOptDef opts_attach_disk[] = {
     },
     {.name = "serial",
      .type = VSH_OT_STRING,
+     .completer = virshCompleteEmpty,
      .help = N_("serial of disk device")
     },
     {.name = "wwn",
      .type = VSH_OT_STRING,
+     .completer = virshCompleteEmpty,
      .help = N_("wwn of disk device")
     },
     {.name = "alias",
      .type = VSH_OT_STRING,
+     .completer = virshCompleteEmpty,
      .help = N_("custom alias name of disk device")
     },
     {.name = "rawio",
@@ -456,6 +460,7 @@ static const vshCmdOptDef opts_attach_disk[] = {
     },
     {.name = "address",
      .type = VSH_OT_STRING,
+     .completer = virshCompleteEmpty,
      .help = N_("address of disk device")
     },
     {.name = "multifunction",
@@ -472,6 +477,7 @@ static const vshCmdOptDef opts_attach_disk[] = {
     },
     {.name = "source-host-name",
      .type = VSH_OT_STRING,
+     .completer = virshCompleteEmpty,
      .help = N_("host name for source of disk device")
     },
     {.name = "source-host-transport",
@@ -793,10 +799,12 @@ static const vshCmdOptDef opts_attach_interface[] = {
     },
     {.name = "target",
      .type = VSH_OT_STRING,
+     .completer = virshCompleteEmpty,
      .help = N_("target network name")
     },
     {.name = "mac",
      .type = VSH_OT_STRING,
+     .completer = virshCompleteEmpty,
      .help = N_("MAC address")
     },
     {.name = "script",
@@ -809,14 +817,17 @@ static const vshCmdOptDef opts_attach_interface[] = {
     },
     {.name = "alias",
      .type = VSH_OT_STRING,
+     .completer = virshCompleteEmpty,
      .help = N_("custom alias name of interface device")
     },
     {.name = "inbound",
      .type = VSH_OT_STRING,
+     .completer = virshCompleteEmpty,
      .help = N_("control domain's incoming traffics")
     },
     {.name = "outbound",
      .type = VSH_OT_STRING,
+     .completer = virshCompleteEmpty,
      .help = N_("control domain's outgoing traffics")
     },
     VIRSH_COMMON_OPT_DOMAIN_PERSISTENT,
@@ -1277,6 +1288,7 @@ static const vshCmdOptDef opts_blkdeviotune[] = {
     },
     {.name = "group-name",
      .type = VSH_OT_STRING,
+     .completer = virshCompleteEmpty,
      .help = N_("group name to share I/O quota between multiple drives")
     },
     {.name = "total_bytes_sec_max_length",
@@ -1493,22 +1505,27 @@ static const vshCmdOptDef opts_blkiotune[] = {
     },
     {.name = "device-weights",
      .type = VSH_OT_STRING,
+     .completer = virshCompleteEmpty,
      .help = N_("per-device IO Weights, in the form of /path/to/device,weight,...")
     },
     {.name = "device-read-iops-sec",
      .type = VSH_OT_STRING,
+     .completer = virshCompleteEmpty,
      .help = N_("per-device read I/O limit per second, in the form of /path/to/device,read_iops_sec,...")
     },
     {.name = "device-write-iops-sec",
      .type = VSH_OT_STRING,
+     .completer = virshCompleteEmpty,
      .help = N_("per-device write I/O limit per second, in the form of /path/to/device,write_iops_sec,...")
     },
     {.name = "device-read-bytes-sec",
      .type = VSH_OT_STRING,
+     .completer = virshCompleteEmpty,
      .help = N_("per-device bytes read per second, in the form of /path/to/device,read_bytes_sec,...")
     },
     {.name = "device-write-bytes-sec",
      .type = VSH_OT_STRING,
+     .completer = virshCompleteEmpty,
      .help = N_("per-device bytes wrote per second, in the form of /path/to/device,write_bytes_sec,...")
     },
     VIRSH_COMMON_OPT_DOMAIN_CONFIG,
@@ -3210,10 +3227,12 @@ static const vshCmdOptDef opts_domiftune[] = {
     },
     {.name = "inbound",
      .type = VSH_OT_STRING,
+     .completer = virshCompleteEmpty,
      .help = N_("control domain's incoming traffics")
     },
     {.name = "outbound",
      .type = VSH_OT_STRING,
+     .completer = virshCompleteEmpty,
      .help = N_("control domain's outgoing traffics")
     },
     VIRSH_COMMON_OPT_DOMAIN_CONFIG,
@@ -3991,6 +4010,7 @@ static const vshCmdOptDef opts_start[] = {
     },
     {.name = "pass-fds",
      .type = VSH_OT_STRING,
+     .completer = virshCompleteEmpty,
      .help = N_("pass file descriptors N,M,... to the guest")
     },
     {.name = NULL}
@@ -5741,6 +5761,7 @@ static const vshCmdOptDef opts_set_user_password[] = {
     {.name = "password",
      .type = VSH_OT_DATA,
      .flags = VSH_OFLAG_REQ,
+     .completer = virshCompleteEmpty,
      .help = N_("the new password")
     },
     {.name = "encrypted",
@@ -8100,6 +8121,7 @@ static const vshCmdOptDef opts_create[] = {
     },
     {.name = "pass-fds",
      .type = VSH_OT_STRING,
+     .completer = virshCompleteEmpty,
      .help = N_("pass file descriptors N,M,... to the guest")
     },
     {.name = "validate",
@@ -8457,6 +8479,7 @@ static const vshCmdOptDef opts_metadata[] = {
     },
     {.name = "set",
      .type = VSH_OT_STRING,
+     .completer = virshCompleteEmpty,
      .help = N_("new metadata to set"),
     },
     {.name = "remove",
@@ -8718,6 +8741,7 @@ static const vshCmdOptDef opts_send_process_signal[] = {
     {.name = "pid",
      .type = VSH_OT_DATA,
      .flags = VSH_OFLAG_REQ,
+     .completer = virshCompleteEmpty,
      .help = N_("the process ID")
     },
     {.name = "signame",
@@ -9659,6 +9683,7 @@ static const vshCmdOptDef opts_qemu_attach[] = {
     {.name = "pid",
      .type = VSH_OT_DATA,
      .flags = VSH_OFLAG_REQ,
+     .completer = virshCompleteEmpty,
      .help = N_("pid")
     },
     {.name = NULL}
@@ -10173,6 +10198,7 @@ static const vshCmdOptDef opts_domrename[] = {
     {.name = "new-name",
      .type = VSH_OT_DATA,
      .flags = VSH_OFLAG_REQ,
+     .completer = virshCompleteEmpty,
      .help = N_("new domain name")
     },
     {.name = NULL}
@@ -10289,6 +10315,7 @@ static const vshCmdOptDef opts_migrate[] = {
     {.name = "desturi",
      .type = VSH_OT_DATA,
      .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)")
     },
     VIRSH_COMMON_OPT_LIVE(N_("live migration")),
@@ -10370,18 +10397,22 @@ static const vshCmdOptDef opts_migrate[] = {
     },
     {.name = "migrateuri",
      .type = VSH_OT_STRING,
+     .completer = virshCompleteEmpty,
      .help = N_("migration URI, usually can be omitted")
     },
     {.name = "graphicsuri",
      .type = VSH_OT_STRING,
+     .completer = virshCompleteEmpty,
      .help = N_("graphics URI to be used for seamless graphics migration")
     },
     {.name = "listen-address",
      .type = VSH_OT_STRING,
+     .completer = virshCompleteEmpty,
      .help = N_("listen address that destination should bind to for incoming migration")
     },
     {.name = "dname",
      .type = VSH_OT_STRING,
+     .completer = virshCompleteEmpty,
      .help = N_("rename to new name during migration (if supported)")
     },
     {.name = "timeout",
@@ -10413,6 +10444,7 @@ static const vshCmdOptDef opts_migrate[] = {
     },
     {.name = "disks-uri",
      .type = VSH_OT_STRING,
+     .completer = virshCompleteEmpty,
      .help = N_("URI to use for disks migration (overrides --disks-port)")
     },
     {.name = "comp-methods",
@@ -10471,6 +10503,7 @@ static const vshCmdOptDef opts_migrate[] = {
     },
     {.name = "tls-destination",
      .type = VSH_OT_STRING,
+     .completer = virshCompleteEmpty,
      .help = N_("override the destination host name used for TLS verification")
     },
     {.name = NULL}
diff --git a/tools/virsh-pool.c b/tools/virsh-pool.c
index 6ab0490b89..b9948ea622 100644
--- a/tools/virsh-pool.c
+++ b/tools/virsh-pool.c
@@ -59,6 +59,7 @@
     {.name = "name", \
      .type = VSH_OT_DATA, \
      .flags = VSH_OFLAG_REQ, \
+     .completer = virshCompleteEmpty, \
      .help = N_("name of the pool") \
     }, \
     {.name = "type", \
@@ -73,6 +74,7 @@
     }, \
     {.name = "source-host", \
      .type = VSH_OT_STRING, \
+     .completer = virshCompleteEmpty, \
      .help = N_("source-host for underlying storage") \
     }, \
     {.name = "source-path", \
@@ -101,6 +103,7 @@
     }, \
     {.name = "auth-username", \
      .type = VSH_OT_STRING, \
+     .completer = virshCompleteEmpty, \
      .help = N_("auth username to be used for underlying storage") \
     }, \
     {.name = "secret-usage", \
@@ -145,6 +148,7 @@
     }, \
     {.name = "source-initiator", \
      .type = VSH_OT_STRING, \
+     .completer = virshCompleteEmpty, \
      .help = N_("initiator iqn for underlying storage") \
     }

@@ -1425,14 +1429,17 @@ static const vshCmdOptDef opts_find_storage_pool_sources_as[] = {
     },
     {.name = "host",
      .type = VSH_OT_STRING,
+     .completer = virshCompleteEmpty,
      .help = N_("optional host to query")
     },
     {.name = "port",
      .type = VSH_OT_STRING,
+     .completer = virshCompleteEmpty,
      .help = N_("optional port to query")
     },
     {.name = "initiator",
      .type = VSH_OT_STRING,
+     .completer = virshCompleteEmpty,
      .help = N_("optional initiator IQN to use for query")
     },
     {.name = NULL}
diff --git a/tools/virsh-secret.c b/tools/virsh-secret.c
index d23cbf04bf..dff2710928 100644
--- a/tools/virsh-secret.c
+++ b/tools/virsh-secret.c
@@ -199,6 +199,7 @@ static const vshCmdOptDef opts_secret_set_value[] = {
     },
     {.name = "base64",
      .type = VSH_OT_STRING,
+     .completer = virshCompleteEmpty,
      .help = N_("base64-encoded secret value")
     },
     {.name = NULL}
diff --git a/tools/virsh-snapshot.c b/tools/virsh-snapshot.c
index 5a3c468c53..2659b4340d 100644
--- a/tools/virsh-snapshot.c
+++ b/tools/virsh-snapshot.c
@@ -324,10 +324,12 @@ static const vshCmdOptDef opts_snapshot_create_as[] = {
     VIRSH_COMMON_OPT_DOMAIN_FULL(0),
     {.name = "name",
      .type = VSH_OT_STRING,
+     .completer = virshCompleteEmpty,
      .help = N_("name of snapshot")
     },
     {.name = "description",
      .type = VSH_OT_STRING,
+     .completer = virshCompleteEmpty,
      .help = N_("description of snapshot")
     },
     {.name = "print-xml",
diff --git a/tools/virsh-volume.c b/tools/virsh-volume.c
index b73837f4c8..103a9b9237 100644
--- a/tools/virsh-volume.c
+++ b/tools/virsh-volume.c
@@ -185,15 +185,18 @@ static const vshCmdOptDef opts_vol_create_as[] = {
     {.name = "name",
      .type = VSH_OT_DATA,
      .flags = VSH_OFLAG_REQ,
+     .completer = virshCompleteEmpty,
      .help = N_("name of the volume")
     },
     {.name = "capacity",
      .type = VSH_OT_DATA,
      .flags = VSH_OFLAG_REQ,
+     .completer = virshCompleteEmpty,
      .help = N_("size of the vol, as scaled integer (default bytes)")
     },
     {.name = "allocation",
      .type = VSH_OT_STRING,
+     .completer = virshCompleteEmpty,
      .help = N_("initial allocation size, as scaled integer (default bytes)")
     },
     {.name = "format",
@@ -561,6 +564,7 @@ static const vshCmdOptDef opts_vol_clone[] = {
     {.name = "newname",
      .type = VSH_OT_DATA,
      .flags = VSH_OFLAG_REQ,
+     .completer = virshCompleteEmpty,
      .help = N_("clone name")
     },
     VIRSH_COMMON_OPT_POOL_OPTIONAL,
@@ -1131,6 +1135,7 @@ static const vshCmdOptDef opts_vol_resize[] = {
     {.name = "capacity",
      .type = VSH_OT_DATA,
      .flags = VSH_OFLAG_REQ,
+     .completer = virshCompleteEmpty,
      .help = N_("new capacity for the vol, as scaled integer (default bytes)")
     },
     VIRSH_COMMON_OPT_POOL_OPTIONAL,
diff --git a/tools/virsh.c b/tools/virsh.c
index 3c6f60f176..b9f3f851d3 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -252,6 +252,7 @@ static const vshCmdOptDef opts_connect[] = {
     {.name = "name",
      .type = VSH_OT_STRING,
      .flags = VSH_OFLAG_EMPTY_OK,
+     .completer = virshCompleteEmpty,
      .help = N_("hypervisor connection URI")
     },
     {.name = "readonly",
-- 
2.31.1




More information about the libvir-list mailing list