Last active
October 9, 2019 14:07
-
-
Save jaysn/c724593f0e98587a7e419a723aaabe8d to your computer and use it in GitHub Desktop.
basic Cron Bash Script to automatically save specific VirtualBox VMs using savestate, copy, tar and p7zip
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Vars | |
# BUDATE - our date used for the Backup-Folder name which is created in our Backup-Path | |
# VBOXUSER - used if your VirtualBox is started and managed by a special/specific user | |
# BACKUPMNT - the mountpoint of your Backup-Media/HDD/SSD/whatever | |
# VMPATH - Path to your VirtualBox VMs Folder | |
# BUPATH - complete Path to your Backup-Folder - where date-based folders are created for each (Daily-)Backup | |
# VMLIST - List of VMs (Names only) to backup - passed to vboxmanage and used for the Copy-Part so please use names only.. | |
BUDATE=`date +%Y-%m-%d` | |
VBOXUSER=vbox | |
BACKUPMNT='/mnt/backupdrive' | |
VMPATH="/path/to/VirtualBox VMs" # edit me to match your path to VirtualBox VMs | |
BUPATH=${BACKUPMNT}/backup/virtualbox | |
#Change this list of VMs to match your needs | |
VM_LIST=("VM-NAME-1" "VM-NAME-2" "USE-ONLY-VM-NAMES") | |
#this functions can be used to check if a device or path it mounted for example our Backup-Mount | |
isMounted() { findmnt -rno SOURCE,TARGET "$1" >/dev/null; } # path or device | |
isDevMounted() { findmnt -rno SOURCE "$1" >/dev/null; } # device only | |
isPathMounted() { findmnt -rno TARGET "$1" >/dev/null; } # path only | |
writelog() { /usr/bin/logger -tsave-vms -plocal6.notice $1; } # writes $1 to predefined syslog facility with our save-vms tag | |
# | |
#Let the games begin | |
# | |
writelog "Starting VM Backup ${BUDATE}" # Log for our Syslog | |
echo "Starting VM Backup ${BUDATE}" # Output for our Cron-Mail | |
# | |
#Mountcheck - Check if our Backup-Space is mounted | |
# | |
if ! isPathMounted $BACKUPMNT; | |
then | |
writelog "${BACKUPMNT} not mounted! mounting now" | |
echo "${BACKUPMNT} not mounted! mounting now" | |
mount ${BACKUPMNT} | |
fi | |
writelog "Pausing VMs" | |
echo "Pausing VMs" | |
for vm in "${VM_LIST[@]}" | |
do | |
writelog "Pausing ${vm}"; | |
echo "Pausing ${vm}"; | |
su -l $VBOXUSER -c "VBoxManage controlvm '${vm}' savestate" | |
done | |
unset vm | |
writelog "all VMs paused" | |
echo "all VMs paused" | |
if [ ! -d ${BUPATH}/${BUDATE} ] | |
then | |
echo "Make Dir ${BUPATH}/${BUDATE}" | |
mkdir ${BUPATH}/${BUDATE} | |
fi | |
for cvm in "${VM_LIST[@]}" | |
do | |
writelog "Copying VM ${cvm}" | |
echo "Copying VM ${cvm}" | |
cp -r "${VMPATH}/${cvm}" ${BUPATH}/${BUDATE}/${cvm} | |
done | |
unset cvm | |
for vm in "${VM_LIST[@]}" | |
do | |
echo "" | |
su -l ${VBOXUSER} -c "VBoxManage startvm '${vm}' --type=headless" | |
done | |
unset vm | |
echo "All VMs should be Back online, Start compression of our temporary copies." | |
for bakdir in ${BUPATH}/${BUDATE}/*/ | |
do | |
writelog "Compressing ${bakdir}" | |
tar c "${bakdir}" | 7z a -t7z -m0=lzma2 -mx=5 -si "${bakdir%/}.tar.7z" | |
done | |
echo "All backups compressed" | |
unset bakdir | |
#removing the copied, uncompressed VM Folders | |
for vm in "${VM_LIST[@]}" | |
do | |
rm -r ${BUPATH}/${BUDATE}/${vm} | |
done | |
# | |
# TODO | |
# | |
# delete older backups. using find -not -newermt or find -mtime +7 for a week or sth like this.. | |
# | |
# find ${BUPATH} -type d -mtime +7 -exec rm -r {} | |
# or | |
# find ${BUDATE} -maxdepth 1 -type d -mtime +7 -not -mtime +14 | |
# the -not -mtime condition in my case prevents deletion of backups older than x days | |
# in my case i have master-copies in the same folder which i need to be untouched ;) | |
# this could be less specific if you, other than me, use a dedicated folder only for this backups-purpose... | |
# | |
# also | |
# | |
# Adding a separate temporary working directory and or space for the copies before compressing them and | |
# copying only the final archives to the backup-space could be better on smaller backup-targets. | |
# for example u could use /tmp for this.. or another ssd/hdd drive - just check for it using the isMounted functions. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment