[Pkg-libvirt-commits] [libguestfs] 13/63: p2v: Support for interface to network map.

Hilko Bengen bengen at moszumanska.debian.org
Fri Oct 3 14:43:24 UTC 2014


This is an automated email from the git hooks/post-receive script.

bengen pushed a commit to annotated tag debian/1%1.27.39-1
in repository libguestfs.

commit 10f6206202b70f1f92807f5d5fed768a3f9e524c
Author: Richard W.M. Jones <rjones at redhat.com>
Date:   Tue Sep 2 16:49:25 2014 +0100

    p2v: Support for interface to network map.
    
    Instead of having all interfaces connect to the "default" network on
    the hypervisor target, you can now create a map of interface to target
    network, either on the kernel command line, eg:
    
      p2v.network=em1:rhevm
      p2v.network=em1:rhevm,em2:management,other
    
    or through the GUI.
---
 p2v/config.c         |  3 ++
 p2v/conversion.c     | 44 +++++++++++++++++++++++-
 p2v/gui.c            | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 p2v/kernel.c         | 11 ++++++
 p2v/p2v.h            |  1 +
 p2v/test-virt-p2v.sh |  2 +-
 p2v/virt-p2v.pod     | 18 ++++++++++
 v2v/TODO             |  1 -
 8 files changed, 168 insertions(+), 6 deletions(-)

diff --git a/p2v/config.c b/p2v/config.c
index f0e9d9c..b4abb40 100644
--- a/p2v/config.c
+++ b/p2v/config.c
@@ -73,6 +73,8 @@ copy_config (struct config *old)
     c->removable = guestfs___copy_string_list (c->removable);
   if (c->interfaces)
     c->interfaces = guestfs___copy_string_list (c->interfaces);
+  if (c->network_map)
+    c->network_map = guestfs___copy_string_list (c->network_map);
   if (c->output)
     c->output = strdup (c->output);
   if (c->output_connection)
@@ -95,6 +97,7 @@ free_config (struct config *c)
   guestfs___free_string_list (c->disks);
   guestfs___free_string_list (c->removable);
   guestfs___free_string_list (c->interfaces);
+  guestfs___free_string_list (c->network_map);
   free (c->output);
   free (c->output_connection);
   free (c->output_format);
diff --git a/p2v/conversion.c b/p2v/conversion.c
index 0f83820..fb17ec0 100644
--- a/p2v/conversion.c
+++ b/p2v/conversion.c
@@ -52,6 +52,7 @@ static int send_quoted (mexp_h *, const char *s);
 static pid_t start_qemu_nbd (int nbd_local_port, const char *device);
 static void cleanup_data_conns (struct data_conn *data_conns, size_t nr);
 static char *generate_libvirt_xml (struct config *, struct data_conn *);
+static const char *map_interface_to_network (struct config *, const char *interface);
 static void debug_parameters (struct config *);
 
 static char *conversion_error;
