guestfish recipes

You can also find these in the recipes/ subdirectory of the source.

Download libguestfs and guestfish here or go to the libguestfs home page.

Table of recipes

clone.sh: Clone and edit a virtual machinepermalink

This script shows how you might have a library of premade virtual machines ready for cloning, but as a final step you use libguestfs or guestfish to customize some configuration files inside the VM before it's ready to go.

In this simple recipe, we overwrite the /etc/resolv.conf file with a new nameserver entry, and change /etc/HOSTNAME.

There are lots of possible improvements to this script, such as using qcow snapshots so that cloned VMs share storage with their "parent" preimages.

clone.sh

#!/bin/sh -

preimage="$1"
newimage="$2"
root="$3"
nameserver="$4"
hostname="$5"

dd if="$preimage" of="$newimage"

guestfish -a "$newimage" -m "$root" <<EOF
write-file /etc/resolv.conf "nameserver $nameserver" 0
write-file /etc/HOSTNAME "$hostname" 0
sync
EOF

Example output

$ clone.sh /tmp/test.img /tmp/new.img /dev/sda1 192.168.1.1 newmachine
204800+0 records in
204800+0 records out
104857600 bytes (105 MB) copied, 2.02821 s, 51.7 MB/s

$ guestfish -a /tmp/new.img -m /dev/sda1

Welcome to guestfish, the libguestfs filesystem interactive shell for
editing virtual machine filesystems.

Type: 'help' for help with commands
      'quit' to quit the shell

><fs> cat /etc/resolv.conf
nameserver 192.168.1.1
><fs> cat /etc/HOSTNAME
newmachine

editgrub.sh: Fix an unbootable VM by editing /boot/grub/grub.confpermalink

If you messed up your VM and made it unbootable, it's often useful to be able to go in and edit /boot/grub/grub.conf. This guestfish script shows how to do that.

Usage assumes that the VM has a separate /boot partition containing grub, which is usually the case. So for example:

editgrub.sh broken-guest.img /dev/sda1

editgrub.sh

#!/bin/sh -

guestfish -a "$1" -m "$2" vi /grub/grub.conf

export2tar.sh: Export the /home directory from a virtual machine into a tarballpermalink

This script lets you export any directory you like from a virtual machine as a tarball. For example, to export /home from a standard Fedora or RHEL virtual machine you would do:

export2tar.sh guest.img /dev/VolGroup00/LogVol00 /home home.tar.gz

/dev/VolGroup00/LogVol00 is the partition or LV inside the VM which contains the directory you want.

export2tar.sh

#!/bin/sh -

guestfish -a "$1" --ro -m "$2" tgz-out "$3" "$4"

Example output

$ ./export2tar.sh /dev/mapper/Guests-RHEL53PV32 /dev/VolGroup00/LogVol00 \
    /home /tmp/home.tar.gz
$ ll /tmp/home.tar.gz
-rw-rw-r--. 1 rjones rjones 824 2009-04-25 12:33 /tmp/home.tar.gz
$ tar ztf /tmp/home.tar.gz
./
./rjones/
./rjones/.bash_profile
./rjones/.mozilla/
./rjones/.mozilla/extensions/
./rjones/.mozilla/plugins/
./rjones/.bash_logout
./rjones/.bashrc
./rjones/.emacs

iso2tar.sh: Convert a CD-ROM or DVD ISO to a tarballpermalink

Convert a CD-ROM or DVD ISO to a tarball.

Usage is very simple:

iso2tar.sh cd.iso output.tar.gz

iso2tar.sh

#!/bin/sh -

guestfish -a "$1" --ro -m /dev/sda tgz-out / "$2"

Example output

$ ll -h /tmp/Fedora-11-Beta-i386-netinst.iso
-r--r--r--. 1 rjones rjones 168M 2009-04-25 22:38 /tmp/Fedora-11-Beta-i386-netinst.iso
$ ./iso2tar.sh /tmp/Fedora-11-Beta-i386-netinst.iso /tmp/cd.tar.gz
$ ls -lh /tmp/cd.tar.gz
-rw-rw-r--. 1 rjones rjones 177M 2009-04-25 22:50 /tmp/cd.tar.gz
$ tar ztf /tmp/cd.tar.gz
./
./EFI/
./EFI/BOOT/
./EFI/BOOT/BOOT.conf
./EFI/BOOT/BOOTIA32.conf
./EFI/BOOT/splash.xpm.gz
./EFI/BOOT/TRANS.TBL
./images/
./images/efiboot.img
[etc]

resize.sh: Repartition and resize a block devicepermalink

This example shows how a block device containing a partition and a physical volume can be resized.

If you try this out, you may find that attempts to repartition the disk fail because the disk is locked by the LVM devices which exist on it. You have to deactivate (temporarily) the volume groups, perform the fdisk, and then activate them again.

This example script is self-contained. It first creates a block device (a temporary file) containing some LVs, then it extends the temporary file, and shows how to deactivate volgroups, repartition, and activate them again.

resize.sh

#!/bin/sh -

guestfish <<EOF
alloc test.img 130M
run
# You can uncomment the following to see the
# geometry (CHS), which is needed to repartition.
#sfdisk-disk-geometry /dev/sda
sfdisk /dev/sda 0 0 0 ,
pvcreate /dev/sda1
vgcreate VG /dev/sda1
lvcreate LV1 VG 32M
lvcreate LV2 VG 32M
lvcreate LV3 VG 32M
sync
EOF

truncate --size=260M test.img

