Virt-sysprep – KVM CLI Tool for Admins

If you’re rolling out multiple virtual machines, it makes sense to create a clean image that doesn’t contain sensitive information such as SSH host keys, MAC addresses, logs, temporary files, and machine IDs. As a KVM admin, this is the point where virt-sysprep will be your best friend.

The virt-sysprep utility is used to prepare a virtual machine (VM) image for cloning by removing or resetting specific configurations and data. It is a tool provided by libguestfs package. By using virt-sysprep, we ensure that the cloned VM instance do not retain conflicting data.

Some common operations performed by virt-sysprep:

  • Hostname: Reset the hostname.
  • SSH-related: Remove ~/.ssh/ and /etc/ssh/*key*.
  • Logs: Clear log files in /var/log/.
  • User Accounts: Remove user accounts except root.
  • Temporary Files: Remove /tmp/* and /var/tmp/*.
  • Machine ID: Reset /etc/machine-id.
🔥 TRENDING - Our #1 Selling eBook

Mastering KVM Virtualization - The Ultimate eBook

From home labs to production clouds - master KVM Host management, automating KVM administration using Terraform, Vagrant, and cloud automation. This eBook will enable you to build scalable virtual infrastructure that works whether you're learning at home or deploying enterprise solutions. Get your full copy today

Only $10 $20
Get Instant Access →

Before we can use virt-sysprep, ensure it’s installed by checking the version of the software.

virt-sysprep --version

If the virt-sysprep command is not available in your system, then you can get it by installing the libguestfs-tools package.

  • Debian-based OS systems
sudo apt update
sudo apt install libguestfs-tools
  • RHEL-based OS systems
sudo dnf install libguestfs-tools guestfs-tools
  • openSUSE
sudo zypper -n install guestfs-tools
  • Arch-based Linux
sudo pacman -S libguestfs guestfs-tools

Clone VM and run virt-sysprep

Below is a simple example of cloning a guest operating system using virt-clone commands. 

# Set guest names
SOURCE_VM="my-old-vm"
CLONED_VM="my-new-vm"

# Clone a VM
sudo virt-clone \
  --original $SOURCE_VM \
  --name $CLONED_VM \
  --auto-clone

When a VM is cloned, all data from the original guest is carried over to the new one. However, in many cases, we don’t want this and instead aim to create a fresh instance based on a template. In such scenarios, it’s often necessary to clean up the image by removing log files, resetting SSH host keys (to establish a new identity), and performing similar housekeeping tasks to ensure the new VM is truly unique.

This operation is done by running the following after the virt-sysprep command.

sudo virt-sysprep \
  --domain $CLONED_VM \
  --operations machine-id,dhcp-client-state,bash-history,logfiles,customize,ssh-hostkeys \
  --firstboot-command 'dpkg-reconfigure openssh-server && systemctl restart ssh'

The tool modifies the disk image offline, meaning the VM should not be running.

If you don’t specify --operations, all available operations will be executed, which might not be desirable. For instance, you may want to preserve the authorized SSH keys and avoid them being wiped.

To get a full list of virt-sysprep command operations, run the following command:

virt-sysprep --list-operations

Note that the customize operation is required for the --firstboot-command option to function correctly.

Run virt-sysprep on a VM Image

virt-sysprep can also be used to modify an existing VM image directly. This could be an image from an old VM or a cloud image that you want to configure, upload files to, and adjust internal settings before booting.

virt-sysprep --help
1. Specify disk image file

Use -a or --add followed by the disk file to specify the image file.

-a <file>
2. Setting custom root password

To set a custom root user password, use --root-password <SELECTOR>. In this example we are setting root user password to StrongPassw0rd

--root-password password:StrongPassw0rd
3. Setting hostname

Use --hostname <HOSTNAME> to set the hostname.

--hostname dbserver.cloudspinx.com
4. Install software package into VM image

The command options for installing software packages is --install <PKG,PKG..>. Let’s consider and example to install openssh-server, mariadb-server, apache2, and php packages.

--install openssh-server,mariadb-server,apache2,libapache2-mod-php,php-mysql
5. Run command at first guest boot

We can provide the commands that will be run on first boot using --firstboot-command <'CMD+ARGS'>

--firstboot-command 'apt update && apt upgrade -y'
6. Set the default timezone

The default timezone can be set by passing --timezone <TIMEZONE>

--timezone America/Los_Angeles
7. Upload local file to destination

It is possible to upload files from your local machine into the image with --upload <FILE:DEST>

Let’s begin by creating a Hello World Bash script.

echo 'echo "Hello, World!"' > helloworld.sh
chmod +x helloworld.sh

The example below will copy the php script created into /root/ on the VM image.

--upload ./helloworld.sh:/root

Files can also be moved instead of copy by using --move <SOURCE:DEST>

8. Inject SSH public key into the guest

SSH public key can be injected into the guest VM using --ssh-inject <USER[:SELECTOR]>

Generate ssh keys if you don’t have:

ssh-keygen -t rsa -b 4096

The default path location for the SSH public key is ~/.ssh/id_rsa.pub. We can inject this file.

--ssh-inject root:file:/home/$USER/.ssh/id_rsa.pub
  • root is the name of guest OS user account
  • /home/$USER/.ssh/id_rsa.pub is the absolute path to the ssh public key. If using root user account this will be /root/.ssh/id_rsa.pub

The final set of virt-sysprep commands to run in our example is as follows:

sudo virt-sysprep \
-a noble-server-cloudimg-amd64.img \
--root-password password:StrongPassw0rd \
--hostname dbserver.cloudspinx.com \
--network \
--firstboot-command 'apt update && apt upgrade -y' \
--timezone America/Los_Angeles \
--upload ./helloworld.sh:/root \
--ssh-inject root:file:/home/$USER/.ssh/id_rsa.pub

Sample execution output:

[   0.0] Examining the guest ...
[  12.4] Performing "abrt-data" ...
[  12.4] Performing "backup-files" ...
[  12.6] Performing "bash-history" ...
[  12.6] Performing "blkid-tab" ...
[  12.6] Performing "crash-data" ...
[  12.6] Performing "cron-spool" ...
[  12.6] Performing "dhcp-client-state" ...
[  12.6] Performing "dhcp-server-state" ...
[  12.6] Performing "dovecot-data" ...
[  12.6] Performing "ipa-client" ...
[  12.6] Performing "kerberos-hostkeytab" ...
[  12.6] Performing "logfiles" ...
[  12.6] Performing "lvm-system-devices" ...
[  12.6] Performing "machine-id" ...
[  12.7] Performing "mail-spool" ...
[  12.7] Performing "net-hostname" ...
[  12.7] Performing "net-hwaddr" ...
[  12.7] Performing "net-nmconn" ...
[  12.7] Performing "pacct-log" ...
[  12.7] Performing "package-manager-cache" ...
[  12.7] Performing "pam-data" ...
[  12.7] Performing "passwd-backups" ...
[  12.7] Performing "puppet-data-log" ...
[  12.7] Performing "rh-subscription-manager" ...
[  12.7] Performing "rhn-systemid" ...
[  12.7] Performing "rpm-db" ...
[  12.7] Performing "samba-db-log" ...
[  12.7] Performing "script" ...
[  12.7] Performing "smolt-uuid" ...
[  12.7] Performing "ssh-hostkeys" ...
[  12.7] Performing "ssh-userdir" ...
[  12.7] Performing "sssd-db-log" ...
[  12.7] Performing "tmp-files" ...
[  12.7] Performing "udev-persistent-net" ...
[  12.7] Performing "utmp" ...
[  12.8] Performing "yum-uuid" ...
[  12.8] Performing "customize" ...
[  12.8] Setting a random seed
virt-sysprep: warning: random seed could not be set for this type of guest
[  12.8] Setting the machine ID in /etc/machine-id
[  12.8] Setting the hostname: dbserver.cloudspinx.com
[  13.5] Installing firstboot command: apt update && apt upgrade -y
[  13.5] Setting the timezone: America/Los_Angeles
[  13.5] Uploading: ./helloworld.php to /root
[  13.5] SSH key inject: root
[  14.0] Setting passwords
[  14.5] SELinux relabelling
[  14.6] Performing "lvm-uuids" ...
9. Disable SELinux (Valid for RHEL based systems)

The --edit <FILE:EXPR> allows you to edit file using Perl expression. Here is an example that will disable SELinux.

--edit '/etc/selinux/config: s/^SELINUX=.*/SELINUX=disabled/'

