====== Backup ====== This snapshot backup enable you to have retention.\\ this manage my infrastructure backup on ec2. ==== Requirement : ==== * perl * Net::Amazon::EC2 * DBI:SQLite * bash ==== Files : ==== * config # store your amazon key here * db.pl # manage local DB for your snapshot / dates / volume * backup.sh # Cron this script * create_snap.pl # Create Snapshot * config_bash # Manage config of your retention / backup * snap_status.pl # Check status of your snapshot * delete_snap.pl # Delete Snapshot which is out of retention. ===== C0D3s ===== ==== config ==== #!/usr/bin/perl $awsId = ''; $awsKey = ''; $awsinstance = ''; ## right now it is not used anywhere ==== bash config ==== # this file contain what need to be backup. # Follow the format of value # instance = instance1="vol-2222pqrs 7 2" instance2="vol-1111abcd 1 1" ==== db.pl ==== #!/usr/bin/perl # developed by k2patel # k2patel@hotmail.com # this Script Manage all Backup Record. use Switch; use DBI; $filename = 'machine.db'; unless (-e $filename) { print "Creating Database..."; $dbh = DBI->connect( "dbi:SQLite:machine.db" ) || die "Cannot connect: $DBI::errstr"; $dbh->do( "CREATE TABLE DESK ( v_ID, s_ID, Dte )" ); $dbh->disconnect; } my($num_args) = $#ARGV + 1; if ($num_args < 3) { print "\nUsage: db.pl []\n"; print "Operation : Allowed \"add / get / del\" \n"; print "All three Value require\n"; print "Snapshot ID must provided when the Operation is Add / Del\n"; exit 1; } $dbh = DBI->connect( "dbi:SQLite:machine.db" ) || die "Cannot connect: $DBI::errstr"; switch( $ARGV[0] ){ case "add" { if ($ARGV[3] eq ''){ print "You can not use ADD without Snapshot"; exit 1; }else{ $dbh->do( "INSERT INTO DESK VALUES ( '$ARGV[1]', '$ARGV[2]', '$ARGV[3]' )" ); } } case "del" { if ($ARGV[3] eq ''){ print "You can not use DEL without Snapshot"; exit 1; }else{ $dbh->do( "DELETE FROM DESK WHERE s_ID = '$ARGV[2]' AND Dte = '$ARGV[3]'" ); } } case "get" { $res = $dbh->selectall_arrayref( "SELECT s_ID, Dte FROM DESK WHERE v_ID = '$ARGV[1]' AND Dte = '$ARGV[2]'" ); foreach( @$res ) { #print "$_->[0] $_->[1] $_->[2]\n"; print "$_->[0] $_->[1] $_->[2]\n" } } else { $res = $dbh->selectall_arrayref( "SELECT * FROM DESK" ); foreach( @$res ) { print "$_->[0] $_->[1] $_->[2]\n"; } } } $dbh->disconnect; ==== backup.sh ==== #!/bin/bash # developed by k2patel # k2patel@hotmail.com ############# Read ME ############### # this Script will do the Backup and remove old copy. # This script work based on existing DB Entry. # When you initialize it only create one copy rest of the dummy entry need to be entered by you. ##################################### BASE="$( cd "$( dirname "$0" )" && pwd )" cd $BASE source config_bash DATE=$(date +%Y%m%d) perl=$(which perl) for inst in instance{1..10} do eval var1=\$$inst arry=($var1) if [[ $1 == "init" ]]; then if [ "$var1" != "" ] then vol=${arry[0]} echo "Running backup for $vol stored in " newsnp=`$perl create_snap.pl $vol $DATE` $perl db.pl add $vol $newsnp $DATE echo "waiting." $perl snap_status.pl $newsnp echo "done" fi else if [ "$var1" != "" ] then freq=${arry[1]} vol=${arry[0]} iter=${arry[2]} lookup=$(echo "$iter * $freq" | bc) isit=`date -d "now -$lookup days" +%Y%m%d` isit_nxt=`date -d "now -$freq days" +%Y%m%d` lstnc=(`$perl $BASE/db.pl get "$vol" "$isit"`) if [ "$isit" == "${lstnc[1]}" ];then echo "Running backup for $vol stored in " newsnp=`$perl create_snap.pl $vol $DATE` $perl db.pl add $vol $newsnp $DATE echo "waiting." $perl snap_status.pl $newsnp echo "done" lstnx=(`$perl $BASE/db.pl get "$vol" "$isit_nxt"`) if [ "${lstnx[0]}" == '' ]; then echo "Notify Admin" else if [ "${lstnc[0]}" != '' ]; then $perl delete_snap.pl ${lstnc[0]} fi fi else echo "backup is not needed" fi fi fi done ==== create snapshot ==== #!/usr/bin/perl -w # Created / written by k2patel@hotmail.com # this script create snapshot for given volume. use Data::Dumper; use strict; #use Date::Calc qw( :all ); use lib "/usr/share/perl5/vendor_perl"; use Net::Amazon::EC2; # Configuration. require "config"; # our $ec2; our $awsId; our $awsKey; our $awsinstance; my($num_args) = $#ARGV + 1; if ($num_args < 2) { print "\nUsage: create_snap.pl \n"; print "This will create Snapshot for given Volume\n"; print "Format for today's Date must be \"YYYYMMDD\"\n"; exit 1; } ## Define Access Keys for Amazon. my $ec2 = Net::Amazon::EC2->new( AWSAccessKeyId => $awsId, SecretAccessKey => $awsKey ); my @result = $ec2->create_snapshot( VolumeId => $ARGV[0], Description => $ARGV[1] ); print $result[0]->{snapshot_id}; #print Dumper \@result; ==== delete shnapshot ==== # This script delete snapshot of requested volume # Author : k2patel # Please send me message for suggestion or update. # this script delete snapshot use Data::Dumper; use strict; #use Date::Calc qw( :all ); use lib "/usr/share/perl5/vendor_perl"; use Net::Amazon::EC2; # Configuration. require "config"; # our $ec2; our $awsId; our $awsKey; our $awsinstance; my($num_args) = $#ARGV + 1; if ($num_args < 1) { print "\nUsage: delete_snap.pl \n"; print "This will Delete Snapshot\n"; exit 1; } ## Define Access Keys for Amazon. my $ec2 = Net::Amazon::EC2->new( AWSAccessKeyId => $awsId, SecretAccessKey => $awsKey ); my @result = $ec2->delete_snapshot( SnapshotId => $ARGV[0] ); if ( $result[0] eq 1 ){ #print "Good to go \n"; exit 0; }else{ my $err = Dumper \@result; open F,">./rnd895896"; print F $err; close F; if(system ("/bin/mail -s \"ERROR : Dump Of Error\" k2patel\@hotmail.com < ./rnd895896") == 0){ unlink "./rnd895896"; } exit 1; } ==== Check Snapshot status ==== # This script check status of given snapshot and wait for it get completed. # Author : k2patel # Please send me message for suggestion or update. use Data::Dumper; use strict; #use Date::Calc qw( :all ); use lib "/usr/share/perl5/vendor_perl"; use Net::Amazon::EC2; # Configuration. require "config"; # our $ec2; our $awsId; our $awsKey; our $awsinstance; my($num_args) = $#ARGV + 1; if ($num_args < 1) { print "\nUsage: snap_status.pl \n"; print "This will check Snapshot Status\n"; exit 1; } ## Define Access Keys for Amazon. my $ec2 = Net::Amazon::EC2->new( AWSAccessKeyId => $awsId, SecretAccessKey => $awsKey ); my @result = $ec2->describe_snapshots( SnapshotId => $ARGV[0] ); while ( $result[0][0]->{status} ne 'completed' ){ sleep 10; } if ( $result[0][0]->{status} eq 'completed' ){ my $tst = "Good to go \n"; exit 0; }else{ my $err = Dumper \@result; open F,">./rnd892346"; print F $err; close F; if(system ("/bin/mail -s \"ERROR : Dump Of Error\" k2patel\@hotmail.com < ./rnd892346") == 0){ unlink "./rnd892346"; } exit 1; } ==== Machine DB ==== sqlite3 machine.db PRAGMA foreign_keys=OFF; BEGIN TRANSACTION; CREATE TABLE DESK ( v_ID, s_ID, Dte );