source: trunk/backuppc-silzigan/backuppc-silzigan @ 221

Last change on this file since 221 was 101, checked in by g7moreau, 10 years ago
  • Add sub-project silzigan for backuppc
  • Property svn:executable set to *
File size: 10.3 KB
Line 
1#!/usr/bin/perl
2#
3# 2011/06/21 gabriel
4
5use strict;
6use warnings;
7
8use YAML;
9use IO::All;
10use File::Basename;
11use File::Finder;
12use Net::LDAP;
13use List::Util qw(shuffle);
14
15my %CMD_DB = (
16   help           => \&cmd_help,
17   version        => \&cmd_version,
18   generate       => \&cmd_generate,
19   update         => \&cmd_update,
20   init           => \&cmd_init_db,
21   'exclude-list' => \&cmd_exclude_list,
22   );
23
24my ($LDAP_H, $LDAP_BASE);
25my $LIMIT_TIMESTAMP = time() - (8 * 24 * 3600); # 8 days
26
27my $cmd = shift @ARGV || 'help';
28if (defined $CMD_DB{$cmd}) {
29   $CMD_DB{$cmd}->(@ARGV);
30   }
31else {
32   print {*STDERR} "backuppc-silzigan: command $cmd not found\n\n";
33   $CMD_DB{help}->();
34   exit 1;
35   }
36
37exit;
38
39sub open_ldap {
40   # AuthLDAPUrl          "ldap://ldapserver.mylab.fr/ou=Users,dc=mylab,dc=fr?uid?sub"
41   # AuthLDAPBindDN       "cn=ldapconnect,ou=System,dc=mylab,dc=fr"
42   # AuthLDAPBindPassword "Rhalala128"
43
44   my ($masterLDAP, $masterDN, $masterPw);
45
46   for my $config_line (io('/etc/apache2/conf.d/backuppc.conf')->chomp->slurp) {
47      ($masterLDAP, $LDAP_BASE) = ($1, $2) if $config_line =~ m{ ^\s* AuthLDAPUrl [^/]+ // ([^/]+) / (ou=[^?]+) }xms;
48      $masterDN = $1 if $config_line =~ m{ ^\s* AuthLDAPBindDN \s+ " ([^"]+) " }xms;
49      $masterPw = $1 if $config_line =~ m{ ^\s* AuthLDAPBindPassword \s+ " ([^"]+) " }xms;
50      }
51
52   $LDAP_H = Net::LDAP->new( "$masterLDAP" ) or die "$@";
53   my $mesg = $LDAP_H->bind("$masterDN", password => "$masterPw");
54
55   return;
56   }
57
58sub close_ldap {
59   $LDAP_H->unbind();
60   return;
61   }
62
63sub cmd_update {
64   my $search_config_file = File::Finder->type('f')->name('*.yaml');
65   for my $config_file (File::Finder->eval($search_config_file)->in('/etc/backuppc')) {
66      cmd_generate("$config_file");
67      }
68
69   update_hosts();
70   }
71
72sub cmd_generate {
73   my $config_file = shift;
74   
75   my $CONFIG = YAML::LoadFile($config_file);
76
77   $CONFIG->{default}{namespace} ||= basename($config_file, '.yaml');
78   $CONFIG->{default}{path}      ||= "/etc/backuppc/auto/$CONFIG->{default}{namespace}";
79   $CONFIG->{default}{hosts}     ||= "$CONFIG->{default}{path}/hosts";
80   $CONFIG->{default}{exclude}   ||= "/usr/lib/kont/etc/backuppc/exclude.txt";
81
82   if (not -d "/etc/backuppc/auto/$CONFIG->{default}{namespace}") {
83      io("/etc/backuppc/auto/$CONFIG->{default}{namespace}")->mkpath({mode => 0755});
84      }
85
86   print '' > io($CONFIG->{default}{hosts});
87
88   open_ldap();
89   LOOP_ON_COMPUTER:
90   for my $computer ( keys %{$CONFIG->{computers}}) {
91      my $login = $CONFIG->{computers}{$computer}{login} || 'root';
92
93      LOOP_ON_USER:
94      for my $user (  keys %{$CONFIG->{computers}{$computer}{users}}) {
95         my $pathshare = $CONFIG->{computers}{$computer}{share}
96                   || $CONFIG->{default}{share}
97                   || "/home/users";
98         my $share  = $CONFIG->{computers}{$computer}{users}{$user}{share}
99                   || "$pathshare/$user";
100         my $status = $CONFIG->{computers}{$computer}{users}{$user}{status}
101                   || $CONFIG->{computers}{$computer}{status}
102                   || $CONFIG->{default}{status}
103                   || 'auto';
104         my $admin  = $CONFIG->{computers}{$computer}{users}{$user}{admin}
105                   || $CONFIG->{computers}{$computer}{admin}
106                   || $CONFIG->{default}{admin}
107                   || 'root';
108
109         my $exclude = $CONFIG->{computers}{$computer}{users}{$user}{exclude}
110                   || $CONFIG->{computers}{$computer}{exclude}
111                   || '';
112
113         my @exclude_list = ();
114         if (ref($exclude) eq "ARRAY") {
115            push @exclude_list, @{$exclude};
116            }
117         else {
118            push @exclude_list, $exclude if not $exclude =~ m/^$/;
119            }
120         push @exclude_list, io($CONFIG->{default}{exclude})->chomp->slurp;
121         my $exclude_string = join ",\n", map { "    '$_'" } @exclude_list;
122
123         if ($status eq "auto") {
124            $status = "disable";
125            my $ldb = $LDAP_H->search(
126               base     => "$LDAP_BASE",
127               filter   => "(uid=$user)",
128               attrs    => ['shadowExpire', 'sambaKickoffTime'],
129               );
130            if (not $ldb->code ) {
131
132               LDAP_RESULT:
133               foreach my $entry ($ldb->entries) {
134
135                  my $user_expire_timestamp = $entry->get_value('sambaKickoffTime') || 0;
136                  my $user_shadow_expire = $entry->get_value('shadowExpire') || 0;
137
138                  if ($user_shadow_expire == 0) {
139                     $status = "enable";
140                     last LDAP_RESULT;
141                     }
142                  elsif (
143                     ( $user_expire_timestamp ne "" )
144                        and ( $user_expire_timestamp >  $LIMIT_TIMESTAMP )
145                     ) {
146                     $status = "enable";
147                     last LDAP_RESULT;
148                     }
149
150                  }
151               }
152            }
153
154         write_config($user, $computer, $share, $login, $admin, $status, $CONFIG, $exclude_string);
155
156         }
157
158      if (exists $CONFIG->{computers}{$computer}{subfolder}) {
159         my $home_path = $CONFIG->{computers}{$computer}{subfolder};
160         my @ls = `/bin/ping -W 2 -c 1 $computer > /dev/null 2>&1 && {
161            /usr/bin/rsync --dry-run $login\@$computer:$home_path /tmp/backuppc-test/ || echo Error for $login\@$computer | logger -t backuppc-silzigan;
162            }`;
163
164         $home_path =~ s{/[^/]*$}{};
165         LINE:
166         for my $line (@ls) {
167            chomp $line;
168            next LINE if not $line =~ m/skipping\sdirectory/;
169            next LINE if $line =~ m/lost+found/;
170            next LINE if $line =~ m/administrator/;
171            my ($user) = reverse split /\s+/, $line;
172            $user =~ s{/$}{};
173            $user =~ s{.*/}{};
174            next LINE if not $user =~ m/^\w/;
175
176            my $share = "$home_path/$user";
177
178            my @exclude_list = ();
179            push @exclude_list, io($CONFIG->{default}{exclude})->chomp->slurp;
180            my $exclude_string = join ",\n", map { "    '$_'" } @exclude_list;
181
182            my $admin = $CONFIG->{computers}{$computer}{admin}
183                     || $CONFIG->{default}{admin}
184                     || 'root';
185
186            my $status = "disable";
187            my $ldb = $LDAP_H->search(
188               base     => "$LDAP_BASE",
189               filter   => "(uid=$user)",
190               attrs    => ['shadowExpire', 'sambaKickoffTime'],
191               );
192            if (not $ldb->code ) {
193
194               LDAP_RESULT:
195               foreach my $entry ($ldb->entries) {
196
197                  my $user_expire_timestamp = $entry->get_value('sambaKickoffTime') || 0;
198                  my $user_shadow_expire = $entry->get_value('shadowExpire') || 0;
199
200                  if ($user_shadow_expire == 0) {
201                     $status = "enable";
202                     last LDAP_RESULT;
203                     }
204                  elsif (
205                     ( $user_expire_timestamp ne "" )
206                        and ( $user_expire_timestamp >  $LIMIT_TIMESTAMP )
207                     ) {
208                     $status = "enable";
209                     last LDAP_RESULT;
210                     }
211
212                  }
213               }
214
215            write_config($user, $computer, $share, $login, $admin, $status, $CONFIG, $exclude_string);
216            }
217         }
218      }
219   close_ldap();
220   }
221
222sub cmd_exclude_list {
223   print io('/usr/lib/kont/etc/backuppc/exclude.txt')->all;
224   }
225
226sub write_config {
227   my ($user, $computer, $share, $login, $admin, $status, $CONFIG, $exclude) = @_;
228   my ($c) = split /\./, $computer;
229   my $backup_name = $c . '_'. $user;
230
231   return if $status eq 'disable' and not -e "/var/lib/backuppc/pc/$backup_name/backups";
232
233   print "$backup_name 0 $login $admin,$user\n" >> io($CONFIG->{default}{hosts});
234
235   my $share_string = "'$share'";
236   if (ref($share) eq "ARRAY") {
237      $share_string = join ', ', map("'$_'", @{$share});
238      }
239
240#   my $exclude = join ",\n", map { "    '$_'" } io('/usr/lib/kont/etc/backuppc/exclude.txt')->chomp->slurp;
241
242   print <<END > io("$CONFIG->{default}{path}/$backup_name.pl");
243\$Conf{XferMethod} = 'rsync';
244\$Conf{ClientNameAlias} = '$computer';
245\$Conf{RsyncShareName} = [ $share_string ];
246\$Conf{RsyncClientCmd} = '\$sshPath -q -x -l $login \$host \$rsyncPath \$argList+';
247\$Conf{RsyncClientRestoreCmd} = '\$sshPath -q -x -l $login \$host \$rsyncPath \$argList+';
248\$Conf{BackupFilesExclude} = {
249  '$share' => [
250$exclude
251  ]
252};
253END
254
255   print '$Conf{FullPeriod} = "-2";' >> io("$CONFIG->{default}{path}/$backup_name.pl") if $status eq 'disable';
256   symlink "$CONFIG->{default}{path}/$backup_name.pl", "/etc/backuppc/pc/$backup_name.pl";
257   }
258
259sub update_hosts {
260   io->catfile('/etc/backuppc/hosts.main') > io('/etc/backuppc/hosts.order');
261   my @hosts = io('/etc/backuppc/hosts.main')->chomp->slurp;
262
263   my $search_host_file = File::Finder->type('f')->name('hosts');
264   for my $host_file (File::Finder->eval($search_host_file)->in('/etc/backuppc/auto')) {
265      print "#\n# $host_file\n#\n" >> io('/etc/backuppc/hosts.order');
266      io->catfile("$host_file") >> io('/etc/backuppc/hosts.order');
267      push @hosts, io("$host_file")->chomp->slurp;
268      }
269   my ($first, @host) = grep(/./, grep(!/^#/, @hosts));
270   print "$first\n" > io('/etc/backuppc/hosts');
271   print "$_\n" >> io('/etc/backuppc/hosts') for shuffle(@host);
272   }
273
274sub cmd_init_db {
275   my $cfg = {
276      computers => {
277         'machine36.hmg.priv' => {
278            login => 'root',
279            share => '/home/users/%u',
280            status => 'auto',
281            users => {
282               'dupond' => {
283                  share => [ '/home/users/dupond', '/var/www/dupond' ],
284                  status => 'enable',
285                  },
286               'durand' => {
287                  share => '/home/users/durand',
288                  },
289               },
290            },
291         },
292      };
293
294   YAML::DumpFile("/tmp/template-backuppc.yaml", $cfg);
295   }
296
297sub cmd_help {
298   print <<'END';
299backuppc-silzigan - cut into small pieces a computer configuration for backuppc
300
301 backuppc-silzigan init
302 backuppc-silzigan generate config_file.yaml
303 backuppc-silzigan update
304 backuppc-silzigan help
305 backuppc-silzigan version
306 backuppc-silzigan exclude-list
307END
308   return;
309   }
310
311sub cmd_version {
312   print <<'END';
313backuppc-silzigan - cut into small pieces a computer configuration for backuppc
314Copyright (C) 2011-2013 Gabriel Moreau
315
316$Id: backuppc-silzigan..host.legilnx32 3821 2013-12-20 08:03:14Z g7moreau $
317END
318   return;
319   }
Note: See TracBrowser for help on using the repository browser.