line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package App::Rsnapshot::Rotate; |
2
|
|
|
|
|
|
|
|
3
|
2
|
|
|
2
|
|
62497
|
use strict; |
|
2
|
|
|
|
|
7
|
|
|
2
|
|
|
|
|
77
|
|
4
|
2
|
|
|
2
|
|
11
|
use warnings; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
60
|
|
5
|
2
|
|
|
2
|
|
2411
|
use Data::Dumper; |
|
2
|
|
|
|
|
21908
|
|
|
2
|
|
|
|
|
156
|
|
6
|
|
|
|
|
|
|
|
7
|
2
|
|
|
2
|
|
20
|
use vars qw($VERSION); |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
1425
|
|
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
$VERSION = '1.0'; |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
=head1 NAME |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
App::Rsnapshot::Rotate - rotate snapshots |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
=head1 SYNOPSIS |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
# rotate the 'alpha' interval |
18
|
|
|
|
|
|
|
App::Rsnapshot::Rotate::go(config => $config, interval => 'alpha'); |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
=head1 DESCRIPTION |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
Rotates the named interval in your backups |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
=head1 SUBROUTINES |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
=head2 go |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
Takes two named parameters, C and C, being the name |
29
|
|
|
|
|
|
|
of the interval you want to rotate. |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
If the named interval is the first interval, then every foo.$number |
32
|
|
|
|
|
|
|
directory is renamed to foo.$number+1 except the highest numbered, |
33
|
|
|
|
|
|
|
which is renamde to _delete.$$ where $$ is the process ID, and foo.0 |
34
|
|
|
|
|
|
|
which is left alone. |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
If the named interval is *not* the first interval then it only rotates |
37
|
|
|
|
|
|
|
if previous.last exists. In that case, every foo.$number directory is |
38
|
|
|
|
|
|
|
renamed to foo.$number+1 except the highest numbered, which is renamde |
39
|
|
|
|
|
|
|
to _delete.$$, and previous.last is moved to foo.0. |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
=cut |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
sub go { |
44
|
11
|
|
|
11
|
1
|
118233
|
my($c, $interval) = map { {@_}->{$_} } (qw(config interval)); |
|
22
|
|
|
|
|
135
|
|
45
|
11
|
|
|
|
|
100
|
my @intervals = $c->intervals->interval('*'); |
46
|
11
|
|
|
|
|
26
|
my $interval0 = $intervals[0]; |
47
|
11
|
|
|
|
|
55
|
my $i = $c->intervals->interval($interval); |
48
|
11
|
|
|
|
|
46
|
my $s = $c->snapshotroot(); |
49
|
|
|
|
|
|
|
# print Dumper(\@intervals, $interval0, $interval); |
50
|
|
|
|
|
|
|
# print $c->snapshotroot; |
51
|
|
|
|
|
|
|
|
52
|
11
|
100
|
|
|
|
189
|
if($i->name() eq $interval0->name()) { # first interval ... |
53
|
|
|
|
|
|
|
# schedule oldest for deletion |
54
|
4
|
100
|
|
|
|
17
|
rename "$s/".$i->name().'.'.($i->retain() - 1), |
55
|
|
|
|
|
|
|
"$s/_delete.$$" |
56
|
|
|
|
|
|
|
if(-d "$s/".$i->name().'.'.($i->retain() - 1)); |
57
|
|
|
|
|
|
|
# now rotate the middle, oldest first |
58
|
4
|
|
|
|
|
27
|
foreach my $number (grep { |
|
16
|
|
|
|
|
58
|
|
59
|
|
|
|
|
|
|
-d "$s/".$i->name().".$_" |
60
|
|
|
|
|
|
|
} reverse(1 .. $i->retain() - 2)) { |
61
|
7
|
|
|
|
|
24
|
rename "$s/".$i->name().".$number", |
62
|
|
|
|
|
|
|
"$s/".$i->name().'.'.($number + 1) |
63
|
|
|
|
|
|
|
} |
64
|
|
|
|
|
|
|
} else { # this isn't the first interval ... |
65
|
|
|
|
|
|
|
# find previous interval |
66
|
7
|
|
|
|
|
9
|
my $previous = ''; |
67
|
7
|
|
|
|
|
15
|
foreach (@intervals) { |
68
|
21
|
100
|
|
|
|
87
|
last if($_->name() eq $i->name()); |
69
|
14
|
|
|
|
|
30
|
$previous = $_; |
70
|
|
|
|
|
|
|
} |
71
|
|
|
|
|
|
|
# if previous.last exists ... |
72
|
7
|
100
|
|
|
|
41
|
if(-d "$s/".$previous->name().'.'.($previous->retain() - 1)) { |
73
|
|
|
|
|
|
|
# schedule oldest for deletion |
74
|
4
|
100
|
|
|
|
13
|
rename "$s/".$i->name().'.'.($i->retain() - 1), |
75
|
|
|
|
|
|
|
"$s/_delete.$$" |
76
|
|
|
|
|
|
|
if(-d "$s/".$i->name().'.'.($i->retain() - 1)); |
77
|
|
|
|
|
|
|
# rotate what's already there ... |
78
|
4
|
|
|
|
|
24
|
foreach my $number (grep { |
|
12
|
|
|
|
|
37
|
|
79
|
|
|
|
|
|
|
-d "$s/".$i->name().".$_" |
80
|
|
|
|
|
|
|
} reverse(0 .. $i->retain() - 2)) { |
81
|
6
|
|
|
|
|
21
|
rename "$s/".$i->name().".$number", |
82
|
|
|
|
|
|
|
"$s/".$i->name().'.'.($number + 1) |
83
|
|
|
|
|
|
|
} |
84
|
|
|
|
|
|
|
# move previous.last to this.0 |
85
|
4
|
|
|
|
|
19
|
rename "$s/".$previous->name().'.'.($previous->retain() - 1), |
86
|
|
|
|
|
|
|
"$s/".$i->name().".0"; |
87
|
|
|
|
|
|
|
} |
88
|
|
|
|
|
|
|
} |
89
|
|
|
|
|
|
|
} |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
=head1 BUGS/WARNINGS/LIMITATIONS |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
None known. |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
=head1 SOURCE CODE REPOSITORY |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
L |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
=head1 AUTHOR, COPYRIGHT and LICENCE |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
Copyright 2009 David Cantrell |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
This software is free-as-in-speech software, and may be used, |
104
|
|
|
|
|
|
|
distributed, and modified under the terms of either the GNU |
105
|
|
|
|
|
|
|
General Public Licence version 2 or the Artistic Licence. It's |
106
|
|
|
|
|
|
|
up to you which one you use. The full text of the licences can |
107
|
|
|
|
|
|
|
be found in the files GPL2.txt and ARTISTIC.txt, respectively. |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
=head1 CONSPIRACY |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
This module is also free-as-in-mason software. |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
=cut |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
1; |