In a nutshel this is what happens
- some sanity checks and destination creation.
- copy xml-config for chosen VM.
- create snapshot for chosen VM so that original vdi-file is released.
- will pause running VM for 1-2s.
There is a --live switch for the snapshot command but I have not tested this. - copy original vdi-file to backup destination.
- remove snapshot thus "merging" the changes back into the running vdi.
- ???
- profit!
Input is name of VM-machine and index of backup.
Output is a backup of your machine ... who'da thunk it.
The usage of rsync is mostly cause of access to --progress but this could be substituted for simple "cp" or similar.
Update 1: Now using --live switch for the snapshot command. Without it one guest with USB attached kept getting Aborted when snapshot was taken. With --live it's working again.
Update 2: The --live switch was not the issue :(. Apparently snapshots does not work with anything lower than the USB 3.0 controller. This controller does however lose the attached devices when you snapshot the guest instead. Bah. Workaround is a detach and re-attach of the device to the affected guest. In my case this is not a problem but if you are attaching a disk drive or something that the guest is using constantly this might lead to bad stuff. Take care.
Update 3: So the UUID changes with every boot and every physical reattach of the device, how very practical. Well, let's fix that.
That's it. It works for me, ymmw. :)
#!/bin/bash if (( "$#" < 2 )); then echo "Usage: `basename $0` VM_NAME BACKUP_INDEX" exit 65 fi # using rsync for progress while copying # not using deltas (-W) for vdi/vmdk as it tends to break copycmd="rsync -ahW --progress" dest="/mnt/vmbackup/$1/$2" # check if VM exists vboxmanage showvminfo "$1" &> /dev/null || { echo "OOPS: VM not found"; exit 1; } # change dir # (change this if using non default) cd ~/"VirtualBox VMs"/ || { echo "OOPS: directory not found, check script"; exit 1; } # create directory at destination with index mkdir -p $dest echo "[START] Backup of $1 is GO!" echo echo "[i] copy $1/*.vbox to backup ..." $copycmd "$1/"*.vbox* "$dest" $copycmd -R "$1/./Logs/" "$dest" sleep 1 echo echo "[i] create snapshot of $1" vboxmanage snapshot "$1" take backup --live sleep 1 echo # reattaching USB-device, it gets lost on snapshot for some reason. # find device_guid with vboxmanage list usbhost. if [[ "$1" == "your_special_usb_needing_guest_name" ]]; then # this is not pretty but it works. fluff=$(vboxmanage list usbhost | grep "0x1781" -B 1 | head -n 1 | sed -e 's/^UUID:\s*//') echo "[i] doing special stuff to host $1 ..." vboxmanage controlvm "$1" usbdetach $fluff sleep 1 vboxmanage controlvm "$1" usbattach $fluff sleep 1 echo fi echo "[i] copy $1/*.vdi and $1/*.vmdk to backup ..." $copycmd "$1/"*.vdi "$dest" 2> /dev/null $copycmd "$1/"*.vmdk "$dest" 2> /dev/null sleep 1 echo # "merge" the changes that has been made since we snapshotted back into running VM. # yes, delete is sort of merge, look it up ... it's complicated. echo "[i] \"merging\" snapshot back into $1 ..." vboxmanage snapshot "$1" delete backup sleep 1 echo echo "[END] ^_^" exit 0