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:
parent
0e01a7ae93
commit
3f7cacffb1
1
Makefile
1
Makefile
@ -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
81
PVE/ReplicationState.pm
Normal 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;
|
Loading…
x
Reference in New Issue
Block a user