]>
git.proxmox.com Git - pve-ha-manager.git/blob - src/PVE/API2/HA/Resources.pm
1 package PVE
::API2
::HA
::Resources
;
7 use PVE
::Tools
qw(extract_param);
10 use PVE
::HA
::Resources
;
11 use HTTP
::Status
qw(:constants);
12 use Storable
qw(dclone);
13 use PVE
::JSONSchema
qw(get_standard_option);
14 use PVE
::RPCEnvironment
;
19 use base
qw(PVE::RESTHandler);
21 # fixme: use cfs_read_file
23 my $resource_type_enum = PVE
::HA
::Resources-
>lookup_types();
25 my $api_copy_config = sub {
28 die "no such resource '$sid'\n" if !$cfg->{ids
}->{$sid};
30 my $scfg = dclone
($cfg->{ids
}->{$sid});
32 $scfg->{digest
} = $cfg->{digest
};
37 __PACKAGE__-
>register_method ({
41 description
=> "List HA resources.",
43 check
=> ['perm', '/', [ 'Sys.Audit' ]],
46 additionalProperties
=> 0,
49 description
=> "Only list resources of specific type",
51 enum
=> $resource_type_enum,
60 properties
=> { sid
=> { type
=> 'string'} },
62 links
=> [ { rel
=> 'child', href
=> "{sid}" } ],
67 my $cfg = PVE
::HA
::Config
::read_resources_config
();
68 my $groups = PVE
::HA
::Config
::read_group_config
();
71 foreach my $sid (keys %{$cfg->{ids
}}) {
72 my $scfg = &$api_copy_config($cfg, $sid);
73 next if $param->{type
} && $param->{type
} ne $scfg->{type
};
74 if ($scfg->{group
} && !$groups->{ids
}->{$scfg->{group
}}) {
75 $scfg->{errors
}->{group
} = "group '$scfg->{group}' does not exist";
83 __PACKAGE__-
>register_method ({
88 check
=> ['perm', '/', [ 'Sys.Audit' ]],
90 description
=> "Read resource configuration.",
92 additionalProperties
=> 0,
94 sid
=> get_standard_option
('pve-ha-resource-or-vm-id',
95 { completion
=> \
&PVE
::HA
::Tools
::complete_sid
}),
102 my $cfg = PVE
::HA
::Config
::read_resources_config
();
104 my $sid = PVE
::HA
::Tools
::parse_sid
($param->{sid
});
106 return &$api_copy_config($cfg, $sid);
109 __PACKAGE__-
>register_method ({
115 check
=> ['perm', '/', [ 'Sys.Console' ]],
117 description
=> "Create a new HA resource.",
118 parameters
=> PVE
::HA
::Resources-
>createSchema(),
119 returns
=> { type
=> 'null' },
123 # create /etc/pve/ha directory
124 PVE
::Cluster
::check_cfs_quorum
();
125 mkdir("/etc/pve/ha");
127 my ($sid, $type, $name) = PVE
::HA
::Tools
::parse_sid
(extract_param
($param, 'sid'));
129 if (my $param_type = extract_param
($param, 'type')) {
130 # useless, but do it anyway
131 die "types does not match\n" if $param_type ne $type;
134 my $plugin = PVE
::HA
::Resources-
>lookup($type);
135 $plugin->verify_name($name);
137 $plugin->exists($name);
139 my $opts = $plugin->check_config($sid, $param, 1, 1);
141 PVE
::HA
::Config
::lock_ha_domain
(
144 my $cfg = PVE
::HA
::Config
::read_resources_config
();
146 if ($cfg->{ids
}->{$sid}) {
147 die "resource ID '$sid' already defined\n";
150 $cfg->{ids
}->{$sid} = $opts;
152 PVE
::HA
::Config
::write_resources_config
($cfg)
154 }, "create resource failed");
159 __PACKAGE__-
>register_method ({
164 description
=> "Update resource configuration.",
166 check
=> ['perm', '/', [ 'Sys.Console' ]],
168 parameters
=> PVE
::HA
::Resources-
>updateSchema(),
169 returns
=> { type
=> 'null' },
173 my $digest = extract_param
($param, 'digest');
174 my $delete = extract_param
($param, 'delete');
176 my ($sid, $type, $name) = PVE
::HA
::Tools
::parse_sid
(extract_param
($param, 'sid'));
178 if (my $param_type = extract_param
($param, 'type')) {
179 # useless, but do it anyway
180 die "types does not match\n" if $param_type ne $type;
183 if (my $group = $param->{group
}) {
184 my $group_cfg = PVE
::HA
::Config
::read_group_config
();
186 die "HA group '$group' does not exist\n"
187 if !$group_cfg->{ids
}->{$group};
190 PVE
::HA
::Config
::lock_ha_domain
(
193 my $cfg = PVE
::HA
::Config
::read_resources_config
();
195 PVE
::SectionConfig
::assert_if_modified
($cfg, $digest);
197 my $scfg = $cfg->{ids
}->{$sid} ||
198 die "no such resource '$sid'\n";
200 my $plugin = PVE
::HA
::Resources-
>lookup($scfg->{type
});
201 my $opts = $plugin->check_config($sid, $param, 0, 1);
203 foreach my $k (%$opts) {
204 $scfg->{$k} = $opts->{$k};
208 my $options = $plugin->private()->{options
}->{$type};
209 foreach my $k (PVE
::Tools
::split_list
($delete)) {
210 my $d = $options->{$k} ||
211 die "no such option '$k'\n";
212 die "unable to delete required option '$k'\n"
214 die "unable to delete fixed option '$k'\n"
220 PVE
::HA
::Config
::write_resources_config
($cfg)
222 }, "update resource failed");
227 __PACKAGE__-
>register_method ({
232 description
=> "Delete resource configuration.",
234 check
=> ['perm', '/', [ 'Sys.Console' ]],
237 additionalProperties
=> 0,
239 sid
=> get_standard_option
('pve-ha-resource-or-vm-id',
240 { completion
=> \
&PVE
::HA
::Tools
::complete_sid
}),
243 returns
=> { type
=> 'null' },
247 my ($sid, $type, $name) = PVE
::HA
::Tools
::parse_sid
(extract_param
($param, 'sid'));
249 PVE
::HA
::Config
::service_is_ha_managed
($sid);
251 PVE
::HA
::Config
::lock_ha_domain
(
254 my $cfg = PVE
::HA
::Config
::read_resources_config
();
256 delete $cfg->{ids
}->{$sid};
258 PVE
::HA
::Config
::write_resources_config
($cfg)
260 }, "delete resource failed");
265 __PACKAGE__-
>register_method ({
268 path
=> '{sid}/migrate',
270 description
=> "Request resource migration (online) to another node.",
272 check
=> ['perm', '/', [ 'Sys.Console' ]],
275 additionalProperties
=> 0,
277 sid
=> get_standard_option
('pve-ha-resource-or-vm-id',
278 { completion
=> \
&PVE
::HA
::Tools
::complete_sid
}),
279 node
=> get_standard_option
('pve-node',
280 { completion
=> \
&PVE
::Cluster
::get_nodelist
}),
283 returns
=> { type
=> 'null' },
287 my ($sid, $type, $name) = PVE
::HA
::Tools
::parse_sid
(extract_param
($param, 'sid'));
289 PVE
::HA
::Config
::service_is_ha_managed
($sid);
291 PVE
::HA
::Config
::queue_crm_commands
("migrate $sid $param->{node}");
296 __PACKAGE__-
>register_method ({
299 path
=> '{sid}/relocate',
301 description
=> "Request resource relocatzion to another node. This stops the service on the old node, and restarts it on the target node.",
303 check
=> ['perm', '/', [ 'Sys.Console' ]],
306 additionalProperties
=> 0,
308 sid
=> get_standard_option
('pve-ha-resource-or-vm-id',
309 { completion
=> \
&PVE
::HA
::Tools
::complete_sid
}),
310 node
=> get_standard_option
('pve-node',
311 { completion
=> \
&PVE
::Cluster
::get_nodelist
}),
314 returns
=> { type
=> 'null' },
318 my ($sid, $type, $name) = PVE
::HA
::Tools
::parse_sid
(extract_param
($param, 'sid'));
320 PVE
::HA
::Config
::service_is_ha_managed
($sid);
322 PVE
::HA
::Config
::queue_crm_commands
("relocate $sid $param->{node}");