Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl
- ################################################################################
- #
- # Perl implementation of rsync-backup.sh
- #
- ################################################################################
- use Mojo::Base -strict;
- use Data::Dumper;
- $Data::Dumper::Sortkeys = 1;
- use File::Basename;
- my $program_name = basename($0,q{.pl});
- ##############################################################################################
- #
- # Rarely changed system configuration variables
- #
- # Backup volumnes, sources, and exclusions are defined in a config file # $DRIVES_CONF
- # Note: for sources and exclusions in config, bin lib lib64 and sbin are symlinks to /usr
- #
- ##############################################################################################
- my $DRIVES_CONF = q{/root/etc/rsync-backup/drives.conf};
- my $FS_MOUNTPOINT = q{/mnt};
- my $LOG_DIR = q{/root/log};
- my $VERBOSE = q{-v};
- #
- # Init logging
- #
- use Log::Log4perl qw(:easy);
- Log::Log4perl->easy_init( { level => $DEBUG, file => ">>$LOG_DIR/$program_name.log"},
- { level => $DEBUG, file => "STDOUT" } );
- INFO("$0 - Begin Program");
- #
- # Load Drives config
- #
- my $backup_vols = do($DRIVES_CONF);
- die "Error parsing config file: $@" if $@;
- die "Error reading config file: $!" unless defined $backup_vols;
- TRACE(Dumper $backup_vols);
- #
- # Setup Commands
- #
- my $cmds = setup_commands();
- TRACE(Dumper $cmds);
- ################################################################################
- #
- # Step 1: Let's find out what backup volume ( if any ) is mounted.
- #
- ################################################################################
- # Initialize Target variables
- my $T_UUID;
- my $T_FSTYPE;
- my $T_LABEL;
- # Loop through lsblk
- foreach my $line ( qx{ $cmds->{'lsblk'}->{'cmd'} } ) {
- # while we don't have a T_UUID
- if ( not $T_UUID ) {
- # Extract data from lsblk row
- my ($UUID) = 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_UUID, $T_FSTYPE, $T_LABEL ) = split(/\s+/,$line);
- }; # if grep
- }; # 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{ $cmds->{'lsblk'}->{'cmd'} };
- FATAL "$0 - End Program";
- exit 1;
- }
- INFO "Target Volume: $T_UUID, $T_FSTYPE, $T_LABEL";
- ################################################################################
- #
- # We now have the $T_UUID, $T_FSTYPE, $T_LABEL
- # so we're ready to construct the rest of the commands and options
- #
- # mount->cmd needs T_FSTYPE and T_UUID
- # rsync-opt needs excludes filename, derived from T_UUID
- #
- ################################################################################
- $cmds->{'mount'}->{'cmd'} = $cmds->{'mount'}->{'bin'} . qq{ $VERBOSE -t $T_FSTYPE -U $T_UUID $FS_MOUNTPOINT } . $cmds->{'mount'}->{'opt'};
- # force checksums = -c
- $cmds->{'rsync'}->{'opt'} = qq{-a $VERBOSE --delete --delete-excluded --delete-before --exclude-from=$backup_vols->{$T_UUID}->{'EXCLUDES'} };
- $cmds->{'rsync'}->{'cmd'} = qq{$cmds->{'ionice'}->{'bin'} $cmds->{'ionice'}->{'opt'} }
- . qq{$cmds->{'rsync'}->{'bin'} $cmds->{'rsync'}->{'opt'} }
- . qq{$backup_vols->{$T_UUID}->{'SOURCES'} $FS_MOUNTPOINT};
- TRACE(Dumper $cmds);
- ##############################################################################################
- #
- # Begin
- #
- ##############################################################################################
- INFO "Beginning rsync backup of data to portable drive.";
- INFO "--------------------------------------------------------------------------------";
- INFO " Backup up directories: $backup_vols->{$T_UUID}->{'SOURCES'}";
- INFO " to: $FS_MOUNTPOINT";
- INFO " with rsync options: $cmds->{'rsync'}->{'opt'}";
- INFO "---- Mounting Portable Drive ---";
- my $rtn_code = execute_cmd ( $cmds->{'mount'}->{'cmd'} );
- if ( $rtn_code == 0 ) {
- INFO "---- Beginning Sync Operation ---";
- execute_cmd ( $cmds->{'rsync'}->{'cmd'} );
- };
- INFO "---- Unmounting Portable Drive ---";
- execute_cmd ( $cmds->{'umount'}->{'cmd'} );
- INFO("$0 - End Program");
- exit 0;
- ##############################################################################################
- #
- # Subroutine: setup_commands()
- #
- ##############################################################################################
- sub setup_commands {
- my $c;
- # lsblk
- my $retval = qx{ which lsblk };
- chomp $retval;
- $c->{'lsblk'}->{'bin'} = $retval;
- $c->{'lsblk'}->{'opt'} = q{-bnp -o UUID,FSTYPE,LABEL};
- $c->{'lsblk'}->{'cmd'} = qq{$c->{'lsblk'}->{'bin'} $c->{'lsblk'}->{'opt'}};
- # mount
- $retval = qx{ which mount };
- chomp $retval;
- $c->{'mount'}->{'bin'} = $retval;
- $c->{'mount'}->{'opt'} = qq{-o context="system_u:object_r:removable_t:s0"};
- # cmd needs $T_FSTYPE and $T_UUID, defer undtil drive selected
- # umount
- $retval = qx{ which umount };
- chomp $retval;
- $c->{'umount'}->{'bin'} = $retval;
- $c->{'umount'}->{'opt'} = $VERBOSE;
- $c->{'umount'}->{'cmd'} = qq{$c->{'umount'}->{'bin'} $c->{'umount'}->{'opt'} $FS_MOUNTPOINT};
- # ionice
- $retval = qx{ which ionice };
- chomp $retval;
- $c->{'ionice'}->{'bin'} = $retval;
- $c->{'ionice'}->{'opt'} = qq{-c 3};
- $c->{'ionice'}->{'cmd'} = qq{$c->{'ionice'}->{'bin'} $c->{'ionice'}->{'opt'}};
- # rsync
- $retval = qx{ which rsync };
- chomp $retval;
- $c->{'rsync'}->{'bin'} = $retval;
- # rsync->opt needs $backup_vols, defer
- # rsync-cmd needs rsync-opt, defer
- return $c;
- }; # sub setup_commands
- ##############################################################################################
- #
- # Subroutine: execute_cmd( qq{ some command text $variable } );
- #
- ##############################################################################################
- sub execute_cmd {
- my $cmd = shift;
- INFO " Execute Command='$cmd'";
- DEBUG "---- Command Output ----";
- open(STATUS, "$cmd 2>&1 |") or die "can't fork: $!";
- while (my $line = <STATUS>) {
- DEBUG $line;
- }
- close STATUS or die "bad $cmd $! $?";
- DEBUG "CHILD_ERROR_NATIVE=${^CHILD_ERROR_NATIVE}";
- DEBUG "--------------------------";
- return ${^CHILD_ERROR_NATIVE};
- }; # sub execute_cmd
- ##############################################################################################
- __END__
- ##############################################################################################
- =pod
- =head1 Old error handling
- ###############################################
- # Subroutine sad_trombone (signifies failure)
- ###############################################
- sad_trombone () {
- umount $FS_MOUNTPOINT;
- # umount $MNT_LAURIE_C;
- exit;
- }
- =head1 Old automation instrucations
- Sticking:
- rsync-backup.sh >> logfile.txt 2>&1
- into your crontab should take care of this. As long as everything's hooked up.
- There is NO error checking beyond rudimentary checks for the presence of a backup drive.
- =head1 Sample Output from lsblk
- [root@orion bin]# lsblk -bnp -o KNAME,MAJ:MIN,SIZE,UUID,FSTYPE,LABEL
- /dev/sda 8:0 1000204886016
- /dev/sda1 8:1 524288000 a33dd657-0219-45ac-b972-b2776d544119 ext4
- /dev/sda2 8:2 999678803968 P4Igma-nf61-96np-EDMc-Grio-BUIL-j12JgR LVM2_member
- /dev/dm-0 253:0 53687091200 e4a64529-37ca-4006-917b-b480e98886cc ext4
- /dev/dm-1 253:1 4227858432 faa6b4f4-1697-409e-be8a-aea4e31f028b swap
- /dev/dm-2 253:2 679615660032 7ef0fc8b-f444-4e68-b54b-5e38eff7ed84 ext4
- /dev/dm-3 253:3 262144000000 7629eb3d-7fb2-46f1-8d9a-244fd3960fb7 ext4
- /dev/sdb 8:16 1000204886016
- /dev/sdb1 8:17 1000203837440 6720f72b-86ad-4568-b8dc-b22f69cf2923 btrfs backup02
- /dev/sr0 11:0 1073741312
- =cut
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement