Added guestfish -i option to run virt-inspector.
authorRichard W.M. Jones <rjones@redhat.com>
Wed, 24 Jun 2009 10:54:48 +0000 (11:54 +0100)
committerRichard W.M. Jones <rjones@redhat.com>
Wed, 24 Jun 2009 10:54:48 +0000 (11:54 +0100)
You can invoke guestfish with:
 guestfish -i libvirt-domain
 guestfish -i disk-image(s)

TODO
fish/fish.c
guestfish.pod
inspector/virt-inspector.pl

diff --git a/TODO b/TODO
index 233ac3c..1d7cb36 100644 (file)
--- a/TODO
+++ b/TODO
@@ -111,7 +111,3 @@ PPC problems:
 ----------------------------------------------------------------------
 
 Supermin appliance should be moved into febootstrap.
-
-----------------------------------------------------------------------
-
-guestfish -i (runs inspector)
index cba0343..b46fd7e 100644 (file)
@@ -90,6 +90,8 @@ usage (void)
             "Copyright (C) 2009 Red Hat Inc.\n"
             "Usage:\n"
             "  guestfish [--options] cmd [: cmd : cmd ...]\n"
+            "  guestfish -i libvirt-domain\n"
+            "  guestfish -i disk-image(s)\n"
             "or for interactive use:\n"
             "  guestfish\n"
             "or from a shell script:\n"
@@ -103,6 +105,7 @@ usage (void)
             "  -a|--add image       Add image\n"
             "  -D|--no-dest-paths   Don't tab-complete paths from guest fs\n"
             "  -f|--file file       Read commands from file\n"
+            "  -i|--inspector       Run virt-inspector to get disk mountpoints\n"
             "  -m|--mount dev[:mnt] Mount dev on mnt (if omitted, /)\n"
             "  -n|--no-sync         Don't autosync\n"
             "  -r|--ro              Mount read-only\n"
