#!/usr/bin/perl
################################################################################
#
# Perl implementation of rsync-backup.sh
#
# 2014-11-17 - MSL
#
################################################################################
use warnings;
use strict;
use v5.10;
use Log::Log4perl qw(:easy);
Log::Log4perl->easy_init( { level => $DEBUG, file => ">>$0.log"},
{ level => $DEBUG, file => "STDOUT" } );
INFO("$0 - Begin Program");
################################################################################
#
# Define backup volumnes
#
################################################################################
my %backup_vols; # key = partition UUID
# entry 00
$backup_vols{'cc284958-7a1a-4519-b5f6-a068ff1397dc'}->{'EXCLUDES'} = "/root/etc/rsync-backup/excludes.conf";
# Volume: /dev/sdb1, 8:17, 750126104576, 6f1a98f5-70ea-4870-ae51-53e52f0383af, ext2, backup001
$backup_vols{'6f1a98f5-70ea-4870-ae51-53e52f0383af'}->{'EXCLUDES'} = "/root/etc/rsync-backup/excludes.conf";
# Volume: /dev/sdb1, 8:17, 1000203837440, 6720f72b-86ad-4568-b8dc-b22f69cf2923, btrfs, backup02
$backup_vols{'6720f72b-86ad-4568-b8dc-b22f69cf2923'}->{'EXCLUDES'} = "/root/etc/rsync-backup/excludes-1tb.conf";
# Volume: /dev/sdb1, 8:17, 999500546048, ed4f4207-7ee5-4263-8b2e-4267a4abf1f9, btrfs, backup03
$backup_vols{'ed4f4207-7ee5-4263-8b2e-4267a4abf1f9'}->{'EXCLUDES'} = "/root/etc/rsync-backup/excludes-1tb.conf";
##############################################################################################
#
# Occasionally changed system configuration variables
#
##############################################################################################
# bin boot cgroup dev etc home lib lost+found media mnt opt proc root run sbin selinux srv storage sys tmp usr var
my $SOURCES="/bin /boot /etc /home /lib /opt /root /sbin /storage /usr /var";
my $FS_MOUNTPOINT = q{/mnt};
my $VERBOSE = q{-v};
################################################################################
#
# Utility Paths and options.
#
################################################################################
my $BIN_LSBLK = qx{ which lsblk };
chomp $BIN_LSBLK;
INFO ("lsblk=$BIN_LSBLK");
my $LSBLKOPTS = q{ -bnp -o KNAME,MAJ:MIN,SIZE,UUID,FSTYPE,LABEL };
my $LSBLK_CMD = qq{ $BIN_LSBLK $LSBLKOPTS };
################################################################################
#
# Step 1: Let's find out what backup volume ( if any ) is mounted.
#
################################################################################
# Initialize Target variables
my ( $T_KNAME, $T_MAJ_MIN, $T_SIZE, $T_UUID, $T_FSTYPE, $T_LABEL ) = ();
# Loop through lsblk
foreach my $line ( qx{ $LSBLK_CMD } ) {
# while we don't have a T_UUID
if ( not $T_UUID ) {
# Extract data from lsblk row
my ($KNAME, $MAJ_MIN, $SIZE, $UUID, $FSTYPE, $LABEL) = split(/\s+/,$line);
# if we match one of the UUIDs on our list
if ( grep (/$UUID/, sort keys %backup_vols) ) {
# save off the device information
($T_KNAME, $T_MAJ_MIN, $T_SIZE, $T_UUID, $T_FSTYPE, $T_LABEL ) = split(/\s+/,$line);
}; # if
}; # if not T_UUID
} # foreach $line
# Check to make sure we have a device attached
if ( not $T_UUID ) {
FATAL("Fatal Error: Could not find a drive to use.");
FATAL qx{ echo "Output of: $LSBLK_CMD"; $LSBLK_CMD };
FATAL "$0 - End Program";
exit 1;
}
INFO "Volume: $T_KNAME, $T_MAJ_MIN, $T_SIZE, $T_UUID, $T_FSTYPE, $T_LABEL";
################################################################################
#
# Utility Paths and options (continued)
#
################################################################################
my $BIN_MOUNT = qx{ which mount };
chomp $BIN_MOUNT;
INFO ("mount=$BIN_MOUNT");
my $MOUNTOPTS = qq{-o context="system_u:object_r:removable_t:s0" };
my $CMD_MOUNT = qq{ $BIN_MOUNT $VERBOSE -t $T_FSTYPE -U $T_UUID $FS_MOUNTPOINT $MOUNTOPTS };
################################################################################
my $BIN_RSYNC = qx{ which rsync };
chomp $BIN_RSYNC;
INFO ("rsync=$BIN_RSYNC");
my $RSYNCOPTS = qq{-a $VERBOSE --delete --delete-excluded --exclude-from=$backup_vols{$T_UUID}->{'EXCLUDES'} };
my $CMD_RSYNC = qq{ $BIN_RSYNC $RSYNCOPTS $SOURCES $FS_MOUNTPOINT };
################################################################################
my $BIN_UMOUNT = qx{ which umount };
chomp $BIN_UMOUNT;
INFO ("umount=$BIN_UMOUNT");
my $UMOUNTOPTS = qq{};
my $CMD_UMOUNT = qq{ $BIN_UMOUNT $VERBOSE $FS_MOUNTPOINT };
##############################################################################################
#
# Subroutine: execute_cmd( qq{ some command text $variable } );
#
##############################################################################################
sub execute_cmd {
my $cmd = shift;
INFO " Command='$cmd'";
my $retval = qx{$cmd 2>&1}; # || sad_trombone
DEBUG "CHILD_ERROR_NATIVE=${^CHILD_ERROR_NATIVE}";
DEBUG "---- Command Output ----";
DEBUG "$retval";
DEBUG "--------------------------";
return ${^CHILD_ERROR_NATIVE};
}; # sub execute_cmd
##############################################################################################
#
# Begin
#
##############################################################################################
INFO "Beginning rsync backup of data to portable drive.";
INFO "--------------------------------------------------------------------------------";
INFO " Backup up directories: $SOURCES";
INFO " to: $FS_MOUNTPOINT";
INFO " with rsync options: $RSYNCOPTS";
INFO "---- Mounting Portable Drive ---";
my $rtn_code = execute_cmd ( $CMD_MOUNT );
if ( $rtn_code == 0 ) {
INFO "---- Beginning Sync Operation ---";
execute_cmd ( $CMD_RSYNC );
};
INFO "---- Unmounting Portable Drive ---";
execute_cmd ( $CMD_UMOUNT );
INFO("$0 - End Program");
##############################################################################################
__END__
Comments