How to update a (VM) template?

proxwolfe

Well-Known Member
Jun 20, 2020
534
64
48
50
Hi,

I created a VM, installed the OS, added docker and made it all a template. From this template, I have spawned numerous new VMs. Apart from the fact that they all share the same fingerprint for SSH, this works fine for me.

But the older the template gets, the more updates I need to run in every new VM I spawn from it.

Now what I can do is, make a new VM from it, update it and make a new template and delete the old one.

But might there be a quicker, more elegant way to do update my template? Or is this the best practice?

Thanks
 
Hi,
you can create a full clone from the template, update that, and convert it to template again. If the other VMs spawned from the old template are linked clones, the original template still needs to be kept around (because the VMs disks will reference the disk of the original template then). Otherwise, you can remove the old template afterwards.
 
you can create a full clone from the template, update that, and convert it to template again.

Thanks - that's exactly what I am doing:

Now what I can do is, make a new VM from it, update it and make a new template and delete the old one.

I just find this cumbersome and was wondering whether there might be a more elegant, potentially more automated, way to achieve the same result.
 
I just find this cumbersome and was wondering whether there might be a more elegant, potentially more automated, way to achieve the same result.
In theory, it could be supported to temporarily start a template if there are no linked clones. But it's at odds with the design: templates are supposed to be static (the disks are even marked as immutable on storages that support it), and they are very often used for linked clones.
 
The best idea I've come across implemented was a template with updates scripted into it, so each clone has the script running keeping them current.

Every so often -- when the admin feels updates from the base take too long, they clone the base template, update it, and make a new clone with the update-to date in the name. All new VMs are made off of this.

It has it's pro's and cons but it was something that may help you. I liked how one template mistake couldn't crash the whole tree (been there), but I also recognize that, at somepoint, the oldest vms will have to be migrated to a newer template (I feel this is natural anyway)
 
Take a look at virt-customize (https://libguestfs.org/virt-customize.1.html) and virt-edit packages from libguestfs (https://libguestfs.org/). I use virt-customize inside my ansible scripts to build my cloud-init images to pre-install the qemu agent on my linux machines and some other tools required for automated discovery. I almost use debian exclusively for all my vms.
Code:
virt-customize -a /path/to/templateimage.qcow2 --install qemu-guest, sudo
-- update is also available
 
Last edited:
  • Like
Reactions: lauhub
so I like you am trying to run this command:

virt-customize -a /mnt/data/images/107/base-107-disk-0.qcow2 --update

and I get this error:

libguestfs: trace: launch = -1 (error)
virt-customize: error: libguestfs error: guestfs_launch failed, see earlier
error messages

If reporting bugs, run virt-customize with debugging enabled and include
the complete output:

virt-customize -v -x [...]
libguestfs: trace: close
libguestfs: closing guestfs handle 0x5c5224c9ba20 (state 0)


The full message is:

root@proxmox:/mnt/data/images/117# virt-customize -a /mnt/data/images/107/base-107-disk-0.qcow2 --update
[ 0.0] Examining the guest ...
libguestfs: trace: set_verbose true
libguestfs: trace: set_verbose = 0
libguestfs: trace: set_network true
libguestfs: trace: set_network = 0
libguestfs: trace: add_drive "/mnt/data/images/107/base-107-disk-0.qcow2" "readonly:false" "protocol:file" "discard:besteffort"
libguestfs: trace: add_drive = 0
libguestfs: trace: launch
libguestfs: trace: max_disks
libguestfs: trace: max_disks = 255
libguestfs: trace: get_tmpdir
libguestfs: trace: get_tmpdir = "/tmp"
libguestfs: trace: version
libguestfs: trace: version = <struct guestfs_version = major: 1, minor: 48, release: 6, extra: , >
libguestfs: trace: get_backend
libguestfs: trace: get_backend = "direct"
libguestfs: launch: program=virt-customize
libguestfs: launch: version=1.48.6
libguestfs: launch: backend registered: libvirt
libguestfs: launch: backend registered: direct
libguestfs: launch: backend=direct
libguestfs: launch: tmpdir=/tmp/libguestfskMMaeU
libguestfs: launch: umask=0022
libguestfs: launch: euid=0
libguestfs: trace: get_cachedir
libguestfs: trace: get_cachedir = "/var/tmp"
libguestfs: begin building supermin appliance
libguestfs: run supermin
libguestfs: command: run: /usr/bin/supermin
libguestfs: command: run: \ --build
libguestfs: command: run: \ --verbose
libguestfs: command: run: \ --if-newer
libguestfs: command: run: \ --lock /var/tmp/.guestfs-0/lock
libguestfs: command: run: \ --copy-kernel
libguestfs: command: run: \ -f ext2
libguestfs: command: run: \ --host-cpu x86_64
libguestfs: command: run: \ /usr/lib/x86_64-linux-gnu/guestfs/supermin.d
libguestfs: command: run: \ -o /var/tmp/.guestfs-0/appliance.d
supermin: version: 5.2.2
supermin: package handler: debian/dpkg
supermin: acquiring lock on /var/tmp/.guestfs-0/lock
supermin: if-newer: output does not need rebuilding
libguestfs: finished building supermin appliance
libguestfs: begin testing qemu features
libguestfs: trace: get_cachedir
libguestfs: trace: get_cachedir = "/var/tmp"
libguestfs: checking for previously cached test results of /usr/bin/qemu-system-x86_64, in /var/tmp/.guestfs-0
libguestfs: loading previously cached test results
libguestfs: qemu version: 9.2
libguestfs: qemu mandatory locking: yes
libguestfs: qemu KVM: enabled
libguestfs: trace: get_backend_setting "force_tcg"
libguestfs: trace: get_backend_setting = NULL (error)
libguestfs: trace: get_backend_setting "force_kvm"
libguestfs: trace: get_backend_setting = NULL (error)
libguestfs: trace: get_sockdir
libguestfs: trace: get_sockdir = "/tmp"
libguestfs: finished testing qemu features
libguestfs: trace: get_backend_setting "gdb"
libguestfs: trace: get_backend_setting = NULL (error)
/usr/bin/qemu-system-x86_64 \
-global virtio-blk-pci.scsi=off \
-no-user-config \
-nodefaults \
-display none \
-machine accel=kvm:tcg,graphics=off \
-cpu max,la57=off \
-m 1280 \
-no-reboot \
-rtc driftfix=slew \
-global kvm-pit.lost_tick_policy=discard \
-kernel /var/tmp/.guestfs-0/appliance.d/kernel \
-initrd /var/tmp/.guestfs-0/appliance.d/initrd \
-object rng-random,filename=/dev/urandom,id=rng0 \
-device virtio-rng-pci,rng=rng0 \
-device virtio-scsi-pci,id=scsi \
-drive file=/mnt/data/images/107/base-107-disk-0.qcow2,cache=writeback,discard=unmap,id=hd0,if=none \
-device scsi-hd,drive=hd0 \
-drive file=/var/tmp/.guestfs-0/appliance.d/root,snapshot=on,id=appliance,cache=unsafe,if=none,format=raw \
-device scsi-hd,drive=appliance \
-device virtio-serial-pci \
-serial stdio \
-chardev socket,path=/tmp/libguestfsvuosYn/guestfsd.sock,id=channel0 \
-device virtserialport,chardev=channel0,name=org.libguestfs.channel.0 \
-netdev user,id=usernet,net=169.254.0.0/16 \
-device virtio-net-pci,netdev=usernet \
-append "panic=1 console=ttyS0 edd=off udevtimeout=6000 udev.event-timeout=6000 no_timer_check printk.time=1 cgroup_disable=memory usbcore.nousb cryptomgr.notests tsc=reliable 8250.nr_uarts=1 root=UUID=8849a280-45de-4287-8968-ee072aa62637 selinux=0 guestfs_verbose=1 guestfs_network=1 TERM=xterm"
qemu-system-x86_64: -drive file=/mnt/data/images/107/base-107-disk-0.qcow2,cache=writeback,discard=unmap,id=hd0,if=none: Could not open '/mnt/data/images/107/base-107-disk-0.qcow2': Operation not permitted
libguestfs: child_cleanup: 0x5c5224c9ba20: child process died
libguestfs: sending SIGTERM to process 1435820
libguestfs: trace: launch = -1 (error)
virt-customize: error: libguestfs error: guestfs_launch failed, see earlier
error messages

If reporting bugs, run virt-customize with debugging enabled and include
the complete output:

virt-customize -v -x [...]
libguestfs: trace: close
libguestfs: closing guestfs handle 0x5c5224c9ba20 (state 0)
libguestfs: command: run: rm
libguestfs: command: run: \ -rf /tmp/libguestfskMMaeU
libguestfs: command: run: rm
libguestfs: command: run: \ -rf /tmp/libguestfsvuosYn
root@proxmox:/mnt/data/images/117#




I have no clue what to do any help would be great
 
Hi,
qemu-system-x86_64: -drive file=/mnt/data/images/107/base-107-disk-0.qcow2,cache=writeback,discard=unmap,id=hd0,if=none: Could not open '/mnt/data/images/107/base-107-disk-0.qcow2': Operation not permitted
when a template is created its images are converted to base images and the immutable flag is set (if the underlying file system supports it). You'd need to prepare the image before converting to a template. E.g. you can create a full clone, do the modification there and then convert to template again.