= Domain Cloning = Once a template system has been installed, that system can be cloned. `virt-clone` will automatically change the MAC address of your network device. == Cloning == Use the script below to clone your template. `domain_clone_bullseye.sh` {{{#!highlight bash #!/bin/sh SRC_VOLUME_GROUP="vg_storage" DST_VOLUME_GROUP="vg_storage" SRC_NAME="bullseye-template" SRC_VOLUME="kvm_${SRC_NAME}_vda" SRC_VOLUME_SIZE=`lvs /dev/${SRC_VOLUME_GROUP}/${SRC_VOLUME} -o LV_SIZE --noheadings --units B --nosuffix` DST_NAME="bullseye-clone" DST_VOLUME="kvm_${DST_NAME}_vda" DST_MEMORY="256M" MOUNTPOINT="/mnt/domain_root" MAC="" if [ ! -e /sbin/kpartx ] then apt-get install -y kpartx fi if [ $# -gt 0 ] then DST_NAME=${1} DST_VOLUME="kvm_${DST_NAME}_vda" fi if [ "${2}" != "" ] then MAC="--mac ${2} " else MAC=$(grep ${DST_NAME} /root/scripts/mac | awk -F "\t" {'print $1'}) MAC="--mac ${MAC}" fi if [ ! -e /dev/${DST_VOLUME_GROUP}/${DST_VOLUME} ] then # create lvm partition lvcreate --yes --size ${SRC_VOLUME_SIZE}B --name ${DST_VOLUME} ${DST_VOLUME_GROUP} # clone the domain virt-clone \ --original ${SRC_NAME} \ --name ${DST_NAME} \ --file /dev/${DST_VOLUME_GROUP}/${DST_VOLUME} \ ${MAC} \ --check path_in_use=off,path_exists=off # mount the domains / partition OFFSET=`kpartx /dev/${DST_VOLUME_GROUP}/${DST_VOLUME} | tail -n1|awk {'print $6'}` OFFSET_BYTES="$((${OFFSET} * 512))" losetup -o ${OFFSET_BYTES} /dev/loop0 /dev/${DST_VOLUME_GROUP}/${DST_VOLUME} pvscan vgscan vgchange -ay vg_os if [ ! -e ${MOUNTPOINT} ] then mkdir -p ${MOUNTPOINT} fi mount -o subvol=@rootfs /dev/vg_os/root ${MOUNTPOINT} # manipulate domain mkdir ${MOUNTPOINT}/root/scripts cp /root/scripts/guest_cleanup.sh ${MOUNTPOINT}/root/scripts # hostname cp ${MOUNTPOINT}/etc/hosts ${MOUNTPOINT}/etc/hosts.kk sed -i "s/${SRC_NAME}/${DST_NAME}/g" ${MOUNTPOINT}/etc/hosts cp ${MOUNTPOINT}/etc/hostname ${MOUNTPOINT}/etc/hostname.kk sed -i "s/${SRC_NAME}/${DST_NAME}/g" ${MOUNTPOINT}/etc/hostname # rc.local echo "#!/bin/sh" > ${MOUNTPOINT}/etc/rc.local # this delay is needed for the network to settle, works with 32, but using 64 to be sure #echo "sleep 64" >> ${MOUNTPOINT}/etc/rc.local echo "/root/scripts/guest_cleanup.sh ${DST_NAME}" >> ${MOUNTPOINT}/etc/rc.local echo "rm /etc/rc.local" >> ${MOUNTPOINT}/etc/rc.local echo "shutdown -h 0" >> ${MOUNTPOINT}/etc/rc.local echo "exit 0" >> ${MOUNTPOINT}/etc/rc.local chmod +x ${MOUNTPOINT}/etc/rc.local # ssh keys mkdir ${MOUNTPOINT}/root/.ssh cat /root/scripts/login_id_rsa.pub >> ${MOUNTPOINT}/root/.ssh/authorized_keys mkdir ${MOUNTPOINT}/home/kale/.ssh cat /root/scripts/login_id_rsa.pub >> ${MOUNTPOINT}/home/kale/.ssh/authorized_keys chown -R kale:kale ${MOUNTPOINT}/home/kale/ # unmount and cleanup umount ${MOUNTPOINT} vgchange -an vg_os losetup -d /dev/loop0 # cleanup domain virt-xml ${DST_NAME} --edit --graphics password=${DST_NAME} #virt-xml ${DST_NAME} --remove-device --graphics all virsh setmaxmem ${DST_NAME} --size ${DST_MEMORY} --config virsh setmem ${DST_NAME} --size ${DST_MEMORY} --config virsh start ${DST_NAME} else echo "${0}: refusing to overwrite existing domain" fi }}} === Cleaning up Guest OS on First Boot === Before using this script, notice that the root password is set to the hostname. Please make up your own method for setting the root password. Preferable it should be randomized and ssh keys should be used instead of knowing the password. `guest_cleanup.sh` {{{#!highlight bash #!/bin/sh NAME="" if [ $# -gt 0 ] then # the new hostname NAME=${1} # root password echo "root:${NAME}" | chpasswd # sshd rm /etc/ssh/ssh_host_* dpkg-reconfigure openssh-server systemctl restart sshd # extend filesystem size lvextend --size 3G /dev/vg_os/root btrfs filesystem resize max / # network cp /etc/default/grub /etc/default/grub.kk sed -i 's/GRUB_CMDLINE_LINUX=""/GRUB_CMDLINE_LINUX="net.ifnames=0 biosdevname=0"/g' /etc/default/grub update-grub cp /etc/network/interfaces /etc/network/interfaces.kk sed -i 's/allow-hotplug enp1s0/allow-hotplug eth0/' /etc/network/interfaces sed -i 's/allow-hotplug eth0/#allow-hotplug eth0\nauto eth0/' /etc/network/interfaces sed -i 's/iface enp1s0 inet dhcp/iface eth0 inet dhcp/' /etc/network/interfaces # cleanup rm /root/scripts/guest_cleanup.sh rmdir /root/scripts shutdown -h 0 else echo ${0}: requires a hostname as parameter fi }}} === A List of Predefined MAC Adresses === `mac` {{{ # # virtual devices for redundant setup 52:54:00:52:de:25 ns01 52:54:00:cf:5c:d3 ns02 52:54:00:65:0f:42 dhcp01 52:54:00:47:84:7d dhcp02 52:54:00:e0:0f:1d ntp01 52:54:00:b6:76:ee ntp02 # virtual devices for maintenance 52:54:00:94:a4:2e login }}} Make a clone. {{{ ./domain_clone_bullseye.sh clone }}} == Memory == Increase or decrease amount of memory by [[Domain Editing|editing the domain]]. == Network == For your convenience add the MAC address to the DHCP servers list of fixed IP-adresses before starting the system for the first time. This way you know beforehand which IP-address to connect to. == Guest OS == Continue by configuring the [[KVM Guest Operating System|KVM Guest Operating System]].