Laszlo Ersek
2023-Jan-30  14:22 UTC
[Libguestfs] [p2v PATCH 00/11] Expose virt-v2v's "-oo"; re-enable openstack
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1792141 Let the user pass "-oo" options from the kernel cmdline and from the GUI to virt-v2v. This is primarily useful with the OpenStack output mode, so reenable that mode. Cc: Alban Lecorps <alban.lecorps at ubisoft.com> Laszlo Alban Lecorps (1): Introduce "p2v.output.misc" for passing "-oo" options to virt-v2v Laszlo Ersek (10): test-virt-p2v-cmdline: turn option list into a shell array guestfs-utils: import guestfs_int_join_strings() gui: factor out entry_text_dup() gui: factor out tgl_btn_is_act() gui: flatten get_phys_topo_from_conv_dlg() gui: wrap overlong function declaration lines gui: wrap string literals gui: expose "p2v.output.misc" (-oo) Reenable the OpenStack output mode make-kickstart: add URLs for RHEL-9 conversion.c | 9 ++ generate-p2v-config.pl | 10 ++ gui.c | 168 ++++++++++++++++---- libguestfs/guestfs-utils.c | 35 ++++ libguestfs/guestfs-utils.h | 1 + ssh.c | 5 +- test-virt-p2v-cmdline.sh | 24 ++- virt-p2v-make-kickstart.in | 13 ++ virt-p2v.pod | 2 + 9 files changed, 230 insertions(+), 37 deletions(-)
Laszlo Ersek
2023-Jan-30  14:22 UTC
[Libguestfs] [p2v PATCH 01/11] test-virt-p2v-cmdline: turn option list into a shell array
The argument for virt-p2v's "--cmdline" option has grown huge.
Break it to
multiple lines. That's easiest to do with a shell array.
Cc: Alban Lecorps <alban.lecorps at ubisoft.com>
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1792141
Signed-off-by: Laszlo Ersek <lersek at redhat.com>
---
 test-virt-p2v-cmdline.sh | 22 +++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/test-virt-p2v-cmdline.sh b/test-virt-p2v-cmdline.sh
index 79c3061b1e7c..7d5434cf8428 100755
--- a/test-virt-p2v-cmdline.sh
+++ b/test-virt-p2v-cmdline.sh
@@ -26,7 +26,27 @@ out=test-virt-p2v-cmdline.out
 rm -f $out
 
 # The Linux kernel command line.
-$VG virt-p2v --cmdline='p2v.server=localhost p2v.port=123 p2v.username=user
p2v.password=secret p2v.skip_test_connection p2v.name=test p2v.vcpu.cores=4
p2v.memory=1G p2v.disks=sda,sdb,sdc p2v.removable=sdd p2v.interfaces=eth0,eth1
p2v.o=local p2v.oa=sparse p2v.oc=qemu:///session p2v.of=raw p2v.os=/var/tmp
p2v.network=em1:wired,other p2v.dump_config_and_exit' > $out
+P2V_OPTS=(
+  p2v.server=localhost
+  p2v.port=123
+  p2v.username=user
+  p2v.password=secret
+  p2v.skip_test_connection
+  p2v.name=test
+  p2v.vcpu.cores=4
+  p2v.memory=1G
+  p2v.disks=sda,sdb,sdc
+  p2v.removable=sdd
+  p2v.interfaces=eth0,eth1
+  p2v.o=local
+  p2v.oa=sparse
+  p2v.oc=qemu:///session
+  p2v.of=raw
+  p2v.os=/var/tmp
+  p2v.network=em1:wired,other
+  p2v.dump_config_and_exit
+)
+$VG virt-p2v --cmdline="${P2V_OPTS[*]}" > $out
 
 # For debugging purposes.
 cat $out
Laszlo Ersek
2023-Jan-30  14:22 UTC
[Libguestfs] [p2v PATCH 02/11] Introduce "p2v.output.misc" for passing "-oo" options to virt-v2v
From: Alban Lecorps <alban.lecorps at ubisoft.com>
The "-oo" option will be useful primarily for the openstack output
mode
(currently disabled, from commit b74c126629e3, "Ignore 'openstack'
driver", 2020-03-16).
Use a ConfigStringList knob for "-oo", and for each OPTION=VALUE
element
in that list, create a separate "-oo OPTION=VALUE" option. Do this
because
there are too many "-oo" options, and because they are
output-dependent,
and because even virt-v2v "blindly" forwards some of those (such as
"-oo
os-*=*" for openstack).
The "p2v.oo" shorthand is not needed for compatibility, but it's
still a
good idea for user convenience.
(Various tweaks, documentation, and test case update, by Laszlo.)
Cc: Alban Lecorps <alban.lecorps at ubisoft.com>
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1792141
Signed-off-by: Laszlo Ersek <lersek at redhat.com>
---
 generate-p2v-config.pl   | 10 ++++++++++
 conversion.c             |  9 +++++++++
 test-virt-p2v-cmdline.sh |  2 ++
 3 files changed, 21 insertions(+)
diff --git a/generate-p2v-config.pl b/generate-p2v-config.pl
index 47487f7b0f35..5e1d8519bd91 100755
--- a/generate-p2v-config.pl
+++ b/generate-p2v-config.pl
@@ -147,6 +147,7 @@ my @fields = [
       ConfigString->new(name => 'connection'),
       ConfigString->new(name => 'format'),
       ConfigString->new(name => 'storage'),
+      ConfigStringList->new(name => 'misc'),
     ],
   ),
 ];
@@ -168,6 +169,7 @@ my @cmdline_aliases = (
   ["p2v.output.connection", "p2v.oc"],
   ["p2v.output.format",     "p2v.of"],
   ["p2v.output.storage",    "p2v.os"],
+  ["p2v.output.misc",       "p2v.oo"],
 );
 
 # Some config entries are not exposed on the kernel command line.
@@ -379,6 +381,14 @@ option.  See L<virt-v2v(1)/OPTIONS>.
 
 If not specified, the default is F</var/tmp> (on the conversion
server).",
   ),
+  "p2v.output.misc" => manual_entry->new(
+    shortopt => "OPTION=VALUE,...",
+    description => "
+Set miscellaneous output option(s) related to the selected output mode.
+This is the same as the virt-v2v I<-oo> option; each
C<OPTION=VALUE>
+element in the list will be turned into a separate I<-oo OPTION=VALUE>
+option on the virt-v2v command line.  See L<virt-v2v(1)/OPTIONS>.",
+  ),
 );
 
 # Clean up the program name.
diff --git a/conversion.c b/conversion.c
index b9af47deda74..cc6387c88af8 100644
--- a/conversion.c
+++ b/conversion.c
@@ -526,6 +526,15 @@ generate_wrapper_script (struct config *config, const char
*remote_dir,
     print_quoted (fp, config->output.storage);
   }
 
+  if (config->output.misc) { /* -oo */
+    size_t i;
+
+    for (i = 0; config->output.misc[i]; ++i) {
+      fprintf (fp, " -oo ");
+      print_quoted (fp, config->output.misc[i]);
+    }
+  }
+
   fprintf (fp, " --root first");
   fprintf (fp, " physical.xml");
   fprintf (fp, " </dev/null");  /* no stdin */
diff --git a/test-virt-p2v-cmdline.sh b/test-virt-p2v-cmdline.sh
index 7d5434cf8428..bcec86089b00 100755
--- a/test-virt-p2v-cmdline.sh
+++ b/test-virt-p2v-cmdline.sh
@@ -43,6 +43,7 @@ P2V_OPTS=(
   p2v.oc=qemu:///session
   p2v.of=raw
   p2v.os=/var/tmp
+  p2v.oo=opt1=val1,opt2=val2
   p2v.network=em1:wired,other
   p2v.dump_config_and_exit
 )
@@ -69,5 +70,6 @@ grep "^output\.allocation.*sparse" $out
 grep "^output\.connection.*qemu:///session" $out
 grep "^output\.format.*raw" $out
 grep "^output\.storage.*/var/tmp" $out
+grep "^output\.misc.*opt1=val1 opt2=val2" $out
 
 rm $out
Laszlo Ersek
2023-Jan-30  14:22 UTC
[Libguestfs] [p2v PATCH 03/11] guestfs-utils: import guestfs_int_join_strings()
Copy the guestfs_int_join_strings() function from libguestfs-common @
3253cd99d135 ("mldrivers: Add support for reading Windows drivers from
DriverDatabase", 2023-01-26).
Cc: Alban Lecorps <alban.lecorps at ubisoft.com>
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1792141
Signed-off-by: Laszlo Ersek <lersek at redhat.com>
---
 libguestfs/guestfs-utils.h |  1 +
 libguestfs/guestfs-utils.c | 35 ++++++++++++++++++++
 2 files changed, 36 insertions(+)
diff --git a/libguestfs/guestfs-utils.h b/libguestfs/guestfs-utils.h
index d5557a49680c..62402ccdd202 100644
--- a/libguestfs/guestfs-utils.h
+++ b/libguestfs/guestfs-utils.h
@@ -48,6 +48,7 @@
 extern void guestfs_int_free_string_list (char **);
 extern size_t guestfs_int_count_strings (char *const *);
 extern char **guestfs_int_copy_string_list (char *const *);
+extern char *guestfs_int_join_strings (const char *sep, char *const *);
 extern char **guestfs_int_split_string (char sep, const char *);
 extern int guestfs_int_random_string (char *ret, size_t len);
 extern char *guestfs_int_drive_name (size_t index, char *ret);
diff --git a/libguestfs/guestfs-utils.c b/libguestfs/guestfs-utils.c
index 505c9f6c0a32..9f0b012d2968 100644
--- a/libguestfs/guestfs-utils.c
+++ b/libguestfs/guestfs-utils.c
@@ -77,6 +77,41 @@ guestfs_int_copy_string_list (char *const *argv)
   return ret;
 }
 
+char *
+guestfs_int_join_strings (const char *sep, char *const *argv)
+{
+  size_t i, len, seplen, rlen;
+  char *r;
+
+  seplen = strlen (sep);
+
+  len = 0;
+  for (i = 0; argv[i] != NULL; ++i) {
+    if (i > 0)
+      len += seplen;
+    len += strlen (argv[i]);
+  }
+  len++; /* for final \0 */
+
+  r = malloc (len);
+  if (r == NULL)
+    return NULL;
+
+  rlen = 0;
+  for (i = 0; argv[i] != NULL; ++i) {
+    if (i > 0) {
+      memcpy (&r[rlen], sep, seplen);
+      rlen += seplen;
+    }
+    len = strlen (argv[i]);
+    memcpy (&r[rlen], argv[i], len);
+    rlen += len;
+  }
+  r[rlen] = '\0';
+
+  return r;
+}
+
 /**
  * Split string at separator character C<sep>, returning the list of
  * strings.  Returns C<NULL> on memory allocation failure.
Laszlo Ersek
2023-Jan-30  14:22 UTC
[Libguestfs] [p2v PATCH 04/11] gui: factor out entry_text_dup()
Some of the overlong lines in "gui.c" originate from function calls
like
  config->whatever = strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
These are hard to wrap -- we generally break the second and further
arguments in a function call to new lines, and start those new lines
aligned with the opening parenthesis of the function call. However, in the
above expression, each function only takes one parameter -- the problem is
the deep nesting, and our wrapping style generally strives to reflect
nesting.
Extract the expression to a small (somewhat accidental) helper function.
This function is then used from multiple dialogs (the connection dialog
and the conversion dialog).
Cc: Alban Lecorps <alban.lecorps at ubisoft.com>
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1792141
Signed-off-by: Laszlo Ersek <lersek at redhat.com>
---
 gui.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/gui.c b/gui.c
index 3068c97c3ba3..5c53883ff2ae 100644
--- a/gui.c
+++ b/gui.c
@@ -150,6 +150,16 @@ gui_conversion (struct config *config,
   gtk_main ();
 }
 
+/**
+ * Trivial helper (shorthand) function for duplicating the contents of a
+ * GTK_ENTRY.
+ */
+static char *
+entry_text_dup (GtkWidget *entry)
+{
+  return strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
+}
+
 /*----------------------------------------------------------------------*/
 /* Connection dialog. */
 
@@ -426,7 +436,7 @@ test_connection_clicked (GtkWidget *w, gpointer data)
 
   /* Get the fields from the various widgets. */
   free (config->remote.server);
-  config->remote.server = strdup (gtk_entry_get_text (GTK_ENTRY
(server_entry)));
+  config->remote.server = entry_text_dup (server_entry);
   if (STREQ (config->remote.server, "")) {
     gtk_label_set_text (GTK_LABEL (spinner_message),
                         _("error: No conversion server given."));
@@ -442,7 +452,7 @@ test_connection_clicked (GtkWidget *w, gpointer data)
     errors++;
   }
   free (config->auth.username);
-  config->auth.username = strdup (gtk_entry_get_text (GTK_ENTRY
(username_entry)));
+  config->auth.username = entry_text_dup (username_entry);
   if (STREQ (config->auth.username, "")) {
     gtk_label_set_text (GTK_LABEL (spinner_message),
                         _("error: No user name.  If in doubt, use
\"root\"."));
@@ -450,7 +460,7 @@ test_connection_clicked (GtkWidget *w, gpointer data)
     errors++;
   }
   free (config->auth.password);
-  config->auth.password = strdup (gtk_entry_get_text (GTK_ENTRY
(password_entry)));
+  config->auth.password = entry_text_dup (password_entry);
 
   free (config->auth.identity.url);
   identity_str = gtk_entry_get_text (GTK_ENTRY (identity_entry));
@@ -2064,7 +2074,7 @@ start_conversion_clicked (GtkWidget *w, gpointer data)
 
   /* Unpack dialog fields and check them. */
   free (config->guestname);
-  config->guestname = strdup (gtk_entry_get_text (GTK_ENTRY
(guestname_entry)));
+  config->guestname = entry_text_dup (guestname_entry);
 
   if (STREQ (config->guestname, "")) {
     dlg = gtk_message_dialog_new (GTK_WINDOW (conv_dlg),
Laszlo Ersek
2023-Jan-30  14:22 UTC
[Libguestfs] [p2v PATCH 05/11] gui: factor out tgl_btn_is_act()
Repeat the previous refactoring for
  gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (toggle_button))
which is another source of overlong lines in "gui.c". The new function
is
again used in both the connection dialog and the conversion dialog.
Cc: Alban Lecorps <alban.lecorps at ubisoft.com>
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1792141
Signed-off-by: Laszlo Ersek <lersek at redhat.com>
---
 gui.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/gui.c b/gui.c
index 5c53883ff2ae..3c0f21ca87d0 100644
--- a/gui.c
+++ b/gui.c
@@ -160,6 +160,16 @@ entry_text_dup (GtkWidget *entry)
   return strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
 }
 
+/**
+ * Trivial helper (shorthand) function for getting the active/inactive state
+ * of a GTK_TOGGLE_BUTTON.
+ */
+static bool
+tgl_btn_is_act (GtkWidget *toggle_button)
+{
+  return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (toggle_button));
+}
+
 /*----------------------------------------------------------------------*/
 /* Connection dialog. */
 
@@ -360,7 +370,7 @@ username_changed_callback (GtkWidget *w, gpointer data)
 
   str = gtk_entry_get_text (GTK_ENTRY (username_entry));
   username_is_root = str != NULL && STREQ (str, "root");
-  sudo_is_set = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (sudo_button));
+  sudo_is_set = tgl_btn_is_act (sudo_button);
 
   /* The sudo button is sensitive if:
    * - The username is not "root", or
@@ -470,7 +480,7 @@ test_connection_clicked (GtkWidget *w, gpointer data)
     config->auth.identity.url = NULL;
   config->auth.identity.file_needs_update = 1;
 
-  config->auth.sudo = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
(sudo_button));
+  config->auth.sudo = tgl_btn_is_act (sudo_button);
 
   if (errors)
     return;
@@ -1713,7 +1723,7 @@ vcpus_or_memory_check_callback (GtkWidget *w, gpointer
data)
 static bool
 get_phys_topo_from_conv_dlg (void)
 {
-  return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (vcpu_topo));
+  return tgl_btn_is_act (vcpu_topo);
 }
 
 static int
Laszlo Ersek
2023-Jan-30  14:22 UTC
[Libguestfs] [p2v PATCH 06/11] gui: flatten get_phys_topo_from_conv_dlg()
At this point, the get_phys_topo_from_conv_dlg() function has become
useless -- it doesn't save any work, so flatten (inline) its definition at
all call sites, and remove the declaration and the definition.
Cc: Alban Lecorps <alban.lecorps at ubisoft.com>
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1792141
Signed-off-by: Laszlo Ersek <lersek at redhat.com>
---
 gui.c | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)
diff --git a/gui.c b/gui.c
index 3c0f21ca87d0..e29a9534a195 100644
--- a/gui.c
+++ b/gui.c
@@ -686,7 +686,6 @@ static void start_conversion_clicked (GtkWidget *w, gpointer
data);
 static void vcpu_topo_toggled (GtkWidget *w, gpointer data);
 static void vcpus_or_memory_check_callback (GtkWidget *w, gpointer data);
 static void notify_ui_callback (int type, const char *data);
-static bool get_phys_topo_from_conv_dlg (void);
 static int get_vcpus_from_conv_dlg (void);
 static uint64_t get_memory_from_conv_dlg (void);
 
@@ -1662,7 +1661,7 @@ vcpu_topo_toggled (GtkWidget *w, gpointer data)
   unsigned vcpus;
   char vcpus_str[64];
 
-  phys_topo = get_phys_topo_from_conv_dlg ();
+  phys_topo = tgl_btn_is_act (vcpu_topo);
   if (phys_topo) {
     struct cpu_topo topo;
 
@@ -1720,12 +1719,6 @@ vcpus_or_memory_check_callback (GtkWidget *w, gpointer
data)
     gtk_label_set_text (GTK_LABEL (target_warning_label), "");
 }
 
-static bool
-get_phys_topo_from_conv_dlg (void)
-{
-  return tgl_btn_is_act (vcpu_topo);
-}
-
 static int
 get_vcpus_from_conv_dlg (void)
 {
@@ -2099,7 +2092,7 @@ start_conversion_clicked (GtkWidget *w, gpointer data)
     return;
   }
 
-  config->vcpu.phys_topo = get_phys_topo_from_conv_dlg ();
+  config->vcpu.phys_topo = tgl_btn_is_act (vcpu_topo);
   config->vcpu.cores = get_vcpus_from_conv_dlg ();
   config->memory = get_memory_from_conv_dlg ();
Laszlo Ersek
2023-Jan-30  14:22 UTC
[Libguestfs] [p2v PATCH 07/11] gui: wrap overlong function declaration lines
Cc: Alban Lecorps <alban.lecorps at ubisoft.com>
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1792141
Signed-off-by: Laszlo Ersek <lersek at redhat.com>
---
 gui.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/gui.c b/gui.c
index e29a9534a195..f3dbea7d725a 100644
--- a/gui.c
+++ b/gui.c
@@ -672,8 +672,13 @@ static void populate_removable_store (GtkListStore
*removable_store,
 static void populate_removable (GtkTreeView *removable_list_p,
                                 const char * const *removable);
 static void populate_interfaces (GtkTreeView *interfaces_list_p);
-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 toggled (GtkCellRendererToggle *cell,
+                     gchar *path_str,
+                     gpointer data);
+static void network_edited_callback (GtkCellRendererToggle *cell,
+                                     gchar *path_str,
+                                     gchar *new_text,
+                                     gpointer data);
 static gboolean maybe_identify_click (GtkWidget *interfaces_list_p,
                                       GdkEventButton *event,
                                       gpointer data);
@@ -1755,10 +1760,14 @@ static void *start_conversion_thread (void *data);
 static gboolean conversion_error (gpointer user_data);
 static gboolean conversion_finished (gpointer user_data);
 static void cancel_conversion_dialog (GtkWidget *w, gpointer data);
-static void activate_action (GSimpleAction *action, GVariant *parameter,
gpointer user_data);
+static void activate_action (GSimpleAction *action,
+                             GVariant *parameter,
+                             gpointer user_data);
 static void shutdown_clicked (GtkWidget *w, gpointer data);
 static void reboot_clicked (GtkWidget *w, gpointer data);
-static gboolean close_running_dialog (GtkWidget *w, GdkEvent *event, gpointer
data);
+static gboolean close_running_dialog (GtkWidget *w,
+                                      GdkEvent *event,
+                                      gpointer data);
 
 static const GActionEntry shutdown_actions[] = {
   { .name = "shutdown", .activate = activate_action },
Laszlo Ersek
2023-Jan-30  14:22 UTC
[Libguestfs] [p2v PATCH 08/11] gui: wrap string literals
In "gui.c", we use many long string literals, for labels, warnings,
tooltips etc. Wrap them so the source code never exceeds 80 characters in
width.
Cc: Alban Lecorps <alban.lecorps at ubisoft.com>
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1792141
Signed-off-by: Laszlo Ersek <lersek at redhat.com>
---
 gui.c | 58 ++++++++++++++++----
 1 file changed, 46 insertions(+), 12 deletions(-)
diff --git a/gui.c b/gui.c
index f3dbea7d725a..f86cab649785 100644
--- a/gui.c
+++ b/gui.c
@@ -215,7 +215,8 @@ create_connection_dialog (struct config *config)
   gtk_window_set_resizable (GTK_WINDOW (conn_dlg), FALSE);
 
   /* The main dialog area. */
-  intro = gtk_label_new (_("Connect to a virt-v2v conversion server over
SSH:"));
+  intro = gtk_label_new (_("Connect to a virt-v2v conversion server over
"
+                           "SSH:"));
   gtk_label_set_line_wrap (GTK_LABEL (intro), TRUE);
   set_padding (intro, 10, 10);
 
@@ -457,7 +458,8 @@ test_connection_clicked (GtkWidget *w, gpointer data)
   if (sscanf (port_str, "%d", &config->remote.port) != 1 ||
       config->remote.port <= 0 || config->remote.port >= 65536) {
     gtk_label_set_text (GTK_LABEL (spinner_message),
-                        _("error: Invalid port number. If in doubt, use
\"22\"."));
+                        _("error: Invalid port number. If in doubt, use
"
+                          "\"22\"."));
     gtk_widget_grab_focus (port_entry);
     errors++;
   }
@@ -838,7 +840,17 @@ create_conversion_dialog (struct config *config,
   set_alignment (o_label, 1., 0.5);
   o_combo = gtk_combo_box_text_new ();
   gtk_label_set_mnemonic_widget (GTK_LABEL (o_label), o_combo);
-  gtk_widget_set_tooltip_markup (o_combo, _("<b>libvirt</b>
means send the converted guest to libvirt-managed KVM on the conversion server. 
<b>local</b> means put it in a directory on the conversion server. 
<b>rhv</b> means write it to RHV-M/oVirt.  <b>glance</b>
means write it to OpenStack Glance.  See the virt-v2v(1) manual page for more
information about output options."));
+  gtk_widget_set_tooltip_markup (o_combo,
+                                 _("<b>libvirt</b> means send
the converted "
+                                   "guest to libvirt-managed KVM on the
"
+                                   "conversion server.  "
+                                   "<b>local</b> means put it
in a directory "
+                                   "on the conversion server.  "
+                                   "<b>rhv</b> means write it
to RHV-M/oVirt.  "
+                                   "<b>glance</b> means write
it to OpenStack "
+                                   "Glance.  "
+                                   "See the virt-v2v(1) manual page for
more "
+                                   "information about output
options."));
   repopulate_output_combo (config);
   table_attach (output_tbl, o_combo,
                 1, 2, row, GTK_FILL, GTK_FILL, 1, 1);
@@ -850,7 +862,12 @@ create_conversion_dialog (struct config *config,
   set_alignment (oc_label, 1., 0.5);
   oc_entry = gtk_entry_new ();
   gtk_label_set_mnemonic_widget (GTK_LABEL (oc_label), oc_entry);
-  gtk_widget_set_tooltip_markup (oc_entry, _("For
<b>libvirt</b> only, the libvirt connection URI, or leave blank to
add the guest to the default libvirt instance on the conversion server.  For
others, leave this field blank."));
+  gtk_widget_set_tooltip_markup (oc_entry,
+                                 _("For <b>libvirt</b> only,
the libvirt "
+                                   "connection URI, or leave blank to add
the "
+                                   "guest to the default libvirt instance
on "
+                                   "the conversion server.  "
+                                   "For others, leave this field
blank."));
   if (config->output.connection != NULL)
     gtk_entry_set_text (GTK_ENTRY (oc_entry), config->output.connection);
   table_attach (output_tbl, oc_entry,
@@ -863,7 +880,12 @@ create_conversion_dialog (struct config *config,
   set_alignment (os_label, 1., 0.5);
   os_entry = gtk_entry_new ();
   gtk_label_set_mnemonic_widget (GTK_LABEL (os_label), os_entry);
-  gtk_widget_set_tooltip_markup (os_entry, _("For
<b>local</b>, put the directory name on the conversion server.  For
<b>rhv</b>, put the Export Storage Domain (server:/mountpoint).  For
others, leave this field blank."));
+  gtk_widget_set_tooltip_markup (os_entry,
+                                 _("For <b>local</b>, put the
directory name "
+                                   "on the conversion server.  "
+                                   "For <b>rhv</b>, put the
Export Storage "
+                                   "Domain (server:/mountpoint).  "
+                                   "For others, leave this field
blank."));
   if (config->output.storage != NULL)
     gtk_entry_set_text (GTK_ENTRY (os_entry), config->output.storage);
   table_attach (output_tbl, os_entry,
@@ -876,7 +898,10 @@ create_conversion_dialog (struct config *config,
   set_alignment (of_label, 1., 0.5);
   of_entry = gtk_entry_new ();
   gtk_label_set_mnemonic_widget (GTK_LABEL (of_label), of_entry);
-  gtk_widget_set_tooltip_markup (of_entry, _("The output disk format,
typically <b>raw</b> or <b>qcow2</b>.  If blank,
defaults to <b>raw</b>."));
+  gtk_widget_set_tooltip_markup (of_entry,
+                                 _("The output disk format, typically
"
+                                   "<b>raw</b> or
<b>qcow2</b>.  "
+                                   "If blank, defaults to
<b>raw</b>."));
   if (config->output.format != NULL)
     gtk_entry_set_text (GTK_ENTRY (of_entry), config->output.format);
   table_attach (output_tbl, of_entry,
@@ -947,7 +972,9 @@ create_conversion_dialog (struct config *config,
   /* See maybe_identify_click below for what we're doing. */
   g_signal_connect (interfaces_list, "button-press-event",
                     G_CALLBACK (maybe_identify_click), NULL);
-  gtk_widget_set_tooltip_markup (interfaces_list, _("Left click on an
interface name to flash the light on the physical interface."));
+  gtk_widget_set_tooltip_markup (interfaces_list,
+                                 _("Left click on an interface name to
flash "
+                                   "the light on the physical
interface."));
   populate_interfaces (GTK_TREE_VIEW (interfaces_list));
   scrolled_window_add_with_viewport (interfaces_sw, interfaces_list);
   gtk_container_add (GTK_CONTAINER (interfaces_frame), interfaces_sw);
@@ -1273,7 +1300,9 @@ populate_interfaces (GtkTreeView *interfaces_list_p)
                     "%s\n"
                     "%s"
                     "</small>\n"
-                    "<small><u><span
foreground=\"blue\">Identify
interface</span></u></small>",
+                    "<small><u><span
foreground=\"blue\">"
+                    "Identify interface"
+                    "</span></u></small>",
                     if_name,
                     if_addr ? : _("Unknown"),
                     if_vendor ? : _("Unknown")) == -1)
@@ -1699,7 +1728,8 @@ vcpus_or_memory_check_callback (GtkWidget *w, gpointer
data)
     gtk_widget_show (vcpus_warning);
 
     warning = concat_warning (warning,
-                              _("Number of virtual CPUs is larger than
what is supported for KVM (max: %d)."),
+                              _("Number of virtual CPUs is larger than
what is "
+                                "supported for KVM (max: %d)."),
                               MAX_SUPPORTED_VCPUS);
   }
   else
@@ -1709,7 +1739,8 @@ vcpus_or_memory_check_callback (GtkWidget *w, gpointer
data)
     gtk_widget_show (memory_warning);
 
     warning = concat_warning (warning,
-                              _("Memory size is larger than what is
supported for KVM (max: %" PRIu64 ")."),
+                              _("Memory size is larger than what is
supported "
+                                "for KVM (max: %" PRIu64
")."),
                               MAX_SUPPORTED_MEMORY_MB);
   }
   else
@@ -1717,7 +1748,9 @@ vcpus_or_memory_check_callback (GtkWidget *w, gpointer
data)
 
   if (warning != NULL) {
     warning = concat_warning (warning,
-                              _("If you ignore this warning, conversion
can still succeed, but the guest may not work or may not be supported on the
target."));
+                              _("If you ignore this warning, conversion
can "
+                                "still succeed, but the guest may not work
or "
+                                "may not be supported on the
target."));
     gtk_label_set_text (GTK_LABEL (target_warning_label), warning);
   }
   else
@@ -2115,7 +2148,8 @@ start_conversion_clicked (GtkWidget *w, gpointer data)
                                   GTK_MESSAGE_ERROR,
                                   GTK_BUTTONS_OK,
                                   _("No disks were selected for
conversion.\n"
-                                    "At least one fixed hard disk must be
selected.\n"));
+                                    "At least one fixed hard disk must be
"
+                                    "selected.\n"));
     gtk_window_set_title (GTK_WINDOW (dlg), _("Error"));
     gtk_dialog_run (GTK_DIALOG (dlg));
     gtk_widget_destroy (dlg);
Laszlo Ersek
2023-Jan-30  14:22 UTC
[Libguestfs] [p2v PATCH 09/11] gui: expose "p2v.output.misc" (-oo)
Introduce a new GTK_ENTRY field in the Output options box.  Similarly to
"p2v.output.misc" on the kernel cmdline, the contents of this
GTK_ENTRY
are a comma-separated list of OPTION=VALUE options, where each option is
passed to virt-v2v as the argument of a separate "-oo" option.
Refresh the manual accordingly.
For initially populating the text entry (in case the kernel command line
specified "p2v.output.misc"), call the guestfs_int_join_strings()
function
that we imported previously in this series.
For unpacking the contents in start_conversion_clicked(), call
guestfs_int_split_string(), just like the generated kernel cmdline parser
does, in update_config_from_kernel_cmdline() [kernel-config.c].
Cc: Alban Lecorps <alban.lecorps at ubisoft.com>
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1792141
Signed-off-by: Laszlo Ersek <lersek at redhat.com>
---
 gui.c        | 47 +++++++++++++++++++-
 virt-p2v.pod |  2 +
 2 files changed, 47 insertions(+), 2 deletions(-)
diff --git a/gui.c b/gui.c
index f86cab649785..040b43dd235d 100644
--- a/gui.c
+++ b/gui.c
@@ -116,7 +116,7 @@ static GtkWidget *conn_dlg,
 static GtkWidget *conv_dlg,
   *guestname_entry, *vcpu_topo, *vcpus_entry, *memory_entry,
   *vcpus_warning, *memory_warning, *target_warning_label,
-  *o_combo, *oc_entry, *os_entry, *of_entry, *oa_combo,
+  *o_combo, *oc_entry, *os_entry, *of_entry, *oa_combo, *oo_entry,
   *info_label,
   *disks_list, *removable_list, *interfaces_list;
 static int vcpus_entry_when_last_sensitive;
@@ -674,6 +674,7 @@ static void populate_removable_store (GtkListStore
*removable_store,
 static void populate_removable (GtkTreeView *removable_list_p,
                                 const char * const *removable);
 static void populate_interfaces (GtkTreeView *interfaces_list_p);
+static void populate_misc_opts (GtkEntry *entry, char * const *misc);
 static void toggled (GtkCellRendererToggle *cell,
                      gchar *path_str,
                      gpointer data);
@@ -733,7 +734,7 @@ create_conversion_dialog (struct config *config,
   GtkWidget *target_frame, *target_vbox, *target_tbl;
   GtkWidget *guestname_label, *vcpus_label, *memory_label;
   GtkWidget *output_frame, *output_vbox, *output_tbl;
-  GtkWidget *o_label, *oa_label, *oc_label, *of_label, *os_label;
+  GtkWidget *o_label, *oa_label, *oc_label, *of_label, *os_label, *oo_label;
   GtkWidget *info_frame;
   GtkWidget *disks_frame, *disks_sw;
   GtkWidget *removable_frame, *removable_sw;
@@ -929,6 +930,23 @@ create_conversion_dialog (struct config *config,
   table_attach (output_tbl, oa_combo,
                 1, 2, row, GTK_FILL, GTK_FILL, 1, 1);
 
+  row++;
+  oo_label = gtk_label_new_with_mnemonic (_("M_isc. options
(-oo):"));
+  table_attach (output_tbl, oo_label,
+                0, 1, row, GTK_FILL, GTK_FILL, 1, 1);
+  set_alignment (oo_label, 1., 0.5);
+  oo_entry = gtk_entry_new ();
+  gtk_label_set_mnemonic_widget (GTK_LABEL (oo_label), oo_entry);
+  gtk_widget_set_tooltip_markup (oo_entry,
+                                 _("A comma-separated list of "
+                                   "<b>OPTION=VALUE</b>
output-specific "
+                                   "options.  Each option is passed to
"
+                                   "virt-v2v as the argument of a separate
"
+                                   "<b>-oo</b>
option."));
+  populate_misc_opts (GTK_ENTRY (oo_entry), config->output.misc);
+  table_attach (output_tbl, oo_entry,
+                1, 2, row, GTK_FILL, GTK_FILL, 1, 1);
+
   gtk_box_pack_start (GTK_BOX (output_vbox), output_tbl, TRUE, TRUE, 0);
   gtk_container_add (GTK_CONTAINER (output_frame), output_vbox);
 
@@ -1356,6 +1374,25 @@ populate_interfaces (GtkTreeView *interfaces_list_p)
                     G_CALLBACK (network_edited_callback), interfaces_store);
 }
 
+/**
+ * Populate the C<Misc. options> text entry.
+ */
+static void
+populate_misc_opts (GtkEntry *entry, char * const *misc)
+{
+  char *joined;
+
+  if (misc == NULL)
+    return;
+
+  joined = guestfs_int_join_strings (",", misc);
+  if (joined == NULL)
+    error (EXIT_FAILURE, errno, "malloc");
+
+  gtk_entry_set_text (entry, joined);
+  free(joined);
+}
+
 static void
 toggled (GtkCellRendererToggle *cell, gchar *path_str, gpointer data)
 {
@@ -2197,6 +2234,12 @@ start_conversion_clicked (GtkWidget *w, gpointer data)
   else
     config->output.storage = NULL;
 
+  str = gtk_entry_get_text (GTK_ENTRY (oo_entry));
+  guestfs_int_free_string_list (config->output.misc);
+  config->output.misc = guestfs_int_split_string (',', str);
+  if (config->output.misc == NULL)
+    error (EXIT_FAILURE, errno, "strdup");
+
   /* Display the UI for conversion. */
   show_running_dialog ();
 
diff --git a/virt-p2v.pod b/virt-p2v.pod
index ecdae46eaaf6..a7e8edcbf9f0 100644
--- a/virt-p2v.pod
+++ b/virt-p2v.pod
@@ -175,6 +175,8 @@ first-time virt-p2v user.
  ?
  ? Output allocation (-oa): [sparse            ?]
  ?
+ ?     Misc. options (-oo): [___________________]
+ ?
 
 All output options and paths are relative to the conversion server
 (I<not> to the physical server).
Laszlo Ersek
2023-Jan-30  14:22 UTC
[Libguestfs] [p2v PATCH 10/11] Reenable the OpenStack output mode
With "-oo" exposed on the GUI, the reason for disabling the openstack
driver (from commit b74c126629e3, "Ignore 'openstack' driver",
2020-03-16)
is gone. Reenable the driver.
At the same time, add two small openstack-related hints to the GUI.
Cc: Alban Lecorps <alban.lecorps at ubisoft.com>
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1792141
Signed-off-by: Laszlo Ersek <lersek at redhat.com>
---
 gui.c | 5 ++++-
 ssh.c | 5 ++---
 2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/gui.c b/gui.c
index 040b43dd235d..d61069dc0404 100644
--- a/gui.c
+++ b/gui.c
@@ -848,6 +848,8 @@ create_conversion_dialog (struct config *config,
                                    "<b>local</b> means put it
in a directory "
                                    "on the conversion server.  "
                                    "<b>rhv</b> means write it
to RHV-M/oVirt.  "
+                                   "<b>openstack</b> means
write it to "
+                                   "OpenStack.  "
                                    "<b>glance</b> means write
it to OpenStack "
                                    "Glance.  "
                                    "See the virt-v2v(1) manual page for
more "
@@ -942,7 +944,8 @@ create_conversion_dialog (struct config *config,
                                    "<b>OPTION=VALUE</b>
output-specific "
                                    "options.  Each option is passed to
"
                                    "virt-v2v as the argument of a separate
"
-                                   "<b>-oo</b>
option."));
+                                   "<b>-oo</b> option.  Mainly
useful for "
+                                   "<b>openstack</b>."));
   populate_misc_opts (GTK_ENTRY (oo_entry), config->output.misc);
   table_attach (output_tbl, oo_entry,
                 1, 2, row, GTK_FILL, GTK_FILL, 1, 1);
diff --git a/ssh.c b/ssh.c
index 513a20318359..ec44e77895a5 100644
--- a/ssh.c
+++ b/ssh.c
@@ -1015,11 +1015,10 @@ static void
 add_output_driver (const char *name)
 {
   /* Ignore the 'vdsm' driver, since that should only be used by VDSM.
-   * Ignore the 'openstack' and 'rhv-upload' drivers, since we
do not
-   * support passing all the options for them.
+   * Ignore the 'rhv-upload' driver, since we do not support passing
all the
+   * options for it.
    */
   if (STRNEQ (name, "vdsm") &&
-      STRNEQ (name, "openstack") &&
       STRNEQ (name, "rhv-upload"))
     add_option ("output", &output_drivers, name);
 }
Laszlo Ersek
2023-Jan-30  14:22 UTC
[Libguestfs] [p2v PATCH 11/11] make-kickstart: add URLs for RHEL-9
This is similar to commit 2d608e252bbe ("Add kickstart URLs for RHEL
8",
2020-02-18), but we also need to add EPEL-9 (cf. commit f4c7ae6ba98f,
"make-disk: inject EPEL9 repo in RHEL9 disk image", 2023-01-20).
Cc: Alban Lecorps <alban.lecorps at ubisoft.com>
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1792141
Signed-off-by: Laszlo Ersek <lersek at redhat.com>
---
 virt-p2v-make-kickstart.in | 13 +++++++++++++
 1 file changed, 13 insertions(+)
diff --git a/virt-p2v-make-kickstart.in b/virt-p2v-make-kickstart.in
index 7f215fc4ebb4..d16161f97398 100644
--- a/virt-p2v-make-kickstart.in
+++ b/virt-p2v-make-kickstart.in
@@ -190,6 +190,19 @@ repo --name=rhel7_${minor}_server_optional
--baseurl=$baseurl/Server-optional/$a
             repos="$repos
 repo --name=rhel8_${minor}_0_baseos --baseurl=$baseurl/BaseOS/$arch/os $proxy
 repo --name=rhel8_${minor}_0_appstream --baseurl=$baseurl/AppStream/$arch/os
$proxy
+"
+            # Avoid recommends by default.
+            packages_options="--excludeWeakdeps"
+            ;;
+        rhel-9.*)
+            minor=$( echo "$repo" | sed
's/rhel-[0-9]*\.\([0-9]*\)/\1/' )
+            baseurl=http://download.devel.redhat.com/released/RHEL-9/9.$minor.0
+            # '$basearch' cannot be used in kickstart, so:
+            arch=`uname -m`
+            repos="$repos
+repo --name=rhel9_${minor}_0_baseos --baseurl=$baseurl/BaseOS/$arch/os $proxy
+repo --name=rhel9_${minor}_0_appstream --baseurl=$baseurl/AppStream/$arch/os
$proxy
+repo --name=epel9
--mirrorlist=http://mirrors.fedoraproject.org/mirrorlist?repo=epel-9\\\\&arch=$arch
 "
             # Avoid recommends by default.
             packages_options="--excludeWeakdeps"