Skip to content

Instantly share code, notes, and snippets.

@mrverrall
Last active December 14, 2015 02:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mrverrall/5014487 to your computer and use it in GitHub Desktop.
Save mrverrall/5014487 to your computer and use it in GitHub Desktop.
This script will automatically take and mergeback VirtualBox snapshots to keep a rolling archive of a running machine. Call with, # ./vbox_auto_snapshots vm_name_1 [vm_name_n...]
#! /bin/bash
# This script will automatically take and mergeback VirtualBox snapshots to
# keep a rolling archive of a running machine.
# Call with,
# ./vbox_auto_snapshots vm_name_1 [vm_name_n...]
# Define snapshot retention periods
KEEP_WEEKLY=4
KEEP_DAILY=6
# Day to take weekly
# Monday = 1
WEEK_ENDS=5
SNAP_LIST="$(mktemp /tmp/vbox_snaps.XXXXXXXXXX)"
function extractDate {
# extract the date from a snapshot name
# this is not smart, only send formatted names
echo "$1" | sed -e 's#.*-[0-9]\{8\}-[0-9]\{6\}-\([0-9]\+\)\"*#\1#'
}
function extractName {
echo "$1" | sed -e 's#.*="\('"$PREFIX"'[0-9-]*\)"#\1#'
}
function setSnaps {
# populate a list of current snapshots for a machine
VBoxManage showvminfo "$1" --machinereadable | \
grep "SnapshotName.*$PREFIX" > "$SNAP_LIST"
}
function getLastSnapDate {
local _lastSnap=0
setSnaps "$1"
while read line; do
local _newdate=`extractDate "$line"`
if [ "$_newdate" -gt "$_lastSnap" ]
then
_lastSnap="$_newdate"
fi
done < "$SNAP_LIST"
echo $_lastSnap
}
function getAge {
expr $(date "+%s") - $1
}
function takeSnapshot {
VBoxManage snapshot "$1" take "$PREFIX"-"$(date '+%Y%m%d-%H%M%S-%s')"
}
function deleteOldSnaps {
setSnaps "$1"
while read line; do
local _age=`getAge "$(extractDate $line)"`
if [[ $_age -gt $MAX_RETENTION ]]
then
VBoxManage snapshot "$1" delete "$(extractName $line)"
fi
done < "$SNAP_LIST"
}
if [[ "$WEEK_ENDS" -eq $(date "+%u") ]]
then
IS_WEEKLY=true
PREFIX=weekly
MIN_RETENTION=604800 # a week in seconds
MAX_RETENTION=`expr $MIN_RETENTION \* $KEEP_WEEKLY`
else
IS_WEEKLY=false
PREFIX=daily
MIN_RETENTION=86400 # a month in seconds
MAX_RETENTION=`expr $MIN_RETENTION \* $KEEP_DAILY`
fi
for vm in "$@"; do
# check if vm exists
if [[ $(VBoxManage list vms | grep $vm) ]]
then
# get the age of the last snapshot
LAST_SNAP_DATE=`getLastSnapDate "$vm"`
SECONDS_SINCE=`getAge "$LAST_SNAP_DATE"`
# if enough time has elapsed take a new snap
if [[ "$SECONDS_SINCE" -ge $MIN_RETENTION ]]
then
takeSnapshot "$vm"
fi
fi
# clean up old snapshots
deleteOldSnaps "$vm"
fi
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment