recursion support in sanoid, die on unknown values in sanoid.conf
This commit is contained in:
parent
5bad8ec6a7
commit
2031b64a8e
|
@ -1,3 +1,5 @@
|
|||
1.1.0 woooo - working recursive definitions in Sanoid! Also intelligent config errors in Sanoid; will die with errors if unknown config value is set.
|
||||
|
||||
1.0.20 greatly cleaned up config parsing in sanoid, got rid of 'hardcoded defaults' in favor of /etc/sanoid/sanoid.defaults.conf
|
||||
|
||||
1.0.19 working recursive sync (sync specified dataset and all child datasets, ie pool/ds, pool/ds/1, pool, ds/1/a, pool/ds/2 ...) with --recursive or -r in syncoid!
|
||||
|
|
94
sanoid
94
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.19';
|
||||
my $version = '1.1.0';
|
||||
|
||||
use strict;
|
||||
use Config::IniFiles; # read samba-style conf file
|
||||
|
@ -327,9 +327,11 @@ sub take_snapshots {
|
|||
if ( (scalar(@newsnaps)) > 0) {
|
||||
foreach my $snap ( @newsnaps ) {
|
||||
if ($args{'verbose'}) { print "taking snapshot $snap\n"; }
|
||||
if (!$args{'readonly'}) { system($zfs, "snapshot", "$snap"); }
|
||||
# make sure we don't end up with multiple snapshots with the same ctime
|
||||
sleep 1;
|
||||
if (!$args{'readonly'}) {
|
||||
system($zfs, "snapshot", "$snap");
|
||||
# make sure we don't end up with multiple snapshots with the same ctime
|
||||
sleep 1;
|
||||
}
|
||||
}
|
||||
$forcecacheupdate = 1;
|
||||
%snaps = getsnaps(%config,$cacheTTL,$forcecacheupdate);
|
||||
|
@ -525,30 +527,40 @@ sub init {
|
|||
tie my %ini, 'Config::IniFiles', ( -file => $conf_file );
|
||||
|
||||
# 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');
|
||||
my @toggles = ('autosnap','autoprune','monitor_dont_warn','monitor_dont_crit','monitor','recursive');
|
||||
my @istrue=(1,"true","True","TRUE","yes","Yes","YES","on","On","ON");
|
||||
my @isfalse=(0,"false","False","FALSE","no","No","NO","off","Off","OFF");
|
||||
|
||||
foreach my $section (keys %ini) {
|
||||
if ($section =~ /^template_/) { next; } # don't process templates directly
|
||||
|
||||
# set default values from %defaults, which can then be overriden by template
|
||||
# and/or local settings within the module.
|
||||
|
||||
foreach my $key (keys %{$defaults{'template_default'}}) {
|
||||
if (! ($key =~ /template/)) {
|
||||
if ($args{'debug'}) { print "INFO: setting $key on $section from $default_conf_file.\n"; }
|
||||
$config{$section}{$key} = $defaults{'template_default'}{$key};
|
||||
# first up - die with honor if unknown parameters are set in any modules or templates by the user.
|
||||
foreach my $key (keys %{$ini{$section}}) {
|
||||
if (! defined ($defaults{'template_default'}{$key})) {
|
||||
die "FATAL ERROR: I don't understand the setting $key you've set in \[$section\] in $conf_file.\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# override with values from user-defined default template, if any
|
||||
|
||||
foreach my $key (keys %{$ini{'template_default'}}) {
|
||||
if (! ($key =~ /template/)) {
|
||||
if ($args{'debug'}) { print "INFO: overriding $key on $section with value from user-defined default template.\n"; }
|
||||
$config{$section}{$key} = $ini{'template_default'}{$key};
|
||||
if ($section =~ /^template_/) { next; } # don't process templates directly
|
||||
|
||||
# only set defaults on sections that haven't already been initialized - this allows us to override values
|
||||
# for sections directly when they've already been defined recursively, without starting them over from scratch.
|
||||
if (! defined ($config{$section}{'initialized'})) {
|
||||
if ($args{'debug'}) { print "DEBUG: initializing \$config\{$section\} with default values from $default_conf_file.\n"; }
|
||||
# set default values from %defaults, which can then be overriden by template
|
||||
# and/or local settings within the module.
|
||||
foreach my $key (keys %{$defaults{'template_default'}}) {
|
||||
if (! ($key =~ /template|recursive/)) {
|
||||
$config{$section}{$key} = $defaults{'template_default'}{$key};
|
||||
}
|
||||
}
|
||||
|
||||
# override with values from user-defined default template, if any
|
||||
|
||||
foreach my $key (keys %{$ini{'template_default'}}) {
|
||||
if (! ($key =~ /template|recursive/)) {
|
||||
if ($args{'debug'}) { print "DEBUG: overriding $key on $section with value from user-defined default template.\n"; }
|
||||
$config{$section}{$key} = $ini{'template_default'}{$key};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -559,8 +571,8 @@ sub init {
|
|||
foreach my $rawtemplate (@templates) {
|
||||
my $template = 'template_'.$rawtemplate;
|
||||
foreach my $key (keys %{$ini{$template}}) {
|
||||
if (! ($key =~ /template/)) {
|
||||
if ($args{'debug'}) { print "INFO: overriding $key on $section with value from user-defined template $template.\n"; }
|
||||
if (! ($key =~ /template|recursive/)) {
|
||||
if ($args{'debug'}) { print "DEBUG: overriding $key on $section with value from user-defined template $template.\n"; }
|
||||
$config{$section}{$key} = $ini{$template}{$key};
|
||||
}
|
||||
}
|
||||
|
@ -569,8 +581,8 @@ sub init {
|
|||
|
||||
# override with any locally set values in the module itself
|
||||
foreach my $key (keys %{$ini{$section}} ) {
|
||||
if (! ($key =~ /template/)) {
|
||||
if ($args{'debug'}) { print "INFO: overriding $key on $section with value directly set in module.\n"; }
|
||||
if (! ($key =~ /template|recursive/)) {
|
||||
if ($args{'debug'}) { print "DEBUG: overriding $key on $section with value directly set in module.\n"; }
|
||||
$config{$section}{$key} = $ini{$section}{$key};
|
||||
}
|
||||
}
|
||||
|
@ -591,6 +603,26 @@ sub init {
|
|||
} else {
|
||||
$config{$section}{'path'} = $section;
|
||||
}
|
||||
|
||||
# how 'bout some recursion? =)
|
||||
my @datasets;
|
||||
if ($ini{$section}{'recursive'}) {
|
||||
@datasets = getchilddatasets($config{$section}{'path'});
|
||||
foreach my $dataset(@datasets) {
|
||||
chomp $dataset;
|
||||
foreach my $key (keys %{$config{$section}} ) {
|
||||
if (! ($key =~ /template|recursive/)) {
|
||||
if ($args{'debug'}) { print "DEBUG: recursively setting $key from $section to $dataset.\n"; }
|
||||
$config{$dataset}{$key} = $config{$section}{$key};
|
||||
}
|
||||
}
|
||||
$config{$dataset}{'path'} = $dataset;
|
||||
$config{$dataset}{'initialized'} = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
return %config;
|
||||
|
@ -1043,3 +1075,17 @@ sub getargs {
|
|||
return %args;
|
||||
}
|
||||
|
||||
sub getchilddatasets {
|
||||
# for later, if we make sanoid itself support sudo use
|
||||
my $fs = shift;
|
||||
my $mysudocmd;
|
||||
|
||||
my $getchildrencmd = "$mysudocmd $zfs list -o name -Hr $fs |";
|
||||
if ($args{'debug'}) { print "DEBUG: getting list of child datasets on $fs using $getchildrencmd...\n"; }
|
||||
open FH, $getchildrencmd;
|
||||
my @children = <FH>;
|
||||
close FH;
|
||||
|
||||
return @children;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
hourly = 30
|
||||
daily = 90
|
||||
monthly = 12
|
||||
yearlies = 0
|
||||
yearly = 0
|
||||
|
||||
### don't take new snapshots - snapshots on backup
|
||||
### datasets are replicated in from source, not
|
||||
|
|
4
syncoid
4
syncoid
|
@ -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.19';
|
||||
my $version = '1.1.0';
|
||||
|
||||
use strict;
|
||||
use Data::Dumper;
|
||||
|
@ -82,7 +82,7 @@ sub getchilddatasets {
|
|||
if ($isroot) { $mysudocmd = ''; } else { $mysudocmd = $sudocmd; }
|
||||
if ($rhost ne '') { $rhost = "$sshcmd $rhost"; }
|
||||
|
||||
my $getchildrencmd = "$rhost $mysudocmd $zfscmd list -o name -Hpr $fs |";
|
||||
my $getchildrencmd = "$rhost $mysudocmd $zfscmd list -o name -Hr $fs |";
|
||||
if ($debug) { print "DEBUG: getting list of child datasets on $fs using $getchildrencmd...\n"; }
|
||||
open FH, $getchildrencmd;
|
||||
my @children = <FH>;
|
||||
|
|
Loading…
Reference in New Issue