mirror of https://github.com/jimsalterjrs/sanoid
vastly improved sanoid argument parsing
This commit is contained in:
parent
4621942a9d
commit
109d2ce5ca
134
sanoid
134
sanoid
|
|
@ -4,7 +4,7 @@
|
|||
# from http://www.gnu.org/licenses/gpl-3.0.html on 2014-11-17. A copy should also be available in this
|
||||
# project's Git repository at https://github.com/jimsalterjrs/sanoid/blob/master/LICENSE.
|
||||
|
||||
my $version = '1.0.15';
|
||||
my $version = '1.0.16';
|
||||
|
||||
use strict;
|
||||
use Config::IniFiles; # read samba-style conf file
|
||||
|
|
@ -32,24 +32,26 @@ my %snapsbypath = getsnapsbypath( \%config, \%snaps );
|
|||
# let's make it a little easier to be consistent passing these hashes in the same order to each sub
|
||||
my @params = ( \%config, \%snaps, \%snapsbytype, \%snapsbypath );
|
||||
|
||||
if ($ARGV[0] eq '--verbose') {
|
||||
blabber (@params);
|
||||
} elsif ($ARGV[0] eq '--monitor-snapshots') {
|
||||
monitor_snapshots(@params);
|
||||
} elsif ($ARGV[0] eq '--monitor-health') {
|
||||
monitor_health(@params);
|
||||
} elsif ($ARGV[0] eq '--force-update') {
|
||||
my %snaps = getsnaps( \%config, $cacheTTL, 1 );
|
||||
} elsif ($ARGV[0] eq '--version') {
|
||||
print "Sanoid version: $version\n";
|
||||
exit 0;
|
||||
} elsif ($ARGV[0] eq '--cron' || 1) {
|
||||
my %args = getargs(@ARGV);
|
||||
|
||||
if ($args{'debug'}) { $args{'verbose'}=1; blabber (@params); }
|
||||
if ($args{'monitor-snapshots'}) { monitor_snapshots(@params); }
|
||||
if ($args{'monitor-health'}) { monitor_health(@params); }
|
||||
if ($args{'force-update'}) { my $snaps = getsnaps( \%config, $cacheTTL, 1 ); }
|
||||
if ($args{'version'}) { print "INFO: Sanoid version: $version\n"; }
|
||||
|
||||
if ($args{'cron'} || $args{'noargs'}) {
|
||||
if ($args{'noargs'}) { print "INFO: No arguments given - assuming --cron and --verbose.\n"; }
|
||||
$args{'verbose'} = 1;
|
||||
take_snapshots (@params);
|
||||
prune_snapshots (@params);
|
||||
} else {
|
||||
if ($args{'take-snapshots'}) { take_snapshots (@params); }
|
||||
if ($args{'prune-snapshots'}) { prune_snapshots (@params); }
|
||||
}
|
||||
|
||||
exit 0;
|
||||
|
||||
|
||||
|
||||
####################################################################################
|
||||
####################################################################################
|
||||
|
|
@ -163,6 +165,7 @@ sub monitor_snapshots() {
|
|||
|
||||
sub prune_snapshots {
|
||||
|
||||
if ($args{'verbose'}) { print "INFO: pruning snapshots...\n"; }
|
||||
my ($config, $snaps, $snapsbytype, $snapsbypath) = @_;
|
||||
|
||||
my %datestamp = get_date();
|
||||
|
|
@ -211,7 +214,7 @@ sub prune_snapshots {
|
|||
if (checklock('sanoid_pruning')) {
|
||||
writelock('sanoid_pruning');
|
||||
foreach my $snap( @prunesnaps ){
|
||||
print "pruning $snap ... \n";
|
||||
if ($args{'verbose'}) { print "INFO: pruning $snap ... \n"; }
|
||||
if (iszfsbusy($path)) {
|
||||
print "INFO: deferring pruning of $snap - $path is currently in zfs send or receive.\n";
|
||||
} else {
|
||||
|
|
@ -231,6 +234,7 @@ sub prune_snapshots {
|
|||
|
||||
} # end prune_snapshots
|
||||
|
||||
|
||||
####################################################################################
|
||||
####################################################################################
|
||||
####################################################################################
|
||||
|
|
@ -244,6 +248,7 @@ sub take_snapshots {
|
|||
|
||||
my @newsnaps;
|
||||
|
||||
if ($args{'verbose'}) { print "INFO: taking snapshots...\n"; }
|
||||
foreach my $section (keys %config) {
|
||||
if ($section =~ /^template/) { next; }
|
||||
if (! $config{$section}{'autosnap'}) { next; }
|
||||
|
|
@ -318,7 +323,7 @@ sub take_snapshots {
|
|||
|
||||
if ( (scalar(@newsnaps)) > 0) {
|
||||
foreach my $snap ( @newsnaps ) {
|
||||
print "taking snapshot $snap\n";
|
||||
if ($args{'verbose'}) { print "taking snapshot $snap\n"; }
|
||||
system($zfs, "snapshot", "$snap");
|
||||
# make sure we don't end up with multiple snapshots with the same ctime
|
||||
sleep 1;
|
||||
|
|
@ -368,6 +373,7 @@ sub blabber {
|
|||
|
||||
} # end blabber
|
||||
|
||||
|
||||
####################################################################################
|
||||
####################################################################################
|
||||
####################################################################################
|
||||
|
|
@ -464,7 +470,13 @@ sub getsnaps {
|
|||
if ( $forcecacheupdate || (time() - $mtime) > $cacheTTL ) {
|
||||
if (checklock('sanoid_cacheupdate')) {
|
||||
writelock('sanoid_cacheupdate');
|
||||
# print "cache expired - updating from zfs list.\n";
|
||||
if ($args{'verbose'}) {
|
||||
if ($args{'force-update'}) {
|
||||
print "INFO: cache forcibly expired - updating from zfs list.\n";
|
||||
} else {
|
||||
print "INFO: cache expired - updating from zfs list.\n";
|
||||
}
|
||||
}
|
||||
open FH, "$zfs get -Hpt snapshot creation |";
|
||||
@rawsnaps = <FH>;
|
||||
close FH;
|
||||
|
|
@ -474,13 +486,13 @@ sub getsnaps {
|
|||
close FH;
|
||||
removelock('sanoid_cacheupdate');
|
||||
} else {
|
||||
print "INFO: deferring cache update - valid cache update lock held by another sanoid process.\n";
|
||||
if ($args{'verbose'}) { print "INFO: deferring cache update - valid cache update lock held by another sanoid process.\n"; }
|
||||
open FH, "< $cache";
|
||||
@rawsnaps = <FH>;
|
||||
close FH;
|
||||
}
|
||||
} else {
|
||||
#print "cache not expired (" . (time() - $mtime) . " seconds old with TTL of $cacheTTL): pulling snapshot list from cache.\n";
|
||||
# if ($args{'debug'}) { print "DEBUG: cache not expired (" . (time() - $mtime) . " seconds old with TTL of $cacheTTL): pulling snapshot list from cache.\n"; }
|
||||
open FH, "< $cache";
|
||||
@rawsnaps = <FH>;
|
||||
close FH;
|
||||
|
|
@ -654,6 +666,7 @@ sub displaytime {
|
|||
return $humanreadable;
|
||||
}
|
||||
|
||||
|
||||
####################################################################################
|
||||
####################################################################################
|
||||
####################################################################################
|
||||
|
|
@ -928,9 +941,9 @@ sub removelock {
|
|||
unlink $lockfile;
|
||||
return;
|
||||
} elsif (checklock($lockname) == 1) {
|
||||
die "No valid lockfile found - Did a rogue process or user update or delete it?\n";
|
||||
die "ERROR: No valid lockfile found - Did a rogue process or user update or delete it?\n";
|
||||
} else {
|
||||
die "A valid lockfile exists but does not belong to me! I refuse to remove it.\n";
|
||||
die "ERROR: A valid lockfile exists but does not belong to me! I refuse to remove it.\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -945,7 +958,7 @@ sub writelock {
|
|||
|
||||
# die honorably rather than overwriting a valid, existing lock
|
||||
if (! checklock($lockname)) {
|
||||
die "Valid lock already exists - I refuse to overwrite it. Committing seppuku now.\n";
|
||||
die "ERROR: Valid lock already exists - I refuse to overwrite it. Committing seppuku now.\n";
|
||||
}
|
||||
|
||||
my $pid = $$;
|
||||
|
|
@ -967,20 +980,18 @@ sub iszfsbusy {
|
|||
# check to see if ZFS filesystem passed in as argument currently has a zfs send or zfs receive process referencing it.
|
||||
# return true if busy (currently being sent or received), return false if not.
|
||||
|
||||
my $debug; #REMOVE THIS LATER when global $debug is actually implemented in sanoid!
|
||||
|
||||
my $fs = shift;
|
||||
if ($debug) { print "DEBUG: checking to see if $fs on is already in zfs receive using $pscmd axo args= ...\n"; }
|
||||
# if (args{'debug'}) { print "DEBUG: checking to see if $fs on is already in zfs receive using $pscmd axo args= ...\n"; }
|
||||
|
||||
open PL, "$pscmd axo args= |";
|
||||
my @processes = <PL>;
|
||||
close PL;
|
||||
|
||||
foreach my $process (@processes) {
|
||||
# if ($debug) { print "DEBUG: checking process $process...\n"; }
|
||||
# if ($args{'debug'}) { print "DEBUG: checking process $process...\n"; }
|
||||
if ($process =~ /zfs *(send|receive).*$fs/) {
|
||||
# there's already a zfs send/receive process for our target filesystem - return true
|
||||
# if ($debug) { print "DEBUG: process $process matches target $fs!\n"; }
|
||||
# if ($args{'debug'}) { print "DEBUG: process $process matches target $fs!\n"; }
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
|
@ -989,3 +1000,72 @@ sub iszfsbusy {
|
|||
return 0;
|
||||
}
|
||||
|
||||
#######################################################################################################################3
|
||||
#######################################################################################################################3
|
||||
#######################################################################################################################3
|
||||
|
||||
sub getargs {
|
||||
my @args = @_;
|
||||
my %args;
|
||||
|
||||
my @validargs;
|
||||
my @novalueargs;
|
||||
my %validargs;
|
||||
my %novalueargs;
|
||||
|
||||
push my @validargs, 'verbose','debug','version','monitor-health','monitor-snapshots','force-update','cron','take-snapshots','prune-snapshots';
|
||||
push my @novalueargs, 'verbose','debug','version','monitor-health','monitor-snapshots','force-update','cron','take-snapshots','prune-snapshots';
|
||||
foreach my $item (@validargs) { $validargs{$item}=1; }
|
||||
foreach my $item (@novalueargs) { $novalueargs{$item}=1; }
|
||||
|
||||
if (! (scalar @args)) {
|
||||
$args{'noargs'} = 1;
|
||||
}
|
||||
|
||||
while (my $rawarg = shift(@args)) {
|
||||
my $argvalue;
|
||||
my $arg = $rawarg;
|
||||
if ($rawarg =~ /=/) {
|
||||
# user specified the value for a CLI argument with =
|
||||
# instead of with blank space. separate appropriately.
|
||||
$argvalue = $arg;
|
||||
$arg =~ s/=.*$//;
|
||||
$argvalue =~ s/^.*=//;
|
||||
}
|
||||
if ($rawarg =~ /^--/) {
|
||||
# doubledash arg
|
||||
$arg =~ s/^--//;
|
||||
if ($novalueargs{$arg}) {
|
||||
$args{$arg} = 1;
|
||||
} else {
|
||||
# if this CLI arg takes a user-specified value and
|
||||
# we don't already have it, then the user must have
|
||||
# specified with a space, so pull in the next value
|
||||
# from the array as this value rather than as the
|
||||
# next argument.
|
||||
if ($argvalue eq '') { $argvalue = shift(@args); }
|
||||
$args{$arg} = $argvalue;
|
||||
}
|
||||
} elsif ($rawarg =~ /^-/) {
|
||||
# singledash arg
|
||||
$arg =~ s/^-//;
|
||||
if ($novalueargs{$arg}) {
|
||||
$args{$arg} = 1;
|
||||
} else {
|
||||
# if this CLI arg takes a user-specified value and
|
||||
# we don't already have it, then the user must have
|
||||
# specified with a space, so pull in the next value
|
||||
# from the array as this value rather than as the
|
||||
# next argument.
|
||||
if ($argvalue eq '') { $argvalue = shift(@args); }
|
||||
$args{$arg} = $argvalue;
|
||||
}
|
||||
} else {
|
||||
# bare arg
|
||||
die "ERROR: don't know what to do with bare argument $rawarg.\n";
|
||||
}
|
||||
if (! ($validargs{$arg})) { die "ERROR: don't understand argument $rawarg.\n"; }
|
||||
}
|
||||
return %args;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue