]> git.proxmox.com Git - pve-ha-manager.git/blob - src/PVE/HA/Resources.pm
Resources.pm: use PVE::API2::LXC
[pve-ha-manager.git] / src / PVE / HA / Resources.pm
1 package PVE::HA::Resources;
2
3 use strict;
4 use warnings;
5
6 use Data::Dumper;
7 use PVE::JSONSchema qw(get_standard_option);
8 use PVE::SectionConfig;
9 use PVE::HA::Tools;
10
11 use base qw(PVE::SectionConfig);
12
13 my $defaultData = {
14 propertyList => {
15 type => { description => "Resource type.", optional => 1 },
16 sid => get_standard_option('pve-ha-resource-or-vm-id',
17 { completion => \&PVE::HA::Tools::complete_sid }),
18 state => {
19 description => "Resource state.",
20 type => 'string',
21 enum => ['enabled', 'disabled'],
22 optional => 1,
23 default => 'enabled',
24 },
25 group => get_standard_option('pve-ha-group-id',
26 { optional => 1,
27 completion => \&PVE::HA::Tools::complete_group }),
28 max_restart => {
29 description => "Maximal number of tries to restart the service on".
30 " a node after its start failed.",
31 type => 'integer',
32 optional => 1,
33 default => 1,
34 minimum => 0,
35 },
36 max_relocate => {
37 description => "Maximal number of service relocate tries when a".
38 " service failes to start.",
39 type => 'integer',
40 optional => 1,
41 default => 1,
42 minimum => 0,
43 },
44 comment => {
45 description => "Description.",
46 type => 'string',
47 optional => 1,
48 maxLength => 4096,
49 },
50 },
51 };
52
53 sub verify_name {
54 my ($class, $name) = @_;
55
56 die "implement this in subclass";
57 }
58
59 sub private {
60 return $defaultData;
61 }
62
63 sub format_section_header {
64 my ($class, $type, $sectionId) = @_;
65
66 my (undef, $name) = split(':', $sectionId, 2);
67
68 return "$type: $name\n";
69 }
70
71 sub parse_section_header {
72 my ($class, $line) = @_;
73
74 if ($line =~ m/^(\S+):\s*(\S+)\s*$/) {
75 my ($type, $name) = (lc($1), $2);
76 my $errmsg = undef; # set if you want to skip whole section
77 eval {
78 if (my $plugin = $defaultData->{plugins}->{$type}) {
79 $plugin->verify_name($name);
80 } else {
81 die "no such resource type '$type'\n";
82 }
83 };
84 $errmsg = $@ if $@;
85 my $config = {}; # to return additional attributes
86 return ($type, "$type:$name", $errmsg, $config);
87 }
88 return undef;
89 }
90
91 sub start {
92 my ($class, $haenv, $params) = @_;
93
94 die "implement in subclass";
95 }
96
97 sub shutdown {
98 my ($class, $haenv, $param) = @_;
99
100 die "implement in subclass";
101 }
102
103 sub migrate {
104 my ($class, $haenv, $params) = @_;
105
106 die "implement in subclass";
107 }
108
109 sub config_file {
110 my ($class, $id, $nodename) = @_;
111
112 die "implement in subclass"
113 }
114
115 sub exists {
116 my ($class, $id, $noerr) = @_;
117
118 die "implement in subclass"
119 }
120
121 sub check_running {
122 my ($class, $id) = @_;
123
124 die "implement in subclass";
125 }
126
127
128 # virtual machine resource class
129 package PVE::HA::Resources::PVEVM;
130
131 use strict;
132 use warnings;
133
134 use PVE::QemuServer;
135 use PVE::API2::Qemu;
136
137 use base qw(PVE::HA::Resources);
138
139 sub type {
140 return 'vm';
141 }
142
143 sub verify_name {
144 my ($class, $name) = @_;
145
146 die "invalid VMID\n" if $name !~ m/^[1-9][0-9]+$/;
147 }
148
149 sub options {
150 return {
151 state => { optional => 1 },
152 group => { optional => 1 },
153 comment => { optional => 1 },
154 max_restart => { optional => 1 },
155 max_relocate => { optional => 1 },
156 };
157 }
158
159 sub config_file {
160 my ($class, $vmid, $nodename) = @_;
161
162 return PVE::QemuServer::config_file($vmid, $nodename);
163 }
164
165 sub exists {
166 my ($class, $vmid, $noerr) = @_;
167
168 my $vmlist = PVE::Cluster::get_vmlist();
169
170 if(!defined($vmlist->{ids}->{$vmid})) {
171 die "resource 'vm:$vmid' does not exists in cluster\n" if !$noerr;
172 return undef;
173 } else {
174 return 1;
175 }
176 }
177
178 sub start {
179 my ($class, $haenv, $params) = @_;
180
181 my $upid = PVE::API2::Qemu->vm_start($params);
182 $haenv->upid_wait($upid);
183 }
184
185 sub shutdown {
186 my ($class, $haenv, $param) = @_;
187
188 my $upid = PVE::API2::Qemu->vm_shutdown($param);
189 $haenv->upid_wait($upid);
190 }
191
192
193 sub migrate {
194 my ($class, $haenv, $params) = @_;
195
196 my $upid = PVE::API2::Qemu->migrate_vm($params);
197 $haenv->upid_wait($upid);
198 }
199
200 sub check_running {
201 my ($class, $vmid) = @_;
202
203 return PVE::QemuServer::check_running($vmid, 1);
204 }
205
206
207 # container resource class
208 package PVE::HA::Resources::PVECT;
209
210 use strict;
211 use warnings;
212
213 use PVE::LXC;
214 use PVE::API2::LXC;
215 use PVE::API2::LXC::Status;
216
217 use base qw(PVE::HA::Resources);
218
219 sub type {
220 return 'ct';
221 }
222
223 sub verify_name {
224 my ($class, $name) = @_;
225
226 die "invalid VMID\n" if $name !~ m/^[1-9][0-9]+$/;
227 }
228
229 sub options {
230 return {
231 state => { optional => 1 },
232 group => { optional => 1 },
233 comment => { optional => 1 },
234 max_restart => { optional => 1 },
235 max_relocate => { optional => 1 },
236 };
237 }
238
239 sub config_file {
240 my ($class, $vmid, $nodename) = @_;
241
242 return PVE::LXC::config_file($vmid, $nodename);
243 }
244
245 sub exists {
246 my ($class, $vmid, $noerr) = @_;
247
248 my $vmlist = PVE::Cluster::get_vmlist();
249
250 if(!defined($vmlist->{ids}->{$vmid})) {
251 die "resource 'ct:$vmid' does not exists in cluster\n" if !$noerr;
252 return undef;
253 } else {
254 return 1;
255 }
256 }
257
258 sub start {
259 my ($class, $haenv, $params) = @_;
260
261 my $upid = PVE::API2::LXC::Status->vm_start($params);
262 $haenv->upid_wait($upid);
263 }
264
265 sub shutdown {
266 my ($class, $haenv, $params) = @_;
267
268 my $upid = PVE::API2::LXC::Status->vm_shutdown($params);
269 $haenv->upid_wait($upid);
270 }
271
272 sub migrate {
273 my ($class, $haenv, $params) = @_;
274
275 my $upid = PVE::API2::LXC->migrate_vm($params);
276 $haenv->upid_wait($upid);
277 }
278
279 sub check_running {
280 my ($class, $vmid) = @_;
281
282 return PVE::LXC::check_running($vmid);
283 }
284
285
286 # package PVE::HA::Resources::IPAddr;
287
288 # use strict;
289 # use warnings;
290 # use PVE::Tools qw($IPV4RE $IPV6RE);
291
292 # use base qw(PVE::HA::Resources);
293
294 # sub type {
295 # return 'ipaddr';
296 # }
297
298 # sub verify_name {
299 # my ($class, $name) = @_;
300
301 # die "invalid IP address\n" if $name !~ m!^$IPV6RE|$IPV4RE$!;
302 # }
303
304 # sub options {
305 # return {
306 # state => { optional => 1 },
307 # group => { optional => 1 },
308 # comment => { optional => 1 },
309 # };
310 # }
311
312 1;