@@ -582,9 +583,13 @@ generate_libvirt_xml (struct config *config, struct data_conn *data_conns)
 
       if (config->interfaces) {
         for (i = 0; config->interfaces[i] != NULL; ++i) {
+          const char *target_network;
           CLEANUP_FREE char *mac_filename = NULL;
           CLEANUP_FREE char *mac = NULL;
 
+          target_network =
+            map_interface_to_network (config, config->interfaces[i]);
+
           if (asprintf (&mac_filename, "/sys/class/net/%s/address",
                         config->interfaces[i]) == -1) {
             perror ("asprintf");
@@ -600,7 +605,7 @@ generate_libvirt_xml (struct config *config, struct data_conn *data_conns)
           start_element ("interface") {
             attribute ("type", "network");
             start_element ("source") {
-              attribute ("network", "default");
+              attribute ("network", target_network);
             } end_element ();
             start_element ("target") {
               attribute ("dev", config->interfaces[i]);
@@ -631,6 +636,37 @@ generate_libvirt_xml (struct config *config, struct data_conn *data_conns)
   return ret;
 }
 
+/* Using config->network_map, map the interface to a target network
+ * name.  If no map is found, return "default".  See virt-p2v(1)
+ * documentation of "p2v.network" for how the network map works.
+ *
+ * Note this returns a static string which is only valid as long as
+ * config->network_map is not freed.
+ */
+static const char *
+map_interface_to_network (struct config *config, const char *interface)
+{
+  size_t i, len;
+
+  if (config->network_map == NULL)
+    return "default";
+
+  for (i = 0; config->network_map[i] != NULL; ++i) {
+    /* The default map maps everything. */
+    if (strchr (config->network_map[i], ':') == NULL)
+      return config->network_map[i];
+
+    /* interface: ? */
+    len = strlen (interface);
+    if (STRPREFIX (config->network_map[i], interface) &&
+        config->network_map[i][len] == ':')
+      return &config->network_map[i][len+1];
+  }
+
+  /* No mapping found. */
+  return "default";
+}
+
 static void
 debug_parameters (struct config *config)
 {
@@ -674,6 +710,12 @@ debug_parameters (struct config *config)
       fprintf (stderr, " %s", config->interfaces[i]);
   }
   fprintf (stderr, "\n");
+  fprintf (stderr, "network map  . .  ");
+  if (config->network_map != NULL) {
+    for (i = 0; config->network_map[i] != NULL; ++i)
+      fprintf (stderr, " %s", config->network_map[i]);
+  }
+  fprintf (stderr, "\n");
   fprintf (stderr, "output . . . . .   %s\n",
            config->output ? config->output : "none");
   fprintf (stderr, "output alloc . .   %d\n", config->output_allocation);
diff --git a/p2v/gui.c b/p2v/gui.c
index 0f80d63..430b18d 100644
--- a/p2v/gui.c
+++ b/p2v/gui.c
@@ -360,6 +360,7 @@ static void populate_disks (GtkTreeView *disks_list);
 static void populate_removable (GtkTreeView *removable_list);
 static void populate_interfaces (GtkTreeView *interfaces_list);
 static void toggled (GtkCellRendererToggle *cell, gchar *path_str, gpointer data);
+static void network_edited_callback (GtkCellRendererToggle *cell, gchar *path_str, gchar *new_text, gpointer data);
 static void set_disks_from_ui (struct config *);
 static void set_removable_from_ui (struct config *);
 static void set_interfaces_from_ui (struct config *);
@@ -384,6 +385,7 @@ enum {
 enum {
   INTERFACES_COL_CONVERT = 0,
   INTERFACES_COL_DEVICE,
+  INTERFACES_COL_NETWORK,
   NUM_INTERFACES_COLS,
 };
 
@@ -766,18 +768,25 @@ static void
 populate_interfaces (GtkTreeView *interfaces_list)
 {
   GtkListStore *interfaces_store;
-  GtkCellRenderer *interfaces_col_convert, *interfaces_col_device;
+  GtkCellRenderer *interfaces_col_convert, *interfaces_col_device,
+    *interfaces_col_network;
   GtkTreeIter iter;
   size_t i;
 
   interfaces_store = gtk_list_store_new (NUM_INTERFACES_COLS,
-                                         G_TYPE_BOOLEAN, G_TYPE_STRING);
+                                         G_TYPE_BOOLEAN, G_TYPE_STRING,
+                                         G_TYPE_STRING);
   if (all_interfaces) {
     for (i = 0; all_interfaces[i] != NULL; ++i) {
       gtk_list_store_append (interfaces_store, &iter);
       gtk_list_store_set (interfaces_store, &iter,
-                          INTERFACES_COL_CONVERT, TRUE,
+                          /* Only convert the first interface.  As
+                           * they are sorted, this is usually the
+                           * physical interface.
+                           */
+                          INTERFACES_COL_CONVERT, i == 0,
                           INTERFACES_COL_DEVICE, all_interfaces[i],
+                          INTERFACES_COL_NETWORK, "default",
                           -1);
     }
   }
@@ -798,9 +807,20 @@ populate_interfaces (GtkTreeView *interfaces_list)
                                                interfaces_col_device,
                                                "text", INTERFACES_COL_DEVICE,
                                                NULL);
+  interfaces_col_network = gtk_cell_renderer_text_new ();
+  gtk_tree_view_insert_column_with_attributes (interfaces_list,
+                                               -1,
+                                               _("Connect to virtual network"),
+                                               interfaces_col_network,
+                                               "text", INTERFACES_COL_NETWORK,
+                                               NULL);
 
   g_signal_connect (interfaces_col_convert, "toggled",
                     G_CALLBACK (toggled), interfaces_store);
+
+  g_object_set (interfaces_col_network, "editable", TRUE, NULL);
+  g_signal_connect (interfaces_col_network, "edited",
+                    G_CALLBACK (network_edited_callback), interfaces_store);
 }
 
 static void
@@ -819,6 +839,25 @@ toggled (GtkCellRendererToggle *cell, gchar *path_str, gpointer data)
 }
 
 static void
+network_edited_callback (GtkCellRendererToggle *cell, gchar *path_str,
+                         gchar *new_text, gpointer data)
+{
+  GtkTreeModel *model = data;
+  GtkTreePath *path;
+  GtkTreeIter iter;
+
+  if (new_text == NULL || STREQ (new_text, ""))
+    return;
+
+  path = gtk_tree_path_new_from_string (path_str);
+
+  gtk_tree_model_get_iter (model, &iter, path);
+  gtk_list_store_set (GTK_LIST_STORE (model), &iter,
+                      INTERFACES_COL_NETWORK, new_text, -1);
+  gtk_tree_path_free (path);
+}
+
+static void
 set_from_ui_generic (char **all, char ***ret, GtkTreeView *list)
 {
   GtkTreeModel *model;
@@ -877,6 +916,54 @@ set_interfaces_from_ui (struct config *config)
                        GTK_TREE_VIEW (interfaces_list));
 }
 
+static void
+set_network_map_from_ui (struct config *config)
+{
+  GtkTreeView *list;
+  GtkTreeModel *model;
+  GtkTreeIter iter;
+  gboolean b;
+  const char *s;
+  size_t i, j;
+
+  if (all_interfaces == NULL) {
+    guestfs___free_string_list (config->network_map);
+    config->network_map = NULL;
+    return;
+  }
+
+  list = GTK_TREE_VIEW (interfaces_list);
+  model = gtk_tree_view_get_model (list);
+
+  guestfs___free_string_list (config->network_map);
+  config->network_map =
+    malloc ((1 + guestfs___count_strings (all_interfaces))
+            * sizeof (char *));
+  if (config->network_map == NULL) {
+    perror ("malloc");
+    exit (EXIT_FAILURE);
+  }
+  i = j = 0;
+
+  b = gtk_tree_model_get_iter_first (model, &iter);
+  while (b) {
+    gtk_tree_model_get (model, &iter, INTERFACES_COL_NETWORK, &s, -1);
+    if (s) {
+      assert (all_interfaces[i] != NULL);
+      if (asprintf (&config->network_map[j], "%s:%s",
+                    all_interfaces[i], s) == -1) {
+        perror ("asprintf");
+        exit (EXIT_FAILURE);
+      }
+      ++j;
+    }
+    b = gtk_tree_model_iter_next (model, &iter);
+    ++i;
+  }
+
+  config->network_map[j] = NULL;
+}
+
 /* The conversion dialog Back button has been clicked. */
 static void
 conversion_back_clicked (GtkWidget *w, gpointer data)
@@ -1064,6 +1151,7 @@ start_conversion_clicked (GtkWidget *w, gpointer data)
   /* List of removable media and network interfaces. */
   set_removable_from_ui (config);
   set_interfaces_from_ui (config);
+  set_network_map_from_ui (config);
 
   /* Output selection. */
   free (config->output);
diff --git a/p2v/kernel.c b/p2v/kernel.c
index 9317bb5..e29355d 100644
--- a/p2v/kernel.c
+++ b/p2v/kernel.c
@@ -161,6 +161,17 @@ kernel_configuration (struct config *config, const char *cmdline)
     config->interfaces = guestfs___split_string (',', t);
   }
 
