use Getopt::Long qw(GetOptionsFromArray);
use File::Copy qw(move);
use File::Path qw(make_path);
-use Switch;
use JSON;
use IO::File;
use String::ShellQuote 'shell_quote';
check_bin ('ssh');
check_bin ('scp');
+$SIG{TERM} = $SIG{QUIT} = $SIG{PIPE} = $SIG{HUP} = $SIG{KILL} = $SIG{INT} =
+ sub {
+ die "Signal aborting sync\n";
+ };
+
sub check_bin {
my ($bin) = @_;
}
sub cut_target_width {
- my ($target, $max) = @_;
+ my ($path, $maxlen) = @_;
+ $path =~ s@/+@/@g;
+
+ return $path if length($path) <= $maxlen;
+
+ return '..'.substr($path, -$maxlen+2) if $path !~ m@/@;
- return $target if (length($target) <= $max);
- my @spl = split('/', $target);
+ $path =~ s@/([^/]+/?)$@@;
+ my $tail = $1;
- my $count = length($spl[@spl-1]);
- return "..\/".substr($spl[@spl-1],($count-$max)+3 , $count) if $count > $max;
+ if (length($tail)+3 == $maxlen) {
+ return "../$tail";
+ } elsif (length($tail)+2 >= $maxlen) {
+ return '..'.substr($tail, -$maxlen+2)
+ }
- $count += length($spl[0]) if @spl > 1;
- return substr($spl[0], 0, $max-4-length($spl[@spl-1]))."\/..\/".$spl[@spl-1] if $count > $max;
+ $path =~ s@(/[^/]+)(?:/|$)@@;
+ my $head = $1;
+ my $both = length($head) + length($tail);
+ my $remaining = $maxlen-$both-4; # -4 for "/../"
- my $rest = 1;
- $rest = $max-$count if ($max-$count > 0);
+ if ($remaining < 0) {
+ return substr($head, 0, $maxlen - length($tail) - 3) . "../$tail"; # -3 for "../"
+ }
- return "$spl[0]".substr($target, length($spl[0]), $rest)."..\/".$spl[@spl-1];
+ substr($path, ($remaining/2), (length($path)-$remaining), '..');
+ return "$head/" . $path . "/$tail";
}
sub lock {
my ($target) = @_;
my $cmd = [];
- push @$cmd, 'ssh', "root\@$target->{ip}", '--', if $target->{ip};
+
+ if ($target->{ip}) {
+ push @$cmd, 'ssh', "root\@$target->{ip}", '--';
+ }
push @$cmd, 'zfs', 'list', '-H', '--', $target->{all};
eval {
run_cmd($cmd);
};
if ($@) {
- return 1;
+ return 0;
}
- return undef;
+ return 1;
}
sub parse_target {
run_cmd(['ssh-copy-id', '-i', '/root/.ssh/id_rsa.pub', "root\@$ip"]);
}
- die "Pool $dest->{all} does not exists\n" if check_pool_exists($dest);
-
- my $check = check_pool_exists($source->{path}, $source->{ip}) if !$source->{vmid} && $source->{path};
+ die "Pool $dest->{all} does not exists\n" if !check_pool_exists($dest);
- die "Pool $source->{path} does not exists\n" if undef($check);
+ if (!defined($source->{vmid})) {
+ die "Pool $source->{all} does not exists\n" if !check_pool_exists($source);
+ }
my $vm_type = vm_exists($source);
$job->{vm_type} = $vm_type;
while ($raw && $raw =~ s/^(.*?)(\n|$)//) {
$line = $1;
- if ($line =~ m/(rep_$name.*)$/) {
+ if ($line =~ m/(rep_\Q${name}\E_\d{4}-\d{2}-\d{2}_\d{2}:\d{2}:\d{2})$/) {
$last_snap = $1 if (!$last_snap);
$old_snap = $1;
my $disk = undef;
my $stor = undef;
- if($line =~ m/^(?:((?:virtio|ide|scsi|sata|mp)\d+)|rootfs): ([^:]+:)([A-Za-z0-9\-]+),(.*)$/) {
- $disk = $3;
- $stor = $2;
+ if($line =~ m/^(?:(?:(?:virtio|ide|scsi|sata|mp)\d+)|rootfs): (.*)$/) {
+ my @parameter = split(/,/,$1);
+
+ foreach my $opt (@parameter) {
+ if ($opt =~ m/^(?:file=|volume=)?([^:]+:)([A-Za-z0-9\-]+)$/){
+ $disk = $2;
+ $stor = $1;
+ last;
+ }
+ }
+
} else {
print "Disk: \"$line\" will not include in pve-sync\n" if $get_err || $error;
next;
my $cmd = [];
- push @$cmd, 'ssh', "root\@$source->{ip}", '--' if $source->{ip};
+ push @$cmd, 'ssh', '-o', 'BatchMode=yes', "root\@$source->{ip}", '--' if $source->{ip};
push @$cmd, 'zfs', 'send';
push @$cmd, '-v' if $param->{verbose};
$target =~ s!/+!/!g;
push @$cmd, \'|';
- push @$cmd, 'ssh', "root\@$dest->{ip}", '--' if $dest->{ip};
+ push @$cmd, 'ssh', '-o', 'BatchMode=yes', "root\@$dest->{ip}", '--' if $dest->{ip};
push @$cmd, 'zfs', 'recv', '-F', '--';
push @$cmd, "$target";
sub help {
my ($command) = @_;
- switch($command){
- case 'help'
- {
- die "$help_help\n";
- }
- case 'sync'
- {
- die "$help_sync\n";
- }
- case 'destroy'
- {
- die "$help_destroy\n";
- }
- case 'create'
- {
- die "$help_create\n";
- }
- case 'list'
- {
- die "$help_list\n";
- }
- case 'status'
- {
- die "$help_status\n";
- }
- case 'enable'
- {
- die "$help_enable\n";
- }
- case 'disable'
- {
- die "$help_enable\n";
- }
+ if ($command eq 'help') {
+ die "$help_help\n";
+
+ } elsif ($command eq 'sync') {
+ die "$help_sync\n";
+
+ } elsif ($command eq 'destroy') {
+ die "$help_destroy\n";
+
+ } elsif ($command eq 'create') {
+ die "$help_create\n";
+
+ } elsif ($command eq 'list') {
+ die "$help_list\n";
+
+ } elsif ($command eq 'status') {
+ die "$help_status\n";
+
+ } elsif ($command eq 'enable') {
+ die "$help_enable\n";
+
+ } elsif ($command eq 'disable') {
+ die "$help_disable\n";
+
}
}
my @arg = @ARGV;
my $param = parse_argv(@arg);
+ if ($command eq 'destroy') {
+ die "$help_destroy\n" if !$param->{source};
+
+ check_target($param->{source});
+ destroy_job($param);
+
+ } elsif ($command eq 'sync') {
+ die "$help_sync\n" if !$param->{source} || !$param->{dest};
+
+ check_target($param->{source});
+ check_target($param->{dest});
+ sync($param);
+
+ } elsif ($command eq 'create') {
+ die "$help_create\n" if !$param->{source} || !$param->{dest};
+
+ check_target($param->{source});
+ check_target($param->{dest});
+ init($param);
+
+ } elsif ($command eq 'status') {
+ print status();
+
+ } elsif ($command eq 'list') {
+ print list();
+
+ } elsif ($command eq 'help') {
+ my $help_command = $ARGV[1];
+
+ if ($help_command && $commands->{$help_command}) {
+ print help($help_command);
- switch($command) {
- case "destroy"
- {
- die "$help_destroy\n" if !$param->{source};
- check_target($param->{source});
- destroy_job($param);
- }
- case "sync"
- {
- die "$help_sync\n" if !$param->{source} || !$param->{dest};
- check_target($param->{source});
- check_target($param->{dest});
- sync($param);
- }
- case "create"
- {
- die "$help_create\n" if !$param->{source} || !$param->{dest};
- check_target($param->{source});
- check_target($param->{dest});
- init($param);
- }
- case "status"
- {
- print status();
- }
- case "list"
- {
- print list();
- }
- case "help"
- {
- my $help_command = $ARGV[1];
- if ($help_command && $commands->{$help_command}) {
- print help($help_command);
- }
- if ($param->{verbose} == 1){
- exec("man $PROGNAME");
- } else {
- usage(1);
- }
- }
- case "enable"
- {
- die "$help_enable\n" if !$param->{source};
- check_target($param->{source});
- enable_job($param);
}
- case "disable"
- {
- die "$help_disable\n" if !$param->{source};
- check_target($param->{source});
- disable_job($param);
+ if ($param->{verbose} == 1){
+ exec("man $PROGNAME");
+
+ } else {
+ usage(1);
+
}
+
+ } elsif ($command eq 'enable') {
+ die "$help_enable\n" if !$param->{source};
+
+ check_target($param->{source});
+ enable_job($param);
+
+ } elsif ($command eq 'disable') {
+ die "$help_disable\n" if !$param->{source};
+
+ check_target($param->{source});
+ disable_job($param);
+
}
sub usage {