You can also find these in the
recipes/
subdirectory of the source.
Download libguestfs and guestfish here or go to the libguestfs home page.
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.
#!/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
$ 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
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
#!/bin/sh - guestfish -a "$1" -m "$2" vi /grub/grub.conf
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.
#!/bin/sh - guestfish -a "$1" --ro -m "$2" tgz-out "$3" "$4"
$ ./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
Convert a CD-ROM or DVD ISO to a tarball.
Usage is very simple:
iso2tar.sh cd.iso output.tar.gz
#!/bin/sh - guestfish -a "$1" --ro -m /dev/sda tgz-out / "$2"
$ 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]
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.
#!/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
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.
#!/bin/sh - guestfish -a "$1" --ro -m "$2" command "rpm -qa"
$ ./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
This very simple script shows how you can display an overview of what devices, partitions and LVM data are found in a guest image.
#!/bin/sh - guestfish -a "$1" <<EOF run list-devices list-partitions pvs vgs lvs EOF
$ show-devices.sh /dev/mapper/Guests-RHEL53PV32 /dev/sda /dev/sda1 /dev/sda2 /dev/sda2 VolGroup00 /dev/VolGroup00/LogVol00 /dev/VolGroup00/LogVol01
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.
#!/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
$ 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
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.
#!/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
$ ./tar2vm.sh ../libguestfs-1.0.10.tar.gz /tmp/test.img 10M