Or putting it in permissive mode:

--edit '/etc/selinux/config: s/^SELINUX=.*/SELINUX=permissive/'

For more usage guide of the virt-sysprep command, run:

virt-sysprep --help

The resulting image can be imported to KVM using virt-install commands. Check relevant chapter in the ebook for a step-by-step guidance.

Join our Linux and open source community. Subscribe to our newsletter for tips, tricks, and collaboration opportunities!

Recent Post

Unlock the Right Solutions with Confidence

At CloudSpinx, we don’t just offer services - we deliver clarity, direction, and results. Whether you're navigating cloud adoption, scaling infrastructure, or solving DevOps challenges, our seasoned experts help you make smart, strategic decisions with total confidence. Let us turn complexity into opportunity and bring your vision to life.

Leave a Comment

Your email address will not be published. Required fields are marked *

Related Post

As a Linux user, you might think that just because Linux systems are pretty much more secure than Windows, there […]

As a manager of the KVM virtual machines, you may need to execute certain operations over image files. Whether it’s […]

It takes more than starting and stopping them to manage virtual machines efficiently. KVM is a set of command-line tools […]

Let's Connect

Unleash the full potential of your business with CloudSpinx. Our expert solutions specialists are standing by to answer your questions and tailor a plan that perfectly aligns with your unique needs.
You will get a response from our solutions specialist within 12 hours
We understand emergencies can be stressful. For immediate assistance, chat with us now

Contact CloudSpinx today!

Download CloudSpinx Profile

Discover the full spectrum of our expertise and services by downloading our detailed Company Profile. Simply enter your first name, last name, and email address.