Differences between revisions 13 and 39 (spanning 26 versions)
Revision 13 as of 2017-11-11 22:00:07
Size: 1445
Editor: shran
Comment:
Revision 39 as of 2021-12-31 14:57:50
Size: 5623
Comment:
Deletions are marked like this. Additions are marked like this.
Line 2: Line 2:
Line 6: Line 5:
Line 9: Line 7:
`clonedomain.sh` `domain_clone_bullseye.sh`
Line 13: Line 11:
LVM_GROUP="vg2"
NAME_ORIGINAL="stretch-template"
LVM_NAME_ORIGINAL="kvm_${NAME_ORIGINAL}_vda"
LVM_SIZE_ORIGINAL=`lvs /dev/${LVM_GROUP}/${LVM_NAME_ORIGINAL} -o LV_SIZE --noheadings --units B --nosuffix`
NAME_CLONE="stretch-clone"
LVM_NAME_CLONE="kvm_${NAME_CLONE}_vda"
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
Line 22: Line 29:
        NAME_CLONE=${1}
        LVM_NAME_CLONE="kvm_${NAME_CLONE}_vda"
 DST_NAME=${1}
 DST_VOLUME="kvm_${DST_NAME}_vda"
Line 26: Line 33:
if [ ! -e /dev/${LVM_GROUP}/${LVM_NAME_CLONE} ] if [ "${2}" != "" ]
Line 28: Line 35:
        # create lvm partition
        lvcreate --size ${LVM_SIZE_ORIGINAL}B --name ${LVM_NAME_CLONE} ${LVM_GROUP}
 MAC="--mac ${2} "
else
        MAC=$(grep ${DST_NAME} /root/scripts/mac | awk -F "\t" {'print $1'})
        MAC="--mac ${MAC}"
fi
Line 31: Line 41:
        # clone the domain
        virt-clone --original ${NAME_ORIGINAL} --name ${NAME_CLONE} --file /dev/${LVM_GROUP}/${LVM_NAME_CLONE} --check path_in_use=off,path_exists=off
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}
Line 34: Line 101:
        echo "${0}: refusing to overwrite existing domain"  echo "${0}: refusing to overwrite existing domain"
Line 36: Line 103:
}}}

