X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=pve-zsync;h=881b9c85cbfb98c6cd8a0e0341a4482ba4ad07c5;hb=f06c336b2a3fd5f97a95cc48e9fe6b62d46e7e8f;hp=ea3178e8e68d41dceba4356bf295b5b241ef73af;hpb=a6117db57329d35957a6c6b4da7e9ba3c85f61f0;p=pve-zsync.git diff --git a/pve-zsync b/pve-zsync index ea3178e..881b9c8 100755 --- a/pve-zsync +++ b/pve-zsync @@ -53,6 +53,8 @@ my $HOSTRE = "(?:$HOSTv4RE1|\\[$IPV6RE\\])"; # ipv6 must always be in brac # targets are either a VMID, or a 'host:zpool/path' with 'host:' being optional my $TARGETRE = qr!^(?:($HOSTRE):)?(\d+|(?:[\w\-_]+)(/.+)?)$!; +my $DISK_KEY_RE = qr/^(?:(?:(?:virtio|ide|scsi|sata|efidisk|mp)\d+)|rootfs): /; + my $command = $ARGV[0]; if (defined($command) && $command ne 'help' && $command ne 'printpod') { @@ -632,13 +634,13 @@ sub sync { my $sync_path = sub { my ($source, $dest, $job, $param, $date) = @_; - ($source->{old_snap}, $source->{last_snap}) = snapshot_get($source, $dest, $param->{maxsnap}, $param->{name}, $param->{source_user}); + ($dest->{old_snap}, $dest->{last_snap}) = snapshot_get($source, $dest, $param->{maxsnap}, $param->{name}, $param->{dest_user}); snapshot_add($source, $dest, $param->{name}, $date, $param->{source_user}, $param->{dest_user}); send_image($source, $dest, $param); - snapshot_destroy($source, $dest, $param->{method}, $source->{old_snap}, $param->{source_user}, $param->{dest_user}) if ($source->{destroy} && $source->{old_snap}); + snapshot_destroy($source, $dest, $param->{method}, $dest->{old_snap}, $param->{source_user}, $param->{dest_user}) if ($source->{destroy} && $dest->{old_snap}); }; @@ -692,14 +694,22 @@ sub sync { } sub snapshot_get{ - my ($source, $dest, $max_snap, $name, $source_user) = @_; + my ($source, $dest, $max_snap, $name, $dest_user) = @_; my $cmd = []; - push @$cmd, 'ssh', "$source_user\@$source->{ip}", '--', if $source->{ip}; + push @$cmd, 'ssh', "$dest_user\@$dest->{ip}", '--', if $dest->{ip}; push @$cmd, 'zfs', 'list', '-r', '-t', 'snapshot', '-Ho', 'name', '-S', 'creation'; - push @$cmd, $source->{all}; - my $raw = run_cmd($cmd); + my $path = $dest->{all}; + $path .= "/$source->{last_part}" if $source->{last_part}; + push @$cmd, $path; + + my $raw; + eval {$raw = run_cmd($cmd)}; + if (my $erro =$@) { #this means the volume doesn't exist on dest yet + return undef; + } + my $index = 0; my $line = ""; my $last_snap = undef; @@ -707,9 +717,10 @@ sub snapshot_get{ while ($raw && $raw =~ s/^(.*?)(\n|$)//) { $line = $1; - if ($line =~ m/(rep_\Q${name}\E_\d{4}-\d{2}-\d{2}_\d{2}:\d{2}:\d{2})$/) { - + if ($line =~ m/@(.*)$/) { $last_snap = $1 if (!$last_snap); + } + if ($line =~ m/(rep_\Q${name}\E_\d{4}-\d{2}-\d{2}_\d{2}:\d{2}:\d{2})$/) { $old_snap = $1; $index++; if ($index == $max_snap) { @@ -746,42 +757,6 @@ sub snapshot_add { } } -sub write_cron { - my ($cfg) = @_; - - my $text = "SHELL=/bin/sh\n"; - $text .= "PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin\n"; - - my $fh = IO::File->new("> $CRONJOBS"); - die "Could not open file: $!\n" if !$fh; - - foreach my $source (sort keys%{$cfg}) { - foreach my $sync_name (sort keys%{$cfg->{$source}}) { - next if $cfg->{$source}->{$sync_name}->{status} ne 'ok'; - $text .= "$PROG_PATH sync"; - $text .= " -source "; - if ($cfg->{$source}->{$sync_name}->{vmid}) { - $text .= "$cfg->{$source}->{$sync_name}->{source_ip}:" if $cfg->{$source}->{$sync_name}->{source_ip}; - $text .= "$cfg->{$source}->{$sync_name}->{vmid} "; - } else { - $text .= "$cfg->{$source}->{$sync_name}->{source_ip}:" if $cfg->{$source}->{$sync_name}->{source_ip}; - $text .= "$cfg->{$source}->{$sync_name}->{source_pool}"; - $text .= "$cfg->{$source}->{$sync_name}->{source_path}" if $cfg->{$source}->{$sync_name}->{source_path}; - } - $text .= " -dest "; - $text .= "$cfg->{$source}->{$sync_name}->{dest_ip}:" if $cfg->{$source}->{$sync_name}->{dest_ip}; - $text .= "$cfg->{$source}->{$sync_name}->{dest_pool}"; - $text .= "$cfg->{$source}->{$sync_name}->{dest_path}" if $cfg->{$source}->{$sync_name}->{dest_path}; - $text .= " -name $sync_name "; - $text .= " -limit $cfg->{$source}->{$sync_name}->{limit}" if $cfg->{$source}->{$sync_name}->{limit}; - $text .= " -maxsnap $cfg->{$source}->{$sync_name}->{maxsnap}" if $cfg->{$source}->{$sync_name}->{maxsnap}; - $text .= "\n"; - } - } - die "Can't write to cron\n" if (!print($fh $text)); - close($fh); -} - sub get_disks { my ($target, $user) = @_; @@ -830,7 +805,7 @@ sub parse_disks { my $line = $1; next if $line =~ /media=cdrom/; - next if $line !~ m/^(?:((?:virtio|ide|scsi|sata|mp)\d+)|rootfs): /; + next if $line !~ m/$DISK_KEY_RE/; #QEMU if backup is not set include in sync next if $vm_type eq 'qemu' && ($line =~ m/backup=(?i:0|no|off|false)/); @@ -840,7 +815,7 @@ sub parse_disks { my $disk = undef; my $stor = undef; - if($line =~ m/^(?:(?:(?:virtio|ide|scsi|sata|mp)\d+)|rootfs): (.*)$/) { + if($line =~ m/$DISK_KEY_RE(.*)$/) { my @parameter = split(/,/,$1); foreach my $opt (@parameter) { @@ -931,31 +906,25 @@ sub snapshot_destroy { } } +# check if snapshot for incremental sync exist on source side sub snapshot_exist { - my ($source , $dest, $method, $dest_user) = @_; + my ($source , $dest, $method, $source_user) = @_; my $cmd = []; - push @$cmd, 'ssh', "$dest_user\@$dest->{ip}", '--' if $dest->{ip}; + push @$cmd, 'ssh', "$source_user\@$source->{ip}", '--' if $source->{ip}; push @$cmd, 'zfs', 'list', '-rt', 'snapshot', '-Ho', 'name'; - my $path = $dest->{all}; - $path .= "/$source->{last_part}" if $source->{last_part}; - $path .= "\@$source->{old_snap}"; + my $path = $source->{all}; + $path .= "\@$dest->{last_snap}"; push @$cmd, $path; - - my $text = ""; - eval {$text =run_cmd($cmd);}; + eval {run_cmd($cmd)}; if (my $erro =$@) { warn "WARN: $erro"; return undef; } - - while ($text && $text =~ s/^(.*?)(\n|$)//) { - my $line =$1; - return 1 if $line =~ m/^.*$source->{old_snap}$/; - } + return 1; } sub send_image { @@ -968,8 +937,8 @@ sub send_image { push @$cmd, '-p', if $param->{properties}; push @$cmd, '-v' if $param->{verbose}; - if($source->{last_snap} && snapshot_exist($source , $dest, $param->{method}, $param->{dest_user})) { - push @$cmd, '-i', "$source->{all}\@$source->{last_snap}"; + if($dest->{last_snap} && snapshot_exist($source , $dest, $param->{method}, $param->{source_user})) { + push @$cmd, '-i', "$source->{all}\@$dest->{last_snap}"; } push @$cmd, '--', "$source->{all}\@$source->{new_snap}"; @@ -1021,7 +990,7 @@ sub send_config{ } if ($source->{destroy}){ - my $dest_target_old ="${config_dir}/$source->{vmid}.conf.$source->{vm_type}.$source->{old_snap}"; + my $dest_target_old ="${config_dir}/$source->{vmid}.conf.$source->{vm_type}.$dest->{old_snap}"; if($dest->{ip}){ run_cmd(['ssh', "$dest_user\@$dest->{ip}", '--', 'rm', '-f', '--', $dest_target_old]); } else {