|
|
e76f14 |
From 16bd3feeb15684fa729012b419e9722904907bab Mon Sep 17 00:00:00 2001
|
|
|
e76f14 |
From: "Richard W.M. Jones" <rjones@redhat.com>
|
|
|
e76f14 |
Date: Sat, 18 Jun 2016 10:40:09 +0100
|
|
|
e76f14 |
Subject: [PATCH] p2v: Use virt-v2v --colours option, support colour in the run
|
|
|
e76f14 |
dialog (RHBZ#1314244).
|
|
|
e76f14 |
|
|
|
e76f14 |
(cherry picked from commit 5e8f820494e70766a48fee38bc617c37b0c61a48)
|
|
|
e76f14 |
---
|
|
|
e76f14 |
p2v/conversion.c | 5 +-
|
|
|
e76f14 |
p2v/gui.c | 179 +++++++++++++++++++++++++++++++++++++++++++++----------
|
|
|
e76f14 |
p2v/main.c | 1 +
|
|
|
e76f14 |
p2v/p2v.h | 3 +
|
|
|
e76f14 |
p2v/ssh.c | 24 ++++++--
|
|
|
e76f14 |
5 files changed, 172 insertions(+), 40 deletions(-)
|
|
|
e76f14 |
|
|
|
e76f14 |
diff --git a/p2v/conversion.c b/p2v/conversion.c
|
|
|
e76f14 |
index f221f84..5265a76 100644
|
|
|
e76f14 |
--- a/p2v/conversion.c
|
|
|
e76f14 |
+++ b/p2v/conversion.c
|
|
|
e76f14 |
@@ -320,9 +320,10 @@ start_conversion (struct config *config,
|
|
|
e76f14 |
/* Build the virt-v2v command up in pieces to make the quoting
|
|
|
e76f14 |
* slightly more sane.
|
|
|
e76f14 |
*/
|
|
|
e76f14 |
- if (mexp_printf (control_h, "( %s virt-v2v%s -i libvirtxml",
|
|
|
e76f14 |
+ if (mexp_printf (control_h, "( %s virt-v2v%s%s -i libvirtxml",
|
|
|
e76f14 |
config->sudo ? "sudo -n " : "",
|
|
|
e76f14 |
- config->verbose ? " -v -x" : "") == -1) {
|
|
|
e76f14 |
+ config->verbose ? " -v -x" : "",
|
|
|
e76f14 |
+ feature_colours_option ? " --colours" : "") == -1) {
|
|
|
e76f14 |
printf_fail:
|
|
|
e76f14 |
set_conversion_error ("mexp_printf: virt-v2v command: %m");
|
|
|
e76f14 |
goto out;
|
|
|
e76f14 |
diff --git a/p2v/gui.c b/p2v/gui.c
|
|
|
e76f14 |
index 142d2eb..a3b4af9 100644
|
|
|
e76f14 |
--- a/p2v/gui.c
|
|
|
e76f14 |
+++ b/p2v/gui.c
|
|
|
e76f14 |
@@ -26,6 +26,7 @@
|
|
|
e76f14 |
#include <unistd.h>
|
|
|
e76f14 |
#include <fcntl.h>
|
|
|
e76f14 |
#include <errno.h>
|
|
|
e76f14 |
+#include <error.h>
|
|
|
e76f14 |
#include <locale.h>
|
|
|
e76f14 |
#include <assert.h>
|
|
|
e76f14 |
#include <libintl.h>
|
|
|
e76f14 |
@@ -71,6 +72,9 @@ static GtkWidget *run_dlg,
|
|
|
e76f14 |
*v2v_output_sw, *v2v_output, *log_label, *status_label,
|
|
|
e76f14 |
*cancel_button, *reboot_button;
|
|
|
e76f14 |
|
|
|
e76f14 |
+/* Colour tags used in the v2v_output GtkTextBuffer. */
|
|
|
e76f14 |
+static GtkTextTag *v2v_output_tags[16];
|
|
|
e76f14 |
+
|
|
|
e76f14 |
/* The entry point from the main program.
|
|
|
e76f14 |
* Note that gtk_init etc have already been called in main.
|
|
|
e76f14 |
*/
|
|
|
e76f14 |
@@ -1407,7 +1411,6 @@ get_memory_from_conv_dlg (void)
|
|
|
e76f14 |
static void set_log_dir (const char *remote_dir);
|
|
|
e76f14 |
static void set_status (const char *msg);
|
|
|
e76f14 |
static void add_v2v_output (const char *msg);
|
|
|
e76f14 |
-static void add_v2v_output_2 (const char *msg, size_t len);
|
|
|
e76f14 |
static void *start_conversion_thread (void *data);
|
|
|
e76f14 |
static void cancel_conversion_dialog (GtkWidget *w, gpointer data);
|
|
|
e76f14 |
static void reboot_clicked (GtkWidget *w, gpointer data);
|
|
|
e76f14 |
@@ -1416,6 +1419,12 @@ static gboolean close_running_dialog (GtkWidget *w, GdkEvent *event, gpointer da
|
|
|
e76f14 |
static void
|
|
|
e76f14 |
create_running_dialog (void)
|
|
|
e76f14 |
{
|
|
|
e76f14 |
+ size_t i;
|
|
|
e76f14 |
+ static const char *tags[16] =
|
|
|
e76f14 |
+ { "black", "maroon", "green", "olive", "navy", "purple", "teal", "silver",
|
|
|
e76f14 |
+ "gray", "red", "lime", "yellow", "blue", "fuchsia", "cyan", "white" };
|
|
|
e76f14 |
+ GtkTextBuffer *buf;
|
|
|
e76f14 |
+
|
|
|
e76f14 |
run_dlg = gtk_dialog_new ();
|
|
|
e76f14 |
gtk_window_set_title (GTK_WINDOW (run_dlg), guestfs_int_program_name);
|
|
|
e76f14 |
gtk_window_set_resizable (GTK_WINDOW (run_dlg), FALSE);
|
|
|
e76f14 |
@@ -1428,6 +1437,17 @@ create_running_dialog (void)
|
|
|
e76f14 |
gtk_text_view_set_editable (GTK_TEXT_VIEW (v2v_output), FALSE);
|
|
|
e76f14 |
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (v2v_output), GTK_WRAP_CHAR);
|
|
|
e76f14 |
gtk_widget_set_size_request (v2v_output, 700, 400);
|
|
|
e76f14 |
+
|
|
|
e76f14 |
+ buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (v2v_output));
|
|
|
e76f14 |
+ for (i = 0; i < 16; ++i) {
|
|
|
e76f14 |
+ CLEANUP_FREE char *tag_name;
|
|
|
e76f14 |
+
|
|
|
e76f14 |
+ if (asprintf (&tag_name, "tag_%s", tags[i]) == -1)
|
|
|
e76f14 |
+ error (EXIT_FAILURE, errno, "asprintf");
|
|
|
e76f14 |
+ v2v_output_tags[i] =
|
|
|
e76f14 |
+ gtk_text_buffer_create_tag (buf, tag_name, "foreground", tags[i], NULL);
|
|
|
e76f14 |
+ }
|
|
|
e76f14 |
+
|
|
|
e76f14 |
log_label = gtk_label_new (NULL);
|
|
|
e76f14 |
gtk_misc_set_alignment (GTK_MISC (log_label), 0., 0.5);
|
|
|
e76f14 |
gtk_misc_set_padding (GTK_MISC (log_label), 10, 10);
|
|
|
e76f14 |
@@ -1510,38 +1530,133 @@ set_status (const char *msg)
|
|
|
e76f14 |
static void
|
|
|
e76f14 |
add_v2v_output (const char *msg)
|
|
|
e76f14 |
{
|
|
|
e76f14 |
+ const char *p;
|
|
|
e76f14 |
static size_t linelen = 0;
|
|
|
e76f14 |
- const char *p0, *p;
|
|
|
e76f14 |
-
|
|
|
e76f14 |
- /* Gtk2 (in ~ Fedora 23) has a regression where it takes much
|
|
|
e76f14 |
- * longer to display long lines, to the point where the virt-p2v
|
|
|
e76f14 |
- * UI would still be slowly display kernel modules while the
|
|
|
e76f14 |
- * conversion had finished. For this reason, arbitrarily break
|
|
|
e76f14 |
- * long lines.
|
|
|
e76f14 |
- */
|
|
|
e76f14 |
- for (p0 = p = msg; *p; ++p) {
|
|
|
e76f14 |
- linelen++;
|
|
|
e76f14 |
- if (*p == '\n' || linelen > 1024) {
|
|
|
e76f14 |
- add_v2v_output_2 (p0, p-p0+1);
|
|
|
e76f14 |
- if (*p != '\n')
|
|
|
e76f14 |
- add_v2v_output_2 ("\n", 1);
|
|
|
e76f14 |
- linelen = 0;
|
|
|
e76f14 |
- p0 = p+1;
|
|
|
e76f14 |
- }
|
|
|
e76f14 |
- }
|
|
|
e76f14 |
- add_v2v_output_2 (p0, p-p0);
|
|
|
e76f14 |
-}
|
|
|
e76f14 |
-
|
|
|
e76f14 |
-static void
|
|
|
e76f14 |
-add_v2v_output_2 (const char *msg, size_t len)
|
|
|
e76f14 |
-{
|
|
|
e76f14 |
- GtkTextBuffer *buf;
|
|
|
e76f14 |
- GtkTextIter iter;
|
|
|
e76f14 |
-
|
|
|
e76f14 |
- /* Insert it at the end. */
|
|
|
e76f14 |
- buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (v2v_output));
|
|
|
e76f14 |
- gtk_text_buffer_get_end_iter (buf, &iter);
|
|
|
e76f14 |
- gtk_text_buffer_insert (buf, &iter, msg, len);
|
|
|
e76f14 |
+ static enum {
|
|
|
e76f14 |
+ state_normal,
|
|
|
e76f14 |
+ state_escape1, /* seen ESC, expecting [ */
|
|
|
e76f14 |
+ state_escape2, /* seen ESC [, expecting 0 or 1 */
|
|
|
e76f14 |
+ state_escape3, /* seen ESC [ 0/1, expecting ; or m */
|
|
|
e76f14 |
+ state_escape4, /* seen ESC [ 0/1 ;, expecting 3 */
|
|
|
e76f14 |
+ state_escape5, /* seen ESC [ 0/1 ; 3, expecting 1/2/4/5 */
|
|
|
e76f14 |
+ state_escape6, /* seen ESC [ 0/1 ; 3 1/2/5/5, expecting m */
|
|
|
e76f14 |
+ state_cr, /* seen CR */
|
|
|
e76f14 |
+ state_truncating, /* truncating line until next \n */
|
|
|
e76f14 |
+ } state = state_normal;
|
|
|
e76f14 |
+ static int colour = 0;
|
|
|
e76f14 |
+ static GtkTextTag *tag = NULL;
|
|
|
e76f14 |
+ GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (v2v_output));
|
|
|
e76f14 |
+ GtkTextIter iter, iter2;
|
|
|
e76f14 |
+ const char *dots = " [...]";
|
|
|
e76f14 |
+
|
|
|
e76f14 |
+ for (p = msg; *p != '\0'; ++p) {
|
|
|
e76f14 |
+ char c = *p;
|
|
|
e76f14 |
+
|
|
|
e76f14 |
+ switch (state) {
|
|
|
e76f14 |
+ case state_normal:
|
|
|
e76f14 |
+ if (c == '\r') /* Start of possible CRLF sequence. */
|
|
|
e76f14 |
+ state = state_cr;
|
|
|
e76f14 |
+ else if (c == '\x1b') { /* Start of an escape sequence. */
|
|
|
e76f14 |
+ state = state_escape1;
|
|
|
e76f14 |
+ colour = 0;
|
|
|
e76f14 |
+ }
|
|
|
e76f14 |
+ else if (c != '\n' && linelen >= 256) {
|
|
|
e76f14 |
+ /* Gtk2 (in ~ Fedora 23) has a regression where it takes much
|
|
|
e76f14 |
+ * longer to display long lines, to the point where the
|
|
|
e76f14 |
+ * virt-p2v UI would still be slowly displaying kernel modules
|
|
|
e76f14 |
+ * while the conversion had finished. For this reason,
|
|
|
e76f14 |
+ * arbitrarily truncate very long lines.
|
|
|
e76f14 |
+ */
|
|
|
e76f14 |
+ gtk_text_buffer_get_end_iter (buf, &iter);
|
|
|
e76f14 |
+ gtk_text_buffer_insert_with_tags (buf, &iter,
|
|
|
e76f14 |
+ dots, strlen (dots), tag, NULL);
|
|
|
e76f14 |
+ state = state_truncating;
|
|
|
e76f14 |
+ colour = 0;
|
|
|
e76f14 |
+ tag = NULL;
|
|
|
e76f14 |
+ }
|
|
|
e76f14 |
+ else { /* Treat everything else as a normal char. */
|
|
|
e76f14 |
+ if (c != '\n') linelen++; else linelen = 0;
|
|
|
e76f14 |
+ gtk_text_buffer_get_end_iter (buf, &iter);
|
|
|
e76f14 |
+ gtk_text_buffer_insert_with_tags (buf, &iter, &c, 1, tag, NULL);
|
|
|
e76f14 |
+ }
|
|
|
e76f14 |
+ break;
|
|
|
e76f14 |
+
|
|
|
e76f14 |
+ case state_escape1:
|
|
|
e76f14 |
+ if (c == '[')
|
|
|
e76f14 |
+ state = state_escape2;
|
|
|
e76f14 |
+ else
|
|
|
e76f14 |
+ state = state_normal;
|
|
|
e76f14 |
+ break;
|
|
|
e76f14 |
+
|
|
|
e76f14 |
+ case state_escape2:
|
|
|
e76f14 |
+ if (c == '0')
|
|
|
e76f14 |
+ state = state_escape3;
|
|
|
e76f14 |
+ else if (c == '1') {
|
|
|
e76f14 |
+ state = state_escape3;
|
|
|
e76f14 |
+ colour += 8;
|
|
|
e76f14 |
+ }
|
|
|
e76f14 |
+ else
|
|
|
e76f14 |
+ state = state_normal;
|
|
|
e76f14 |
+ break;
|
|
|
e76f14 |
+
|
|
|
e76f14 |
+ case state_escape3:
|
|
|
e76f14 |
+ if (c == ';')
|
|
|
e76f14 |
+ state = state_escape4;
|
|
|
e76f14 |
+ else if (c == 'm') {
|
|
|
e76f14 |
+ tag = NULL; /* restore text colour */
|
|
|
e76f14 |
+ state = state_normal;
|
|
|
e76f14 |
+ }
|
|
|
e76f14 |
+ else
|
|
|
e76f14 |
+ state = state_normal;
|
|
|
e76f14 |
+ break;
|
|
|
e76f14 |
+
|
|
|
e76f14 |
+ case state_escape4:
|
|
|
e76f14 |
+ if (c == '3')
|
|
|
e76f14 |
+ state = state_escape5;
|
|
|
e76f14 |
+ else
|
|
|
e76f14 |
+ state = state_normal;
|
|
|
e76f14 |
+ break;
|
|
|
e76f14 |
+
|
|
|
e76f14 |
+ case state_escape5:
|
|
|
e76f14 |
+ if (c >= '0' && c <= '7') {
|
|
|
e76f14 |
+ state = state_escape6;
|
|
|
e76f14 |
+ colour += c - '0';
|
|
|
e76f14 |
+ }
|
|
|
e76f14 |
+ else
|
|
|
e76f14 |
+ state = state_normal;
|
|
|
e76f14 |
+ break;
|
|
|
e76f14 |
+
|
|
|
e76f14 |
+ case state_escape6:
|
|
|
e76f14 |
+ if (c == 'm') {
|
|
|
e76f14 |
+ assert (colour >= 0 && colour <= 15);
|
|
|
e76f14 |
+ tag = v2v_output_tags[colour]; /* set colour tag */
|
|
|
e76f14 |
+ }
|
|
|
e76f14 |
+ state = state_normal;
|
|
|
e76f14 |
+ break;
|
|
|
e76f14 |
+
|
|
|
e76f14 |
+ case state_cr:
|
|
|
e76f14 |
+ if (c == '\n')
|
|
|
e76f14 |
+ /* Process CRLF as single a newline character. */
|
|
|
e76f14 |
+ p--;
|
|
|
e76f14 |
+ else { /* Delete current (== last) line. */
|
|
|
e76f14 |
+ linelen = 0;
|
|
|
e76f14 |
+ gtk_text_buffer_get_end_iter (buf, &iter);
|
|
|
e76f14 |
+ iter2 = iter;
|
|
|
e76f14 |
+ gtk_text_iter_set_line_offset (&iter, 0);
|
|
|
e76f14 |
+ /* Delete from iter..iter2 */
|
|
|
e76f14 |
+ gtk_text_buffer_delete (buf, &iter, &iter2);
|
|
|
e76f14 |
+ }
|
|
|
e76f14 |
+ state = state_normal;
|
|
|
e76f14 |
+ break;
|
|
|
e76f14 |
+
|
|
|
e76f14 |
+ case state_truncating:
|
|
|
e76f14 |
+ if (c == '\n') {
|
|
|
e76f14 |
+ p--;
|
|
|
e76f14 |
+ state = state_normal;
|
|
|
e76f14 |
+ }
|
|
|
e76f14 |
+ break;
|
|
|
e76f14 |
+ } /* switch (state) */
|
|
|
e76f14 |
+ } /* for */
|
|
|
e76f14 |
|
|
|
e76f14 |
/* Scroll to the end of the buffer. */
|
|
|
e76f14 |
gtk_text_buffer_get_end_iter (buf, &iter);
|
|
|
e76f14 |
diff --git a/p2v/main.c b/p2v/main.c
|
|
|
e76f14 |
index 99da3e4..99d0011 100644
|
|
|
e76f14 |
--- a/p2v/main.c
|
|
|
e76f14 |
+++ b/p2v/main.c
|
|
|
e76f14 |
@@ -42,6 +42,7 @@ char **all_disks;
|
|
|
e76f14 |
char **all_removable;
|
|
|
e76f14 |
char **all_interfaces;
|
|
|
e76f14 |
int is_iso_environment = 0;
|
|
|
e76f14 |
+int feature_colours_option = 0;
|
|
|
e76f14 |
|
|
|
e76f14 |
static void udevadm_settle (void);
|
|
|
e76f14 |
static void set_config_defaults (struct config *config);
|
|
|
e76f14 |
diff --git a/p2v/p2v.h b/p2v/p2v.h
|
|
|
e76f14 |
index 9ccaf0f..12dd210 100644
|
|
|
e76f14 |
--- a/p2v/p2v.h
|
|
|
e76f14 |
+++ b/p2v/p2v.h
|
|
|
e76f14 |
@@ -58,6 +58,9 @@ extern char **all_interfaces;
|
|
|
e76f14 |
*/
|
|
|
e76f14 |
extern int is_iso_environment;
|
|
|
e76f14 |
|
|
|
e76f14 |
+/* True if virt-v2v supports the --colours option. */
|
|
|
e76f14 |
+extern int feature_colours_option;
|
|
|
e76f14 |
+
|
|
|
e76f14 |
/* config.c */
|
|
|
e76f14 |
struct config {
|
|
|
e76f14 |
int verbose;
|
|
|
e76f14 |
diff --git a/p2v/ssh.c b/p2v/ssh.c
|
|
|
e76f14 |
index d9210f3..266c236 100644
|
|
|
e76f14 |
--- a/p2v/ssh.c
|
|
|
e76f14 |
+++ b/p2v/ssh.c
|
|
|
e76f14 |
@@ -101,6 +101,7 @@ static pcre *ssh_message_re;
|
|
|
e76f14 |
static pcre *prompt_re;
|
|
|
e76f14 |
static pcre *version_re;
|
|
|
e76f14 |
static pcre *feature_libguestfs_rewrite_re;
|
|
|
e76f14 |
+static pcre *feature_colours_option_re;
|
|
|
e76f14 |
static pcre *feature_input_re;
|
|
|
e76f14 |
static pcre *feature_output_re;
|
|
|
e76f14 |
static pcre *portfwd_re;
|
|
|
e76f14 |
@@ -149,6 +150,7 @@ compile_regexps (void)
|
|
|
e76f14 |
"virt-v2v ([1-9].*)",
|
|
|
e76f14 |
0);
|
|
|
e76f14 |
COMPILE (feature_libguestfs_rewrite_re, "libguestfs-rewrite", 0);
|
|
|
e76f14 |
+ COMPILE (feature_colours_option_re, "colours-option", 0);
|
|
|
e76f14 |
COMPILE (feature_input_re, "input:((?:\\w)*)", 0);
|
|
|
e76f14 |
COMPILE (feature_output_re, "output:((?:\\w)*)", 0);
|
|
|
e76f14 |
COMPILE (portfwd_re, "Allocated port ((?:\\d)+) for remote forward", 0);
|
|
|
e76f14 |
@@ -162,6 +164,7 @@ free_regexps (void)
|
|
|
e76f14 |
pcre_free (prompt_re);
|
|
|
e76f14 |
pcre_free (version_re);
|
|
|
e76f14 |
pcre_free (feature_libguestfs_rewrite_re);
|
|
|
e76f14 |
+ pcre_free (feature_colours_option_re);
|
|
|
e76f14 |
pcre_free (feature_input_re);
|
|
|
e76f14 |
pcre_free (feature_output_re);
|
|
|
e76f14 |
pcre_free (portfwd_re);
|
|
|
e76f14 |
@@ -613,28 +616,37 @@ test_connection (struct config *config)
|
|
|
e76f14 |
switch (mexp_expect (h,
|
|
|
e76f14 |
(mexp_regexp[]) {
|
|
|
e76f14 |
{ 100, .re = feature_libguestfs_rewrite_re },
|
|
|
e76f14 |
- { 101, .re = feature_input_re },
|
|
|
e76f14 |
- { 102, .re = feature_output_re },
|
|
|
e76f14 |
- { 103, .re = prompt_re },
|
|
|
e76f14 |
+ { 101, .re = feature_colours_option_re },
|
|
|
e76f14 |
+ { 102, .re = feature_input_re },
|
|
|
e76f14 |
+ { 103, .re = feature_output_re },
|
|
|
e76f14 |
+ { 104, .re = prompt_re },
|
|
|
e76f14 |
{ 0 }
|
|
|
e76f14 |
}, ovector, ovecsize)) {
|
|
|
e76f14 |
case 100: /* libguestfs-rewrite. */
|
|
|
e76f14 |
feature_libguestfs_rewrite = 1;
|
|
|
e76f14 |
break;
|
|
|
e76f14 |
|
|
|
e76f14 |
- case 101:
|
|
|
e76f14 |
+ case 101: /* virt-v2v supports --colours option */
|
|
|
e76f14 |
+#if DEBUG_STDERR
|
|
|
e76f14 |
+ fprintf (stderr, "%s: remote virt-v2v supports --colours option\n",
|
|
|
e76f14 |
+ guestfs_int_program_name);
|
|
|
e76f14 |
+#endif
|
|
|
e76f14 |
+ feature_colours_option = 1;
|
|
|
e76f14 |
+ break;
|
|
|
e76f14 |
+
|
|
|
e76f14 |
+ case 102:
|
|
|
e76f14 |
/* input:<driver-name> corresponds to an -i option in virt-v2v. */
|
|
|
e76f14 |
add_input_driver (&h->buffer[ovector[2]],
|
|
|
e76f14 |
(size_t) (ovector[3]-ovector[2]));
|
|
|
e76f14 |
break;
|
|
|
e76f14 |
|
|
|
e76f14 |
- case 102:
|
|
|
e76f14 |
+ case 103:
|
|
|
e76f14 |
/* output:<driver-name> corresponds to an -o option in virt-v2v. */
|
|
|
e76f14 |
add_output_driver (&h->buffer[ovector[2]],
|
|
|
e76f14 |
(size_t) (ovector[3]-ovector[2]));
|
|
|
e76f14 |
break;
|
|
|
e76f14 |
|
|
|
e76f14 |
- case 103: /* Got prompt, so end of output. */
|
|
|
e76f14 |
+ case 104: /* Got prompt, so end of output. */
|
|
|
e76f14 |
goto end_of_machine_readable;
|
|
|
e76f14 |
|
|
|
e76f14 |
case MEXP_EOF:
|
|
|
e76f14 |
--
|
|
|
e76f14 |
1.8.3.1
|
|
|
e76f14 |
|