From 870fff896be7142a24d163e3751cbf54026b75c7 Mon Sep 17 00:00:00 2001 From: Ondrej Famera Date: Sun, 4 Dec 2016 18:20:36 +0100 Subject: [PATCH 01/28] FEATURE: make fast-vm notes visible in virt-manager by saving them also in 'title' of libvirt XML definition --- fast-vm | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fast-vm b/fast-vm index 4fdad19..cd807b1 100755 --- a/fast-vm +++ b/fast-vm @@ -799,10 +799,17 @@ case "$1" in pmsg $P_ERROR "no VM with number '$vm_number' found\n" exit 1 fi + vm_name=$(virsh --connect qemu:///system list --all |grep "$VM_PREFIX"|awk '{print $2}'|egrep "\-$vm_number$") if [ -z "$3" ]; then $EDITOR "$FASTVM_NOTES_DIR/$vm_number" else echo "$3" > "$FASTVM_NOTES_DIR/$vm_number" + owner="-----" + if [ -f "$FASTVM_NOTES_DIR/$vm_number" ]; then + owner=$(stat --format="%U" "$FASTVM_NOTES_DIR/$vm_number") + fi + # edit also title in libvirt XMl definition so applications like virt-manager can show same notes as seen in 'fast-vm list' + virsh --connect qemu:///system desc $vm_name --title --new-desc "$vm_number $owner $3" --config fi ;; list) From c9eb7191ca4d54c32286301e34a65604e431450d Mon Sep 17 00:00:00 2001 From: Ondrej Famera Date: Tue, 13 Dec 2016 00:03:06 +0100 Subject: [PATCH 02/28] add support for VM_NUMBER templating in libvirt XML files --- fast-vm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fast-vm b/fast-vm index cd807b1..590a048 100755 --- a/fast-vm +++ b/fast-vm @@ -559,7 +559,7 @@ case "$1" in VM_NAME="$VM_PREFIX$image_name" tmp_xml=$(mktemp --suffix=.xml) - sed -e "s/VM_NAME/$VM_PREFIX$image_name/g; s/THINPOOL_VG/$THINPOOL_VG/g; s/LIBVIRT_NETWORK/$LIBVIRT_NETWORK/g;" "$image_xml_path" > $tmp_xml + sed -e "s/VM_NAME/$VM_PREFIX$image_name/g; s/THINPOOL_VG/$THINPOOL_VG/g; s/LIBVIRT_NETWORK/$LIBVIRT_NETWORK/g; s/VM_NUMBER/$vm_number/g;" "$image_xml_path" > $tmp_xml virsh --connect qemu:///system define $tmp_xml if [ ! "$?" -eq '0' ]; then pmsg $P_ERROR "defining base VM for $image_name failed, doesn't it exists already?\n" @@ -596,7 +596,7 @@ case "$1" in pmsg $P_DEBUG "defining virtual machine '$VM_PREFIX$image_name-$vm_number' in libvirt\n" tmp_xml=$(mktemp --suffix=.xml) - sed -e "s/VM_NAME/$VM_PREFIX$image_name-$vm_number/g; s/THINPOOL_VG/$THINPOOL_VG/g; s/LIBVIRT_NETWORK/$LIBVIRT_NETWORK/g;" "$image_xml_path" > $tmp_xml + sed -e "s/VM_NAME/$VM_PREFIX$image_name-$vm_number/g; s/THINPOOL_VG/$THINPOOL_VG/g; s/LIBVIRT_NETWORK/$LIBVIRT_NETWORK/g; s/VM_NUMBER/$vm_number/g;" "$image_xml_path" > $tmp_xml virsh --connect qemu:///system define $tmp_xml if [ ! "$?" -eq '0' ]; then pmsg $P_ERROR "Unable to define virtual machine from $tmp_xml. Check syslog for more details\n" From 5f3f6bb8c177c83b5f614965ce5e218d8a6170a6 Mon Sep 17 00:00:00 2001 From: Ondrej Famera Date: Thu, 15 Dec 2016 23:07:18 +0100 Subject: [PATCH 03/28] FIX: use xmllint to properly detect MAC addreses associated with fast-vm managed network. This should allow creation and deletion of machines with multiple network adapter from which only one is managed by fast-vm. --- README | 1 + fast-vm | 4 ++-- rpm/fast-vm-centos7.spec | 1 + rpm/fast-vm.spec | 1 + 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/README b/README index 3f95482..52803b3 100644 --- a/README +++ b/README @@ -13,6 +13,7 @@ starting VM using the 'hack files'. ====== Requirements ====== * libvirt with qemu/kvm +* libxml2 (xmllint) * LVM thin pool support * LVM VG with reasonable amount of free space (to create LV with thin pool) ** you can use 'losetup' to create a loopback device with LVM diff --git a/fast-vm b/fast-vm index 590a048..0805a9e 100755 --- a/fast-vm +++ b/fast-vm @@ -608,7 +608,7 @@ case "$1" in echo "chgrp" "/dev/$THINPOOL_VG/$VM_PREFIX$image_name-$vm_number" | sudo -n $FASTVM_HELPER pmsg $P_DEBUG "adding static lease for 192.168.$SUBNET_NUMBER.$vm_number into libvirts DHCP\n" - VM_MAC=$(virsh --connect qemu:///system dumpxml "$VM_PREFIX$image_name-$vm_number"|grep 'mac address'|cut -d\' -f 2) + VM_MAC=$(virsh --connect qemu:///system dumpxml "$VM_PREFIX$image_name-$vm_number"|xmllint --xpath "//interface[.//source[@network='$LIBVIRT_NETWORK']]/mac/@address" -|cut -d\" -f 2|head -1) virsh --connect qemu:///system net-update "$LIBVIRT_NETWORK" add-last ip-dhcp-host --xml "" --live --config 2>&1|$DEBUG_LOG_CMD # source file with hacks and apply them @@ -762,7 +762,7 @@ case "$1" in fi fi - VM_MAC=$(virsh --connect qemu:///system dumpxml "$vm_name"|grep 'mac address'|cut -d\' -f 2) + VM_MAC=$(virsh --connect qemu:///system dumpxml "$vm_name"|xmllint --xpath "//interface[.//source[@network='$LIBVIRT_NETWORK']]/mac/@address" -|cut -d\" -f 2|head -1) pmsg $P_DEBUG "removing DHCP reservation 192.168.$SUBNET_NUMBER.$vm_number for $VM_MAC\n" virsh --connect qemu:///system net-update "$LIBVIRT_NETWORK" delete ip-dhcp-host --xml "" --live --config diff --git a/rpm/fast-vm-centos7.spec b/rpm/fast-vm-centos7.spec index b78cd83..a2d856d 100644 --- a/rpm/fast-vm-centos7.spec +++ b/rpm/fast-vm-centos7.spec @@ -14,6 +14,7 @@ Requires: coreutils Requires: gawk Requires: libvirt-client Requires: libvirt-daemon +Requires: libxml2 Requires: lvm2 Requires: ncurses Requires: openssh-clients diff --git a/rpm/fast-vm.spec b/rpm/fast-vm.spec index 699b7b2..fbe6700 100755 --- a/rpm/fast-vm.spec +++ b/rpm/fast-vm.spec @@ -14,6 +14,7 @@ Requires: coreutils Requires: gawk Requires: libvirt-client Requires: libvirt-daemon +Requires: libxml2 Requires: lvm2 Requires: ncurses Requires: openssh-clients From 01b39dc1f36962beb260d5a6625ca05f7d388131 Mon Sep 17 00:00:00 2001 From: Ondrej Famera Date: Thu, 15 Dec 2016 23:09:28 +0100 Subject: [PATCH 04/28] add IP address of fast-vm VM to 'fast-vm start' output so it can be seen when VM is just started without specifying 'console' or 'ssh' --- fast-vm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fast-vm b/fast-vm index 0805a9e..60c46c3 100755 --- a/fast-vm +++ b/fast-vm @@ -643,7 +643,7 @@ case "$1" in # if there is any third argument start VM and console after if [ -z "$3" ]; then - pmsg $P_DEBUG "starting VM $vm_name\n" + pmsg $P_DEBUG "starting VM $vm_name (192.168.$SUBNET_NUMBER.$vm_number)\n" virsh --connect qemu:///system start $vm_name if [ "$?" != '0' ]; then pmsg $P_ERROR "failed to start VM, check syslog for more information\n" From bc23450ebce167c5a91aaf88a76be99f762c6d6f Mon Sep 17 00:00:00 2001 From: Ondrej Famera Date: Thu, 19 Jan 2017 22:37:01 +0100 Subject: [PATCH 05/28] FIX listing the VM when the non-engligh LANG is used --- fast-vm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fast-vm b/fast-vm index 60c46c3..2567ba0 100755 --- a/fast-vm +++ b/fast-vm @@ -822,7 +822,7 @@ case "$1" in echo "$vm_list" else printf "%3s %-20s %-12s %s\n" "VM#" "Image name" "Status" "Notes" - data=$(virsh --connect qemu:///system list --all|awk '{print $2,$3,$4}'|egrep "^${VM_PREFIX}.*-[0-9]+ "|sed "s/${VM_PREFIX}\(.\+\)-\([0-9]\+\) \([a-zA-Z ]\+\)$/\2 \1 \3/"|awk '{printf "%3s %-20s %s %s\n",$1,$2,$3,$4}') + data=$(virsh --connect qemu:///system list --all|awk '{print $2,$3,$4}'|egrep "^${VM_PREFIX}.*-[0-9]+ "|sed "s/${VM_PREFIX}\(.\+\)-\([0-9]\+\) \(.\+\)$/\2 \1 \3/"|awk '{printf "%3s %-20s %s %s\n",$1,$2,$3,$4}') for vm in $vm_list; do out=$(echo "$data"|egrep "(^ $vm|^$vm) ") From 378747e37373ab79aa64e40adec5336a8afdbf23 Mon Sep 17 00:00:00 2001 From: Ondrej Famera Date: Thu, 19 Jan 2017 22:48:15 +0100 Subject: [PATCH 06/28] add function 'info'showin so far IP address of the machine that is assigned by fast-vm.Later this can be used to display more information about the machine from the fast-vm point of view. --- fast-vm | 9 +++++++++ fast-vm.bash_completion | 6 +++--- man/fast-vm.8 | 7 ++++++- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/fast-vm b/fast-vm index 2567ba0..b77e995 100755 --- a/fast-vm +++ b/fast-vm @@ -180,6 +180,9 @@ usage () { edit_note) echo "$0 edit_note VmNumber [NoteText]" ;; + info) + echo "$0 info VmNumber" + ;; list) echo "$0 list [all|active|inactive [short]]" ;; @@ -194,6 +197,7 @@ fast-vm list_images [short] fast-vm create ImageName [PathToLibvirtXML] [PathToHacksFile] fast-vm delete VmNumber fast-vm edit_note VmNumber [NoteText] +fast-vm info VmNumber fast-vm list [all|active|inactive [short]] fast-vm start VmNumber [console|ssh [/path/to/custom/script]] fast-vm stop VmNumber [graceful] @@ -893,6 +897,11 @@ case "$1" in printf "\n USER XML and hack files takes precendense before SYSTEM ones.\n" fi ;; + info) + vm_number="$2" + if [ -z "$vm_number" ]; then pmsg $P_ERROR "VM number missing\n"; usage delete; fi + pmsg $P_DEBUG "IP: 192.168.$SUBNET_NUMBER.$vm_number\n" + ;; *) pmsg $P_ERROR "unknown action\n" usage diff --git a/fast-vm.bash_completion b/fast-vm.bash_completion index c3df2e2..851ce68 100644 --- a/fast-vm.bash_completion +++ b/fast-vm.bash_completion @@ -82,13 +82,13 @@ _fast-vm() COMPREPLY=( $( compgen -W "all active inactive" -- "$cur" ) ) return 0 ;; - start|stop|delete|console|ssh) + start|stop|delete|console|ssh|info) local vm_numbers case $prev in start) vm_numbers=$(fast-vm list inactive short) ;; - delete|edit_note) + delete|edit_note|info) vm_numbers=$(fast-vm list all short) ;; console|ssh|stop) @@ -102,7 +102,7 @@ _fast-vm() $split && return 0 if [ "$cword" -lt 2 ]; then - COMPREPLY=( $( compgen -W 'import_image export_image remove_image edit_note list_images create start stop delete console ssh list' -- "$cur" ) ) + COMPREPLY=( $( compgen -W 'import_image export_image remove_image edit_note list_images create start stop delete console ssh list info' -- "$cur" ) ) return 0 fi diff --git a/man/fast-vm.8 b/man/fast-vm.8 index 97c871b..e61f143 100644 --- a/man/fast-vm.8 +++ b/man/fast-vm.8 @@ -1,4 +1,4 @@ -.TH FAST-VM 8 "fast-vm 1.0 (2016-11-13)" "fast-vm" "fast-vm" \" -*- nroff -*- +.TH FAST-VM 8 "fast-vm 1.0 (2017-01-19)" "fast-vm" "fast-vm" \" -*- nroff -*- .SH NAME fast-vm \(em script for defining VMs from images provided in thin LVM pool .SH SYNOPSIS @@ -41,6 +41,11 @@ fast-vm \(em script for defining VMs from images provided in thin LVM pool .RI [ PathToHacksFile ] .br +.B fast-vm +.B info +.I VmNumber +.br + .B fast-vm .B delete .I VmNumber From 0d68d17edff35c22810a4dca36f635361468386f Mon Sep 17 00:00:00 2001 From: Ondrej Famera Date: Sat, 4 Feb 2017 10:47:11 +0100 Subject: [PATCH 07/28] Support for hack files on VM delete. Briefly tested. --- fast-vm | 83 +++++++++++++++++++++++++++++++++++++++++---------- man/fast-vm.8 | 11 ++++++- 2 files changed, 78 insertions(+), 16 deletions(-) diff --git a/fast-vm b/fast-vm index b77e995..2217715 100755 --- a/fast-vm +++ b/fast-vm @@ -148,7 +148,7 @@ usage () { echo '' case $part in import_image) - echo "$0 import_image ImageName PathToLibvirtXML [PathToHacksFile]" + echo "$0 import_image ImageName PathToLibvirtXML [PathToHacksFile] [PathToDeleteHackFile]" ;; export_image) echo "$0 export_image ImageName " @@ -175,7 +175,7 @@ usage () { echo "$0 ssh VmNumber [/path/to/custom/script]" ;; delete) - echo "$0 delete VmNumber" + echo "$0 delete VmNumber [PathToDeleteHackFile]" ;; edit_note) echo "$0 edit_note VmNumber [NoteText]" @@ -190,12 +190,12 @@ usage () { cat < -fast-vm import_image ImageName PathToLibvirtXML [PathToHacksFile] +fast-vm import_image ImageName PathToLibvirtXML [PathToHacksFile] [PathToDeleteHackFile] fast-vm export_image ImageName fast-vm remove_image ImageName fast-vm list_images [short] fast-vm create ImageName [PathToLibvirtXML] [PathToHacksFile] -fast-vm delete VmNumber +fast-vm delete VmNumber [PathToDeleteHackFile] fast-vm edit_note VmNumber [NoteText] fast-vm info VmNumber fast-vm list [all|active|inactive [short]] @@ -327,6 +327,15 @@ case "$1" in hack_file=$(download_file "$hack_file") fi fi + delete_hack_file="$6" + if [ ! -z "$delete_hack_file" ]; then + check_file "$delete_hack_file" "delete hack file" + if [ "$?" = 2 ]; then pmsg $P_ERROR "delete hack file $delete_hack_file not found\n"; exit 2; fi + if [ "$file_local" = '0' ]; then + delete_hack_file=$(download_file "$delete_hack_file") + fi + fi + if [ -b "/dev/$THINPOOL_VG/$VM_PREFIX$image_name" ]; then pmsg $P_ERROR "base image for '$image_name' version already exists. To remove image use 'remove_image' parameter\n" exit 1 @@ -400,6 +409,15 @@ case "$1" in chmod +rx "$FASTVM_USER_CONF_DIR/hacks-${image_name}.sh" 2>&1|$DEBUG_LOG_CMD fi fi + if [ ! -z "$delete_hack_file" ] && [ -f "$delete_hack_file" ]; then + if [ $(whoami) = 'root' ]; then + cp "$delete_hack_file" "$FASTVM_SYSTEM_CONF_DIR/delete-hacks-${image_name}.sh" 2>&1|$DEBUG_LOG_CMD + chmod +rx "$FASTVM_SYSTEM_CONF_DIR/delete-hacks-${image_name}.sh" 2>&1|$DEBUG_LOG_CMD + else + cp "$delete_hack_file" "$FASTVM_USER_CONF_DIR/delete-hacks-${image_name}.sh" 2>&1|$DEBUG_LOG_CMD + chmod +rx "$FASTVM_USER_CONF_DIR/delete-hacks-${image_name}.sh" 2>&1|$DEBUG_LOG_CMD + fi + fi pmsg $P_INFO "Image $image_name imported\n" # end of locked section @@ -477,10 +495,12 @@ case "$1" in pmsg $P_DEBUG "removing XML and hack file of $image_name...\n" if [ -f "$FASTVM_USER_CONF_DIR/config-${image_name}.xml" ]; then rm "$FASTVM_USER_CONF_DIR/config-${image_name}.xml"; fi if [ -f "$FASTVM_USER_CONF_DIR/hacks-${image_name}.sh" ]; then rm "$FASTVM_USER_CONF_DIR/hacks-${image_name}.sh"; fi + if [ -f "$FASTVM_USER_CONF_DIR/delete-hacks-${image_name}.sh" ]; then rm "$FASTVM_USER_CONF_DIR/delete-hacks-${image_name}.sh"; fi if [ $(whoami) = 'root' ]; then pmsg $P_DEBUG "removing system-wide XML and hack file ...\n" if [ -f "$FASTVM_SYSTEM_CONF_DIR/config-${image_name}.xml" ]; then rm "$FASTVM_SYSTEM_CONF_DIR/config-${image_name}.xml"; fi if [ -f "$FASTVM_SYSTEM_CONF_DIR/hacks-${image_name}.sh" ]; then rm "$FASTVM_SYSTEM_CONF_DIR/hacks-${image_name}.sh"; fi + if [ -f "$FASTVM_SYSTEM_CONF_DIR/delete-hacks-${image_name}.sh" ]; then rm "$FASTVM_SYSTEM_CONF_DIR/delete-hacks-${image_name}.sh"; fi fi pmsg $P_INFO "image $image_name removed\n" else @@ -743,6 +763,24 @@ case "$1" in exit 1 fi + # determine image name of VM + image_name=$(virsh --connect qemu:///system list --all|awk '{print $2,$3,$4}'|egrep "^${VM_PREFIX}.*-[0-9]+ "|sed "s/${VM_PREFIX}\(.\+\)-\([0-9]\+\) \(.\+\)$/\2 \1 \3/"|awk "\$1==$vm_number {printf \"%s\",\$2}") + + delete_hack_file="" + for path in "$3" "$FASTVM_USER_CONF_DIR/delete-hacks-${image_name}.sh" "$FASTVM_SYSTEM_CONF_DIR/delete-hacks-${image_name}.sh" + do + check_file "$path" "delete hack file at $path" 2>&1 >/dev/null + if [ "$?" != 2 ]; then + if [ "$file_local" = '0' ]; then + delete_hack_file=$(download_file "$path") + else + delete_hack_file="$path" + fi + pmsg $P_DEBUG "using file $path as delete hack file\n" + break + fi + done + if [ "$FASTVM_OWNER_ONLY_DELETE" == "yes" ]; then owner=$(stat --format="%U" "$FASTVM_NOTES_DIR/$vm_number" 2>/dev/null) if [ $(whoami) != "root" ] && [ $(whoami) != "$owner" ]; then @@ -786,6 +824,17 @@ case "$1" in pmsg $P_DEBUG "removing VM notes\n" if [ -f "$FASTVM_NOTES_DIR/$vm_number" ]; then rm "$FASTVM_NOTES_DIR/$vm_number"; fi + ## apply delete hack file + if [ ! -z "$delete_hack_file" ]; then + delete_hack_file=$(echo "$delete_hack_file"|sed 's/^\([^\/]\)/\.\/\1/g') + pmsg $P_DEBUG "applying delete hacks from $delete_hack_file\n" + . $delete_hack_file + if [ ! "$?" -eq "0" ]; then + pmsg $P_WARNING "there was issue applying delete hacks to this machine, check syslog for more details\n" + fi + pmsg $P_DEBUG "applying delete hacks finished\n" + fi + pmsg $P_DEBUG "undefining VM $vm_name from libvirt\n" virsh --connect qemu:///system undefine $vm_name --nvram if [ "$?" != '0' ]; then @@ -864,8 +913,8 @@ case "$1" in if [ ! -z "$short_output" ] && [ "$short_output" = "short" ]; then echo "$image_name_list" else - printf '%-20s|%-17s |%-17s |\n' 'Image' 'SYSTEM' 'USER' - printf '%-20s|%-8s %-9s|%-8s %-9s|\n' 'Image name' 'XML' 'Hack file' 'XML' 'Hack file' + printf '%-20s|%-21s |%-21s |\n' 'Image' 'SYSTEM' 'USER' + printf '%-20s|%-8s %-13s|%-8s %-13s|\n' 'Image name' 'XML' 'Hack file for' 'XML' 'Hack file for' for image_name in $image_name_list; do # check the existence of the XML file if [ -f "$FASTVM_USER_CONF_DIR/config-${image_name}.xml" ]; then @@ -874,10 +923,12 @@ case "$1" in user_xml_exists="missing" fi # check existence of hack file + user_hacks_exists="no hack files" if [ -f "$FASTVM_USER_CONF_DIR/hacks-${image_name}.sh" ]; then - user_hacks_exists="ok" - else - user_hacks_exists="missing" + user_hacks_exists="create" + fi + if [ -f "$FASTVM_USER_CONF_DIR/delete-hacks-${image_name}.sh" ]; then + user_hacks_exists+=",delete" fi # check the existence of the XML file if [ -f "$FASTVM_SYSTEM_CONF_DIR/config-${image_name}.xml" ]; then @@ -886,15 +937,17 @@ case "$1" in system_xml_exists="missing" fi # check existence of hack file + system_hacks_exists="no hack files" if [ -f "$FASTVM_SYSTEM_CONF_DIR/hacks-${image_name}.sh" ]; then - system_hacks_exists="ok" - else - system_hacks_exists="missing" + system_hacks_exists="create" + fi + if [ -f "$FASTVM_SYSTEM_CONF_DIR/delete-hacks-${image_name}.sh" ]; then + system_hacks_exists=",delete" fi - printf "%-20s %-8s %-9s %-8s %-9s\n" "$image_name" "$system_xml_exists" "$system_hacks_exists" "$user_xml_exists" "$user_hacks_exists" + printf "%-20s|%-8s %-13s|%-8s %-13s|\n" "$image_name" "$system_xml_exists" "$system_hacks_exists" "$user_xml_exists" "$user_hacks_exists" done - printf "\nNOTE: if image is missing XML it wouldn't be possible to create a VM from it!\n Image with missing hack file can work if it's not needed.\n" - printf "\n USER XML and hack files takes precendense before SYSTEM ones.\n" + printf "\nNOTE: if image is missing XML it wouldn't be possible to create a VM from it!\n Image with missing hack file(s) can work if it's not needed.\n" + printf "\n USER XML and hack file(s) takes precendense before SYSTEM ones.\n" fi ;; info) diff --git a/man/fast-vm.8 b/man/fast-vm.8 index e61f143..2b2b799 100644 --- a/man/fast-vm.8 +++ b/man/fast-vm.8 @@ -1,4 +1,4 @@ -.TH FAST-VM 8 "fast-vm 1.0 (2017-01-19)" "fast-vm" "fast-vm" \" -*- nroff -*- +.TH FAST-VM 8 "fast-vm 1.0 (2017-02-04)" "fast-vm" "fast-vm" \" -*- nroff -*- .SH NAME fast-vm \(em script for defining VMs from images provided in thin LVM pool .SH SYNOPSIS @@ -14,6 +14,7 @@ fast-vm \(em script for defining VMs from images provided in thin LVM pool .RI | PathToImage > .IR PathToLibvirtXML .RI [ PathToHacksFile ] +.RI [ PathToDeleteHacksFile ] .br .B fast-vm @@ -49,6 +50,7 @@ fast-vm \(em script for defining VMs from images provided in thin LVM pool .B fast-vm .B delete .I VmNumber +.RI [ PathToDeleteHacksFile ] .br .B fast-vm @@ -131,6 +133,13 @@ for list of supported macros. Local path or http/https URL to shell script which will be executed after creation of the VM and allows to access the disk drive of the VM before first running it. +.TP +.BI "PathToDeleteHacksFile " /path/to/delete-hacks.sh +.TP +.BI "PathToDeleteHacksFile " http://url/to/delete-hacks.sh +Local path or http/https URL to shell script which will be executed during VM delete process as last step +before the VM is undefined from the libvirt. + .TP .B VmNumber Number identifying the VM. Currently limited to range 20-220 to allow to be used as last octet of the IP address and leave some space static addresses. From 0aad6129315fe0915e36fee7cd89de9525184b32 Mon Sep 17 00:00:00 2001 From: Ondrej Famera Date: Sun, 5 Feb 2017 00:33:38 +0100 Subject: [PATCH 08/28] FEATURE: profiles: use same image file with different libvirtXML and hack files TODO: listing of profiles, bash completion, additional documentation --- fast-vm | 118 +++++++++++++++++++++++++++++++++++++++++++++++--- man/fast-vm.8 | 16 ++++++- 2 files changed, 128 insertions(+), 6 deletions(-) diff --git a/fast-vm b/fast-vm index 2217715..cbebd02 100755 --- a/fast-vm +++ b/fast-vm @@ -156,11 +156,17 @@ usage () { remove_image) echo "$0 remove_image ImageName" ;; + import_profile) + echo "$0 import_profile ProfileName ImageName PathToLibvirtXML [PathToHacksFile] [PathToDeleteHackFile]" + ;; + remove_profile) + echo "$0 remove_profile ProfileName" + ;; list_images) echo "$0 list_images [short]" ;; create) - echo "$0 create ImageName [PathToLibvirtXML] [PathToHacksFile]" + echo "$0 create [PathToLibvirtXML] [PathToHacksFile]" ;; start) echo "$0 start VmNumber [console|ssh [/path/to/custom/script]]" @@ -193,8 +199,10 @@ fast-vm fast-vm import_image ImageName PathToLibvirtXML [PathToHacksFile] [PathToDeleteHackFile] fast-vm export_image ImageName fast-vm remove_image ImageName +fast-vm import_profile ProfileName ImageName PathToLibvirtXML [PathToHacksFile] [PathToDeleteHackFile] +fast-vm remove_profile ProfileName fast-vm list_images [short] -fast-vm create ImageName [PathToLibvirtXML] [PathToHacksFile] +fast-vm create [PathToLibvirtXML] [PathToHacksFile] fast-vm delete VmNumber [PathToDeleteHackFile] fast-vm edit_note VmNumber [NoteText] fast-vm info VmNumber @@ -508,12 +516,101 @@ case "$1" in usage remove_image fi ;; + import_profile) + profile_name="$2" + if [ -z "$profile_name" ]; then pmsg $P_ERROR "missing profile name\n"; usage import_profile; fi + profile_name_stripped=$(echo "$profile_name"|tr -d -C '[:alnum:]\-.') + if [ "$profile_name" != "$profile_name_stripped" ]; then + pmsg $P_ERROR "ProfileName contains restricted characters, allowed are only letters, numbers, dot(.) and dash(-)\n" + exit 1 + fi + image_name="$3" + if [ -z "$image_name" ]; then pmsg $P_ERROR "missing image name\n"; usage import_profile; fi + + image_xml_path="$4" + check_file "$image_xml_path" "XML VM definition" + if [ "$?" = 2 ]; then pmsg $P_ERROR "XML file $image_xml_path not found\n"; exit 2; fi + if [ "$file_local" = '0' ]; then + image_xml_path=$(download_file "$image_xml_path") + fi + + hack_file="$5" + if [ ! -z "$hack_file" ]; then + check_file "$hack_file" "hack file" + if [ "$?" = 2 ]; then pmsg $P_ERROR "hack file $hack_file not found\n"; exit 2; fi + if [ "$file_local" = '0' ]; then + hack_file=$(download_file "$hack_file") + fi + fi + delete_hack_file="$6" + if [ ! -z "$delete_hack_file" ]; then + check_file "$delete_hack_file" "delete hack file" + if [ "$?" = 2 ]; then pmsg $P_ERROR "delete hack file $delete_hack_file not found\n"; exit 2; fi + if [ "$file_local" = '0' ]; then + delete_hack_file=$(download_file "$delete_hack_file") + fi + fi + + if [ ! -b "/dev/$THINPOOL_VG/$VM_PREFIX$image_name" ]; then + pmsg $P_ERROR "Missing image for ${image_name}.\n/dev/$THINPOOL_VG/$VM_PREFIX$image_name not found.\nFirst import image using 'fast-vm image_import $image_name'\n" + exit 2 + fi + + # create profile and copy files to right places + if [ $(whoami) = 'root' ]; then + if [ ! -d "$FASTVM_SYSTEM_CONF_DIR/${profile_name}" ]; then mkdir "$FASTVM_SYSTEM_CONF_DIR/${profile_name}"; fi + echo "$image_name" > "$FASTVM_SYSTEM_CONF_DIR/${profile_name}/base_image" + cp "$image_xml_path" "$FASTVM_SYSTEM_CONF_DIR/${profile_name}/config.xml" 2>&1|$DEBUG_LOG_CMD + chmod +r "$FASTVM_SYSTEM_CONF_DIR/${profile_name}/config.xml" 2>&1|$DEBUG_LOG_CMD + else + if [ ! -d "$FASTVM_USER_CONF_DIR/${profile_name}" ]; then mkdir "$FASTVM_USER_CONF_DIR/${profile_name}"; fi + echo "$image_name" > "$FASTVM_USER_CONF_DIR/${profile_name}/base_image" + cp "$image_xml_path" "$FASTVM_USER_CONF_DIR/${profile_name}/config.xml" 2>&1|$DEBUG_LOG_CMD + chmod +r "$FASTVM_USER_CONF_DIR/${profile_name}/config.xml" 2>&1|$DEBUG_LOG_CMD + fi + if [ ! -z "$hack_file" ] && [ -f "$hack_file" ]; then + if [ $(whoami) = 'root' ]; then + cp "$hack_file" "$FASTVM_SYSTEM_CONF_DIR/${profile_name}/hacks.sh" 2>&1|$DEBUG_LOG_CMD + chmod +rx "$FASTVM_SYSTEM_CONF_DIR/${profile_name}/hacks.sh" 2>&1|$DEBUG_LOG_CMD + else + cp "$hack_file" "$FASTVM_USER_CONF_DIR/${profile_name}/hacks.sh" 2>&1|$DEBUG_LOG_CMD + chmod +rx "$FASTVM_USER_CONF_DIR/${profile_name}/hacks.sh" 2>&1|$DEBUG_LOG_CMD + fi + fi + if [ ! -z "$delete_hack_file" ] && [ -f "$delete_hack_file" ]; then + if [ $(whoami) = 'root' ]; then + cp "$delete_hack_file" "$FASTVM_SYSTEM_CONF_DIR/${profile_name}/delete-hacks.sh" 2>&1|$DEBUG_LOG_CMD + chmod +rx "$FASTVM_SYSTEM_CONF_DIR/${profile_name}/delete-hacks.sh" 2>&1|$DEBUG_LOG_CMD + else + cp "$delete_hack_file" "$FASTVM_USER_CONF_DIR/${profile_name}/delete-hacks.sh" 2>&1|$DEBUG_LOG_CMD + chmod +rx "$FASTVM_USER_CONF_DIR/${profile_name}/delete-hacks.sh" 2>&1|$DEBUG_LOG_CMD + fi + fi + + pmsg $P_INFO "Profile $profile_name based on Image $image_name imported\n" + ;; + remove_profile) + profile_name="$2" + if [ -z "$profile_name" ]; then pmsg $P_ERROR "missing profile name\n"; usage remove_profile; fi + + profile_path="$FASTVM_USER_CONF_DIR/${profile_name}" + if [ $(whoami) = 'root' ]; then + profile_path="$FASTVM_SYSTEM_CONF_DIR/${profile_name}" + fi + if [ ! -d "$profile_path" ]; then + pmsg $P_ERROR "profile "$profile_name" not found\n" + usage remove_profile + fi + + rm -rf "$profile_path" 2>&1|$DEBUG_LOG_CMD + pmsg $P_INFO "Profile $profile_name removed\n" + ;; create) image_name="$2" - if [ -z "$image_name" ]; then pmsg $P_ERROR "missing image name\n"; usage create; fi + if [ -z "$image_name" ]; then pmsg $P_ERROR "missing image or profile name\n"; usage create; fi image_xml_path="" - for path in "$4" "$FASTVM_USER_CONF_DIR/config-${image_name}.xml" "$FASTVM_SYSTEM_CONF_DIR/config-${image_name}.xml" + for path in "$4" "$FASTVM_USER_CONF_DIR/config-${image_name}.xml" "$FASTVM_SYSTEM_CONF_DIR/config-${image_name}.xml" "$FASTVM_USER_CONF_DIR/${image_name}/config.xml" "$FASTVM_SYSTEM_CONF_DIR/${image_name}/config.xml" do check_file "$path" "test XML file" 2>&1 >/dev/null if [ "$?" != 2 ]; then @@ -532,7 +629,7 @@ case "$1" in fi hack_file="" - for path in "$5" "$FASTVM_USER_CONF_DIR/hacks-${image_name}.sh" "$FASTVM_SYSTEM_CONF_DIR/hacks-${image_name}.sh" + for path in "$5" "$FASTVM_USER_CONF_DIR/hacks-${image_name}.sh" "$FASTVM_SYSTEM_CONF_DIR/hacks-${image_name}.sh" "$FASTVM_USER_CONF_DIR/${image_name}/hacks.sh" "$FASTVM_SYSTEM_CONF_DIR/${image_name}/hacks.sh" do check_file "$path" "hack file at $path" 2>&1 >/dev/null if [ "$?" != 2 ]; then @@ -545,6 +642,17 @@ case "$1" in break fi done + # NOTE: if profile doesn't contain hacks file the one from base image of that profile is used! + + # if the image_name looks like ProfileName + for profile_base_image in "$FASTVM_USER_CONF_DIR/${image_name}/base_image" "$FASTVM_SYSTEM_CONF_DIR/${image_name}/base_image" + do + if [ -f "$profile_base_image" ]; then + image_name=$(cat $profile_base_image) + pmsg $P_DEBUG "using image $image_name with this profile\n" + break + fi + done if [ ! -b "/dev/$THINPOOL_VG/$VM_PREFIX$image_name" ]; then pmsg $P_ERROR "Missing image for ${image_name}.\n/dev/$THINPOOL_VG/$VM_PREFIX$image_name not found.\nFirst import image using 'fast-vm image_import $image_name'\n" diff --git a/man/fast-vm.8 b/man/fast-vm.8 index 2b2b799..70ec1a5 100644 --- a/man/fast-vm.8 +++ b/man/fast-vm.8 @@ -28,6 +28,20 @@ fast-vm \(em script for defining VMs from images provided in thin LVM pool .IR ImageName .br +.B fast-vm +.BR import_profile +.IR ProfileName +.IR ImageName +.IR PathToLibvirtXML +.RI [ PathToHacksFile ] +.RI [ PathToDeleteHacksFile ] +.br + +.B fast-vm +.BR remove_profile +.IR ProfileName +.br + .B fast-vm .BR list_images .RB [ short ] @@ -35,7 +49,7 @@ fast-vm \(em script for defining VMs from images provided in thin LVM pool .B fast-vm .B create -.I ImageName +.RI < ImageName | ProfileName > .RB < base .RI | VmNumber > .RI [ PathToLibvirtXML ] From a7e9561f39d7cf6f5ce5df1659a1c5e35321c8c3 Mon Sep 17 00:00:00 2001 From: Ondrej Famera Date: Sun, 5 Feb 2017 00:40:35 +0100 Subject: [PATCH 09/28] add profile name to VM note on creation --- fast-vm | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fast-vm b/fast-vm index cbebd02..55ef6b5 100755 --- a/fast-vm +++ b/fast-vm @@ -648,8 +648,9 @@ case "$1" in for profile_base_image in "$FASTVM_USER_CONF_DIR/${image_name}/base_image" "$FASTVM_SYSTEM_CONF_DIR/${image_name}/base_image" do if [ -f "$profile_base_image" ]; then + profile_name=$image_name image_name=$(cat $profile_base_image) - pmsg $P_DEBUG "using image $image_name with this profile\n" + pmsg $P_DEBUG "using image $image_name with profile $profile_name\n" break fi done @@ -714,6 +715,10 @@ case "$1" in else # create empty VM note to identify user which created VM only for non-base VMs touch "$FASTVM_NOTES_DIR/$vm_number" 2>/dev/null + # if machine was created using profile put information about used profile into VM note + if [ "$profile_name" != "$image_name" ]; then + echo "$profile_name" > "$FASTVM_NOTES_DIR/$vm_number" + fi fi ## check if the machine doesn't exists already From 90bcf9e9e8b366b881ade05feab6aae7e14f1de0 Mon Sep 17 00:00:00 2001 From: Ondrej Famera Date: Sun, 5 Feb 2017 00:43:17 +0100 Subject: [PATCH 10/28] on VM creation check earlier if the specified image/profile exists --- fast-vm | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/fast-vm b/fast-vm index 55ef6b5..98eaa1d 100755 --- a/fast-vm +++ b/fast-vm @@ -609,6 +609,22 @@ case "$1" in image_name="$2" if [ -z "$image_name" ]; then pmsg $P_ERROR "missing image or profile name\n"; usage create; fi + # if the image_name looks like ProfileName + for profile_base_image in "$FASTVM_USER_CONF_DIR/${image_name}/base_image" "$FASTVM_SYSTEM_CONF_DIR/${image_name}/base_image" + do + if [ -f "$profile_base_image" ]; then + profile_name=$image_name + image_name=$(cat $profile_base_image) + pmsg $P_DEBUG "using image $image_name with profile $profile_name\n" + break + fi + done + + if [ ! -b "/dev/$THINPOOL_VG/$VM_PREFIX$image_name" ]; then + pmsg $P_ERROR "Missing image for ${image_name}.\n/dev/$THINPOOL_VG/$VM_PREFIX$image_name not found.\nFirst import image using 'fast-vm image_import $image_name'\n" + exit 2 + fi + image_xml_path="" for path in "$4" "$FASTVM_USER_CONF_DIR/config-${image_name}.xml" "$FASTVM_SYSTEM_CONF_DIR/config-${image_name}.xml" "$FASTVM_USER_CONF_DIR/${image_name}/config.xml" "$FASTVM_SYSTEM_CONF_DIR/${image_name}/config.xml" do @@ -644,22 +660,6 @@ case "$1" in done # NOTE: if profile doesn't contain hacks file the one from base image of that profile is used! - # if the image_name looks like ProfileName - for profile_base_image in "$FASTVM_USER_CONF_DIR/${image_name}/base_image" "$FASTVM_SYSTEM_CONF_DIR/${image_name}/base_image" - do - if [ -f "$profile_base_image" ]; then - profile_name=$image_name - image_name=$(cat $profile_base_image) - pmsg $P_DEBUG "using image $image_name with profile $profile_name\n" - break - fi - done - - if [ ! -b "/dev/$THINPOOL_VG/$VM_PREFIX$image_name" ]; then - pmsg $P_ERROR "Missing image for ${image_name}.\n/dev/$THINPOOL_VG/$VM_PREFIX$image_name not found.\nFirst import image using 'fast-vm image_import $image_name'\n" - exit 2 - fi - vm_number="$3" # validate vm_number is a 'number' $(echo "$vm_number" | grep -Eq '^[+-]?[0-9]+$') From 55696aca8f25f13581a7849124290e77037f9cf3 Mon Sep 17 00:00:00 2001 From: Ondrej Famera Date: Sun, 5 Feb 2017 10:54:17 +0100 Subject: [PATCH 11/28] bash completion for delete hack files --- fast-vm.bash_completion | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fast-vm.bash_completion b/fast-vm.bash_completion index 851ce68..cc3c5aa 100644 --- a/fast-vm.bash_completion +++ b/fast-vm.bash_completion @@ -20,7 +20,7 @@ _fast-vm() _filedir '@(xml)' return 0 fi - if [ "$cword" -eq 5 ] && [ ${COMP_WORDS[1]} == "import_image" ]; then + if [ "$cword" -eq 5 ] || [ "$cword" -eq 6 ] && [ ${COMP_WORDS[1]} == "import_image" ]; then _filedir '@(sh)' return 0 fi @@ -62,6 +62,10 @@ _fast-vm() _filedir '@(sh)' return 0 fi + if [ "$cword" -eq 3 ] && [ ${COMP_WORDS[1]} == "delete" ]; then + _filedir '@(sh)' + return 0 + fi case $prev in import_image) From 0c0d81b8ce177734223959b967f8ae19dbe64698 Mon Sep 17 00:00:00 2001 From: Ondrej Famera Date: Sun, 5 Feb 2017 11:20:56 +0100 Subject: [PATCH 12/28] change usage function so there is only one copy of documentation text --- fast-vm | 31 ++++++++----------------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/fast-vm b/fast-vm index 98eaa1d..025881b 100755 --- a/fast-vm +++ b/fast-vm @@ -145,7 +145,6 @@ check_vm_number () { usage () { part="$1" - echo '' case $part in import_image) echo "$0 import_image ImageName PathToLibvirtXML [PathToHacksFile] [PathToDeleteHackFile]" @@ -193,30 +192,16 @@ usage () { echo "$0 list [all|active|inactive [short]]" ;; *) -cat < - -fast-vm import_image ImageName PathToLibvirtXML [PathToHacksFile] [PathToDeleteHackFile] -fast-vm export_image ImageName -fast-vm remove_image ImageName -fast-vm import_profile ProfileName ImageName PathToLibvirtXML [PathToHacksFile] [PathToDeleteHackFile] -fast-vm remove_profile ProfileName -fast-vm list_images [short] -fast-vm create [PathToLibvirtXML] [PathToHacksFile] -fast-vm delete VmNumber [PathToDeleteHackFile] -fast-vm edit_note VmNumber [NoteText] -fast-vm info VmNumber -fast-vm list [all|active|inactive [short]] -fast-vm start VmNumber [console|ssh [/path/to/custom/script]] -fast-vm stop VmNumber [graceful] -fast-vm console VmNumber -fast-vm ssh VmNumber [/path/to/custom/script] - -== fast-vm version 1.0 == -EOF + echo "== fast-vm version 1.0 ==" + echo "$0 " + for cmd in import_image export_image remove_image import_profile remove_profile list_images create delete edit_note info list start stop console ssh; + do + usage $cmd noexit + done ;; esac - exit 1 + # exit only when second parameter is not specified, otherwise just return and continue + if [ -z "$2" ]; then exit 1; fi } #### end common functions From 498a33cc5976546715f35690d32c1efe17fc1ee4 Mon Sep 17 00:00:00 2001 From: Ondrej Famera Date: Sun, 5 Feb 2017 13:29:48 +0100 Subject: [PATCH 13/28] add list_profiles function and connect it to bash completion --- fast-vm | 33 +++++++++++++++++++++++++++++++++ fast-vm.bash_completion | 10 ++++++++-- man/fast-vm.8 | 5 +++++ 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/fast-vm b/fast-vm index 025881b..f19400b 100755 --- a/fast-vm +++ b/fast-vm @@ -164,6 +164,9 @@ usage () { list_images) echo "$0 list_images [short]" ;; + list_profiles) + echo "$0 list_profiles [short]" + ;; create) echo "$0 create [PathToLibvirtXML] [PathToHacksFile]" ;; @@ -1048,6 +1051,36 @@ case "$1" in printf "\n USER XML and hack file(s) takes precendense before SYSTEM ones.\n" fi ;; + list_profiles) + short_output="$2" # if non-zero the output suitable for external processing + profile_dir_list=$(find $FASTVM_SYSTEM_CONF_DIR/ $FASTVM_USER_CONF_DIR/ -mindepth 1 -maxdepth 1 -type d 2>/dev/null) + if [ ! -z "$short_output" ] && [ "$short_output" = "short" ]; then + for dir in $profile_dir_list; + do + # valid profile must contain at least base image name + if [ -f "$dir/base_image" ]; then + basename $dir + fi + done + else + printf "%-41s|%-41s\n" 'Names' 'Changes provided by profile' + printf "%-20s|%-20s|%-5s|%-7s|%-14s\n" 'Profile Name' 'Base Image Name' 'XML' 'hacks' 'delete-hacks' + for dir in $profile_dir_list; + do + profile_name=$(basename $dir) + base_image_name=$(cat $dir/base_image 2>/dev/null) + # skip directories not containing base image name + if [ -z "$base_image_name" ]; then continue; fi + profile_xml='no' + profile_hacks='no' + profile_delete_hacks='no' + if [ -f "$dir/config.xml" ]; then profile_xml='yes'; fi + if [ -f "$dir/hacks.sh" ]; then profile_hacks='yes'; fi + if [ -f "$dir/delete-hacks.sh" ]; then profile_delete_hacks='yes'; fi + printf "%-20s|%-20s|%-5s|%-7s|%-14s\n" "$profile_name" "$base_image_name" "$profile_xml" "$profile_hacks" "$profile_delete_hacks" + done + fi + ;; info) vm_number="$2" if [ -z "$vm_number" ]; then pmsg $P_ERROR "VM number missing\n"; usage delete; fi diff --git a/fast-vm.bash_completion b/fast-vm.bash_completion index cc3c5aa..b31a686 100644 --- a/fast-vm.bash_completion +++ b/fast-vm.bash_completion @@ -73,15 +73,21 @@ _fast-vm() ;; create|remove_image|export_image) local image_name + local profile_name image_name=$(fast-vm list_images short) - COMPREPLY=( $( compgen -W "$image_name" -- "$cur" ) ) + profile_name=$(fast-vm list_profiles short) + COMPREPLY=( $( compgen -W "$image_name $profile_name" -- "$cur" ) ) return 0 ;; list_images) COMPREPLY=( $( compgen -W "short" -- "$cur" ) ) return 0 ;; + list_profiles) + COMPREPLY=( $( compgen -W "short" -- "$cur" ) ) + return 0 + ;; list) COMPREPLY=( $( compgen -W "all active inactive" -- "$cur" ) ) return 0 @@ -106,7 +112,7 @@ _fast-vm() $split && return 0 if [ "$cword" -lt 2 ]; then - COMPREPLY=( $( compgen -W 'import_image export_image remove_image edit_note list_images create start stop delete console ssh list info' -- "$cur" ) ) + COMPREPLY=( $( compgen -W 'import_image export_image remove_image import_profile remove_profile edit_note list_images list_profiles create start stop delete console ssh list info' -- "$cur" ) ) return 0 fi diff --git a/man/fast-vm.8 b/man/fast-vm.8 index 70ec1a5..4d3ca5b 100644 --- a/man/fast-vm.8 +++ b/man/fast-vm.8 @@ -47,6 +47,11 @@ fast-vm \(em script for defining VMs from images provided in thin LVM pool .RB [ short ] .br +.B fast-vm +.BR list_profiles +.RB [ short ] +.br + .B fast-vm .B create .RI < ImageName | ProfileName > From 7ec80d624d014017e37277c5f0a951fc161efb73 Mon Sep 17 00:00:00 2001 From: Ondrej Famera Date: Sun, 5 Feb 2017 13:30:47 +0100 Subject: [PATCH 14/28] optimize operations on config files - untested --- fast-vm | 99 +++++++++++++++++++-------------------------------------- 1 file changed, 32 insertions(+), 67 deletions(-) diff --git a/fast-vm b/fast-vm index f19400b..d5f6ee1 100755 --- a/fast-vm +++ b/fast-vm @@ -142,6 +142,17 @@ check_vm_number () { fi } +config_file_operation () { + cmd="$1" + options="$2" + + if [ "$(whoami)" = 'root' ]; then + "$cmd $FASTVM_SYSTEM_CONF_DIR/$options" 2>&1|$DEBUG_LOG_CMD + else + "$cmd $FASTVM_USER_CONF_DIR/$options" 2>&1|$DEBUG_LOG_CMD + fi +} + usage () { part="$1" @@ -353,11 +364,7 @@ case "$1" in pmsg $P_DEBUG "importing image $image_path into /dev/$THINPOOL_VG/$VM_PREFIX$image_name\n" if [ "$image_path" = "empty" ]; then - if [ "$(whoami)" = 'root' ]; then - cp "$image_xml_path" "$FASTVM_SYSTEM_CONF_DIR/config-${image_name}.xml" 2>&1|$DEBUG_LOG_CMD - else - cp "$image_xml_path" "$FASTVM_USER_CONF_DIR/config-${image_name}.xml" 2>&1|$DEBUG_LOG_CMD - fi + config_file_operation "cp $image_xml_path" "config-${image_name}.xml" pmsg $P_INFO "Empty image imported\n" exit 0 fi @@ -389,30 +396,15 @@ case "$1" in fi # copy the XML configuration file - if [ $(whoami) = 'root' ]; then - cp "$image_xml_path" "$FASTVM_SYSTEM_CONF_DIR/config-${image_name}.xml" 2>&1|$DEBUG_LOG_CMD - chmod +r "$FASTVM_SYSTEM_CONF_DIR/config-${image_name}.xml" 2>&1|$DEBUG_LOG_CMD - else - cp "$image_xml_path" "$FASTVM_USER_CONF_DIR/config-${image_name}.xml" 2>&1|$DEBUG_LOG_CMD - chmod +r "$FASTVM_USER_CONF_DIR/config-${image_name}.xml" 2>&1|$DEBUG_LOG_CMD - fi + config_file_operation "cp $image_xml_path" "config-${image_name}.xml" + config_file_operation "chmod +r" "config-${image_name}.xml" if [ ! -z "$hack_file" ] && [ -f "$hack_file" ]; then - if [ $(whoami) = 'root' ]; then - cp "$hack_file" "$FASTVM_SYSTEM_CONF_DIR/hacks-${image_name}.sh" 2>&1|$DEBUG_LOG_CMD - chmod +rx "$FASTVM_SYSTEM_CONF_DIR/hacks-${image_name}.sh" 2>&1|$DEBUG_LOG_CMD - else - cp "$hack_file" "$FASTVM_USER_CONF_DIR/hacks-${image_name}.sh" 2>&1|$DEBUG_LOG_CMD - chmod +rx "$FASTVM_USER_CONF_DIR/hacks-${image_name}.sh" 2>&1|$DEBUG_LOG_CMD - fi + config_file_operation "cp $hack_file" "hacks-${image_name}.sh" + config_file_operation "chmod +rx" "hacks-${image_name}.sh" fi if [ ! -z "$delete_hack_file" ] && [ -f "$delete_hack_file" ]; then - if [ $(whoami) = 'root' ]; then - cp "$delete_hack_file" "$FASTVM_SYSTEM_CONF_DIR/delete-hacks-${image_name}.sh" 2>&1|$DEBUG_LOG_CMD - chmod +rx "$FASTVM_SYSTEM_CONF_DIR/delete-hacks-${image_name}.sh" 2>&1|$DEBUG_LOG_CMD - else - cp "$delete_hack_file" "$FASTVM_USER_CONF_DIR/delete-hacks-${image_name}.sh" 2>&1|$DEBUG_LOG_CMD - chmod +rx "$FASTVM_USER_CONF_DIR/delete-hacks-${image_name}.sh" 2>&1|$DEBUG_LOG_CMD - fi + config_file_operation "cp $delete_hack_file" "delete-hacks-${image_name}.sh" + config_file_operation "chmod +rx" "delete-hacks-${image_name}.sh" fi pmsg $P_INFO "Image $image_name imported\n" @@ -488,16 +480,10 @@ case "$1" in virsh --connect qemu:///system undefine $VM_PREFIX$image_name --nvram 2>&1|$DEBUG_LOG_CMD pmsg $P_DEBUG "removing LV $VM_PREFIX$image_name ...\n" echo "lvremove" "/dev/$THINPOOL_VG/$VM_PREFIX$image_name" | sudo -n $FASTVM_HELPER - pmsg $P_DEBUG "removing XML and hack file of $image_name...\n" - if [ -f "$FASTVM_USER_CONF_DIR/config-${image_name}.xml" ]; then rm "$FASTVM_USER_CONF_DIR/config-${image_name}.xml"; fi - if [ -f "$FASTVM_USER_CONF_DIR/hacks-${image_name}.sh" ]; then rm "$FASTVM_USER_CONF_DIR/hacks-${image_name}.sh"; fi - if [ -f "$FASTVM_USER_CONF_DIR/delete-hacks-${image_name}.sh" ]; then rm "$FASTVM_USER_CONF_DIR/delete-hacks-${image_name}.sh"; fi - if [ $(whoami) = 'root' ]; then - pmsg $P_DEBUG "removing system-wide XML and hack file ...\n" - if [ -f "$FASTVM_SYSTEM_CONF_DIR/config-${image_name}.xml" ]; then rm "$FASTVM_SYSTEM_CONF_DIR/config-${image_name}.xml"; fi - if [ -f "$FASTVM_SYSTEM_CONF_DIR/hacks-${image_name}.sh" ]; then rm "$FASTVM_SYSTEM_CONF_DIR/hacks-${image_name}.sh"; fi - if [ -f "$FASTVM_SYSTEM_CONF_DIR/delete-hacks-${image_name}.sh" ]; then rm "$FASTVM_SYSTEM_CONF_DIR/delete-hacks-${image_name}.sh"; fi - fi + pmsg $P_DEBUG "removing XML and hack file(s) of $image_name...\n" + config_file_operation "rm" "config-${image_name}.xml" + config_file_operation "rm" "hacks-${image_name}.sh" + config_file_operation "rm" "delete-hacks-${image_name}.sh" pmsg $P_INFO "image $image_name removed\n" else pmsg $P_ERROR "image "$image_name" not found\n" @@ -545,34 +531,17 @@ case "$1" in fi # create profile and copy files to right places - if [ $(whoami) = 'root' ]; then - if [ ! -d "$FASTVM_SYSTEM_CONF_DIR/${profile_name}" ]; then mkdir "$FASTVM_SYSTEM_CONF_DIR/${profile_name}"; fi - echo "$image_name" > "$FASTVM_SYSTEM_CONF_DIR/${profile_name}/base_image" - cp "$image_xml_path" "$FASTVM_SYSTEM_CONF_DIR/${profile_name}/config.xml" 2>&1|$DEBUG_LOG_CMD - chmod +r "$FASTVM_SYSTEM_CONF_DIR/${profile_name}/config.xml" 2>&1|$DEBUG_LOG_CMD - else - if [ ! -d "$FASTVM_USER_CONF_DIR/${profile_name}" ]; then mkdir "$FASTVM_USER_CONF_DIR/${profile_name}"; fi - echo "$image_name" > "$FASTVM_USER_CONF_DIR/${profile_name}/base_image" - cp "$image_xml_path" "$FASTVM_USER_CONF_DIR/${profile_name}/config.xml" 2>&1|$DEBUG_LOG_CMD - chmod +r "$FASTVM_USER_CONF_DIR/${profile_name}/config.xml" 2>&1|$DEBUG_LOG_CMD - fi + config_file_operation "mkdir" "${profile_name}" + config_file_operation "echo $image_name >" "${profile_name}/base_image" + config_file_operation "cp $image_xml_path" "${profile_name}/config.xml" + config_file_operation "chmod +r" "${profile_name}/config.xml" if [ ! -z "$hack_file" ] && [ -f "$hack_file" ]; then - if [ $(whoami) = 'root' ]; then - cp "$hack_file" "$FASTVM_SYSTEM_CONF_DIR/${profile_name}/hacks.sh" 2>&1|$DEBUG_LOG_CMD - chmod +rx "$FASTVM_SYSTEM_CONF_DIR/${profile_name}/hacks.sh" 2>&1|$DEBUG_LOG_CMD - else - cp "$hack_file" "$FASTVM_USER_CONF_DIR/${profile_name}/hacks.sh" 2>&1|$DEBUG_LOG_CMD - chmod +rx "$FASTVM_USER_CONF_DIR/${profile_name}/hacks.sh" 2>&1|$DEBUG_LOG_CMD - fi + config_file_operation "cp $hack_file" "${profile_name}/hacks.sh" + config_file_operation "chmod +rx" "${profile_name}/hacks.sh" fi if [ ! -z "$delete_hack_file" ] && [ -f "$delete_hack_file" ]; then - if [ $(whoami) = 'root' ]; then - cp "$delete_hack_file" "$FASTVM_SYSTEM_CONF_DIR/${profile_name}/delete-hacks.sh" 2>&1|$DEBUG_LOG_CMD - chmod +rx "$FASTVM_SYSTEM_CONF_DIR/${profile_name}/delete-hacks.sh" 2>&1|$DEBUG_LOG_CMD - else - cp "$delete_hack_file" "$FASTVM_USER_CONF_DIR/${profile_name}/delete-hacks.sh" 2>&1|$DEBUG_LOG_CMD - chmod +rx "$FASTVM_USER_CONF_DIR/${profile_name}/delete-hacks.sh" 2>&1|$DEBUG_LOG_CMD - fi + config_file_operation "cp $delete_hack_file" "${profile_name}/delete-hacks.sh" + config_file_operation "chmod +rx" "${profile_name}/delete-hacks.sh" fi pmsg $P_INFO "Profile $profile_name based on Image $image_name imported\n" @@ -581,16 +550,12 @@ case "$1" in profile_name="$2" if [ -z "$profile_name" ]; then pmsg $P_ERROR "missing profile name\n"; usage remove_profile; fi - profile_path="$FASTVM_USER_CONF_DIR/${profile_name}" - if [ $(whoami) = 'root' ]; then - profile_path="$FASTVM_SYSTEM_CONF_DIR/${profile_name}" - fi - if [ ! -d "$profile_path" ]; then + if [ ! -d "$FASTVM_USER_CONF_DIR/${profile_name}" ] && [ ! -d "$FASTVM_SYSTEM_CONF_DIR/${profile_name}" ]; then pmsg $P_ERROR "profile "$profile_name" not found\n" usage remove_profile fi - rm -rf "$profile_path" 2>&1|$DEBUG_LOG_CMD + config_file_operation "rm -rf" "$profile_name" pmsg $P_INFO "Profile $profile_name removed\n" ;; create) From 7e1d3e2fa18b307403435c6efa2fff78f78c4dc1 Mon Sep 17 00:00:00 2001 From: Ondrej Famera Date: Tue, 7 Feb 2017 22:42:30 +0100 Subject: [PATCH 15/28] fix wrong date in spec files --- rpm/fast-vm-centos7.spec | 2 +- rpm/fast-vm.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rpm/fast-vm-centos7.spec b/rpm/fast-vm-centos7.spec index a2d856d..ca42e15 100644 --- a/rpm/fast-vm-centos7.spec +++ b/rpm/fast-vm-centos7.spec @@ -58,7 +58,7 @@ drive of new machine before starting VM using the 'hack files'. %config(noreplace) %{_sysconfdir}/sudoers.d/%{name}-sudoers %changelog -* Sun Now 13 2016 Ondrej Famera 1.0-1 +* Sun Nov 13 2016 Ondrej Famera 1.0-1 - added support for handling machines with UEFI firmware - improve error messages and documentation - fix locking and make it dependent on image block device diff --git a/rpm/fast-vm.spec b/rpm/fast-vm.spec index fbe6700..929d17f 100755 --- a/rpm/fast-vm.spec +++ b/rpm/fast-vm.spec @@ -64,7 +64,7 @@ drive of new machine before starting VM using the 'hack files'. %config(noreplace) %{_sysconfdir}/sudoers.d/%{name}-sudoers %changelog -* Sun Now 13 2016 Ondrej Famera 1.0-1 +* Sun Nov 13 2016 Ondrej Famera 1.0-1 - added support for handling machines with UEFI firmware - improve error messages and documentation - fix locking and make it dependent on image block device From 5344f95de8340a5f267b117df6c5d2f590fcc5e8 Mon Sep 17 00:00:00 2001 From: Ondrej Famera Date: Tue, 7 Feb 2017 22:43:10 +0100 Subject: [PATCH 16/28] FIX config_file_operation to execute parameters --- fast-vm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fast-vm b/fast-vm index d5f6ee1..ebda98b 100755 --- a/fast-vm +++ b/fast-vm @@ -147,9 +147,9 @@ config_file_operation () { options="$2" if [ "$(whoami)" = 'root' ]; then - "$cmd $FASTVM_SYSTEM_CONF_DIR/$options" 2>&1|$DEBUG_LOG_CMD + $cmd $FASTVM_SYSTEM_CONF_DIR/$options 2>&1|$DEBUG_LOG_CMD else - "$cmd $FASTVM_USER_CONF_DIR/$options" 2>&1|$DEBUG_LOG_CMD + $cmd $FASTVM_USER_CONF_DIR/$options 2>&1|$DEBUG_LOG_CMD fi } From d9876487106a19f011c7a725e1359522e4f99c0c Mon Sep 17 00:00:00 2001 From: Ondrej Famera Date: Tue, 7 Feb 2017 22:43:40 +0100 Subject: [PATCH 17/28] FIX config_file_operation call when trying to redirect output, use temporary file and cp instead --- fast-vm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fast-vm b/fast-vm index ebda98b..2a8fa4c 100755 --- a/fast-vm +++ b/fast-vm @@ -532,7 +532,10 @@ case "$1" in # create profile and copy files to right places config_file_operation "mkdir" "${profile_name}" - config_file_operation "echo $image_name >" "${profile_name}/base_image" + tmp_base_image=$(mktemp) + echo $image_name > $tmp_base_image + config_file_operation "cp $tmp_base_image" "${profile_name}/base_image" + rm -f $tmp_base_image config_file_operation "cp $image_xml_path" "${profile_name}/config.xml" config_file_operation "chmod +r" "${profile_name}/config.xml" if [ ! -z "$hack_file" ] && [ -f "$hack_file" ]; then From be963ab4e0532cc807c0481094dff966074105e4 Mon Sep 17 00:00:00 2001 From: Ondrej Famera Date: Tue, 7 Feb 2017 23:02:11 +0100 Subject: [PATCH 18/28] FIX wrong path to profile XML and hacks file when creating VM --- fast-vm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fast-vm b/fast-vm index 2a8fa4c..b3be4f1 100755 --- a/fast-vm +++ b/fast-vm @@ -582,7 +582,7 @@ case "$1" in fi image_xml_path="" - for path in "$4" "$FASTVM_USER_CONF_DIR/config-${image_name}.xml" "$FASTVM_SYSTEM_CONF_DIR/config-${image_name}.xml" "$FASTVM_USER_CONF_DIR/${image_name}/config.xml" "$FASTVM_SYSTEM_CONF_DIR/${image_name}/config.xml" + for path in "$4" "$FASTVM_USER_CONF_DIR/config-${image_name}.xml" "$FASTVM_SYSTEM_CONF_DIR/config-${image_name}.xml" "$FASTVM_USER_CONF_DIR/${profile_name}/config.xml" "$FASTVM_SYSTEM_CONF_DIR/${profile_name}/config.xml" do check_file "$path" "test XML file" 2>&1 >/dev/null if [ "$?" != 2 ]; then @@ -601,7 +601,7 @@ case "$1" in fi hack_file="" - for path in "$5" "$FASTVM_USER_CONF_DIR/hacks-${image_name}.sh" "$FASTVM_SYSTEM_CONF_DIR/hacks-${image_name}.sh" "$FASTVM_USER_CONF_DIR/${image_name}/hacks.sh" "$FASTVM_SYSTEM_CONF_DIR/${image_name}/hacks.sh" + for path in "$5" "$FASTVM_USER_CONF_DIR/hacks-${image_name}.sh" "$FASTVM_SYSTEM_CONF_DIR/hacks-${image_name}.sh" "$FASTVM_USER_CONF_DIR/${profile_name}/hacks.sh" "$FASTVM_SYSTEM_CONF_DIR/${profile_name}/hacks.sh" do check_file "$path" "hack file at $path" 2>&1 >/dev/null if [ "$?" != 2 ]; then From 75121348865053a2a92a44f7373eadbbe707f2df Mon Sep 17 00:00:00 2001 From: Ondrej Famera Date: Tue, 7 Feb 2017 23:04:29 +0100 Subject: [PATCH 19/28] FIX order when detecting profile hacks and XML files --- fast-vm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fast-vm b/fast-vm index b3be4f1..f6bea7d 100755 --- a/fast-vm +++ b/fast-vm @@ -582,7 +582,7 @@ case "$1" in fi image_xml_path="" - for path in "$4" "$FASTVM_USER_CONF_DIR/config-${image_name}.xml" "$FASTVM_SYSTEM_CONF_DIR/config-${image_name}.xml" "$FASTVM_USER_CONF_DIR/${profile_name}/config.xml" "$FASTVM_SYSTEM_CONF_DIR/${profile_name}/config.xml" + for path in "$4" "$FASTVM_USER_CONF_DIR/${profile_name}/config.xml" "$FASTVM_SYSTEM_CONF_DIR/${profile_name}/config.xml" "$FASTVM_USER_CONF_DIR/config-${image_name}.xml" "$FASTVM_SYSTEM_CONF_DIR/config-${image_name}.xml" do check_file "$path" "test XML file" 2>&1 >/dev/null if [ "$?" != 2 ]; then @@ -601,7 +601,7 @@ case "$1" in fi hack_file="" - for path in "$5" "$FASTVM_USER_CONF_DIR/hacks-${image_name}.sh" "$FASTVM_SYSTEM_CONF_DIR/hacks-${image_name}.sh" "$FASTVM_USER_CONF_DIR/${profile_name}/hacks.sh" "$FASTVM_SYSTEM_CONF_DIR/${profile_name}/hacks.sh" + for path in "$5" "$FASTVM_USER_CONF_DIR/${profile_name}/hacks.sh" "$FASTVM_SYSTEM_CONF_DIR/${profile_name}/hacks.sh" "$FASTVM_USER_CONF_DIR/hacks-${image_name}.sh" "$FASTVM_SYSTEM_CONF_DIR/hacks-${image_name}.sh" do check_file "$path" "hack file at $path" 2>&1 >/dev/null if [ "$?" != 2 ]; then From f1a58c2e1834c44645fda89036707e6076f0c756 Mon Sep 17 00:00:00 2001 From: Ondrej Famera Date: Wed, 8 Feb 2017 23:58:51 +0100 Subject: [PATCH 20/28] add profile_* related bash completions --- fast-vm.bash_completion | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/fast-vm.bash_completion b/fast-vm.bash_completion index b31a686..1f8ccf8 100644 --- a/fast-vm.bash_completion +++ b/fast-vm.bash_completion @@ -24,6 +24,21 @@ _fast-vm() _filedir '@(sh)' return 0 fi + if [ "$cword" -eq 3 ] && [ ${COMP_WORDS[1]} == "import_profile" ]; then + local image_name + + image_name=$(fast-vm list_images short) + COMPREPLY=( $( compgen -W "$image_name" -- "$cur" ) ) + return 0 + fi + if [ "$cword" -eq 4 ] && [ ${COMP_WORDS[1]} == "import_profile" ]; then + _filedir '@(xml)' + return 0 + fi + if [ "$cword" -eq 5 ] || [ "$cword" -eq 6 ] && [ ${COMP_WORDS[1]} == "import_profile" ]; then + _filedir '@(sh)' + return 0 + fi if [ "$cword" -eq 3 ] && [ ${COMP_WORDS[1]} == "export_image" ]; then COMPREPLY=( $( compgen -W "xz gz" -- "$cur" ) ) @@ -68,7 +83,7 @@ _fast-vm() fi case $prev in - import_image) + import_image|import_profile) return 0 ;; create|remove_image|export_image) @@ -80,11 +95,14 @@ _fast-vm() COMPREPLY=( $( compgen -W "$image_name $profile_name" -- "$cur" ) ) return 0 ;; - list_images) - COMPREPLY=( $( compgen -W "short" -- "$cur" ) ) + remove_profile) + local profile_name + + profile_name=$(fast-vm list_profiles short) + COMPREPLY=( $( compgen -W "$profile_name" -- "$cur" ) ) return 0 ;; - list_profiles) + list_images|list_profiles) COMPREPLY=( $( compgen -W "short" -- "$cur" ) ) return 0 ;; From c254b3e9132e8524318492daf283bc7ee19f6c58 Mon Sep 17 00:00:00 2001 From: Ondrej Famera Date: Thu, 9 Feb 2017 00:04:17 +0100 Subject: [PATCH 21/28] store profile name in separate note for VM so we can apply the delete hacks of the profile. --- fast-vm | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/fast-vm b/fast-vm index f6bea7d..c26b6f3 100755 --- a/fast-vm +++ b/fast-vm @@ -673,7 +673,7 @@ case "$1" in touch "$FASTVM_NOTES_DIR/$vm_number" 2>/dev/null # if machine was created using profile put information about used profile into VM note if [ "$profile_name" != "$image_name" ]; then - echo "$profile_name" > "$FASTVM_NOTES_DIR/$vm_number" + echo "$profile_name" > "$FASTVM_NOTES_DIR/$vm_number.profile" fi fi @@ -832,11 +832,15 @@ case "$1" in exit 1 fi + if [ -f "$FASTVM_NOTES_DIR/$vm_number.profile" ]; then + profile_name=$(cat $FASTVM_NOTES_DIR/$vm_number.profile) + fi + # determine image name of VM image_name=$(virsh --connect qemu:///system list --all|awk '{print $2,$3,$4}'|egrep "^${VM_PREFIX}.*-[0-9]+ "|sed "s/${VM_PREFIX}\(.\+\)-\([0-9]\+\) \(.\+\)$/\2 \1 \3/"|awk "\$1==$vm_number {printf \"%s\",\$2}") delete_hack_file="" - for path in "$3" "$FASTVM_USER_CONF_DIR/delete-hacks-${image_name}.sh" "$FASTVM_SYSTEM_CONF_DIR/delete-hacks-${image_name}.sh" + for path in "$3" "$FASTVM_USER_CONF_DIR/${profile_name}/delete-hacks.sh" "$FASTVM_SYSTEM_CONF_DIR/${profile_name}/delete-hacks.sh" "$FASTVM_USER_CONF_DIR/delete-hacks-${image_name}.sh" "$FASTVM_SYSTEM_CONF_DIR/delete-hacks-${image_name}.sh" do check_file "$path" "delete hack file at $path" 2>&1 >/dev/null if [ "$?" != 2 ]; then @@ -903,6 +907,8 @@ case "$1" in fi pmsg $P_DEBUG "applying delete hacks finished\n" fi + # remove profile identifier once delete-hacks.sh were applied in case this machine was based on profile + if [ -f "$FASTVM_NOTES_DIR/$vm_number.profile" ]; then rm "$FASTVM_NOTES_DIR/$vm_number.profile"; fi pmsg $P_DEBUG "undefining VM $vm_name from libvirt\n" virsh --connect qemu:///system undefine $vm_name --nvram From 87a5492736c10b984ddff7a73da003b2b2b8379b Mon Sep 17 00:00:00 2001 From: Ondrej Famera Date: Thu, 9 Feb 2017 00:11:00 +0100 Subject: [PATCH 22/28] display profile name in 'fast-vm list' output --- fast-vm | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/fast-vm b/fast-vm index c26b6f3..b81dcc0 100755 --- a/fast-vm +++ b/fast-vm @@ -949,18 +949,22 @@ case "$1" in if [ ! -z "$short_output" ] && [ "$short_output" = "short" ]; then echo "$vm_list" else - printf "%3s %-20s %-12s %s\n" "VM#" "Image name" "Status" "Notes" - data=$(virsh --connect qemu:///system list --all|awk '{print $2,$3,$4}'|egrep "^${VM_PREFIX}.*-[0-9]+ "|sed "s/${VM_PREFIX}\(.\+\)-\([0-9]\+\) \(.\+\)$/\2 \1 \3/"|awk '{printf "%3s %-20s %s %s\n",$1,$2,$3,$4}') + printf "%3s %-15s %-12s %-15s %s\n" "VM#" "Image name" "Status" "Profile_name" "Notes" + data=$(virsh --connect qemu:///system list --all|awk '{print $2,$3,$4}'|egrep "^${VM_PREFIX}.*-[0-9]+ "|sed "s/${VM_PREFIX}\(.\+\)-\([0-9]\+\) \(.\+\)$/\2 \1 \3/"|awk '{printf "%3s %-15s %s %s\n",$1,$2,$3,$4}') for vm in $vm_list; do out=$(echo "$data"|egrep "(^ $vm|^$vm) ") + profile_name='---' if [ -f "$FASTVM_NOTES_DIR/$vm" ]; then owner=$(stat --format="%U" "$FASTVM_NOTES_DIR/$vm") note=$(head -1 "$FASTVM_NOTES_DIR/$vm") note=$(echo "$owner: $note"|cut -c 1-$(($TERMINAL_WIDTH-38))) - printf "%-37s %-s\n" "$out" "$note" + if [ -f "$FASTVM_NOTES_DIR/$vm.profile" ]; then + profile_name=$(cat $FASTVM_NOTES_DIR/$vm.profile) + fi + printf "%-32s %-15s %-s\n" "$out" "$profile_name" "$note" else - printf "%-37s -----\n" "$out" + printf "%-32s -----\n" "$out" fi done From 78a4ce01da4fe25b4be78e4b5155b6c2bf404a3c Mon Sep 17 00:00:00 2001 From: Ondrej Famera Date: Sat, 11 Feb 2017 23:16:19 +0100 Subject: [PATCH 23/28] FIX do not create empty profile name when we use just an image - make the profile_name to default to image_name --- fast-vm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fast-vm b/fast-vm index b81dcc0..a73828d 100755 --- a/fast-vm +++ b/fast-vm @@ -566,7 +566,8 @@ case "$1" in if [ -z "$image_name" ]; then pmsg $P_ERROR "missing image or profile name\n"; usage create; fi # if the image_name looks like ProfileName - for profile_base_image in "$FASTVM_USER_CONF_DIR/${image_name}/base_image" "$FASTVM_SYSTEM_CONF_DIR/${image_name}/base_image" + profile_name=$image_name + for profile_base_image in "$FASTVM_USER_CONF_DIR/${profile_name}/base_image" "$FASTVM_SYSTEM_CONF_DIR/${profile_name}/base_image" do if [ -f "$profile_base_image" ]; then profile_name=$image_name From c523298af45f161faab13ddb625e85c4b7751ec2 Mon Sep 17 00:00:00 2001 From: Ondrej Famera Date: Sat, 11 Feb 2017 23:35:12 +0100 Subject: [PATCH 24/28] testing version of gentoo ebuild for 1.0 version --- ebuild/app-emulation/fast-vm/Manifest | 2 + .../app-emulation/fast-vm/fast-vm-1.0.ebuild | 50 +++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 ebuild/app-emulation/fast-vm/Manifest create mode 100644 ebuild/app-emulation/fast-vm/fast-vm-1.0.ebuild diff --git a/ebuild/app-emulation/fast-vm/Manifest b/ebuild/app-emulation/fast-vm/Manifest new file mode 100644 index 0000000..4f13588 --- /dev/null +++ b/ebuild/app-emulation/fast-vm/Manifest @@ -0,0 +1,2 @@ +DIST 1.0.tar.gz 31600 SHA256 cc7724e9929679120355b4e6d2d6e9bd62983f112560dc9f1ddae866c70925bd SHA512 d3f36e3dbfff31703552462dcc496dd56c33c2852168da9e84f02826a7ba037ce9722b4a9638c31a2f7bb0007af71a60ba20a61ab8f9853f5e02ccc17ba43970 WHIRLPOOL 1742175c84a4c8154cf9139285ce6e2890f0a99a57f218f91b18fef233e9c738f2e875c4dfebca5f69f7226d5c6f05c4ad7916d9d74f9e4eab6518d01c5cf195 +EBUILD fast-vm-1.0.ebuild 1149 SHA256 eda09bf206703d275662491b9fb0ef3344d968d3456e5fe83b7bbbbd10ef1a8d SHA512 b531c249dcbee4f95ae0911438ab607c72c460bae7a7e86d130b9a677b15bce1a6e9b526b7a788cb18cfa2344d6c3fdde92eefa2ee09a3bd1183e20c2914cb72 WHIRLPOOL 55dde988c3e29a1fd884356f5be10612768f7b4fb0fcda6fa8c8533c49fc891f8269bc5d3e2a7bf429d620a47861c160ad4d63b73d36f3d44e5b557cab181ead diff --git a/ebuild/app-emulation/fast-vm/fast-vm-1.0.ebuild b/ebuild/app-emulation/fast-vm/fast-vm-1.0.ebuild new file mode 100644 index 0000000..39c1074 --- /dev/null +++ b/ebuild/app-emulation/fast-vm/fast-vm-1.0.ebuild @@ -0,0 +1,50 @@ +# Copyright 1999-2016 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Id$ + +EAPI=6 + +inherit linux-info + +DESCRIPTION="Script for defining VMs from images provided in thin LVM pool" +HOMEPAGE="https://www.famera.cz/blog/fast-vm/about.html" +SRC_URI="https://github.com/OndrejHome/fast-vm/archive/1.0.tar.gz" + +LICENSE="GPLv3" +SLOT="0" +KEYWORDS="~amd64 ~x86" +IUSE="+hack-file-dependencies +curl +bash-completion" + +# built time dependencies +DEPEND="" +# runtime dependencies +RDEPEND=" + app-emulation/libvirt[virt-networks] + net-dns/dnsmasq[dhcp-tools,script] + sys-apps/gawk + sys-apps/coreutils + app-admin/sudo + dev-libs/libxml2 + sys-fs/lvm2[thin] + curl? ( net-misc/curl ) + hack-file-dependencies? ( + app-emulation/libguestfs + app-emulation/libguestfs-appliance + app-emulation/libvirt[virt-networks,qemu] + ) + bash-completion? ( app-shells/bash-completion ) +" + +src_compile() { + return +} + +pkg_setup() { + # check if some basic kernel modules not checked elsewhere are needed + CONFIG_CHECK=" + ~DM_SNAPSHOT + ~DM_THIN_PROVISIONING" + if [[ -n ${CONFIG_CHECK} ]]; then + linux-info_pkg_setup + fi +} From fab0c0d9159301162ac1f5df75d98d7df7bc1054 Mon Sep 17 00:00:00 2001 From: Ondrej Famera Date: Mon, 13 Feb 2017 13:35:38 +0100 Subject: [PATCH 25/28] add profiles documentation to man page --- man/fast-vm.8 | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/man/fast-vm.8 b/man/fast-vm.8 index 4d3ca5b..b5a7f4c 100644 --- a/man/fast-vm.8 +++ b/man/fast-vm.8 @@ -257,6 +257,10 @@ To use virtual machines with UEFI you will need a UEFI firmware for qemu which i When creating the custom image you will have to specify location of UEFI firmware and provide the location of UEFI variable files in .RI " " "/etc/libvirt/qemu.conf" " file so the libvirt can automaticaly take care of UEFI vars creation and deletion." +.SH IMAGE PROFILES (from fast-vm-1.1) +Profiles simplyfies the use of alternative libvirt XML files and hack files. Profile defines the set of alternative libvirt XML, hack files under one +profile name that can be used as imageName when creating the new VM. If VM was created using profile this will be indicated in the list output of machines. + .SH EXAMPLES Import local image into fast-vm .sp @@ -284,6 +288,12 @@ Create machine with custom definition and hack file. Start it and after it's SSH .sp .BI "fast-vm edit_note " "42 'this is testing machine'" +.RB "Define new profile " "small-6.7" " based on image " "6.7" " with custom libvirt XML and hack files and create machine " "41" " using new profile" +.sp +.BI "fast-vm import_profile " "small-6.7 6.7 /tmp/alternative\-libvirt.xml /tmp/custom\-create\-hacks.sh /tmp/custom\-delete\-hacks.sh" +.br +.BI "fast-vm create " "small-6.7 41" + .SH SEE ALSO .BR fast-vm.conf (5), .BR configure-fast-vm (8) From ed4c4d5e5f5227affe07e2b6346709dad2985644 Mon Sep 17 00:00:00 2001 From: Ondrej Famera Date: Mon, 13 Feb 2017 13:47:32 +0100 Subject: [PATCH 26/28] change the formatting of man fast-vm.8 in several places to be more compact --- man/fast-vm.8 | 40 +++++++++++++++------------------------- 1 file changed, 15 insertions(+), 25 deletions(-) diff --git a/man/fast-vm.8 b/man/fast-vm.8 index b5a7f4c..f59a998 100644 --- a/man/fast-vm.8 +++ b/man/fast-vm.8 @@ -5,7 +5,6 @@ fast-vm \(em script for defining VMs from images provided in thin LVM pool .B fast-vm .RB .RB -.br .B fast-vm .BR import_image @@ -15,18 +14,15 @@ fast-vm \(em script for defining VMs from images provided in thin LVM pool .IR PathToLibvirtXML .RI [ PathToHacksFile ] .RI [ PathToDeleteHacksFile ] -.br .B fast-vm .BR export_image .IR ImageName .RB < xz | gz > -.br .B fast-vm .BR remove_image .IR ImageName -.br .B fast-vm .BR import_profile @@ -35,22 +31,18 @@ fast-vm \(em script for defining VMs from images provided in thin LVM pool .IR PathToLibvirtXML .RI [ PathToHacksFile ] .RI [ PathToDeleteHacksFile ] -.br .B fast-vm .BR remove_profile .IR ProfileName -.br .B fast-vm .BR list_images .RB [ short ] -.br .B fast-vm .BR list_profiles .RB [ short ] -.br .B fast-vm .B create @@ -59,50 +51,41 @@ fast-vm \(em script for defining VMs from images provided in thin LVM pool .RI | VmNumber > .RI [ PathToLibvirtXML ] .RI [ PathToHacksFile ] -.br .B fast-vm .B info .I VmNumber -.br .B fast-vm .B delete .I VmNumber .RI [ PathToDeleteHacksFile ] -.br .B fast-vm .B edit_note .I VmNumber .RI [ NoteText ] -.br .B fast-vm .B list .RB [ all | active | inactive .RB [ short ]] -.br .B fast-vm .BI "start " VmNumber .RB [ console | ssh .RI [ /path/to/custom/script ]] -.br .B fast-vm .BI "stop " VmNumber .RB [ graceful ] -.br .B fast-vm .BI "console " VmNumber -.br .B fast-vm .BI "ssh " VmNumber .RI [ /path/to/custom/script ] -.br .SH DESCRIPTION fast-vm is provides command-line interface to create virtual machines (VMs) in @@ -127,35 +110,42 @@ Primary use case of fast-vm is creation of scratch VMs on single local machine. .TP .B ImageName -Name of image imported in the fast-vm. It should contain only alpha-numerical characters. -.B ImageName +.RB "Name of image imported in the fast-vm. It should contain only alpha-numerical characters. " "ImageName" is part of the LV name and libvirt machine name. -.TP +.TP +.B PathToImage .BI "PathToImage " /path/to/image.{gz,xz} -.TP +.br .BI "PathToImage " http://url/to/image.{gz,xz} +.sp Local path or http/https URL to image file in GZIP or XZ format. .TP +.B PathToLibvirtXML .BI "PathToLibvirtXML " /path/to/libvirt.xml -.TP +.br .BI "PathToLibvirtXML " htto://url/to/libvirt.xml +.sp Local path or http/https URL to libvirt VM XML template. Check the .B TEMPLATE MACROS for list of supported macros. .TP +.B PathToHacksFile .BI "PathToHacksFile " /path/to/hacks.sh -.TP +.br .BI "PathToHacksFile " http://url/to/hacks.sh +.sp Local path or http/https URL to shell script which will be executed after creation of the VM and allows to access the disk drive of the VM before first running it. .TP +.B PathToDeleteHacksFile .BI "PathToDeleteHacksFile " /path/to/delete-hacks.sh -.TP +.br .BI "PathToDeleteHacksFile " http://url/to/delete-hacks.sh +.sp Local path or http/https URL to shell script which will be executed during VM delete process as last step before the VM is undefined from the libvirt. @@ -224,7 +214,7 @@ try to send TRIM (ATA devices) or UNMAP (SCSI devices) so the storage can mark f When you have done all modification to your image export it to GZ or XZ compressed file using one of the commands below. .B fast-vm export_image cool_image xz - +.br .B fast-vm export_image cool_image gz TIP: To test how the fast-vm VM would be created from this image, simply create it based on your custom image From 89db13b5f88a808e9bd2753d8ad64cd6c204fde8 Mon Sep 17 00:00:00 2001 From: Ondrej Famera Date: Mon, 13 Feb 2017 14:08:19 +0100 Subject: [PATCH 27/28] Supported distributions version bump in README file --- README | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README b/README index 52803b3..4866959 100644 --- a/README +++ b/README @@ -65,9 +65,9 @@ configure-fast-vm(8) ====== Supported/Tested OS ===== Distribution Installation method -- RHEL 7.2 RPM -- CentOS 7.2 RPM -- Fedora 24 RPM +- RHEL 7.3 RPM +- CentOS 7.3 RPM +- Fedora 25 RPM - Gentoo make install ====== Known bugs/limitation ====== From 9f3b9842de117b7f1474afd75b7243a5ec98834f Mon Sep 17 00:00:00 2001 From: Ondrej Famera Date: Mon, 13 Feb 2017 14:09:25 +0100 Subject: [PATCH 28/28] version bump 1.0 -> 1.1 --- fast-vm | 2 +- man/configure-fast-vm.8 | 2 +- man/fast-vm.8 | 2 +- man/fast-vm.conf.5 | 2 +- rpm/fast-vm-centos7.spec | 8 +++++++- rpm/fast-vm.spec | 8 +++++++- 6 files changed, 18 insertions(+), 6 deletions(-) diff --git a/fast-vm b/fast-vm index a73828d..697b487 100755 --- a/fast-vm +++ b/fast-vm @@ -206,7 +206,7 @@ usage () { echo "$0 list [all|active|inactive [short]]" ;; *) - echo "== fast-vm version 1.0 ==" + echo "== fast-vm version 1.1 ==" echo "$0 " for cmd in import_image export_image remove_image import_profile remove_profile list_images create delete edit_note info list start stop console ssh; do diff --git a/man/configure-fast-vm.8 b/man/configure-fast-vm.8 index 2d71c77..d61e748 100644 --- a/man/configure-fast-vm.8 +++ b/man/configure-fast-vm.8 @@ -1,4 +1,4 @@ -.TH FAST-VM 8 "configure-fast-vm 1.0 (2016-06-25)" "fast-vm" "configure-fast-vm" \" -*- nroff -*- +.TH FAST-VM 8 "configure-fast-vm 1.1 (2016-06-25)" "fast-vm" "configure-fast-vm" \" -*- nroff -*- .SH NAME configure-fast-vm \(em script for (re)configuring fast-vm .SH SYNOPSIS diff --git a/man/fast-vm.8 b/man/fast-vm.8 index f59a998..13e0155 100644 --- a/man/fast-vm.8 +++ b/man/fast-vm.8 @@ -1,4 +1,4 @@ -.TH FAST-VM 8 "fast-vm 1.0 (2017-02-04)" "fast-vm" "fast-vm" \" -*- nroff -*- +.TH FAST-VM 8 "fast-vm 1.1 (2017-02-04)" "fast-vm" "fast-vm" \" -*- nroff -*- .SH NAME fast-vm \(em script for defining VMs from images provided in thin LVM pool .SH SYNOPSIS diff --git a/man/fast-vm.conf.5 b/man/fast-vm.conf.5 index 34a6a6e..63eca88 100644 --- a/man/fast-vm.conf.5 +++ b/man/fast-vm.conf.5 @@ -1,4 +1,4 @@ -.TH FAST-VM.CONF 5 "fast-vm 1.0 (2016-10-07)" "fast-vm" "/etc/fast-vm.conf" \" -*- nroff -*- +.TH FAST-VM.CONF 5 "fast-vm 1.1 (2016-10-07)" "fast-vm" "/etc/fast-vm.conf" \" -*- nroff -*- .SH NAME .IR /etc/fast-vm.conf " \(em global configuration file for fast-vm" diff --git a/rpm/fast-vm-centos7.spec b/rpm/fast-vm-centos7.spec index ca42e15..ef45425 100644 --- a/rpm/fast-vm-centos7.spec +++ b/rpm/fast-vm-centos7.spec @@ -1,5 +1,5 @@ Name: fast-vm -Version: 1.0 +Version: 1.1 Release: 1%{?dist} Summary: Script for defining VMs from images provided in thin LVM pool @@ -58,6 +58,12 @@ drive of new machine before starting VM using the 'hack files'. %config(noreplace) %{_sysconfdir}/sudoers.d/%{name}-sudoers %changelog +* Mon Feb 13 2017 Ondrej Famera 1.1-1 +- image profiles support +- delete hack files added +- multi-nic VM removal fix +- store VM notes also in libvirt XML definition for external applications + * Sun Nov 13 2016 Ondrej Famera 1.0-1 - added support for handling machines with UEFI firmware - improve error messages and documentation diff --git a/rpm/fast-vm.spec b/rpm/fast-vm.spec index 929d17f..e4bff24 100755 --- a/rpm/fast-vm.spec +++ b/rpm/fast-vm.spec @@ -1,5 +1,5 @@ Name: fast-vm -Version: 1.0 +Version: 1.1 Release: 1%{?dist} Summary: Script for defining VMs from images provided in thin LVM pool @@ -64,6 +64,12 @@ drive of new machine before starting VM using the 'hack files'. %config(noreplace) %{_sysconfdir}/sudoers.d/%{name}-sudoers %changelog +* Mon Feb 13 2017 Ondrej Famera 1.1-1 +- image profiles support +- delete hack files added +- multi-nic VM removal fix +- store VM notes also in libvirt XML definition for external applications + * Sun Nov 13 2016 Ondrej Famera 1.0-1 - added support for handling machines with UEFI firmware - improve error messages and documentation