#!/bin/bash SRCDIR=/var/www DSTDIR=/var/www/backups main() { # Process arguments if [ $# = 1 ]; then SITENAME=$1 else if [ $# = 0 ]; then SITENAMES=( $(ls $SRCDIR | fgrep . ) ) else SITENAMES=( "$@" ) fi while :; do for ((I=0; I<${#SITENAMES[*]}; I++)); do echo "$((I+1))) ${SITENAMES[$I]}" done echo "q) quit" echo read -p "Choice: " CHOICE if ! [[ $CHOICE =~ ^(q|[1-9][0-9]*)$ ]]; then echo "invalid choice" elif [ $CHOICE = q ]; then echo "quiting ..." exit elif [ $CHOICE -gt ${#SITENAMES[*]} ]; then echo "$CHOICE: no such number listed above" else SITENAME=${SITENAMES[$((CHOICE-1))]} echo break fi echo done fi # Sanity checks and derivations DATABASE=${SITENAME//./} # Guts cd $SRCDIR while :; do echo "Site-Name: $SITENAME" echo echo "l) list old checkpoints (names will be displayed in 'YYYYMMDDHHMMSS' format)" echo "c) create checkpoint (i.e. save current state so you can restore to this later)" echo "r) restore old checkpoint (you'll be asked which one to restore)" echo "d) delete old checkpoint (you'll be asked which one to delete)" echo "q) quit" echo read -p "Choice: " CHOICE if ! [[ $CHOICE =~ ^[qcrdl]$ ]]; then echo "invalid choice" elif [ $CHOICE = q ]; then echo "quiting ..." exit elif [ $CHOICE = c ]; then CAPACITY=$(df -P . | sed -nr 's/.* ([1-9][0-9]*)%.*/\1/p') if [ $CAPACITY -gt 80 ]; then echo "there is not enough space to create a new checkpoint (hint: use 'd' to delete any unwanted checkpoints or contact Alexis)" echo continue fi CHECKPOINT_ID=$(date +%Y%m%d%H%M%S) echo -n "$CHECKPOINT_ID: creating checkpointing (this can take a minute, don't panic) ... " tar czf $DSTDIR/$SITENAME.$CHECKPOINT_ID.tar.gz $SITENAME mysqldump --lock-tables --databases $DATABASE | gzip > $DSTDIR/$SITENAME.$CHECKPOINT_ID.sql.gz # Only touch the flag file once everything else is done. touch $DSTDIR/$SITENAME.$CHECKPOINT_ID.flg echo echo "$CHECKPOINT_ID: checkpoint created (hint: note down that id and something about what it contains)" elif [ $CHOICE = r ]; then read -p "Checkpoint-ID: " CHECKPOINT_ID if [ ! -f $DSTDIR/$SITENAME.$CHECKPOINT_ID.flg ]; then echo "$CHECKPOINT_ID: no checkpoint found with this id (hint: use 'l' to list known checkpoints and if it really does exist then contact Alexis)" echo continue fi UNTAR_DIR=$(mktemp -d) echo -n "$CHECKPOINT_ID: restoring checkpoint (this can take a minute, don't panic) ... " tar xzfC $DSTDIR/$SITENAME.$CHECKPOINT_ID.tar.gz $UNTAR_DIR rsync -a --delete $UNTAR_DIR/$SITENAME/ $SITENAME/ zcat $DSTDIR/$SITENAME.$CHECKPOINT_ID.sql.gz | mysql $DATABASE rm -fr $UNTAR_DIR echo echo "$CHECKPOINT_ID: checkpoint restored" elif [ $CHOICE = d ]; then read -p "Checkpoint-ID: " CHECKPOINT_ID if [ ! -f $DSTDIR/$SITENAME.$CHECKPOINT_ID.flg ]; then echo "$CHECKPOINT_ID: no checkpoint found with this id (hint: use 'l' to list known checkpoints and if it really does exist then contact Alexis)" echo continue fi echo -n "$CHECKPOINT_ID: deleting checkpoint ... " rm $DSTDIR/$SITENAME.$CHECKPOINT_ID.{flg,tar.gz,sql.gz} echo echo "$CHECKPOINT_ID: checkpoint deleted" elif [ $CHOICE = l ]; then ls $DSTDIR | sed -nr "s@^$SITENAME\.(.*)\.flg\$@\\1@p" | sort -u else echo "this should not happen (hint: tell Alexis it did!)" fi echo done } main "$@"