Subversion Repositories sysadmin_scripts

Rev

Rev 107 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 107 Rev 119
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