X-Git-Url: https://oss.titaniummirror.com/gitweb?a=blobdiff_plain;f=BackupPC_ovz;h=883b693723273fc789a15fc99245851e4f635121;hb=82ed31db4a0343059d15646d4e15e814e7944115;hp=830de2cc98bb50d671b783d2d69d4d477911a970;hpb=f35dbbee7d25a91f62f22bc3a77bde8d6b75b99b;p=ovzbpc.git diff --git a/BackupPC_ovz b/BackupPC_ovz index 830de2c..883b693 100755 --- a/BackupPC_ovz +++ b/BackupPC_ovz @@ -6,7 +6,6 @@ # with ovz awareness to improve backup and restore efficiency and features. # FIXME: signal handling to clean up mount point and snapshot on termination -# FIXME: saveConfigs and restoreConfigs aren't being used yet use strict; use Socket; @@ -16,12 +15,12 @@ use File::Path; use Proc::PID::File; # Various constants -my @HNS = ('pe18001.titaniummirror.com', 'pe18002.titaniummirror.com'); my @script_ext = qw(start stop mount umount); my @velist = (); my $pidfile = "/tmp/".basename($0).".pid"; my $vzsnap = 'vzsnap'; # Mount point and lv names. Mount is relative to /. my $snapsize = '1g'; +my $hnlistFile = "/etc/backuppc/".basename($0).".hnlist"; my $velistFile = $ENV{HOME}."/log/".basename($0).".velist"; sub cmdExecOrEval @@ -68,6 +67,15 @@ sub refreshConfig() { # Write the VEs on all HNs to a config file on the BackupPC server for # later use. + my @HNS = (); + open my $cfg, "<$hnlistFile" || die "Cannot read $hnlistFile"; + while (<$cfg>) { + chomp; + push(@HNS, split(' ')) if (! /^#/); + } + close($cfg); + die "No HNs defined in $hnlistFile" if ($#HNS < 0); + open my $out, ">$velistFile" || die "Cannot write to $velistFile"; foreach my $hn (@HNS) { open my $fh, "ssh -l root $hn vzlist -a |" || @@ -116,7 +124,7 @@ sub loadVeList() close($fh); } -# For use on the HN +# For use on the HN. Derive the VE record from its VEID. sub localVe($) { my ($veid) = @_; @@ -341,7 +349,8 @@ sub saveConfigs($) my ($ve) = @_; die "No VE record for saveConfigs" if (!defined($ve)); - # Copy configuration and other scripts belonging to VE into VE's snapshot + # Copy configuration and other scripts belonging to VE into VE's snapshot. + # Do this in a manner similar to that supported by vzdump for consistency. my $snapprivate = $ve->{'snapprivate'}; mkpath "$snapprivate/etc/vzdump"; my $conffile = $ve->{'conffile'}; @@ -352,6 +361,8 @@ sub saveConfigs($) } } +# Because of the complexities involved with restoring VE configuartions and +# knowing when and how to do so, this feature is not currently implemented. sub restoreConfigs($) { my ($ve) = @_; @@ -420,27 +431,31 @@ sub runClient($) die "HN needs a VEID argument" if (!defined($veid)); die "HN: no command to execute after VEID" if ($#ARGV < 0); - # Find $host in the list of VEs + # We (the HN where this code is running) must be hosting the requested VE. my $ve = localVe($veid); die "VE $veid not found on this HN" if (!defined($ve)); #printVeEntry($ve); - if (! $restore) { + if (!$restore) { cmdSystemOrEval("vzctl stop $veid >/dev/null 2>&1") if ($ve->{'running'}); makeSnapshot($ve); cmdSystemOrEval("vzctl start $veid >/dev/null 2>&1") if ($ve->{'running'}); die "Failed to make snapshot of filesystem for VE $veid" if (!defined($ve->{'snaproot'})); + # Save the VE configuration from its hosted HN into the filesystem. If + # /etc is backed up, so will the VE configuration. + saveConfigs($ve); + # Make and exec the backup command. Do it in a chroot to the snapshot - # of the VE's root dir so that any relative path information in the + # of the VEs root dir so that any relative path information in the # backup command is accurate. This does mean that each VE needs rsync, # etc. my $cmd = "chroot ".$ve->{'snapprivate'}." ".join(' ', @ARGV); #print "HN: cmd |$cmd|\n"; $? = 0; cmdSystemOrEval($cmd); - my $ret = $?; # FIXME + my $ret = $?; # FIXME - modify cmdSystemOrEval to get a return value. # Remove snapshot, we're done delSnapshot($ve); @@ -463,66 +478,6 @@ sub runServer($) { my ($restore) = @_; - # Build the beginning remote command - my $remoteCmd = "/usr/bin/".basename($0); - #print "Remote command is $remoteCmd\n"; - - my $host = shift(@ARGV); - die "Hostname argument required" if (!defined($host)); - die "No command to execute after hostname" if ($#ARGV < 0); - - # Find $host in the list of VEs - loadVeList(); - my $ve = getVeByHostname($host); - die "VE $host not found" if (!defined($ve)); - #printVeEntry($ve); - - # The command line is bisected by the next occurrence of $host. Everything - # before is the ssh command (sans what to run on the VE) and everything - # after is the xfer command to run on the VE. - my @sshCmd; - my @xferCmd; - my $foundHost = 0; - foreach my $arg (@ARGV) { - if ($arg eq $host) { - $foundHost = 1; - } else { - if ($foundHost) { - push(@xferCmd, $arg); - } else { - push(@sshCmd, $arg); - } - } - } - die "No ssh command found" if ($#sshCmd < 0); - die "No xfer command found" if ($#xferCmd < 0); - #print "ssh command: |".join(' ', @sshCmd)."|\n"; - #print "xfer command: |".join(' ', @xferCmd)."|\n"; - - # Create command line to initiate the remote side of the backup. The - # remote side runs on the VE's HN and is given the VE's VEID. - my $cmd = join(' ', @sshCmd)." ".$ve->{'HN'}." $remoteCmd ". - ($restore ? "restore " : "").$ve->{'VEID'}." ".join(' ', @xferCmd); - #print "remote command: |$cmd|\n"; - - ## Search and replace - #foreach my $key (keys %{$velist[0]}) { - # my $val = $ve->{$key}; - # $cmd =~ s/\@$key\@/$val/g if (defined($val)); - #} - - cmdExecOrEval($cmd); -} - -# A hard-coded test; didn't seem to help -sub runServer_test($) -{ - my ($restore) = @_; - - # Build the beginning remote command - my $remoteCmd = "/usr/bin/".basename($0); - #print "Remote command is $remoteCmd\n"; - my $host = shift(@ARGV); die "Hostname argument required" if (!defined($host)); die "No command to execute after hostname" if ($#ARGV < 0); @@ -530,12 +485,12 @@ sub runServer_test($) # Find $host in the list of VEs loadVeList(); my $ve = getVeByHostname($host); - die "VE $host not found" if (!defined($ve)); + die "$host is not a VE or list of HNs in $0 is wrong" if (!defined($ve)); #printVeEntry($ve); - # The command line is bisected by the next occurrence of $host. Everything - # before is the ssh command (sans what to run on the VE) and everything - # after is the xfer command to run on the VE. + # The client command is bisected by the next occurrence of $host. Everything + # before is the ssh command to reach the client and everything after is the + # xfer command sent to the client via ssh. my @sshCmd; my @xferCmd; my $foundHost = 0; @@ -555,18 +510,13 @@ sub runServer_test($) #print "ssh command: |".join(' ', @sshCmd)."|\n"; #print "xfer command: |".join(' ', @xferCmd)."|\n"; - # Create command line to initiate the remote side of the backup. The - # remote side runs on the VE's HN and is given the VE's VEID. - my $cmd = join(' ', @sshCmd)." pe18002.titaniummirror.com $remoteCmd ". - ($restore ? "restore " : "")."151 ".join(' ', @xferCmd); + # Create the command line to initiate the client side of the backup. We + # contact the HN hosting the VE and run an invocation of this script there + # to perform the required operations for VE backup or restore. + my $cmd; + $cmd = join(' ', @sshCmd)." ".$ve->{'HN'}." /usr/bin/".basename($0)." ". + ($restore ? "restore " : "").$ve->{'VEID'}." ".join(' ', @xferCmd); #print "remote command: |$cmd|\n"; - - ## Search and replace - #foreach my $key (keys %{$velist[0]}) { - # my $val = $ve->{$key}; - # $cmd =~ s/\@$key\@/$val/g if (defined($val)); - #} - cmdExecOrEval($cmd); }