#!/usr/bin/perl # # Script to update an Anvil! system. # # 0 = Normal exit. # 1 = Bad arguments # 2 = No Anvil! specified. # 3 = Failed to parse the prefix and sequence from the Anvil! name. # 4 = Unexpected error building list of targets. # 5 = A source directory wasn't found. # use strict; use warnings; my $conf = { anvil => "", copy => { all => { './tools/*' => '/sbin/striker/', './ScanCore' => '/sbin/striker/', './cgi-bin/Data' => '/sbin/striker/', './AN' => '/usr/share/perl5/', }, dashboards => { './cgi-bin' => '/var/www/', './html' => '/var/www/', }, nodes => {}, }, debug => 0, machines => { node1 => "", node2 => "", striker1 => "", striker2 => "", }, path => { rsync => "/usr/bin/rsync", }, prefix => "", sequence => "", suffix => "", target => "all", targets => [], }; parse_args($conf); foreach my $target (sort {$a cmp $b} @{$conf->{targets}}) { if ($conf->{suffix}) { $target .= "\.".$conf->{suffix}; } print "Updating: [$target]\n"; foreach my $source (sort {$a cmp $b} keys %{$conf->{copy}{all}}) { check_source($conf, $source); rsync($conf, $source, "root\@$target:".$conf->{copy}{all}{$source}) } if ($target =~ /striker/) { foreach my $source (sort {$a cmp $b} keys %{$conf->{copy}{dashboards}}) { check_source($conf, $source); rsync($conf, $source, "root\@$target:".$conf->{copy}{dashboards}{$source}) } } else { foreach my $source (sort {$a cmp $b} keys %{$conf->{copy}{nodes}}) { check_source($conf, $source); rsync($conf, $source, "root\@$target:".$conf->{copy}{nodes}{$source}) } } } exit(0); sub rsync { my ($conf, $source, $target) = @_; my $shell_call = $conf->{path}{rsync}." -av $source $target"; print "shell_call: [$shell_call]\n" if $conf->{debug} >= 0; open (my $file_handle, $shell_call." 2>&1 |") or die "Failed to call: [$shell_call], error was: $!\n"; while (<$file_handle>) { chomp; my $line = $_; if ((not $line) or ($line =~ /sending incremental/) or ($line =~ /total size is/) or ($line =~ /^sent \d/)) { print "- line: [$line]\n" if $conf->{debug} >= 1; } else { print "- line: [$line]\n" if $conf->{debug} >= 0; } } close $file_handle; return(0); } sub check_source { my ($conf, $source) = @_; if ($source =~ /^(.*?)\/\*$/) { $source = $1; print "source: [$source]\n" if $conf->{debug} >= 2; } if (not -e $source) { print "The source directory: [$source] doesn't exist.\n"; exit(5); } return(0); } sub parse_args { my ($conf) = @_; my $get_anvil = 0; my $get_targets = 0; my $get_suffix = 0; foreach my $key (@ARGV) { print "key: [$key]\n" if $conf->{debug}; $key =~ s/^-+//; if ($key eq "anvil") { $get_anvil = 1; $get_targets = 0; $get_suffix = 0; } elsif (($key eq "target") or ($key eq "targets")) { $get_anvil = 0; $get_targets = 1; $get_suffix = 0; } elsif ($key eq "suffix") { $get_anvil = 0; $get_targets = 0; $get_suffix = 1; } elsif ($key eq "debug") { $conf->{debug} = 1; $get_anvil = 0; $get_targets = 0; $get_suffix = 0; } elsif ($get_anvil) { $conf->{anvil} = $key; $get_anvil = 0; $get_targets = 0; $get_suffix = 0; } elsif ($get_targets) { $conf->{target} = $key; $get_anvil = 0; $get_targets = 0; $get_suffix = 0; } elsif ($get_suffix) { $conf->{suffix} = $key; $get_anvil = 0; $get_targets = 0; $get_suffix = 0; } else { print_usage(); exit(1); } } # Pull out the prefix and sequence, if possible. if ($conf->{anvil} =~ /^(\w+)-anvil-(\d+)$/) { $conf->{prefix} = $1; $conf->{sequence} = $2; print "Prefix: [".$conf->{prefix}."], sequence: [".$conf->{sequence}."]\n" if $conf->{debug} > 1; } # Process targets, if specified. if ($conf->{target} eq "all") { if (not $conf->{anvil}) { no_anvil($conf); } elsif ((not $conf->{prefix}) or (not $conf->{sequence})) { bad_anvil($conf); } # Record the names. push @{$conf->{targets}}, $conf->{prefix}."-a".$conf->{sequence}."n01"; push @{$conf->{targets}}, $conf->{prefix}."-a".$conf->{sequence}."n02"; push @{$conf->{targets}}, $conf->{prefix}."-striker01"; push @{$conf->{targets}}, $conf->{prefix}."-striker02"; } elsif ($conf->{target} eq "nodes") { if (not $conf->{anvil}) { no_anvil($conf); } elsif ((not $conf->{prefix}) or (not $conf->{sequence})) { bad_anvil($conf); } push @{$conf->{targets}}, $conf->{prefix}."-a".$conf->{sequence}."n01"; push @{$conf->{targets}}, $conf->{prefix}."-a".$conf->{sequence}."n02"; } elsif ($conf->{target} eq "strikers") { if (not $conf->{anvil}) { no_anvil($conf); } elsif ((not $conf->{prefix}) or (not $conf->{sequence})) { bad_anvil($conf); } push @{$conf->{targets}}, $conf->{prefix}."-striker01"; push @{$conf->{targets}}, $conf->{prefix}."-striker02"; } elsif ($conf->{target}) { foreach my $target (split/,/, $conf->{target}) { push @{$conf->{targets}}, $target; } } else { print "Unexpected error building list of targets.\n"; exit(4); } return(0); } sub no_anvil { my ($conf) = @_; print "No Anvil! specified.\n"; print_usage(); exit(2); return(0); } sub bad_anvil { my ($conf) = @_; print "An Anvil! was specified, but failed to parse the prefix and/or sequence number from it (please use 'xx-anvil-##').\n"; print_usage(); exit(3); return(0); } sub print_usage { print "Bad arguments. Usage; '".$0." --anvil --targets ' --suffix X\n"; }