mirror of https://github.com/jimsalterjrs/sanoid
Merge pull request #280 from phreaker0/pre-post-scripts
add pre, post and prune snapshot scripts
This commit is contained in:
commit
c5965eabc7
77
sanoid
77
sanoid
|
|
@ -309,6 +309,17 @@ sub prune_snapshots {
|
||||||
if (! $args{'readonly'}) {
|
if (! $args{'readonly'}) {
|
||||||
if (system($zfs, "destroy", $snap) == 0) {
|
if (system($zfs, "destroy", $snap) == 0) {
|
||||||
$pruned{$snap} = 1;
|
$pruned{$snap} = 1;
|
||||||
|
my $dataset = (split '@', $snap)[0];
|
||||||
|
my $snapname = (split '@', $snap)[1];
|
||||||
|
if ($config{$dataset}{'pruning_script'}) {
|
||||||
|
$ENV{'SANOID_TARGET'} = $dataset;
|
||||||
|
$ENV{'SANOID_SNAPNAME'} = $snapname;
|
||||||
|
if ($args{'verbose'}) { print "executing pruning_script '".$config{$dataset}{'pruning_script'}."' on dataset '$dataset'\n"; }
|
||||||
|
my $ret = runscript('pruning_script',$dataset);
|
||||||
|
|
||||||
|
delete $ENV{'SANOID_TARGET'};
|
||||||
|
delete $ENV{'SANOID_SNAPNAME'};
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
warn "could not remove $snap : $?";
|
warn "could not remove $snap : $?";
|
||||||
}
|
}
|
||||||
|
|
@ -476,6 +487,24 @@ sub take_snapshots {
|
||||||
|
|
||||||
if ( (scalar(@newsnaps)) > 0) {
|
if ( (scalar(@newsnaps)) > 0) {
|
||||||
foreach my $snap ( @newsnaps ) {
|
foreach my $snap ( @newsnaps ) {
|
||||||
|
my $dataset = (split '@', $snap)[0];
|
||||||
|
my $snapname = (split '@', $snap)[1];
|
||||||
|
my $presnapshotfailure = 0;
|
||||||
|
if ($config{$dataset}{'pre_snapshot_script'} and !$args{'readonly'}) {
|
||||||
|
$ENV{'SANOID_TARGET'} = $dataset;
|
||||||
|
$ENV{'SANOID_SNAPNAME'} = $snapname;
|
||||||
|
if ($args{'verbose'}) { print "executing pre_snapshot_script '".$config{$dataset}{'pre_snapshot_script'}."' on dataset '$dataset'\n"; }
|
||||||
|
my $ret = runscript('pre_snapshot_script',$dataset);
|
||||||
|
|
||||||
|
delete $ENV{'SANOID_TARGET'};
|
||||||
|
delete $ENV{'SANOID_SNAPNAME'};
|
||||||
|
|
||||||
|
if ($ret != 0) {
|
||||||
|
# warning was already thrown by runscript function
|
||||||
|
$config{$dataset}{'no_inconsistent_snapshot'} and next;
|
||||||
|
$presnapshotfailure = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
if ($args{'verbose'}) { print "taking snapshot $snap\n"; }
|
if ($args{'verbose'}) { print "taking snapshot $snap\n"; }
|
||||||
if (!$args{'readonly'}) {
|
if (!$args{'readonly'}) {
|
||||||
system($zfs, "snapshot", "$snap") == 0
|
system($zfs, "snapshot", "$snap") == 0
|
||||||
|
|
@ -483,6 +512,17 @@ sub take_snapshots {
|
||||||
# make sure we don't end up with multiple snapshots with the same ctime
|
# make sure we don't end up with multiple snapshots with the same ctime
|
||||||
sleep 1;
|
sleep 1;
|
||||||
}
|
}
|
||||||
|
if ($config{$dataset}{'post_snapshot_script'} and !$args{'readonly'}) {
|
||||||
|
if (!$presnapshotfailure or $config{$dataset}{'force_post_snapshot_script'}) {
|
||||||
|
$ENV{'SANOID_TARGET'} = $dataset;
|
||||||
|
$ENV{'SANOID_SNAPNAME'} = $snapname;
|
||||||
|
if ($args{'verbose'}) { print "executing post_snapshot_script '".$config{$dataset}{'post_snapshot_script'}."' on dataset '$dataset'\n"; }
|
||||||
|
runscript('post_snapshot_script',$dataset);
|
||||||
|
|
||||||
|
delete $ENV{'SANOID_TARGET'};
|
||||||
|
delete $ENV{'SANOID_SNAPNAME'};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$forcecacheupdate = 1;
|
$forcecacheupdate = 1;
|
||||||
%snaps = getsnaps(%config,$cacheTTL,$forcecacheupdate);
|
%snaps = getsnaps(%config,$cacheTTL,$forcecacheupdate);
|
||||||
|
|
@ -682,7 +722,7 @@ sub init {
|
||||||
tie my %ini, 'Config::IniFiles', ( -file => $conf_file ) or die "FATAL: cannot load $conf_file - please create a valid local config file before running sanoid!";
|
tie my %ini, 'Config::IniFiles', ( -file => $conf_file ) or die "FATAL: cannot load $conf_file - please create a valid local config file before running sanoid!";
|
||||||
|
|
||||||
# we'll use these later to normalize potentially true and false values on any toggle keys
|
# we'll use these later to normalize potentially true and false values on any toggle keys
|
||||||
my @toggles = ('autosnap','autoprune','monitor_dont_warn','monitor_dont_crit','monitor','recursive','process_children_only','skip_children');
|
my @toggles = ('autosnap','autoprune','monitor_dont_warn','monitor_dont_crit','monitor','recursive','process_children_only','skip_children','no_inconsistent_snapshot','force_post_snapshot_script');
|
||||||
my @istrue=(1,"true","True","TRUE","yes","Yes","YES","on","On","ON");
|
my @istrue=(1,"true","True","TRUE","yes","Yes","YES","on","On","ON");
|
||||||
my @isfalse=(0,"false","False","FALSE","no","No","NO","off","Off","OFF");
|
my @isfalse=(0,"false","False","FALSE","no","No","NO","off","Off","OFF");
|
||||||
|
|
||||||
|
|
@ -1405,6 +1445,41 @@ sub removecachedsnapshots {
|
||||||
undef %pruned;
|
undef %pruned;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#######################################################################################################################3
|
||||||
|
#######################################################################################################################3
|
||||||
|
#######################################################################################################################3
|
||||||
|
|
||||||
|
sub runscript {
|
||||||
|
my $key=shift;
|
||||||
|
my $dataset=shift;
|
||||||
|
|
||||||
|
my $timeout=$config{$dataset}{'script_timeout'};
|
||||||
|
|
||||||
|
my $ret;
|
||||||
|
eval {
|
||||||
|
if ($timeout gt 0) {
|
||||||
|
local $SIG{ALRM} = sub { die "alarm\n" };
|
||||||
|
alarm $timeout;
|
||||||
|
}
|
||||||
|
$ret = system($config{$dataset}{$key});
|
||||||
|
alarm 0;
|
||||||
|
};
|
||||||
|
if ($@) {
|
||||||
|
if ($@ eq "alarm\n") {
|
||||||
|
warn "WARN: $key didn't finish in the allowed time!";
|
||||||
|
} else {
|
||||||
|
warn "CRITICAL ERROR: $@";
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
if ($ret != 0) {
|
||||||
|
warn "WARN: $key failed, $?";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
__END__
|
__END__
|
||||||
|
|
||||||
=head1 NAME
|
=head1 NAME
|
||||||
|
|
|
||||||
15
sanoid.conf
15
sanoid.conf
|
|
@ -69,6 +69,21 @@
|
||||||
daily_warn = 48
|
daily_warn = 48
|
||||||
daily_crit = 60
|
daily_crit = 60
|
||||||
|
|
||||||
|
[template_scripts]
|
||||||
|
### dataset and snapshot name will be supplied as environment variables
|
||||||
|
### for all pre/post/prune scripts ($SANOID_TARGET, $SANOID_SNAPNAME)
|
||||||
|
### run script before snapshot
|
||||||
|
pre_snapshot_script = /path/to/script.sh
|
||||||
|
### run script after snapshot
|
||||||
|
post_snapshot_script = /path/to/script.sh
|
||||||
|
### run script after pruning snapshot
|
||||||
|
pruning_script = /path/to/script.sh
|
||||||
|
### don't take an inconsistent snapshot (skip if pre script fails)
|
||||||
|
#no_inconsistent_snapshot = yes
|
||||||
|
### run post_snapshot_script when pre_snapshot_script is failing
|
||||||
|
#force_post_snapshot_script = yes
|
||||||
|
### limit allowed execution time of scripts before continuing (<= 0: infinite)
|
||||||
|
script_timeout = 5
|
||||||
|
|
||||||
[template_ignore]
|
[template_ignore]
|
||||||
autoprune = no
|
autoprune = no
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,13 @@ use_template =
|
||||||
process_children_only =
|
process_children_only =
|
||||||
skip_children =
|
skip_children =
|
||||||
|
|
||||||
|
pre_snapshot_script =
|
||||||
|
post_snapshot_script =
|
||||||
|
pruning_script =
|
||||||
|
script_timeout = 5
|
||||||
|
no_inconsistent_snapshot =
|
||||||
|
force_post_snapshot_script =
|
||||||
|
|
||||||
# for snapshots shorter than one hour, the period duration must be defined
|
# for snapshots shorter than one hour, the period duration must be defined
|
||||||
# in minutes. Because they are executed within a full hour, the selected
|
# in minutes. Because they are executed within a full hour, the selected
|
||||||
# value should divide 60 minutes without remainder so taken snapshots
|
# value should divide 60 minutes without remainder so taken snapshots
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue