This small series for p2v refactors the Reboot menu of the conversion dialog into something slightly more general, and add the possibility to shut the machine down. Lots of work to deal with old GTK versions ... Pino Toscano (2): p2v: turn Reboot button into a Shutdown popup menu button p2v: add a Shutdown action (RHBZ#1642044) p2v/gui.c | 119 +++++++++++++++++++++++++++++++++++++++++++---- p2v/virt-p2v.pod | 2 +- 2 files changed, 110 insertions(+), 11 deletions(-) -- 2.17.2
Pino Toscano
2018-Nov-05 17:31 UTC
[Libguestfs] [PATCH 1/2] p2v: turn Reboot button into a Shutdown popup menu button
To ease adding a proper Shutdown action in the conversion dialog, turn the current Reboot button into a button that pops a menu up, with Reboot as the only available action. The menu is implemented using a popover when using "recent" versions of GLib, and GTK+ 3, because of all the APIs needed. In older versions, a simple toggle button with menu is used, which though needs a manual menu firing when pressing the button itself (and not its side arrow). --- p2v/gui.c | 97 +++++++++++++++++++++++++++++++++++++++++++----- p2v/virt-p2v.pod | 2 +- 2 files changed, 88 insertions(+), 11 deletions(-) diff --git a/p2v/gui.c b/p2v/gui.c index 7ec2900a8..10fb2939a 100644 --- a/p2v/gui.c +++ b/p2v/gui.c @@ -98,6 +98,10 @@ #define MAX_SUPPORTED_VCPUS 160 #define MAX_SUPPORTED_MEMORY_MB (UINT64_C (4000 * 1024)) +#if GLIB_CHECK_VERSION(2,32,0) && GTK_CHECK_VERSION(3,12,0) /* glib >= 2.32 && gtk >= 3.12 */ +#define USE_POPOVERS +#endif + static void create_connection_dialog (struct config *); static void create_conversion_dialog (struct config *); static void create_running_dialog (void); @@ -129,7 +133,7 @@ static GtkWidget *conv_dlg, /* The running dialog which is displayed when virt-v2v is running. */ static GtkWidget *run_dlg, *v2v_output_sw, *v2v_output, *log_label, *status_label, - *cancel_button, *reboot_button; + *cancel_button, *shutdown_button; /* Colour tags used in the v2v_output GtkTextBuffer. */ static GtkTextTag *v2v_output_tags[16]; @@ -1606,9 +1610,20 @@ 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); +#ifdef USE_POPOVERS +static void activate_action (GSimpleAction *action, GVariant *parameter, gpointer user_data); +#else +static void shutdown_button_clicked (GtkToolButton *w, gpointer data); +#endif static void reboot_clicked (GtkWidget *w, gpointer data); static gboolean close_running_dialog (GtkWidget *w, GdkEvent *event, gpointer data); +#ifdef USE_POPOVERS +static const GActionEntry shutdown_actions[] = { + { "reboot", activate_action, NULL, NULL, NULL }, +}; +#endif + /** * Create the running dialog. * @@ -1623,6 +1638,13 @@ create_running_dialog (void) { "black", "maroon", "green", "olive", "navy", "purple", "teal", "silver", "gray", "red", "lime", "yellow", "blue", "fuchsia", "cyan", "white" }; GtkTextBuffer *buf; +#ifdef USE_POPOVERS + GMenu *shutdown_menu; + GSimpleActionGroup *shutdown_group; +#else + GtkWidget *shutdown_menu; + GtkWidget *reboot_menu_item; +#endif run_dlg = gtk_dialog_new (); gtk_window_set_title (GTK_WINDOW (run_dlg), getprogname ()); @@ -1686,15 +1708,47 @@ create_running_dialog (void) (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (run_dlg))), status_label, TRUE, TRUE, 0); + /* Shutdown popup menu. */ +#ifdef USE_POPOVERS + shutdown_menu = g_menu_new (); + g_menu_append (shutdown_menu, _("_Reboot"), "shutdown.reboot"); + + shutdown_group = g_simple_action_group_new (); + g_action_map_add_action_entries (G_ACTION_MAP (shutdown_group), + shutdown_actions, + G_N_ELEMENTS (shutdown_actions), NULL); +#else + shutdown_menu = gtk_menu_new (); + reboot_menu_item = gtk_menu_item_new_with_mnemonic (_("_Reboot")); + gtk_menu_shell_append (GTK_MENU_SHELL (shutdown_menu), reboot_menu_item); + gtk_widget_show (reboot_menu_item); +#endif + /* Buttons. */ gtk_dialog_add_buttons (GTK_DIALOG (run_dlg), _("_Cancel conversion ..."), 1, - _("_Reboot"), 2, NULL); cancel_button = gtk_dialog_get_widget_for_response (GTK_DIALOG (run_dlg), 1); gtk_widget_set_sensitive (cancel_button, FALSE); - reboot_button = gtk_dialog_get_widget_for_response (GTK_DIALOG (run_dlg), 2); - gtk_widget_set_sensitive (reboot_button, FALSE); +#ifdef USE_POPOVERS + shutdown_button = gtk_menu_button_new (); + gtk_button_set_use_underline (GTK_BUTTON (shutdown_button), TRUE); + gtk_button_set_label (GTK_BUTTON (shutdown_button), _("_Shutdown ...")); + gtk_button_set_always_show_image (GTK_BUTTON (shutdown_button), TRUE); + gtk_widget_insert_action_group (shutdown_button, "shutdown", + G_ACTION_GROUP (shutdown_group)); + gtk_menu_button_set_use_popover (GTK_MENU_BUTTON (shutdown_button), TRUE); + gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (shutdown_button), + G_MENU_MODEL (shutdown_menu)); +#else + shutdown_button = GTK_WIDGET (gtk_menu_tool_button_new (NULL, + _("_Shutdown ..."))); + gtk_tool_button_set_use_underline (GTK_TOOL_BUTTON (shutdown_button), TRUE); + gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (shutdown_button), + shutdown_menu); +#endif + gtk_widget_set_sensitive (shutdown_button, FALSE); + gtk_dialog_add_action_widget (GTK_DIALOG (run_dlg), shutdown_button, 2); /* Signals. */ g_signal_connect_swapped (G_OBJECT (run_dlg), "delete_event", @@ -1703,8 +1757,12 @@ create_running_dialog (void) G_CALLBACK (gtk_main_quit), NULL); g_signal_connect (G_OBJECT (cancel_button), "clicked", G_CALLBACK (cancel_conversion_dialog), NULL); - g_signal_connect (G_OBJECT (reboot_button), "clicked", +#ifndef USE_POPOVERS + g_signal_connect (G_OBJECT (shutdown_button), "clicked", + G_CALLBACK (shutdown_button_clicked), shutdown_menu); + g_signal_connect (G_OBJECT (reboot_menu_item), "activate", G_CALLBACK (reboot_clicked), NULL); +#endif } /** @@ -1721,7 +1779,7 @@ show_running_dialog (void) gtk_widget_show_all (run_dlg); gtk_widget_set_sensitive (cancel_button, TRUE); if (is_iso_environment) - gtk_widget_set_sensitive (reboot_button, FALSE); + gtk_widget_set_sensitive (shutdown_button, FALSE); } /** @@ -2077,9 +2135,9 @@ conversion_error (gpointer user_data) /* Disable the cancel button. */ gtk_widget_set_sensitive (cancel_button, FALSE); - /* Enable the reboot button. */ + /* Enable the shutdown button. */ if (is_iso_environment) - gtk_widget_set_sensitive (reboot_button, TRUE); + gtk_widget_set_sensitive (shutdown_button, TRUE); return FALSE; } @@ -2105,9 +2163,9 @@ conversion_finished (gpointer user_data) /* Disable the cancel button. */ gtk_widget_set_sensitive (cancel_button, FALSE); - /* Enable the reboot button. */ + /* Enable the shutdown button. */ if (is_iso_environment) - gtk_widget_set_sensitive (reboot_button, TRUE); + gtk_widget_set_sensitive (shutdown_button, TRUE); return FALSE; } @@ -2192,6 +2250,25 @@ cancel_conversion_dialog (GtkWidget *w, gpointer data) gtk_widget_destroy (dlg); } +#ifdef USE_POPOVERS +static void +activate_action (GSimpleAction *action, GVariant *parameter, gpointer user_data) +{ + const char *action_name = g_action_get_name (G_ACTION (action)); + if (STREQ (action_name, "reboot")) + reboot_clicked (NULL, user_data); +} +#else +static void +shutdown_button_clicked (GtkToolButton *w, gpointer data) +{ + GtkMenu *menu = data; + + gtk_menu_popup (menu, NULL, NULL, NULL, NULL, 1, + gtk_get_current_event_time ()); +} +#endif + static void reboot_clicked (GtkWidget *w, gpointer data) { diff --git a/p2v/virt-p2v.pod b/p2v/virt-p2v.pod index 48548f8c6..6535e8d7b 100644 --- a/p2v/virt-p2v.pod +++ b/p2v/virt-p2v.pod @@ -504,7 +504,7 @@ option. This flag is passed to virt-p2v when it is launched inside the virt-p2v ISO environment, ie. when it is running on a real physical machine (and thus not when testing). It enables various dangerous -features such as the Reboot button. +features such as the Shutdown popup button. =item B<--nbd=server[,server...]> -- 2.17.2
Pino Toscano
2018-Nov-05 17:31 UTC
[Libguestfs] [PATCH 2/2] p2v: add a Shutdown action (RHBZ#1642044)
Add a "Shutdown" action to the Shutdown button in the conversion dialog, before the Reboot action: this way it is possible to shutdown the physical server directly from the GUI after the conversion. --- p2v/gui.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/p2v/gui.c b/p2v/gui.c index 10fb2939a..7aea4afd5 100644 --- a/p2v/gui.c +++ b/p2v/gui.c @@ -1615,11 +1615,13 @@ static void activate_action (GSimpleAction *action, GVariant *parameter, gpointe #else static void shutdown_button_clicked (GtkToolButton *w, gpointer data); #endif +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); #ifdef USE_POPOVERS static const GActionEntry shutdown_actions[] = { + { "shutdown", activate_action, NULL, NULL, NULL }, { "reboot", activate_action, NULL, NULL, NULL }, }; #endif @@ -1643,6 +1645,7 @@ create_running_dialog (void) GSimpleActionGroup *shutdown_group; #else GtkWidget *shutdown_menu; + GtkWidget *shutdown_menu_item; GtkWidget *reboot_menu_item; #endif @@ -1711,6 +1714,7 @@ create_running_dialog (void) /* Shutdown popup menu. */ #ifdef USE_POPOVERS shutdown_menu = g_menu_new (); + g_menu_append (shutdown_menu, _("_Shutdown"), "shutdown.shutdown"); g_menu_append (shutdown_menu, _("_Reboot"), "shutdown.reboot"); shutdown_group = g_simple_action_group_new (); @@ -1719,6 +1723,9 @@ create_running_dialog (void) G_N_ELEMENTS (shutdown_actions), NULL); #else shutdown_menu = gtk_menu_new (); + shutdown_menu_item = gtk_menu_item_new_with_mnemonic (_("_Shutdown")); + gtk_menu_shell_append (GTK_MENU_SHELL (shutdown_menu), shutdown_menu_item); + gtk_widget_show (shutdown_menu_item); reboot_menu_item = gtk_menu_item_new_with_mnemonic (_("_Reboot")); gtk_menu_shell_append (GTK_MENU_SHELL (shutdown_menu), reboot_menu_item); gtk_widget_show (reboot_menu_item); @@ -1760,6 +1767,8 @@ create_running_dialog (void) #ifndef USE_POPOVERS g_signal_connect (G_OBJECT (shutdown_button), "clicked", G_CALLBACK (shutdown_button_clicked), shutdown_menu); + g_signal_connect (G_OBJECT (shutdown_menu_item), "activate", + G_CALLBACK (shutdown_clicked), NULL); g_signal_connect (G_OBJECT (reboot_menu_item), "activate", G_CALLBACK (reboot_clicked), NULL); #endif @@ -2255,7 +2264,9 @@ static void activate_action (GSimpleAction *action, GVariant *parameter, gpointer user_data) { const char *action_name = g_action_get_name (G_ACTION (action)); - if (STREQ (action_name, "reboot")) + if (STREQ (action_name, "shutdown")) + shutdown_clicked (NULL, user_data); + else if (STREQ (action_name, "reboot")) reboot_clicked (NULL, user_data); } #else @@ -2269,6 +2280,17 @@ shutdown_button_clicked (GtkToolButton *w, gpointer data) } #endif +static void +shutdown_clicked (GtkWidget *w, gpointer data) +{ + if (!is_iso_environment) + return; + + sync (); + sleep (2); + ignore_value (system ("/sbin/shutdown")); +} + static void reboot_clicked (GtkWidget *w, gpointer data) { -- 2.17.2
Richard W.M. Jones
2018-Nov-06 09:16 UTC
Re: [Libguestfs] [PATCH 0/2] p2v: add Shutdown option
On Mon, Nov 05, 2018 at 06:31:23PM +0100, Pino Toscano wrote:> This small series for p2v refactors the Reboot menu of the conversion > dialog into something slightly more general, and add the possibility to > shut the machine down. > > Lots of work to deal with old GTK versions ...Unfortunately still required for RHEL 5 compat for people using ancient Compaq RAID controllers :-( Rich.> Pino Toscano (2): > p2v: turn Reboot button into a Shutdown popup menu button > p2v: add a Shutdown action (RHBZ#1642044) > > p2v/gui.c | 119 +++++++++++++++++++++++++++++++++++++++++++---- > p2v/virt-p2v.pod | 2 +- > 2 files changed, 110 insertions(+), 11 deletions(-) > > -- > 2.17.2 > > _______________________________________________ > Libguestfs mailing list > Libguestfs@redhat.com > https://www.redhat.com/mailman/listinfo/libguestfs-- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-df lists disk usage of guests without needing to install any software inside the virtual machine. Supports Linux and Windows. http://people.redhat.com/~rjones/virt-df/
Richard W.M. Jones
2018-Nov-06 10:09 UTC
Re: [Libguestfs] [PATCH 2/2] p2v: add a Shutdown action (RHBZ#1642044)
On Mon, Nov 05, 2018 at 06:31:25PM +0100, Pino Toscano wrote:> +static void > +shutdown_clicked (GtkWidget *w, gpointer data) > +{ > + if (!is_iso_environment) > + return; > + > + sync (); > + sleep (2); > + ignore_value (system ("/sbin/shutdown")); > +} > +The shutdown button doesn't actually work[1]. I don't know why because /sbin/shutdown exists. Rich. [1] Using ‘make -C p2v run-virt-p2v-in-a-vm’ -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-p2v converts physical machines to virtual machines. Boot with a live CD or over the network (PXE) and turn machines into KVM guests. http://libguestfs.org/virt-v2v