| Line 8... |
Line 8... |
| 8 |
# Initial Release
|
8 |
# Initial Release
|
| 9 |
#
|
9 |
#
|
| 10 |
# version 1.0.1 20220430 RWR
|
10 |
# version 1.0.1 20220430 RWR
|
| 11 |
# Removed some debugging, set so it will always log the actions to /tmp/snapShot
|
11 |
# Removed some debugging, set so it will always log the actions to /tmp/snapShot
|
| 12 |
#
|
12 |
#
|
| - |
|
13 |
# version 1.0.2 20220529 RWR
|
| - |
|
14 |
# Fixed error where 86400 was mistyped 864000, replacing all instance of numbers other than 60 and 3600 with contants
|
| - |
|
15 |
# Added DEBUG flag in config which will turn on TESTING, the dump some additional information to screen during run
|
| - |
|
16 |
#
|
| 13 |
# This program is free software: you can redistribute it and/or modify
|
17 |
# This program is free software: you can redistribute it and/or modify
|
| 14 |
# it under the terms of the GNU General Public License as published by
|
18 |
# it under the terms of the GNU General Public License as published by
|
| 15 |
# the Free Software Foundation, either version 3 of the License, or
|
19 |
# the Free Software Foundation, either version 3 of the License, or
|
| 16 |
# (at your option) any later version.
|
20 |
# (at your option) any later version.
|
| 17 |
#
|
21 |
#
|
| Line 29... |
Line 33... |
| 29 |
|
33 |
|
| 30 |
|
34 |
|
| 31 |
use strict;
|
35 |
use strict;
|
| 32 |
use warnings;
|
36 |
use warnings;
|
| 33 |
|
37 |
|
| 34 |
use version; our $VERSION = version->declare( 'v1.0.1');
|
38 |
use version; our $VERSION = version->declare( 'v1.0.2');
|
| 35 |
use Data::Dumper;
|
39 |
use Data::Dumper;
|
| 36 |
use Time::Local;
|
40 |
use Time::Local;
|
| 37 |
use POSIX qw(strftime);
|
41 |
use POSIX qw(strftime);
|
| 38 |
use YAML::Tiny; # apt-get libyaml-tiny-perl under debian, BSD Systems: cpan -i YAML::Tiny
|
42 |
use YAML::Tiny; # apt-get libyaml-tiny-perl under debian, BSD Systems: cpan -i YAML::Tiny
|
| 39 |
use Hash::Merge::Simple qw/ merge clone_merge /; # apt install libhash-merge-simple-perl or cpan -i Hash::Merge::Simple
|
43 |
use Hash::Merge::Simple qw/ merge clone_merge /; # apt install libhash-merge-simple-perl or cpan -i Hash::Merge::Simple
|
| 40 |
|
44 |
|
| 41 |
|
45 |
|
| 42 |
# globals
|
46 |
# globals
|
| 43 |
my $CONFIG_FILE_NAME = 'snapShot.yaml';
|
47 |
my $CONFIG_FILE_NAME = 'snapShot.yaml';
|
| - |
|
48 |
my $SECONDS_PER_DAY = 86400;
|
| - |
|
49 |
my $SECONDS_PER_WEEK = 7 * $SECONDS_PER_DAY;
|
| - |
|
50 |
my $SECONDS_PER_MONTH = 30.5 * $SECONDS_PER_DAY;
|
| - |
|
51 |
my $SECONDS_PER_YEAR = 365.2425 * $SECONDS_PER_DAY;
|
| 44 |
|
52 |
|
| 45 |
# This will be read in from snapShot.yaml
|
53 |
# This will be read in from snapShot.yaml
|
| 46 |
my $config;
|
54 |
my $config;
|
| 47 |
|
55 |
|
| 48 |
#
|
56 |
#
|
| Line 116... |
Line 124... |
| 116 |
}
|
124 |
}
|
| 117 |
}
|
125 |
}
|
| 118 |
return \%dataSets; # return all entries we are looking for
|
126 |
return \%dataSets; # return all entries we are looking for
|
| 119 |
}
|
127 |
}
|
| 120 |
|
128 |
|
| 121 |
# will convert something like 1 day to the number of seconds (86400) for math.
|
129 |
# will convert something like 1 day to the number of seconds ($SECONDS_PER_DAY) for math.
|
| 122 |
# month and year are approximations (30.5 day = a month, 365.2425 days is a year)
|
130 |
# month and year are approximations (30.5 day = a month, 365.2425 days is a year)
|
| 123 |
# For month and year, use the int function to convert back to integer
|
131 |
# For month and year, use the int function to convert back to integer
|
| 124 |
sub period2seconds {
|
132 |
sub period2seconds {
|
| 125 |
my ($count, $unit) = ( shift =~ m/\s*(\d+)\s*([a-z]+)\s*/i );
|
133 |
my ($count, $unit) = ( shift =~ m/\s*(\d+)\s*([a-z]+)\s*/i );
|
| 126 |
$unit = lc $unit;
|
134 |
$unit = lc $unit;
|
| 127 |
if ( $unit eq 'hour' ) {
|
135 |
if ( $unit eq 'hour' ) {
|
| 128 |
$count *= 3600;
|
136 |
$count *= 3600;
|
| 129 |
} elsif ( $unit eq 'day' ) {
|
137 |
} elsif ( $unit eq 'day' ) {
|
| 130 |
$count *= 86400;
|
138 |
$count *= $SECONDS_PER_DAY;
|
| 131 |
} elsif ( $unit eq 'week' ) {
|
139 |
} elsif ( $unit eq 'week' ) {
|
| 132 |
$count *= 864000 * 7;
|
140 |
$count *= $SECONDS_PER_WEEK;
|
| 133 |
} elsif ( $unit eq 'month' ) {
|
141 |
} elsif ( $unit eq 'month' ) {
|
| 134 |
$count *= int( 864000 * 30.5 );
|
142 |
$count *= int( $SECONDS_PER_MONTH );
|
| 135 |
} elsif ( $unit eq 'year' ) {
|
143 |
} elsif ( $unit eq 'year' ) {
|
| 136 |
$count *= int( 86400 * 365.2425 );
|
144 |
$count *= int( $SECONDS_PER_YEAR );
|
| 137 |
} else {
|
145 |
} else {
|
| 138 |
die "Unknown units [$unit] in period2seconds\n";
|
146 |
die "Unknown units [$unit] in period2seconds\n";
|
| 139 |
}
|
147 |
}
|
| 140 |
return $count;
|
148 |
return $count;
|
| 141 |
}
|
149 |
}
|
| 142 |
|
150 |
|
| - |
|
151 |
# quick convert unix time stamp to YYYY-MM-DD HH:MM
|
| - |
|
152 |
sub unix2Gregorian {
|
| - |
|
153 |
use POSIX qw(strftime);
|
| - |
|
154 |
my $timestamp = shift;
|
| - |
|
155 |
|
| - |
|
156 |
return strftime( "%F %R", $timestamp );
|
| - |
|
157 |
}
|
| - |
|
158 |
|
| - |
|
159 |
# just converts a number of seconds to days HH:MM:SS
|
| - |
|
160 |
|
| - |
|
161 |
sub secondsToHuman {
|
| - |
|
162 |
my $seconds = shift;
|
| - |
|
163 |
|
| - |
|
164 |
my $days = int( $seconds / $SECONDS_PER_DAY );
|
| - |
|
165 |
$seconds -= $days * $SECONDS_PER_DAY;
|
| - |
|
166 |
my $hours = int( $seconds / 60);
|
| - |
|
167 |
$seconds -= $hours * 60;
|
| - |
|
168 |
my $minutes = int( $seconds / 60 );
|
| - |
|
169 |
$seconds -= $minutes * 60;
|
| - |
|
170 |
return printf( '%02d days %02:%02:%02', $days, $hours, $minutes, $seconds );
|
| - |
|
171 |
}
|
| - |
|
172 |
|
| 143 |
# Merges datasets, snapshots and some stuff from the configuration into the datasets
|
173 |
# Merges datasets, snapshots and some stuff from the configuration into the datasets
|
| 144 |
# hash. After this, $config and $snapshots should no longer be necessary
|
174 |
# hash. After this, $config and $snapshots should no longer be necessary
|
| 145 |
sub mergeData {
|
175 |
sub mergeData {
|
| 146 |
my ($datasets,$snapshots,$config) = @_;
|
176 |
my ($datasets,$snapshots,$config) = @_;
|
| 147 |
my $confKeys = $config->{'datasets'};
|
177 |
my $confKeys = $config->{'datasets'};
|
| Line 202... |
Line 232... |
| 202 |
my ( $datasets, $now, $snapshotName, $slop ) = @_;
|
232 |
my ( $datasets, $now, $snapshotName, $slop ) = @_;
|
| 203 |
my @toDelete; # will hold all the destroy commands
|
233 |
my @toDelete; # will hold all the destroy commands
|
| 204 |
my @toAdd; # will hold all the create commands
|
234 |
my @toAdd; # will hold all the create commands
|
| 205 |
|
235 |
|
| 206 |
foreach my $thisDataset ( keys %$datasets ) { # Look at each dataset/volume in turn
|
236 |
foreach my $thisDataset ( keys %$datasets ) { # Look at each dataset/volume in turn
|
| - |
|
237 |
if ( $config->{'DEBUG'} ) {
|
| - |
|
238 |
print "Found Datasset $thisDataset\n";
|
| - |
|
239 |
print "\tRetention period set to " . &secondsToHuman( $datasets->{$thisDataset}->{'retention'} ) . "\n";
|
| - |
|
240 |
print "\tNext Snapshot due " .
|
| - |
|
241 |
&unix2Gregorian( $datasets->{$thisDataset}->{'lastSnap'} + $datasets->{$thisDataset}->{'frequency'} - $slop ) . "\n";
|
| - |
|
242 |
}
|
| 207 |
# if any snapshots need to be destroyed, add them to @toDelete
|
243 |
# if any snapshots need to be destroyed, add them to @toDelete
|
| 208 |
push( @toDelete,
|
244 |
push( @toDelete,
|
| 209 |
&checkRetention(
|
245 |
&checkRetention(
|
| 210 |
$datasets->{$thisDataset}->{'retention'},
|
246 |
$datasets->{$thisDataset}->{'retention'},
|
| 211 |
$datasets->{$thisDataset}->{'recursive'},
|
247 |
$datasets->{$thisDataset}->{'recursive'},
|
| Line 252... |
Line 288... |
| 252 |
}
|
288 |
}
|
| 253 |
return 0; # we succeeded
|
289 |
return 0; # we succeeded
|
| 254 |
}
|
290 |
}
|
| 255 |
|
291 |
|
| 256 |
&readConfig() or die "Could not read config file: $!\n";
|
292 |
&readConfig() or die "Could not read config file: $!\n";
|
| - |
|
293 |
# if debug set, be sure testing is set also, so no actions are taken
|
| - |
|
294 |
$config->{'TESTING'} = 1 if $config->{'DEBUG'};
|
| 257 |
|
295 |
|
| 258 |
# we're pre-calculating some things so we don't do it over and over for each entry
|
296 |
# we're pre-calculating some things so we don't do it over and over for each entry
|
| 259 |
# grab the time once
|
297 |
# grab the time once
|
| 260 |
my $now = time;
|
298 |
my $now = time;
|
| 261 |
# create the string to be used for all snapshots, using $now and the template provided
|
299 |
# create the string to be used for all snapshots, using $now and the template provided
|