use Fcntl qw(:flock SEEK_END);
use Getopt::Long qw(GetOptionsFromArray);
use File::Copy qw(move);
+use File::Path qw(make_path);
use Switch;
use JSON;
use IO::File;
return undef;
}
-sub check_pool_exsits {
+sub check_pool_exists {
my ($target) = @_;
my $cmd = '';
sub read_state {
if (!-e $STATE) {
+ make_path $CONFIG_PATH;
my $new_fh = IO::File->new("> $STATE");
die "Could not create $STATE: $!\n" if !$new_fh;
+ print $new_fh "{}";
close($new_fh);
return undef;
}
run_cmd("ssh-copy-id -i /root/.ssh/id_rsa.pub root\@$ip");
}
- die "Pool $dest->{all} does not exists\n" if check_pool_exsits($dest);
+ die "Pool $dest->{all} does not exists\n" if check_pool_exists($dest);
- my $check = check_pool_exsits($source->{path}, $source->{ip}) if !$source->{vmid} && $source->{path};
+ my $check = check_pool_exists($source->{path}, $source->{ip}) if !$source->{vmid} && $source->{path};
die "Pool $source->{path} does not exists\n" if undef($check);
$job = get_job($param);
};
- if ($job && $job->{state} ne "ok") {
- print "To reset error state use $PROGNAME enable\n" if $job->{state} eq "error" ;
- die "Sync will not done! Status: $job->{state}\n";
+ if ($job && $job->{state} eq "syncing") {
+ die "Job --source $param->{source} --name $param->{name} is syncing at the moment";
}
my $dest = parse_target($param->{dest});
($source->{old_snap},$source->{last_snap}) = snapshot_get($source, $dest, $param->{maxsnap}, $param->{name});
- eval{
- snapshot_add($source, $dest, $param->{name}, $date);
+ snapshot_add($source, $dest, $param->{name}, $date);
- send_image($source, $dest, $param);
+ send_image($source, $dest, $param);
+
+ snapshot_destroy($source, $dest, $param->{method}, $source->{old_snap}) if ($source->{destroy} && $source->{old_snap});
- snapshot_destroy($source, $dest, $param->{method}, $source->{old_snap}) if ($source->{destroy} && $source->{old_snap});
- };
- if(my $err = $@) {
- if ($job) {
- $job->{state} = "error";
- update_state($job);
- unlock($lock_fh);
- close($lock_fh);
- }
- die "$err\n";
- }
};
if ($job) {
- die "Job --source $param->{source} --name $param->{name} is syncing" if $job->{state} eq "syncing";
$job->{state} = "syncing";
update_state($job);
}
- if ($source->{vmid}) {
- die "VM $source->{vmid} doesn't exist\n" if !vm_exists($source);
- my $disks = get_disks($source);
-
- foreach my $disk (sort keys %{$disks}) {
- $source->{all} = $disks->{$disk}->{all};
- $source->{pool} = $disks->{$disk}->{pool};
- $source->{path} = $disks->{$disk}->{path} if $disks->{$disk}->{path};
- $source->{last_part} = $disks->{$disk}->{last_part};
+ eval{
+ if ($source->{vmid}) {
+ die "VM $source->{vmid} doesn't exist\n" if !vm_exists($source);
+ my $disks = get_disks($source);
+
+ foreach my $disk (sort keys %{$disks}) {
+ $source->{all} = $disks->{$disk}->{all};
+ $source->{pool} = $disks->{$disk}->{pool};
+ $source->{path} = $disks->{$disk}->{path} if $disks->{$disk}->{path};
+ $source->{last_part} = $disks->{$disk}->{last_part};
+ &$sync_path($source, $dest, $job, $param, $date);
+ }
+ if ($param->{method} eq "ssh") {
+ send_config($source, $dest,'ssh');
+ }
+ } else {
&$sync_path($source, $dest, $job, $param, $date);
}
- if ($param->{method} eq "ssh") {
- send_config($source, $dest,'ssh');
+ };
+ if(my $err = $@) {
+ if ($job) {
+ $job->{state} = "error";
+ update_state($job);
+ unlock($lock_fh);
+ close($lock_fh);
+ print "Job --source $param->{source} --name $param->{name} got an ERROR!!!\nERROR Message:\n";
}
- } else {
- &$sync_path($source, $dest, $job, $param, $date);
+ die "$err\n";
}
if ($job) {
print Dumper $cmd if $DEBUG;
my $output = `$cmd 2>&1`;
- die $output if 0 != $?;
+ die "COMMAND:\n\t$cmd\nGET ERROR:\n\t$output" if 0 != $?;
chomp($output);
print Dumper $output if $DEBUG;
my $num = 0;
while ($text && $text =~ s/^(.*?)(\n|$)//) {
my $line = $1;
+
+ next if $line =~ /cdrom|none/;
+ next if $line !~ m/^(?:virtio|ide|scsi|sata)\d+: /;
+
my $disk = undef;
my $stor = undef;
- my $is_disk = $line =~ m/^(virtio|ide|scsi|sata){1}\d+: /;
- if($line =~ m/^(virtio\d+: )(.+:)([A-Za-z0-9\-]+),(.*)$/) {
- $disk = $3;
- $stor = $2;
- } elsif($line =~ m/^(ide\d+: )(.+:)([A-Za-z0-9\-]+),(.*)$/) {
- $disk = $3;
- $stor = $2;
- } elsif($line =~ m/^(scsi\d+: )(.+:)([A-Za-z0-9\-]+),(.*)$/) {
- $disk = $3;
- $stor = $2;
- } elsif($line =~ m/^(sata\d+: )(.+:)([A-Za-z0-9\-]+),(.*)$/) {
- $disk = $3;
- $stor = $2;
+ if($line =~ m/^(?:virtio|ide|scsi|sata)\d+: (.+:)([A-Za-z0-9\-]+),(.*)$/) {
+ $disk = $2;
+ $stor = $1;
+ } else {
+ die "disk is not on ZFS Storage\n";
}
- die "disk is not on ZFS Storage\n" if $is_disk && !$disk && $line !~ m/cdrom/;
+ my $cmd = "";
+ $cmd .= "ssh root\@$ip " if $ip;
+ $cmd .= "pvesm path $stor$disk";
+ my $path = run_cmd($cmd);
- if($disk && $line !~ m/none/ && $line !~ m/cdrom/ ) {
- my $cmd = "";
- $cmd .= "ssh root\@$ip " if $ip;
- $cmd .= "pvesm path $stor$disk";
- my $path = run_cmd($cmd);
+ if ($path =~ m/^\/dev\/zvol\/(\w+.*)(\/$disk)$/) {
- if ($path =~ m/^\/dev\/zvol\/(\w+).*(\/$disk)$/) {
-
- my @array = split('/', $1);
- $disks->{$num}->{pool} = pop(@array);
- $disks->{$num}->{all} = $disks->{$num}->{pool};
- if (0 < @array) {
- $disks->{$num}->{path} = join('/', @array);
- $disks->{$num}->{all} .= "\/$disks->{$num}->{path}";
- }
- $disks->{$num}->{last_part} = $disk;
- $disks->{$num}->{all} .= "\/$disk";
+ my @array = split('/', $1);
+ $disks->{$num}->{pool} = pop(@array);
+ $disks->{$num}->{all} = $disks->{$num}->{pool};
+ if (0 < @array) {
+ $disks->{$num}->{path} = join('/', @array);
+ $disks->{$num}->{all} .= "\/$disks->{$num}->{path}";
+ }
+ $disks->{$num}->{last_part} = $disk;
+ $disks->{$num}->{all} .= "\/$disk";
- $num++;
+ $num++;
- } else {
- die "ERROR: in path\n";
- }
+ } else {
+ die "ERROR: in path\n";
}
}
$cmd .= "-v " if $param->{verbose};
if($source->{last_snap} && snapshot_exist($source ,$dest, $param->{method})) {
- $cmd .= "-i $source->{all}\@$source->{old_snap} $source->{all}\@$source->{new_snap} ";
+ $cmd .= "-i $source->{all}\@$source->{last_snap} $source->{all}\@$source->{new_snap} ";
} else {
$cmd .= "$source->{all}\@$source->{new_snap} ";
}
pve-zsync create -source=100 -dest=192.168.1.2:zfspool
=head1 IMPORTANT FILES
-
-Cron jobs are stored at /etc/cron.d/pve-zsync
-The VM config get copied on the destination machine to /var/pve-zsync/
+Cron jobs and config are stored at /etc/cron.d/pve-zsync
-The config is stored at /var/pve-zsync/
+The VM config get copied on the destination machine to /var/lib/pve-zsync/
=head1 COPYRIGHT AND DISCLAIMER