#!/bin/bash # Example would be to run this script as follows: # Once a day; retain last 31 days # efs-backup.sh $src $dst daily 31 efs-12345 # Once a week; retain 4 weeks of backup # efs-backup.sh $src $dst weekly 7 efs-12345 # Once a month; retain 3 months of backups # efs-backup.sh $src $dst monthly 3 efs-12345 # # Snapshots will look like: # $dst/$efsid/hourly.0-3; daily.0-30; weekly.0-3; monthly.0-2 # input arguments source=$1 #source_ip:/prefix destination=$2 #destination_ip:/ interval=$3 retain=$4 efsid=$5 region=$6 instance_id=$7 echo "## input from user ##" echo "source: ${source}" echo "destination: ${destination}" echo "interval: ${interval}" echo "retain: ${retain}" echo "efsid: ${efsid}" # prepare system for fpsync echo "-- $(date -u +%FT%T) -- sudo yum -y update" sudo yum -y update echo "-- $(date -u +%FT%T) -- sudo yum -y install nfs-utils" sudo yum -y install nfs-utils echo "-- $(date -u +%FT%T) -- sudo mkdir /backup" sudo mkdir /backup echo "-- $(date -u +%FT%T) -- sudo mkdir /mnt/backups" sudo mkdir /mnt/backups # 12/28/2018 - EFS-21432 - EFS mount best practices echo "-- $(date -u +%FT%T) -- sudo mount -t nfs -o nfsvers=4.1,rsize=1048576,wsize=1048576,timeo=600,retrans=2,hard,_netdev,noresvport $source /backup" sudo mount -t nfs -o nfsvers=4.1,rsize=1048576,wsize=1048576,timeo=600,retrans=2,hard,_netdev,noresvport $source /backup mount_src_status=$? echo "mount status for source efs: ${mount_src_status}" echo "-- $(date -u +%FT%T) -- sudo mount -t nfs -o nfsvers=4.1,rsize=1048576,wsize=1048576,timeo=600,retrans=2,hard,_netdev,noresvport $destination /mnt/backups" sudo mount -t nfs -o nfsvers=4.1,rsize=1048576,wsize=1048576,timeo=600,retrans=2,hard,_netdev,noresvport $destination /mnt/backups mount_backup_status=$? echo "mount status for backup efs: ${mount_backup_status}" # if efs mount fails exit workflow if [ ${mount_src_status} != '0' ] || [ ${mount_backup_status} != '0' ]; then echo "-- $(date -u +%FT%T) -- ERROR:efs_not_mounted" exit $? fi echo "-- $(date -u +%FT%T) -- sudo yum -y install parallel" sudo yum -y install parallel echo "-- $(date -u +%FT%T) -- sudo yum -y install --enablerepo=epel tree" sudo yum -y install --enablerepo=epel tree echo "-- $(date -u +%FT%T) -- sudo yum -y groupinstall 'Development Tools'" sudo yum -y groupinstall "Development Tools" echo '-- $(date -u +%FT%T) -- wget https://github.com/martymac/fpart/archive/fpart-1.0.0.zip' wget https://github.com/martymac/fpart/archive/fpart-1.0.0.zip unzip fpart-1.0.0.zip cd fpart-fpart-1.0.0/ autoreconf -i ./configure make sudo make install # Adding PATH PATH=$PATH:/usr/local/bin _thread_count=$(($(nproc --all) * 16)) # we need to decrement retain because we start counting with 0 and we need to remove the oldest backup echo "remove_snapshot_start:$(date -u +%FT%T)" let "retain=$retain-1" if sudo test -d /mnt/backups/$efsid/$interval.$retain; then echo "-- $(date -u +%FT%T) -- sudo tree /mnt/backups/$efsid/$interval.$retain -dfi | parallel --no-notice -j $_thread_count sudo rm {} -r &>/dev/null" sudo tree /mnt/backups/$efsid/$interval.$retain -dfi | parallel --will-cite -j $_thread_count sudo rm {} -r &>/dev/null echo "-- $(date -u +%FT%T) -- sudo rm /mnt/backups/$efsid/$interval.$retain -r &>/dev/null" sudo rm /mnt/backups/$efsid/$interval.$retain -r &>/dev/null echo "rm status: $?" fi echo "remove_snapshot_stop:$(date -u +%FT%T)" # rotate all previous backups (except the first one), up one level for x in `seq $retain -1 2`; do if sudo test -d /mnt/backups/$efsid/$interval.$[$x-1]; then echo "-- $(date -u +%FT%T) -- sudo mv /mnt/backups/$efsid/$interval.$[$x-1] /mnt/backups/$efsid/$interval.$x" sudo mv /mnt/backups/$efsid/$interval.$[$x-1] /mnt/backups/$efsid/$interval.$x fi done echo "create_snapshot_start:$(date -u +%FT%T)" # copy first backup with hard links, then replace first backup with new backup if sudo test -d /mnt/backups/$efsid/$interval.0 ; then echo "-- $(date -u +%FT%T) -- sudo \"PATH=$PATH\" /usr/local/bin/fpsync -n $_thread_count -o \"-a -v --link-dest=../`basename /mnt/backups/$efsid/$interval.0`\" /mnt/backups/$efsid/$interval.0 /mnt/backups/$efsid/$interval.1" sudo "PATH=$PATH" /usr/local/bin/fpsync -n $_thread_count -o "-a -v --link-dest=../`basename /mnt/backups/$efsid/$interval.0`" /mnt/backups/$efsid/$interval.0 /mnt/backups/$efsid/$interval.1 fi echo "create_snapshot_stop:$(date -u +%FT%T)" if [ ! -d /mnt/backups/$efsid ]; then echo "-- $(date -u +%FT%T) -- sudo mkdir -p /mnt/backups/$efsid" sudo mkdir -p /mnt/backups/$efsid echo "-- $(date -u +%FT%T) -- sudo chmod 700 /mnt/backups/$efsid" sudo chmod 700 /mnt/backups/$efsid fi echo "-- $(date -u +%FT%T) -- sudo rm /tmp/efs-backup.log" sudo rm /tmp/efs-backup.log # start fpsync process echo "Stating backup....." echo "-- $(date -u +%FT%T) -- sudo \"PATH=$PATH\" /usr/local/bin/fpsync -n $_thread_count -o \"-a --stats --numeric-ids --log-file=/tmp/efs-backup.log\" /backup/ /mnt/backups/$efsid/$interval.0/" sudo "PATH=$PATH" /usr/local/bin/fpsync -n $_thread_count -v -o "-a --stats --numeric-ids --log-file=/tmp/efs-backup.log" /backup/ /mnt/backups/$efsid/$interval.0/ &>/tmp/efs-fpsync.log fpsyncStatus=$? echo "fpsyncStatus:$fpsyncStatus" # removing files from target efs which are not in source echo "rsync_delete_start:$(date -u +%FT%T)" echo "-- $(date -u +%FT%T) -- sudo rsync -r --delete --existing --ignore-existing --ignore-errors --log-file=/tmp/efs-backup-rsync.log /backup/ /mnt/backups/$efsid/$interval.0/" sudo rsync -r --delete --existing --ignore-existing --ignore-errors --log-file=/tmp/efs-backup-rsync.log /backup/ /mnt/backups/$efsid/$interval.0/ rsyncDeleteStatus=$? echo "rsyncDeleteStatus:$rsyncDeleteStatus" echo "rsync_delete_stop:$(date -u +%FT%T)" echo "-- $(date -u +%FT%T) -- sudo touch /mnt/backups/$efsid/$interval.0/" sudo touch /mnt/backups/$efsid/$interval.0/ exit $fpsyncStatus