====== 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 );