5
0
mirror of git://git.proxmox.com/git/pve-guest-common.git synced 2025-03-11 16:58:18 +03:00

PVE::ReplicationState - new helper class to read/write replication state

This commit is contained in:
Dietmar Maurer 2017-06-02 08:53:53 +02:00
parent 0e01a7ae93
commit 3f7cacffb1
2 changed files with 82 additions and 0 deletions

View File

@ -25,6 +25,7 @@ install: PVE
install -m 0644 PVE/AbstractConfig.pm ${PERL5DIR}/PVE/
install -m 0644 PVE/AbstractMigrate.pm ${PERL5DIR}/PVE/
install -m 0644 PVE/ReplicationConfig.pm ${PERL5DIR}/PVE/
install -m 0644 PVE/ReplicationState.pm ${PERL5DIR}/PVE/
install -d ${PERL5DIR}/PVE/VZDump
install -m 0644 PVE/VZDump/Plugin.pm ${PERL5DIR}/PVE/VZDump/

81
PVE/ReplicationState.pm Normal file
View File

@ -0,0 +1,81 @@
package PVE::ReplicationState;
use warnings;
use strict;
use JSON;
use PVE::Tools;
use PVE::ReplicationConfig;
# Note: regression tests can overwrite $state_path for testing
our $state_path = "/var/lib/pve-manager/pve-replication-state.json";
our $state_lock = "/var/lib/pve-manager/pve-replication-state.lck";
# Note: We use PVE::Tools::file_set_contents to write state file atomically,
# so read_state() always returns an consistent copy (even when not locked).
sub read_state {
return {} if ! -e $state_path;
my $raw = PVE::Tools::file_get_contents($state_path);
return {} if $raw eq '';
# untaint $raw
if ($raw =~ m/^({.*})$/) {
return decode_json($1);
}
die "invalid json data in '$state_path'\n";
}
sub extract_job_state {
my ($stateobj, $jobcfg) = @_;
my $plugin = PVE::ReplicationConfig->lookup($jobcfg->{type});
my $vmid = $jobcfg->{guest};
my $tid = $plugin->get_unique_target_id($jobcfg);
my $state = $stateobj->{$vmid}->{$tid};
$state = {} if !$state;
$state->{last_iteration} //= 0;
$state->{last_try} //= 0; # last sync start time
$state->{last_sync} //= 0; # last successful sync start time
$state->{fail_count} //= 0;
return $state;
}
sub read_job_state {
my ($jobcfg) = @_;
my $stateobj = read_state();
return extract_job_state($stateobj, $jobcfg);
}
sub write_job_state {
my ($jobcfg, $state) = @_;
my $plugin = PVE::ReplicationConfig->lookup($jobcfg->{type});
my $vmid = $jobcfg->{guest};
my $tid = $plugin->get_unique_target_id($jobcfg);
my $code = sub {
my $stateobj = read_state();
# Note: tuple ($vmid, $tid) is unique
$stateobj->{$vmid}->{$tid} = $state;
PVE::Tools::file_set_contents($state_path, encode_json($stateobj));
};
PVE::Tools::lock_file($state_lock, 10, $code);
die $@ if $@;
}
1;