File Coverage

blib/lib/Sys/RevoBackup.pm
Criterion Covered Total %
statement 11 13 84.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 16 18 88.8


line stmt bran cond sub pod time code
1             package Sys::RevoBackup;
2             {
3             $Sys::RevoBackup::VERSION = '0.27';
4             }
5             BEGIN {
6 1     1   2298 $Sys::RevoBackup::AUTHORITY = 'cpan:TEX';
7             }
8             # ABSTRACT: an rsync-based backup script
9              
10 1     1   24 use 5.010_000;
  1         4  
  1         40  
11 1     1   5 use mro 'c3';
  1         3  
  1         11  
12 1     1   40 use feature ':5.10';
  1         3  
  1         107  
13              
14 1     1   1336 use Moose;
  0            
  0            
15             use namespace::autoclean;
16              
17             # use IO::Handle;
18             # use autodie;
19             # use MooseX::Params::Validate;
20             use English qw( -no_match_vars );
21             use Try::Tiny;
22              
23             use Sys::Run;
24             use Job::Manager;
25             use Sys::RevoBackup::Job;
26              
27             extends 'Sys::Bprsync' => { -version => 0.17 };
28              
29             has 'bank' => (
30             'is' => 'ro',
31             'isa' => 'Str',
32             'required' => 1,
33             );
34              
35             has 'sys' => (
36             'is' => 'rw',
37             'isa' => 'Sys::Run',
38             'lazy' => 1,
39             'builder' => '_init_sys',
40             );
41              
42             has 'job_filter' => (
43             'is' => 'rw',
44             'isa' => 'Str',
45             'default' => '',
46             );
47              
48             with qw(Config::Yak::OrderedPlugins);
49              
50             sub _plugin_base_class { return 'Sys::RevoBackup::Plugin'; }
51              
52             sub _init_sys {
53             my $self = shift;
54              
55             my $Sys = Sys::Run::->new( {
56             'logger' => $self->logger(),
57             'ssh_hostkey_check' => 0,
58             } );
59              
60             return $Sys;
61             }
62              
63             sub _init_config_prefix {
64             return 'Sys::RevoBackup';
65             }
66              
67             sub _init_jobs {
68             my $self = shift;
69              
70             my $JQ = Job::Manager::->new(
71             {
72             'logger' => $self->logger(),
73             'concurrency' => $self->concurrency(),
74             }
75             );
76              
77             my $verbose = $self->config()->get( $self->config_prefix() . '::Verbose' ) ? 1 : 0;
78             my $dry = $self->config()->get( $self->config_prefix() . '::Dry' ) ? 1 : 0;
79              
80             VAULT: foreach my $job_name ( @{$self->vaults()} ) {
81             if($self->job_filter() && $job_name ne $self->job_filter()) {
82             # skip this job if it doesn't match the job filter
83             $self->logger()->log( message => 'Skipping Job '.$job_name.' because it does not match the filter', level => 'debug', );
84             next VAULT;
85             }
86             try {
87             my $Job = Sys::RevoBackup::Job::->new(
88             {
89             'parent' => $self,
90             'name' => $job_name,
91             'verbose' => $verbose,
92             'logger' => $self->logger(),
93             'config' => $self->config(),
94             'bank' => $self->bank(),
95             'vault' => $job_name,
96             'dry' => $dry,
97             }
98             );
99             $JQ->add($Job);
100             }
101             catch {
102             $self->logger()->log( message => 'caught error: '.$_, level => 'error', );
103             };
104             }
105              
106             return $JQ;
107             }
108              
109             sub vaults {
110             my $self = shift;
111              
112             return [$self->config()->get_array( $self->config_prefix() . '::Vaults' )];
113             }
114              
115             sub run {
116             my $self = shift;
117              
118             foreach my $Plugin (@{$self->plugins()}) {
119             try {
120             $Plugin->run_config_hook();
121             } catch {
122             $self->logger()->log( message => 'Failed to run config hook of plugin '.ref($Plugin).' w/ error: '.$_, level => 'error', );
123             };
124             }
125              
126             foreach my $Plugin (@{$self->plugins()}) {
127             try {
128             $Plugin->run_prepare_hook();
129             } catch {
130             $self->logger()->log( message => 'Failed to run prepare hook of plugin '.ref($Plugin).' w/ error: '.$_, level => 'error', );
131             };
132             }
133              
134             if ( !$self->_exec_pre() ) {
135             $self->_cleanup(0);
136             }
137             if ( $self->jobs()->run() ) {
138             $self->_cleanup(1);
139             $self->_exec_post();
140             return 1;
141             }
142             else {
143             return;
144             }
145             }
146              
147             sub _cleanup {
148             my $self = shift;
149             my $ok = shift;
150              
151             foreach my $Plugin (@{$self->plugins()}) {
152             try {
153             $Plugin->run_cleanup_hook($ok);
154             } catch {
155             $self->logger()->log( message => 'Failed to run cleanup hook of plugin '.ref($Plugin).' w/ error: '.$_, level => 'error', );
156             };
157             }
158              
159             return 1;
160             }
161              
162             no Moose;
163             __PACKAGE__->meta->make_immutable;
164              
165             1;
166              
167             __END__
168              
169             =pod
170              
171             =encoding UTF-8
172              
173             =head1 NAME
174              
175             Sys::RevoBackup - an rsync-based backup script
176              
177             =head1 METHODS
178              
179             =head2 run
180              
181             Run the backups.
182              
183             =head2 vaults
184              
185             Return a list of all vaults (i.e. backup jobs).
186              
187             =head1 CONFIGURATION
188              
189             Place the configuration inside /etc/revobackup/revobackup.conf
190              
191             <Sys>
192             <RevoBackup>
193             bank = /srv/backup/bank
194             <Rotations>
195             daily = 10
196             weekly = 4
197             monthly = 12
198             yearly = 10
199             </Rotations>
200             <Vaults>
201             <test001>
202             source = /home/
203             description = Uhm
204             hardlink = 1
205             nocrossfs = 1
206             </test001>
207             <anotherhost>
208             source = anotherhost:/
209             description = Backup anotherhost
210             </anotherhost>
211             </Vaults>
212             </RevoBackup>
213             </Sys>
214              
215             =head1 NAME
216              
217             Sys::RevoBackup - Rsync based backup script
218              
219             =head1 AUTHOR
220              
221             Dominik Schulz <dominik.schulz@gauner.org>
222              
223             =head1 COPYRIGHT AND LICENSE
224              
225             This software is copyright (c) 2012 by Dominik Schulz.
226              
227             This is free software; you can redistribute it and/or modify it under
228             the same terms as the Perl 5 programming language system itself.
229              
230             =cut