guestfish -a test.img <<EOF
run
# Turn off the VGs before we can repartition.
vg-activate-all false
sfdisk-N /dev/sda 1 32 255 63 0,31
vg-activate-all true

pvresize /dev/sda1

# The following command would fail if the
# partition or PV hadn't been resized:
lvcreate LV4 VG 64M

echo New LV list:
lvs
EOF

rpmqa.sh: List the RPMs installed inside a Fedora or RHEL virtual machinepermalink

The command lists the RPMs installed inside a Fedora / RHEL / CentOS or other RPM-based virtual machine. It does this by running the rpm -qa command directly inside the machine.

To use it you need to know the partition or LV inside the VM that contains the root filesystem, so for example:

rpmqa.sh guest.img /dev/VolGroup00/LogVol00 | less

You can write a similar command for Debian-based virtual machines very easily.

rpmqa.sh

#!/bin/sh -

guestfish -a "$1" --ro -m "$2" command "rpm -qa"

Example output

$ ./rpmqa.sh RHEL53PV32.img /dev/VolGroup00/LogVol00 > /tmp/rpms
$ ls -l /tmp/rpms
-rw-rw-r--. 1 rjones rjones 17228 2009-04-26 07:02 /tmp/rpms
$ head /tmp/rpms
tzdata-2008i-1.el5
nash-5.1.19.6-44
gnome-mime-data-2.4.2-3.1
dump-0.4b41-2.fc6
emacs-leim-21.4-20.el5
rootfiles-8.1-1.1.1
glibc-2.5-34
popt-1.10.2.3-9.el5
libart_lgpl-2.3.17-4
audit-libs-1.7.7-6.el5

show-devices.sh: Display the devices, partitions, LVs, VGs and PVs in a guest imagepermalink

This very simple script shows how you can display an overview of what devices, partitions and LVM data are found in a guest image.

show-devices.sh

#!/bin/sh -

guestfish -a "$1" <<EOF
run
list-devices
list-partitions
pvs
vgs
lvs
EOF

Example output

$ show-devices.sh /dev/mapper/Guests-RHEL53PV32
/dev/sda
/dev/sda1
/dev/sda2
/dev/sda2
VolGroup00
/dev/VolGroup00/LogVol00
/dev/VolGroup00/LogVol01

squashfs.sh: Mount data in a guest using squashfspermalink

You can use squashfs to import large amounts of data into a guest. First you prepare the squashfs image:

/sbin/mksquashfs data [...] data.sqsh

and then you can add it to the guest as an extra data drive. In the example below, we show how to make a squashfs from the contents of some local directory (/usr/share/man/man8 in this example) and then make that appear in the guest.

squashfs.sh

#!/bin/sh -

datadir=/usr/share/man/man8
/sbin/mksquashfs $datadir test.sqsh

guestfish <<EOF
alloc test.img 10M
add test.sqsh
run
mount /dev/sdb /
ll /
EOF

Example output

$ squashfs.sh
Parallel mksquashfs: Using 2 processors
Creating 4.0 filesystem on test.sqsh, block size 131072.
[===============================================================|] 663/663 100%
Exportable Squashfs 4.0 filesystem, data block size 131072
        compressed data, compressed metadata, compressed fragments
        duplicates are removed
Filesystem size 1518.07 Kbytes (1.48 Mbytes)
        98.41% of uncompressed filesystem size (1542.53 Kbytes)
Inode table size 8095 bytes (7.91 Kbytes)
        35.59% of uncompressed inode table size (22748 bytes)
Directory table size 7612 bytes (7.43 Kbytes)
        49.11% of uncompressed directory table size (15499 bytes)
Number of duplicate files found 6
Number of inodes 701
Number of files 663
Number of fragments 13
Number of symbolic links  37
Number of device nodes 0
Number of fifo nodes 0
Number of socket nodes 0
Number of directories 1
Number of ids (unique uids + gids) 1
Number of uids 1
        root (0)
Number of gids 1
        root (0)
total 1732
drwxr-xr-x  2 root root 15498 May 27 10:34 .
drwxr-xr-x 18 root root     0 May 29 08:44 ..
-rw-r--r--  1 root root   345 Mar  3 17:53 Kobil_mIDentity_switch.8.gz
-rw-r--r--  1 root root  4878 Mar  8 14:50 MAKEDEV.8.gz
-rw-r--r--  1 root root  1278 May  5 11:36 NetworkManager.8.gz
-rw-r--r--  1 root root  2938 Apr 10 12:15 PAM.8.gz
-rw-r--r--  1 root root   736 Feb 24 20:25 PolicyKit.8.gz
lrwxrwxrwx  1 root root    15 May 14 06:41 accept.8.gz -> cupsaccept.8.gz

tar2vm.sh: Make a virtual machine out of a tarballpermalink

This script shows how you might generate a whole virtual machine, or a disk image for a virtual machine, starting with a tarball that contains the content for the machine.

The usage is:

tar2vm.sh input.tar.gz output.img 100M

where (for example) 100M is the size of the output disk image. You have to specify a size that is large enough to contain all the contents of the tarball, but not too large that there is too much wasted space (unless you want to give the VM extra working space of course).

Alternatively use a squashfs.

tar2vm.sh

#!/bin/sh -

guestfish <<EOF
alloc $2 $3
run
part-disk /dev/sda mbr
mkfs ext3 /dev/sda1
mount /dev/sda1 /
tgz-in $1 /
umount-all
EOF

Example output

$ ./tar2vm.sh ../libguestfs-1.0.10.tar.gz /tmp/test.img 10M