+  r = strstr (cmdline, "p2v.network=");
+  if (r) {
+    CLEANUP_FREE char *t;
+
+    r += 5+7;
+    len = strcspn (r, " ");
+    t = strndup (r, len);
+    guestfs___free_string_list (config->network_map);
+    config->network_map = guestfs___split_string (',', t);
+  }
+
   r = strstr (cmdline, "p2v.o=");
   if (r) {
     r += 5+1;
diff --git a/p2v/p2v.h b/p2v/p2v.h
index 2622adb..3ada7b6 100644
--- a/p2v/p2v.h
+++ b/p2v/p2v.h
@@ -65,6 +65,7 @@ struct config {
   char **disks;
   char **removable;
   char **interfaces;
+  char **network_map;
   char *output;
   int output_allocation;
   char *output_connection;
diff --git a/p2v/test-virt-p2v.sh b/p2v/test-virt-p2v.sh
index 34a5823..2f66c7c 100755
--- a/p2v/test-virt-p2v.sh
+++ b/p2v/test-virt-p2v.sh
@@ -59,7 +59,7 @@ export PATH=$d:$PATH
 # under test (because of the ./run script).
 
 # The Linux kernel command line.
-cmdline="p2v.server=localhost p2v.name=windows p2v.debug p2v.disks=$f p2v.o=local p2v.os=$d"
+cmdline="p2v.server=localhost p2v.name=windows p2v.debug p2v.disks=$f p2v.o=local p2v.os=$d p2v.network=em1:wired,other"
 
 ./virt-p2v --cmdline="$cmdline"
 
diff --git a/p2v/virt-p2v.pod b/p2v/virt-p2v.pod
index d8e96b9..763c54a 100644
--- a/p2v/virt-p2v.pod
+++ b/p2v/virt-p2v.pod
@@ -161,6 +161,24 @@ Note that the content of removable media is never copied over.
 A list of network interfaces to convert.  The default is to create
 virtual network interfaces for every physical network interface found.
 
+=item B<p2v.network=interface:target,...>
+
+Controls how network interfaces are connected to virtual networks on
+the target hypervisor.  The default is to connect all network
+interfaces to the target C<default> network.
+
+You give a comma-separated list of C<interface:target> pairs, plus
+optionally a default target.  For example:
+
+ p2v.network=em1:rhevm
+
+maps interface C<em1> to target network C<rhevm>.
+
+ p2v.network=em1:rhevm,em2:management,other
+
+maps interface C<em1> to C<rhevm>, and C<em2> to C<management>, and
+any other interface that is found to C<other>.
+
 =item B<p2v.o=[libvirt|local|...]>
 
 Set the output mode.  This is the same as the virt-v2v I<-o> option.
diff --git a/v2v/TODO b/v2v/TODO
index 15ec931..c7fb6fa 100644
--- a/v2v/TODO
+++ b/v2v/TODO
@@ -11,7 +11,6 @@ p2v:
  - vmlinuz + initrd? - if not possible, remove from man page
  - PXE boot
  - network dialog and network configuration
- - GUI controls for network mapping
  - why is the Back button insensitive?
 
 p2v/gui.c:  /* XXX It would be nice not to have to set this explicitly, but

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-libvirt/libguestfs.git



More information about the Pkg-libvirt-commits mailing list