Re: [PATCH virt-viewer v2] virt-viewer: Allow more precise VM selection

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On 2 Mar 2017, at 10:37, Pavel Grunt <pgrunt@xxxxxxxxxx> wrote:

On Thu, 2017-03-02 at 10:31 +0100, Christophe de Dinechin wrote:
On 2 Mar 2017, at 09:56, Pavel Grunt <pgrunt@xxxxxxxxxx> wrote:

Theoretically a VM name can be a valid VM id or uuid. In that case
connecting to the VMs may be problematic since virt-viewer selects
the VM by its id then by uuid if not found then by its name.

Introduce new command line options to cover this situation:
"--domain-name" to connect to the VM by its name
"--id" to connect to the VM by its id
"--uuid" to connect to the VM by its uuid
The options are mutually exclusive

Resolves: rhbz#1399077
---
v2: changes per Jonathon's review
- use common code for checking domkey (--wait and the new options)
- move variables to local scope
- do not fail on `virt-viewer --domain-name nonexistent`
---
man/virt-viewer.pod | 14 +++++++++
src/virt-viewer.c   | 90
++++++++++++++++++++++++++++++++++++++++++++++-------
2 files changed, 92 insertions(+), 12 deletions(-)

diff --git a/man/virt-viewer.pod b/man/virt-viewer.pod
index 9abf03c..30af8db 100644
--- a/man/virt-viewer.pod
+++ b/man/virt-viewer.pod
@@ -122,6 +122,20 @@ kiosk-quit option to "on-disconnect" value,
virt-viewer will quit
instead. Please note that --reconnect takes precedence over this
option, and will attempt to do a reconnection before it quits.

+=item --id, --uuid, --domain-name
+
+Connect to the virtual machine by its id, uuid or name. These
options
+are mutual exclusive. For example the following command may
sometimes
+connect to a virtual machine with the id 2 or with the name 2
(depending
+on the number of running machines):
+
+    virt-viewer 2
+
+To always connect to the virtual machine with the name "2" use
the
+"--domain-name" option:
+
+    virt-viewer --domain-name 2
+
=back

=head1 CONFIGURATION
diff --git a/src/virt-viewer.c b/src/virt-viewer.c
index 1f99552..b577f0a 100644
--- a/src/virt-viewer.c
+++ b/src/virt-viewer.c
@@ -82,6 +82,46 @@ static gboolean opt_attach = FALSE;
static gboolean opt_waitvm = FALSE;
static gboolean opt_reconnect = FALSE;

