Using guestfish to modify VM disk image

EarIier I wrote about some ways to modify VM disk images used by Unetlab. Basically it boils down to running a VM, console to it and change things through its shell. Obviously, this approach is no way near a handy way to do small changes like:

  • loading basic config
  • adding license files

In this post I will talk about guestfish utility which is a part of libguestfs tools set. With guestfish one could easily get a shell-like access to the filesystem located on a disk image (qcow2, vmdk, iso and many others). That is how authors of libguestfs tools describe it:

libguestfs is a set of tools for accessing and modifying virtual machine (VM) disk images. You can use this for viewing and editing files inside guests, scripting changes to VMs, monitoring disk used/free statistics, creating guests, P2V, V2V, performing backups, cloning VMs, building VMs, formatting disks, resizing disks, and much more.

libguestfs can access almost any disk image imaginable. It can do it securely — without needing root and with multiple layers of defence against rogue disk images. It can access disk images on remote machines or on CDs/USB sticks. It can access proprietary systems like VMware and Hyper-V.

To demonstrate the way how guestfish works I will solve a particular task of adding a license file to Nokia (Alcatel-Lucent) 7750 Virtual Service Router (VSR) by embedding it to the disk image itself. Tune in!

Working with license file on 7750 SR and VSR

To cure your beloved 7750 VSR from rebooting hourly you need to add and apply a license file (can be bought/obtained from your local Nokia sales representative). Once you have a license file which is basically just a bunch of text you need to apply it somehow:

  • upload the license file to ftp/tftp server and add a line to the bof.cfg file to point to this ftp:// location.
    It could be a very convenient solution if you have FTP server at hand, but what if you don’t?
  • the other way is to upload the license as a file to the routers compact flash and tell BOF to look for by specifying a local path.
    A plus is that you do not need to have FTP server which in most cases is not present in your Unetlab topologies.

Seems like the latter solution suits our needs better, since our goal is to upload a license to an image we are going to use in Unetlab and we do not want to setup FTP server.

Using guestfish shell

guestfish allows you to get a shell-like access to the disk’s filesystem where you can perform a wide variety of commans. A set of  commands posseses a practical interest for our task:

  • copy/move/rename files inside the disk filesystem
  • copy files to the disk from your host

To get this shell access you need to invoke a command

Using guestfish in write mode on live virtual machines, or concurrently with other disk editing tools, can be dangerous, potentially causing disk corruption. The virtual machine must be shut down before you use this command, and disk images must not be edited concurrently.

Use the –ro (read-only) option to use guestfish safely if the disk image or virtual machine might be live. You may see strange or inconsistent results if running concurrently with other changes, but with this option you won’t risk disk corruption.

The only questionable command option is -m <dev> which sets what device do we want to mount. How to get this info? One way to do so is to use guestfish without the device parameter and qeuery them through shell, for example:

This is how you query what devices are available to you, 7750 VSR in a standalone mode has one device – dev/sda1 with a vfat filesystem.

Now you can run guestfish with “device to mount” specified. By default the filesystem will be mounter to /  mountpoint in the guestfish shell.

A sheer amount of commands available to you, read the docs to see them all.

Ok, how do you modify the disks contents? You can use vi editor inside the shell, for example. Or you can use copy-in command to copy file from the host to the VM disk image. What I did (when I used it in a manual way) was using copy-in command to copy file with a license and the editing bof.cfg to point to the license file location.

Add license automatically

Being able to modify images directly, without loading the VM itself is good. But being able to do it in an automated way is twice as good. Since adding a license is a repeatable task (for every 7750 VSR release) it is a good candidate for automation.

This is how vsrlj was born — a bash script which automates manual interaction with guestfish.


Roman Dodin

Network engineer at Nokia
Eagerness to learn multiplied by passion to share.
You can reach me at LinkedIn

You Might Also Like

  • Anton Marchenko

    Good post!

    A few comments. Another way to get the list of available devices is to just specify -m parameter with some dumb device name. For example:
    [root@myhost]# guestfish -a ./image.qcow2 -m /dev/xxx
    libguestfs: error: vfs_type: vfs_type_stub: /dev/xxx: No such file or directory
    libguestfs: error: mount_options: mount_options_stub: /dev/xxx: No such file or directory
    guestfish: ‘/dev/xxx’ could not be mounted.
    guestfish: Did you mean to mount one of these filesystems?
    guestfish: /dev/sda1 (ext2)
    guestfish: /dev/sda2 (unknown)

    Another useful libguestfs tool is guestmount. It allows to mount guest device. Parameters are almost the same as for guestfish:
    guestmount -a ./image.qcow2 -m /dev/sda1 /mnt

    • Roman Dodin

      Thanks Anton,
      valuable info!