From 30f24bb666a11f6fb321d1346031e1e6dfdcfdf1 Mon Sep 17 00:00:00 2001 From: Raphael Dannecker Date: Sun, 10 Mar 2024 10:00:26 +0100 Subject: [PATCH] delete old VM-images when running out of space --- roles/lmn_vm/files/vm-link-images | 4 +++ roles/lmn_vm/files/vm-run | 51 ++++++++++++++++++++++--------- roles/lmn_vm/files/vm-sync | 35 +++++++++++++++++++-- 3 files changed, 74 insertions(+), 16 deletions(-) diff --git a/roles/lmn_vm/files/vm-link-images b/roles/lmn_vm/files/vm-link-images index efa083c..5489ed5 100755 --- a/roles/lmn_vm/files/vm-link-images +++ b/roles/lmn_vm/files/vm-link-images @@ -22,3 +22,7 @@ shift "$((OPTIND -1))" for i in *.qcow2; do [[ -f "${VM_DIR}/${i}" ]] || ln "${i}" "${VM_DIR}/${i}" done + +# allow lmnsynci to remove old vm images +chgrp lmnsyni "${VM_DIR}" +chmod g+w "${VM_DIR}" diff --git a/roles/lmn_vm/files/vm-run b/roles/lmn_vm/files/vm-run index 3ad76db..5ef6e2a 100755 --- a/roles/lmn_vm/files/vm-run +++ b/roles/lmn_vm/files/vm-run @@ -12,6 +12,8 @@ options: -n|--new new clone will be created, even if exists -p|--persistent new clone will be created persistent, so available after reboot too -s|--system qemu:///system instead of default qemu:///session + --no-viewer start without viewer + --heads n number of displays --memory sizeMB memory size in MB --cpu num number of CPUs --os OS operating system (win10|linux|..) @@ -76,8 +78,9 @@ check_images() { sudo -u lmnsynci /usr/local/bin/vm-sync get_image "$(basename "${BACKINGARRAY[$i]}" .qcow2)" fi done - echo "VM-Image and required backingfiles available and checked" + + sudo -u lmnsynci /usr/local/bin/vm-sync update_usage_information ${BACKINGARRAY[*]} } create_clone() { @@ -108,10 +111,11 @@ NEWCLONE=0 PERSISTENT=0 LIBVIRTOSINFO="win10" LIBVIRTOPTS="" +NO_VIEWER=0 source /etc/lmn/vm.conf -TEMP=$(getopt -o no:ps --long new,options:,persistent:,system,memory:,data-disk:,cpu:,bridge:,os:,help -n $0 -- "$@") +TEMP=$(getopt -o no:ps --long new,no-viewer,options:,persistent,system,memory:,data-disk:,heads:,cpu:,bridge:,os:,help -n $0 -- "$@") if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi eval set -- "$TEMP" @@ -135,16 +139,39 @@ while true; do LIBVIRTOPTS=$2 shift 2 ;; + --no-viewer ) + NO_VIEWER=1 + shift + ;; --data-disk ) LIBVIRTOPTS="${LIBVIRTOPTS} --disk ${VM_DIR}/data.qcow2,size=$2,sparse=yes" shift 2 ;; + --heads ) + for i in $(seq $2) + do + LIBVIRTOPTS="${LIBVIRTOPTS} --video model.heads=$i" + done + shift 2 + ;; --memory ) - LIBVIRTOPTS="${LIBVIRTOPTS} --memory $2" + mem_avail=$(sed -En "s/^MemAvailable:\s+([0-9]+)\s+kB/\1/p" /proc/meminfo) + mem_avail=$((mem_avail / 1024 - 2048)) + if (( $2 < mem_avail )); then + LIBVIRTOPTS="${LIBVIRTOPTS} --memory $2" + else + LIBVIRTOPTS="${LIBVIRTOPTS} --memory ${mem_avail}" + fi shift 2 ;; --cpu ) - LIBVIRTOPTS="${LIBVIRTOPTS} --vcpu $2" + #cpu=$(sed -En "0,/^cpu cores/s/^cpu cores\s+:\s+([0-9]+)/\1/p" /proc/cpuinfo) + cpu=$(lscpu | grep "^CPU(s):" | sed 's/.* //g') + if (( $2 < cpu )); then + LIBVIRTOPTS="${LIBVIRTOPTS} --vcpu $2" + else + LIBVIRTOPTS="${LIBVIRTOPTS} --vcpu ${cpu}" + fi shift 2 ;; --bridge ) @@ -199,12 +226,6 @@ if ! virsh --connect="${QEMU}" list | grep "${VM_NAME}-clone"; then # finally, create the new vm -# TODO -# # find macvtap interface MAC address: -# MAC="$(ip link | grep -A1 "vm-macvtap" | -# sed -nE "s%\s+link/ether ([[:xdigit:]:]{17}) .+%\1%p")" -# sed -i -E -e "s/MACMACVTAP/$MAC/" "${VM_XML}" - virt-install \ --osinfo "${LIBVIRTOSINFO}" \ --name "${VM_NAME}-clone" \ @@ -220,14 +241,16 @@ if ! virsh --connect="${QEMU}" list | grep "${VM_NAME}-clone"; then --connect="${QEMU}" \ --noautoconsole \ ${LIBVIRTOPTS} + # --dry-run \ # --print-xml \ # > /tmp/vm.xml # --features hyperv.synic.state=on,xpath1.set=./hyperv/vpindex/@state=on,xpath2.set=./hyperv/stimer/@state=on \ # --network type=ethernet,target.dev=vm-macvtap,xpath1.set=./target/@managed=no \ - # virsh --connect="${QEMU}" start "${VM_NAME}-clone" fi -echo "starting viewer" -trap exit_script SIGHUP SIGINT SIGTERM -virt-viewer --connect="${QEMU}" --full-screen "${VM_NAME}-clone" +if [[ $NO_VIEWER == 0 ]] ; then + echo "starting viewer" + trap exit_script SIGHUP SIGINT SIGTERM + virt-viewer --connect="${QEMU}" --full-screen "${VM_NAME}-clone" +fi diff --git a/roles/lmn_vm/files/vm-sync b/roles/lmn_vm/files/vm-sync index b115154..a9713ed 100755 --- a/roles/lmn_vm/files/vm-sync +++ b/roles/lmn_vm/files/vm-sync @@ -10,6 +10,7 @@ command: get_file get_image delete_outdated_image + update_usage_information EOF } @@ -18,6 +19,22 @@ get_torrent() { echo "No torrent-File found" exit 1 fi + cd "${VM_SYSDIR}" + echo Size needed: $(get_image_size "${VM_NAME}.qcow2.torrent") + echo Size available: $(df --block-size=1 --output=avail "${VM_SYSDIR}" | sed 1d) + while [[ $(get_image_size "${VM_NAME}.qcow2.torrent") -gt $(df --block-size=1 --output=avail "${VM_SYSDIR}" | sed 1d) ]]; do + echo "Not enough space to get ${VM_NAME}." + FILENAME="$(head -1 vm_usage_information.txt)" + if [[ -z $FILENAME ]]; then + echo "No more old VM-files to delete. Unable to get ${VM_NAME}. Please contact system administrator." + exit 1 + fi + echo "Deleting $FILENAME" + sudo vm-aria2 stop "$(basename "${FILENAME}" .qcow2)" + rm -f "${FILENAME}" + [[ -f "${VM_DIR}/${FILENAME}" ]] && rm -f "${VM_DIR}/${FILENAME}" + sed -i -e 1d vm_usage_information.txt + done lockfile="/tmp/sync-vm-${VM_NAME}.lock" if ! flock -n "$lockfile" echo "try to acquire lock"; then echo torrent seems to be in process. @@ -37,7 +54,7 @@ get_torrent() { sudo vm-aria2 stop "${VM_NAME}" cd "${VM_SYSDIR}" # get image - aria2c --seed-time=0 --dht-file-path=$DHTDAT \ + aria2c --seed-time=0 --dht-file-path="$DHTDAT" \ --dht-entry-point="${SEEDBOX_HOST}:${SEEDBOX_PORT}" \ "${VM_SYSDIR}/${VM_NAME}.qcow2.torrent" # and seed @@ -67,9 +84,18 @@ delete_outdated_image() { fi } +update_usage_information() { + cd "${VM_SYSDIR}" + [[ -f vm_usage_information.txt ]] || ls -tr *.qcow2 > vm_usage_information.txt || touch vm_usage_information.txt + FILENAME="$(basename $FILENAME)" + echo sed -i "/${FILENAME}/d" vm_usage_information.txt + sed -i "/${FILENAME}/d" vm_usage_information.txt + echo "${FILENAME}" >> vm_usage_information.txt +} + get_file() { cd "${VM_SYSDIR}" - curl --fail --noproxy ${SEEDBOX_HOST} -o "${FILENAME}" \ + curl --fail --noproxy "${SEEDBOX_HOST}" -o "${FILENAME}" \ "http://${SEEDBOX_HOST}/aria2/${FILENAME}" || echo "File not found on seedbox" } @@ -130,6 +156,11 @@ case "$command" in delete_outdated_image done ;; + update_usage_information) + for FILENAME in "$@"; do + update_usage_information + done + ;; *) show_help exit 1