+typedef enum {
+    DOMAIN_SELECTION_NONE,
+    DOMAIN_SELECTION_NAME,
+    DOMAIN_SELECTION_ID,
+    DOMAIN_SELECTION_UUID,
+} DomainSelection;
+
+static const gchar* domain_selection_to_opt[] = {
+    [DOMAIN_SELECTION_NONE] = NULL,
+    [DOMAIN_SELECTION_NAME] = "--domain-name",
+    [DOMAIN_SELECTION_ID] = "--id",
+    [DOMAIN_SELECTION_UUID] = "--uuid",
+};
+
+static DomainSelection domain_selection_type =
DOMAIN_SELECTION_NONE;
+
+static gboolean
+opt_domain_selection_cb(const gchar *option_name,
+                        const gchar *value G_GNUC_UNUSED,
+                        gpointer data G_GNUC_UNUSED,
+                        GError **error)
+{
+    guint i;
+    if (domain_selection_type != DOMAIN_SELECTION_NONE) {
+        g_set_error(error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
+                    "selection type has been already set");
+        return FALSE;
+    }
+
+    for (i = DOMAIN_SELECTION_NAME; i <=
G_N_ELEMENTS(domain_selection_to_opt); i++) {
+        if (g_strcmp0(option_name, domain_selection_to_opt[i]) ==
0) {
+            domain_selection_type = i;
+            return TRUE;
+        }
+    }
+
+    g_assert_not_reached();
+    return FALSE;
+}
+
static void
virt_viewer_add_option_entries(VirtViewerApp *self, GOptionContext
*context, GOptionGroup *group)
{
@@ -96,6 +136,12 @@ virt_viewer_add_option_entries(VirtViewerApp
*self, GOptionContext *context, GOp
         N_("Wait for domain to start"), NULL },
       { "reconnect", 'r', 0, G_OPTION_ARG_NONE, &opt_reconnect,
         N_("Reconnect to domain upon restart"), NULL },
+        { "domain-name", '\0', G_OPTION_FLAG_NO_ARG,
G_OPTION_ARG_CALLBACK, opt_domain_selection_cb,
+          N_("Select the virtual machine only by its name"), NULL
},
+        { "id", '\0', G_OPTION_FLAG_NO_ARG,
G_OPTION_ARG_CALLBACK, opt_domain_selection_cb,
+          N_("Select the virtual machine only by its id"), NULL
},
+        { "uuid", '\0', G_OPTION_FLAG_NO_ARG,
G_OPTION_ARG_CALLBACK, opt_domain_selection_cb,
+          N_("Select the virtual machine only by its uuid"), NULL
},
       { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY,
&opt_args,
         NULL, "-- DOMAIN-NAME|ID|UUID" },
       { NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL }
@@ -114,6 +160,7 @@ virt_viewer_local_command_line
(GApplication   *gapp,
   gboolean ret = FALSE;
   VirtViewer *self = VIRT_VIEWER(gapp);
   VirtViewerApp *app = VIRT_VIEWER_APP(gapp);
+    const gchar *missing_domkey_fmt = _("\nNo DOMAIN-NAME|ID|UUID 
was specified for '%s'\n\n”);

I would either make an array indexed by the domain_selection_type
with three messages, or write “No argument was specified for %s”. As
is, I find it a bit unreadable. I know this is how it was spelled
before, but still ;-)


   ret = G_APPLICATION_CLASS(virt_viewer_parent_class)-
local_command_line(gapp, args, status);
   if (ret)
@@ -131,15 +178,16 @@ virt_viewer_local_command_line
(GApplication   *gapp,
   }


-    if (opt_waitvm) {
+    if (opt_waitvm || domain_selection_type !=
DOMAIN_SELECTION_NONE) {
       if (!self->priv->domkey) {
-            g_printerr(_("\nNo DOMAIN-NAME|ID|UUID was specified
for '--wait'\n\n"));
+            g_printerr(missing_domkey_fmt,
+                       opt_waitvm ? "--wait" :
domain_selection_to_opt[domain_selection_type]);
           ret = TRUE;
           *status = 1;
           goto end;
       }

-        self->priv->waitvm = TRUE;
+        self->priv->waitvm = opt_waitvm;
   }

   virt_viewer_app_set_direct(app, opt_direct);
@@ -303,24 +351,42 @@ virt_viewer_lookup_domain(VirtViewer *self)
{
   char *end;
   VirtViewerPrivate *priv = self->priv;
-    int id;
   virDomainPtr dom = NULL;
-    unsigned char uuid[16];

   if (priv->domkey == NULL) {
       return NULL;
   }

-    id = strtol(priv->domkey, &end, 10);
-    if (id >= 0 && end && !*end) {
-        dom = virDomainLookupByID(priv->conn, id);
+    switch (domain_selection_type) {
+    default: /* DOMAIN_SELECTION_NONE */

I would add “fallthrough” to the comment as for the next case. GCC
actually takes this as a hint with (see https://gcc.gnu.org/onlinedo
cs/gcc/Warning-Options.html, search for -Wimplicit-fallthrough). We
could also use

   __attribute__ ((fallthrough));

I don’t know if we every build with -Wextra or -Wall?

-Wall, I added “fallthrough” where gcc complained (it didn't complain
about "default" case)

Curious… I would assume it’s more a bug than a feature and add the comment anyways…

tbh I don't understand why it was added to -Wall :)

Because -Wall means “I want to hit a wall everytime there is an update to GCC”. But don’t worry, you can make it worse by using -Wall -Werrors.

Seriously, because fall-through in switch statements is a common mistakes among beginners. Unlike a missing closing parenthesis, brace or ; it is silent and potentially harmful. I ran into a crazy bug due to this last year ;-)



+    case DOMAIN_SELECTION_ID:
+    {
+        long int id = strtol(priv->domkey, &end, 10);
+        if (id >= 0 && end && !*end) {
+            dom = virDomainLookupByID(priv->conn, id);
+        }
+        if (domain_selection_type != DOMAIN_SELECTION_NONE) {
+            break;
+        }
   }
-    if (!dom && virt_viewer_parse_uuid(priv->domkey, uuid) == 0)
{
-        dom = virDomainLookupByUUID(priv->conn, uuid);
+        /* fallthrough */
+    case DOMAIN_SELECTION_UUID:
+    {
+        unsigned char uuid[16];
+        if (!dom && virt_viewer_parse_uuid(priv->domkey, uuid) ==
0) {
+            dom = virDomainLookupByUUID(priv->conn, uuid);
+        }
+        if (domain_selection_type != DOMAIN_SELECTION_NONE) {
+            break;
+        }
   }
-    if (!dom) {
-        dom = virDomainLookupByName(priv->conn, priv->domkey);
+        /* fallthrough */
+    case DOMAIN_SELECTION_NAME:
+        if (!dom) {
+            dom = virDomainLookupByName(priv->conn, priv-
domkey);
+        }
   }
+
   return dom;
}

-- 
2.12.0

_______________________________________________
virt-tools-list mailing list
virt-tools-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/virt-tools-list



_______________________________________________
virt-tools-list mailing list
virt-tools-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/virt-tools-list

_______________________________________________
virt-tools-list mailing list
virt-tools-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/virt-tools-list

[Index of Archives]     [Linux Virtualization]     [KVM Development]     [CentOS Virtualization]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite Forum]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]     [Video 4 Linux]

  Powered by Linux