@@ -114,12 +117,13 @@ usage (void)
 int
 main (int argc, char *argv[])
 {
-  static const char *options = "a:f:h::m:nrv?V";
+  static const char *options = "a:f:h::im:nrv?V";
   static struct option long_options[] = {
     { "add", 1, 0, 'a' },
     { "cmd-help", 2, 0, 'h' },
     { "file", 1, 0, 'f' },
     { "help", 0, 0, '?' },
+    { "inspector", 0, 0, 'i' },
     { "mount", 1, 0, 'm' },
     { "no-dest-paths", 0, 0, 'D' },
     { "no-sync", 0, 0, 'n' },
@@ -133,7 +137,7 @@ main (int argc, char *argv[])
   struct mp *mps = NULL;
   struct mp *mp;
   char *p, *file = NULL;
-  int c;
+  int c, inspector = 0;
 
   initialize_readline ();
 
@@ -202,6 +206,10 @@ main (int argc, char *argv[])
        list_commands ();
       exit (0);
 
+    case 'i':
+      inspector = 1;
+      break;
+
     case 'm':
       mp = malloc (sizeof (struct mp));
       if (!mp) {
@@ -247,6 +255,54 @@ main (int argc, char *argv[])
     }
   }
 
+  /* Inspector mode invalidates most of the other arguments. */
+  if (inspector) {
+    char cmd[1024];
+    int r;
+
+    if (drvs || mps) {
+      fprintf (stderr, _("guestfish: cannot use -i option with -a or -m\n"));
+      exit (1);
+    }
+    if (optind >= argc) {
+      fprintf (stderr, _("guestfish -i requires a libvirt domain or path(s) to disk image(s)\n"));
+      exit (1);
+    }
+
+    strcpy (cmd, "a=`virt-inspector");
+    while (optind < argc) {
+      if (strlen (cmd) + strlen (argv[optind]) + strlen (argv[0]) + 60
+         >= sizeof cmd) {
+       fprintf (stderr, _("guestfish: virt-inspector command too long for fixed-size buffer\n"));
+       exit (1);
+      }
+      strcat (cmd, " ");
+      strcat (cmd, argv[optind]);
+      optind++;
+    }
+
+    if (read_only)
+      strcat (cmd, " --ro-fish");
+    else
+      strcat (cmd, " --fish");
+
+    sprintf (&cmd[strlen(cmd)], "` && %s $a", argv[0]);
+
+    if (guestfs_get_verbose (g))
+      strcat (cmd, " -v");
+    if (!guestfs_get_autosync (g))
+      strcat (cmd, " -n");
+
+    /*printf ("%s\n", cmd);*/
+
+    r = system (cmd);
+    if (r == -1) {
+      perror ("system");
+      exit (1);
+    }
+    exit (WEXITSTATUS (r));
+  }
+
   /* If we've got drives to add, add them now. */
   add_drives (drvs);
 
index 2d39cbf..56d941f 100644 (file)
@@ -8,6 +8,10 @@ guestfish - the libguestfs filesystem interactive shell
 
  guestfish [--options] [commands]
 
+ guestfish -i libvirt-domain
+
+ guestfish -i disk-image(s)
+
 =head1 EXAMPLES
 
 =head2 From shell scripts
@@ -95,6 +99,30 @@ scripts, use:
 
  #!/usr/bin/guestfish -f
 
+=item B<-i> | B<--inspector>
+
+Run virt-inspector on the named libvirt domain or list of disk
+images.  If virt-inspector is available and if it can identify
+the domain or disk images, then partitions will be mounted
+correctly at start-up.
+
+Typical usage is either:
+
+ guestfish -i myguest
+
+(for an inactive libvirt domain called I<myguest>), or:
+
+ guestfish --ro -i myguest
+
+(for active domains, readonly), or specify the block device directly:
+
+ guestfish -i /dev/Guests/MyGuest
+
+You cannot use I<-a> or I<-m> in conjunction with this option, and
+options other than I<--ro> might not behave correctly.
+
+See also: L<virt-inspector(1)>.
+
 =item B<-m dev[:mountpoint]> | B<--mount dev[:mountpoint]>
 
 Mount the named partition or logical volume on the given mountpoint.
index 1d8a84b..717ccb6 100755 (executable)
@@ -145,7 +145,7 @@ If you select I<--fish> then we print a L<guestfish(1)> command
 line which will automatically mount up the filesystems on the
 correct mount points.  Try this for example:
 
- eval `virt-inspector --fish guest.img`
+ guestfish $(virt-inspector --fish guest.img)
 
 I<--ro-fish> is the same, but the I<--ro> option is passed to
 guestfish so that the filesystems are mounted read-only.
@@ -299,7 +299,7 @@ L<guestfish(1)> command line parameters, so that you can go in
 afterwards and inspect the guest with everything mounted in the
 right place.  For example:
 
- eval `virt-inspector --ro-fish guest.img`
+ guestfish $(virt-inspector --ro-fish guest.img)
  ==> guestfish --ro -a guest.img -m /dev/VG/LV:/ -m /dev/sda1:/boot
 
 =cut
@@ -905,18 +905,17 @@ if ($output eq "fish" || $output eq "ro-fish") {
 
     my $root_dev = $osdevs[0];
 
-    print "guestfish";
     if ($output eq "ro-fish") {
-       print " --ro";
+       print "--ro ";
     }
 
-    print " -a $_" foreach @images;
+    print "-a $_ " foreach @images;
 
     my $mounts = $oses{$root_dev}->{mounts};
     # Have to mount / first.  Luckily '/' is early in the ASCII
     # character set, so this should be OK.
     foreach (sort keys %$mounts) {
-       print " -m $mounts->{$_}:$_" if $_ ne "swap";
+       print "-m $mounts->{$_}:$_ " if $_ ne "swap";
     }
     print "\n"
 }