]> git.proxmox.com Git - pve-storage.git/blame - PVE/CLI/pvesr.pm
renamed: PVE/API2/StorageReplication.pm -> PVE/API2/Storage/Replication.pm
[pve-storage.git] / PVE / CLI / pvesr.pm
CommitLineData
663510b8
WL
1package PVE::CLI::pvesr;
2
3use strict;
4use warnings;
76c35814 5use POSIX qw(strftime);
663510b8 6
663510b8
WL
7use PVE::JSONSchema qw(get_standard_option);
8use PVE::INotify;
9use PVE::RPCEnvironment;
10use PVE::Tools qw(extract_param);
11use PVE::SafeSyslog;
12use PVE::CLIHandler;
76c35814
DM
13
14use PVE::API2::Storage::Replication;
663510b8
WL
15
16use base qw(PVE::CLIHandler);
17
18my $nodename = PVE::INotify::nodename();
19
20sub setup_environment {
21 PVE::RPCEnvironment->setup_default_cli_env();
22}
23
24my $print_list = sub {
25 my ($conf, $json) = @_;
26
27 if (defined($json)) {
28 print JSON::encode_json($conf);
29 } else {
30 printf("%-10s%-20s%-20s%-5s%-10s%-5s\n",
31 "VMID", "DEST", "LAST SYNC","IVAL", "STATE", "FAIL");
32
33 foreach my $vmid (sort keys %$conf) {
34 my $job = $conf->{$vmid};
35 my $timestr = strftime("%Y-%m-%d_%H:%M:%S", localtime($job->{lastsync}));
36
37 printf("%-9s ", $vmid);
38 printf("%-19s ", $job->{tnode});
39 printf("%-19s ", $timestr);
40 printf("%-4s ", $job->{interval});
41 printf("%-9s ", $job->{state});
42 printf("%-9s\n", $job->{fail});
43 }
44 }
45
46};
47
48sub set_list {
49 my ($list, $synctime, $vmid) = @_;
50
51 if (defined($list->{$synctime})) {
52 $list = set_list($list,$synctime+1, $vmid);
53 } else {
54 $list->{$synctime} = $vmid;
55 }
56 return $list;
57}
58
59my $get_replica_list = sub {
60
61 my $jobs = PVE::ReplicationTools::read_state();
62 my $list = {};
63
64 foreach my $vmid (keys %$jobs) {
65 my $job = $jobs->{$vmid};
66 my $lastsync = $job->{lastsync};
67
68 # interval in min
69 my $interval = $job->{interval};
70 my $now = time();
71 my $fail = $job->{fail};
72
73 my $synctime = $lastsync + $interval * 60;
74
75 if ($now >= $synctime && $job->{state} eq 'ok') {
76 $list = set_list($list, $synctime, $vmid);
77 } elsif ($job->{state} eq 'sync') {
78
79 my $synctime += $interval * ($job->{fail}+1);
80 $list = set_list($list, $synctime, $vmid)
81 if ($now >= $synctime);
82
83 }
84 }
85
86 return $list;
87};
88
89my $replicate_vms = sub {
90 my ($list) = @_;
91
92 my @sorted_times = reverse sort keys %$list;
93
94 foreach my $synctime (@sorted_times) {
95 eval {
96 PVE::ReplicationTools::sync_guest($list->{$synctime});
97 };
98 if (my $err = $@) {
99 syslog ('err', $err );
100 }
101 }
102};
103
104__PACKAGE__->register_method ({
105 name => 'run',
106 path => 'run',
107 method => 'POST',
108 description => "This method will run by the systemd-timer and sync all jobs",
109 permissions => {
110 description => {
111 check => ['perm', '/', [ 'Sys.Console' ]],
112 },
113 },
114 protected => 1,
115 parameters => {
116 additionalProperties => 0,
117 properties => {
118 },
119 },
120 returns => { type => 'null' },
121 code => sub {
122
123 my $list = &$get_replica_list();
124 &$replicate_vms($list);
125
126 return undef;
127 }});
128
129__PACKAGE__->register_method ({
130 name => 'destroyjob',
131 path => 'destroyjob',
132 method => 'DELETE',
133 description => "Destroy an async replication job",
134 permissions => {
135 description => {
136 check => ['perm', '/storage', ['Datastore.Allocate']],
137 },
138 },
139 protected => 1,
140 parameters => {
141 additionalProperties => 0,
142 properties => {
143 vmid => {
144 type => 'string', format => 'pve-vmid',
145 description => "The VMID of the guest.",
146 completion => \&PVE::Cluster::complete_local_vmid,
147 },
148 },
149 },
150 returns => { type => 'null' },
151 code => sub {
152 my ($param) = @_;
153
154 my $vmid = extract_param($param, 'vmid');
155
156 PVE::ReplicationTools::destroy_replica($vmid);
157
158 }});
159
160__PACKAGE__->register_method ({
161 name => 'list',
162 path => 'list',
163 method => 'GET',
164 description => "List of all replication jobs.",
165 permissions => {
166 user => 'all'
167 },
168 protected => 1,
169 parameters => {
170 additionalProperties => 0,
171 properties => {
172 vmid => {
173 type => 'string', format => 'pve-vmid',
174 description => "The VMID of the guest.",
175 completion => \&PVE::Cluster::complete_local_vmid,
176 },
177 },
178 },
179 protected => 1,
180 proxyto => 'node',
181 parameters => {
182 additionalProperties => 0,
183 properties => {
184 node => get_standard_option('pve-node'),
185 nodes => get_standard_option('pve-node-list' ,
186 {description => "Notes where the jobs is located.",
187 optional => 1}),
188 json => {
189 optional => 1,
190 type => 'boolean',
191 description => "Output in JSON format.",
192 },
193 },
194 },
195 returns => { type => 'string' },
196 code => sub {
197 my ($param) = @_;
198
199 if ($param->{nodes}) {
200 foreach my $node (PVE::Tools::split_list($param->{nodes})) {
201 die "Node: $node does not exists.\n" if
202 !PVE::Cluster::check_node_exists($node);
203 }
204 }
205
206 my $nodes = $param->{nodes} ?
207 $param->{nodes} : $param->{node};
208
209 my $list = PVE::ReplicationTools::get_all_jobs($nodes);
210
211 &$print_list($list, $param->{json});
212}});
213
214
215our $cmddef = {
216 list => [ __PACKAGE__ , 'list' , [], {node => $nodename}],
217 run => [ __PACKAGE__ , 'run'],
218 destroyjob => [ __PACKAGE__ , 'destroyjob', ['vmid']],
219};
220
2211;