#!/usr/bin/perl use strict; use vars qw/$base $svn $machine $ip $debug %missing %adding $nocommit/; use Getopt::Long; GetOptions("n" => \$nocommit); $base = '/data/backups'; $svn = '/data/projects/svn/systems'; chdir($base) || die "Cannot chdir($base)"; $debug = 2; sub __log { my $level = shift; printf @_ if($debug >= $level); } sub mkdirheir { my $dir = shift; $dir =~ /^((.*?))\/.*$(?{-d "$1" || mkdir "$1"})(?!)/; return -d $dir; } sub should_ignore { return 1 if(/~[^\/]+~$/); return 1 if(/(^|\/)#[^\/]+#$/); return 1 if(/(^|\/)\.[^\/]+\.swp$/); return 1 if(/\.core$/); return 1 if(/core\.\d+$/); return 0; } open F, ") { if(/^\[(\S+) (\S+)\]$/) { $machine = $1; $ip = $2; if(! -d $machine) { if(! mkdir $machine, 0755) { __log(0, "mkdir $machine failed\n"); undef $machine; } } next; } if($machine) { if(my ($method, $source, $dest, $options) = /^(\S+)\s*(\S+)\s*(\S+)\s*(.*)$/) { __log(2, "pulling $machine:$source to $machine/$dest via $method $options\n"); if(! mkdirheir("$machine/$dest")) { __log(0, "mkdir failed $machine/$dest"); } else { if($method eq 'rsync') { $options = "-avcz --delete --exclude=.svn $options"; if($ip eq '127.0.0.1') { __log(1, "rsync $options $source/ $machine/$dest/\n"); my $out = `rsync $options $source/ $machine/$dest/`; __log(2, $out); } else { __log(1, "rsync $options ${ip}::$source/ $machine/$dest/\n"); my $out = `rsync $options ${ip}::$source/ $machine/$dest/`; __log(2, $out); } } } } } } close(F); open(STATUS, "/usr/local/bin/svn st|"); while() { if(/^!\s+(.+)$/) { $missing{$1}++; } elsif(/^\?\s+(.+)$/) { $adding{$1}++; } } close(STATUS); my $update = `/usr/local/bin/svn update`; __log(2, $update); foreach (keys %missing) { __log(2, "svn delete $_\n"); `/usr/local/bin/svn delete $_`; } foreach (keys %adding) { next if should_ignore($_); __log(2, "svn add $_\n"); `/usr/local/bin/svn add $_`; } __log(1, "commiting changeset\n"); unless($nocommit) { `/usr/local/bin/svn commit -m "imager"`; }