User Tools

Site Tools


snapshot_backup

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

| config
#!/usr/bin/perl
 
$awsId = '<your AWS_ID>'; 
$awsKey = '<your AWS_KEY>';
$awsinstance = '<AWS_INSTANCES>'; ## right now it is not used anywhere

bash config

| config_bash
# this file contain what need to be backup.  
# Follow the format of value
# instance<serial number must be unique> = <Volume ID> <Retention Freq.> <total Retention>
 
instance1="vol-2222pqrs 7 2"
instance2="vol-1111abcd 1 1"

db.pl

| 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 <Operation> <Volume_ID> <Date> [<Snapshot ID>]\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

| 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

| create_snap.pl
#!/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 <Volume_ID> <Today>\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

| delete_snap.pl
# This script delete snapshot of requested volume
# Author : k2patel <k2patel@hotmail.com>
# 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 <Snapshot_ID>\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

| snap_status.pl
# This script check status of given snapshot and wait for it get completed.
# Author : k2patel <k2patel@hotmail.com>
# 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 <Snapshot_ID>\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
| machine.db
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE DESK ( v_ID, s_ID, Dte );
snapshot_backup.txt · Last modified: 2020/08/10 02:35 (external edit)