#!/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__