1 package PVE
::HA
::Tools
;
10 PVE
::JSONSchema
::register_format
('pve-ha-resource-id', \
&pve_verify_ha_resource_id
);
11 sub pve_verify_ha_resource_id
{
12 my ($sid, $noerr) = @_;
14 if ($sid !~ m/^[a-z]+:\S+$/) {
15 return undef if $noerr;
16 die "value does not look like a valid ha resource id\n";
21 PVE
::JSONSchema
::register_standard_option
('pve-ha-resource-id', {
22 description
=> "HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100).",
23 typetext
=> "<type>:<name>",
24 type
=> 'string', format
=> 'pve-ha-resource-id',
27 PVE
::JSONSchema
::register_format
('pve-ha-resource-or-vm-id', \
&pve_verify_ha_resource_or_vm_id
);
28 sub pve_verify_ha_resource_or_vm_id
{
29 my ($sid, $noerr) = @_;
31 if ($sid !~ m/^([a-z]+:\S+|\d+)$/) {
32 return undef if $noerr;
33 die "value does not look like a valid ha resource id\n";
38 PVE
::JSONSchema
::register_standard_option
('pve-ha-resource-or-vm-id', {
39 description
=> "HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).",
40 typetext
=> "<type>:<name>",
41 type
=> 'string', format
=> 'pve-ha-resource-or-vm-id',
44 PVE
::JSONSchema
::register_format
('pve-ha-group-node', \
&pve_verify_ha_group_node
);
45 sub pve_verify_ha_group_node
{
46 my ($node, $noerr) = @_;
48 if ($node !~ m/^([a-zA-Z0-9]([a-zA-Z0-9\-]*[a-zA-Z0-9])?)(:\d+)?$/) {
49 return undef if $noerr;
50 die "value does not look like a valid ha group node\n";
55 PVE
::JSONSchema
::register_standard_option
('pve-ha-group-node-list', {
56 description
=> "List of cluster node names with optional priority. We use priority '0' as default. The CRM tries to run services on the node with highest priority (also see option 'nofailback').",
57 type
=> 'string', format
=> 'pve-ha-group-node-list',
58 typetext
=> '<node>[:<pri>]{,<node>[:<pri>]}*',
61 PVE
::JSONSchema
::register_standard_option
('pve-ha-group-id', {
62 description
=> "The HA group identifier.",
63 type
=> 'string', format
=> 'pve-configid',
71 if ($sid =~ m/^(\d+)$/) {
73 my $vmlist = PVE
::Cluster
::get_vmlist
();
74 if (defined($vmlist->{ids
}->{$name})) {
75 my $vm_type = $vmlist->{ids
}->{$name}->{type
};
76 if ($vm_type eq 'lxc') {
78 } elsif ($vm_type eq 'qemu') {
86 die "unable do add resource - VM/CT $1 does not exist\n";
88 } elsif ($sid =~m/^(\S+):(\S+)$/) {
92 die "unable to parse service id '$sid'\n";
95 return wantarray ?
($sid, $type, $name) : $sid;
98 sub read_json_from_file
{
99 my ($filename, $default) = @_;
103 if (defined($default) && (! -f
$filename)) {
107 # workaround for bug #775
108 if ($filename =~ m
|^/etc/pve
/|) {
109 $filename =~ s
|^/etc/pve
/+||;
110 $raw = PVE
::Cluster
::get_config
($filename);
111 die "unable to read file '/etc/pve/$filename'\n"
114 $raw = PVE
::Tools
::file_get_contents
($filename);
116 $data = decode_json
($raw);
122 sub write_json_to_file
{
123 my ($filename, $data) = @_;
125 my $raw = encode_json
($data);
127 PVE
::Tools
::file_set_contents
($filename, $raw);
130 sub count_fenced_services
{
131 my ($ss, $node) = @_;
135 foreach my $sid (keys %$ss) {
136 my $sd = $ss->{$sid};
137 next if !$sd->{node
};
138 next if $sd->{node
} ne $node;
139 my $req_state = $sd->{state};
140 next if !defined($req_state);
141 if ($req_state eq 'fence') {
150 # bash auto completion helper
153 my ($cmd, $pname, $cur) = @_;
155 my $cfg = PVE
::HA
::Config
::read_resources_config
();
161 my $vmlist = PVE
::Cluster
::get_vmlist
();
163 while (my ($vmid, $info) = each %{$vmlist->{ids
}}) {
167 if ($info->{type
} eq 'lxc') {
169 } elsif ($info->{type
} eq 'qemu') {
172 next; # should not happen
175 next if $cfg->{ids
}->{$sid};
182 foreach my $sid (keys %{$cfg->{ids
}}) {
190 sub complete_enabled_sid
{
192 my $cfg = PVE
::HA
::Config
::read_resources_config
();
195 foreach my $sid (keys %{$cfg->{ids
}}) {
196 my $state = $cfg->{ids
}->{$sid}->{state} // 'enabled';
197 next if $state ne 'enabled';
204 sub complete_disabled_sid
{
206 my $cfg = PVE
::HA
::Config
::read_resources_config
();
209 foreach my $sid (keys %{$cfg->{ids
}}) {
210 my $state = $cfg->{ids
}->{$sid}->{state} // 'enabled';
211 next if $state eq 'enabled';
219 my ($cmd, $pname, $cur) = @_;
221 my $cfg = PVE
::HA
::Config
::read_group_config
();
224 if ($cmd ne 'groupadd') {
226 foreach my $group (keys %{$cfg->{ids
}}) {