=== 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`
{{{
#<mac><tab><hostname>
# 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
Line 40: Line 168:
./clonedomain.sh clone ./domain_clone_bullseye.sh clone
Line 43: Line 171:
== Cleanup == == Memory ==
Increase or decrease amount of memory by [[Domain Editing|editing the domain]].
Line 45: Line 174:
=== Hostname === == 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.
Line 47: Line 177:
Your new system will need a new hostname

 * /etc/hostname
 * /etc/hosts

{{{
sed -i 's/stretch-template/clone/g' /etc/hosts
sed -i 's/stretch-template/clone/g' /etc/hostname
}}}

=== sshd ===

Make sure the ssh public/private keys are unique.
== Guest OS ==
Continue by configuring the [[KVM Guest Operating System|KVM Guest Operating System]].

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

   1 #!/bin/sh
   2 
   3 SRC_VOLUME_GROUP="vg_storage"
   4 DST_VOLUME_GROUP="vg_storage"
   5 SRC_NAME="bullseye-template"
   6 SRC_VOLUME="kvm_${SRC_NAME}_vda"
   7 SRC_VOLUME_SIZE=`lvs /dev/${SRC_VOLUME_GROUP}/${SRC_VOLUME} -o LV_SIZE --noheadings --units B --nosuffix`
   8 DST_NAME="bullseye-clone"
   9 DST_VOLUME="kvm_${DST_NAME}_vda"
  10 DST_MEMORY="256M"
  11 MOUNTPOINT="/mnt/domain_root"
  12 MAC=""
  13 
  14 if [ ! -e /sbin/kpartx ]
  15 then
  16         apt-get install -y kpartx
  17 fi
  18 
  19 if [ $# -gt 0 ]
  20 then
  21         DST_NAME=${1}
  22         DST_VOLUME="kvm_${DST_NAME}_vda"
  23 fi
  24 
  25 if [ "${2}" != "" ]
  26 then
  27         MAC="--mac ${2} "
  28 else
  29         MAC=$(grep ${DST_NAME} /root/scripts/mac | awk -F "\t" {'print $1'})
  30         MAC="--mac ${MAC}"
  31 fi
  32 
  33 if [ ! -e /dev/${DST_VOLUME_GROUP}/${DST_VOLUME} ]
  34 then
  35         # create lvm partition
  36         lvcreate --yes --size ${SRC_VOLUME_SIZE}B --name ${DST_VOLUME} ${DST_VOLUME_GROUP}
  37 
  38         # clone the domain
  39         virt-clone \
  40                 --original ${SRC_NAME} \
  41                 --name ${DST_NAME} \
  42                 --file /dev/${DST_VOLUME_GROUP}/${DST_VOLUME} \
  43                 ${MAC} \
  44                 --check path_in_use=off,path_exists=off
  45 
  46         # mount the domains / partition
  47         OFFSET=`kpartx /dev/${DST_VOLUME_GROUP}/${DST_VOLUME} | tail -n1|awk {'print $6'}`
  48         OFFSET_BYTES="$((${OFFSET} * 512))"
  49         losetup -o ${OFFSET_BYTES} /dev/loop0 /dev/${DST_VOLUME_GROUP}/${DST_VOLUME}
  50         pvscan
  51         vgscan
  52         vgchange -ay vg_os
  53         if [ ! -e ${MOUNTPOINT} ]
  54         then
  55                 mkdir -p ${MOUNTPOINT}
  56         fi
  57         mount -o subvol=@rootfs /dev/vg_os/root ${MOUNTPOINT}
  58         # manipulate domain
  59         mkdir ${MOUNTPOINT}/root/scripts
  60         cp /root/scripts/guest_cleanup.sh ${MOUNTPOINT}/root/scripts
  61         # hostname
  62         cp ${MOUNTPOINT}/etc/hosts ${MOUNTPOINT}/etc/hosts.kk
  63         sed -i "s/${SRC_NAME}/${DST_NAME}/g" ${MOUNTPOINT}/etc/hosts
  64         cp ${MOUNTPOINT}/etc/hostname ${MOUNTPOINT}/etc/hostname.kk
  65         sed -i "s/${SRC_NAME}/${DST_NAME}/g" ${MOUNTPOINT}/etc/hostname
  66 
  67         # rc.local
  68         echo "#!/bin/sh" > ${MOUNTPOINT}/etc/rc.local
  69         # this delay is needed for the network to settle, works with 32, but using 64 to be sure
  70         #echo "sleep 64" >> ${MOUNTPOINT}/etc/rc.local
  71         echo "/root/scripts/guest_cleanup.sh ${DST_NAME}" >> ${MOUNTPOINT}/etc/rc.local
  72         echo "rm /etc/rc.local" >> ${MOUNTPOINT}/etc/rc.local
  73         echo "shutdown -h 0" >> ${MOUNTPOINT}/etc/rc.local
  74         echo "exit 0" >> ${MOUNTPOINT}/etc/rc.local
  75         chmod +x ${MOUNTPOINT}/etc/rc.local
  76         # ssh keys
  77         mkdir ${MOUNTPOINT}/root/.ssh
  78         cat /root/scripts/login_id_rsa.pub >> ${MOUNTPOINT}/root/.ssh/authorized_keys
  79         mkdir ${MOUNTPOINT}/home/kale/.ssh
  80         cat /root/scripts/login_id_rsa.pub >> ${MOUNTPOINT}/home/kale/.ssh/authorized_keys
  81         chown -R kale:kale ${MOUNTPOINT}/home/kale/
  82         # unmount and cleanup
  83         umount ${MOUNTPOINT}
  84         vgchange -an vg_os
  85         losetup -d /dev/loop0
  86         # cleanup domain
  87         virt-xml ${DST_NAME} --edit --graphics password=${DST_NAME}
  88         #virt-xml ${DST_NAME} --remove-device --graphics all
  89         virsh setmaxmem ${DST_NAME} --size ${DST_MEMORY} --config
  90         virsh setmem ${DST_NAME} --size ${DST_MEMORY} --config
  91         virsh start ${DST_NAME}
  92 else
  93         echo "${0}: refusing to overwrite existing domain"
  94 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

   1 #!/bin/sh
   2 
   3 NAME=""
   4 if [ $# -gt 0 ]
   5 then
   6         # the new hostname
   7         NAME=${1}
   8 
   9         # root password
  10         echo "root:${NAME}" | chpasswd
  11 
  12         # sshd
  13         rm /etc/ssh/ssh_host_*
  14         dpkg-reconfigure openssh-server
  15         systemctl restart sshd
  16 
  17         # extend filesystem size
  18         lvextend --size 3G /dev/vg_os/root
  19         btrfs filesystem resize max /
  20 
  21         # network
  22         cp /etc/default/grub /etc/default/grub.kk
  23         sed -i 's/GRUB_CMDLINE_LINUX=""/GRUB_CMDLINE_LINUX="net.ifnames=0 biosdevname=0"/g' /etc/default/grub
  24         update-grub
  25         cp /etc/network/interfaces /etc/network/interfaces.kk
  26         sed -i 's/allow-hotplug enp1s0/allow-hotplug eth0/' /etc/network/interfaces
  27         sed -i 's/allow-hotplug eth0/#allow-hotplug eth0\nauto eth0/' /etc/network/interfaces
  28         sed -i 's/iface enp1s0 inet dhcp/iface eth0 inet dhcp/' /etc/network/interfaces
  29 
  30         # cleanup
  31         rm /root/scripts/guest_cleanup.sh
  32         rmdir /root/scripts
  33         shutdown -h 0
  34 else
  35         echo ${0}: requires a hostname as parameter
  36 fi

A List of Predefined MAC Adresses

mac

#<mac><tab><hostname>
# 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 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.

None: Domain Cloning (last edited 2021-12-31 14:57:50 by Kristian Kallenberg)