]> git.proxmox.com Git - pve-ha-manager.git/blame - src/PVE/HA/Tools.pm
bump version to 1.0-11
[pve-ha-manager.git] / src / PVE / HA / Tools.pm
CommitLineData
54fc75de
DM
1package PVE::HA::Tools;
2
3use strict;
4use warnings;
a223f4cc
DM
5use JSON;
6use PVE::JSONSchema;
54fc75de 7use PVE::Tools;
427e33b6 8use PVE::Cluster;
54fc75de 9
95ea5d67
DM
10PVE::JSONSchema::register_format('pve-ha-resource-id', \&pve_verify_ha_resource_id);
11sub pve_verify_ha_resource_id {
12 my ($sid, $noerr) = @_;
13
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";
17 }
18 return $sid;
19}
20
21PVE::JSONSchema::register_standard_option('pve-ha-resource-id', {
427e33b6 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).",
95ea5d67
DM
23 typetext => "<type>:<name>",
24 type => 'string', format => 'pve-ha-resource-id',
25});
26
6ca2edcd
DM
27PVE::JSONSchema::register_format('pve-ha-resource-or-vm-id', \&pve_verify_ha_resource_or_vm_id);
28sub pve_verify_ha_resource_or_vm_id {
29 my ($sid, $noerr) = @_;
30
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";
34 }
35 return $sid;
36}
37
38PVE::JSONSchema::register_standard_option('pve-ha-resource-or-vm-id', {
427e33b6 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).",
6ca2edcd
DM
40 typetext => "<type>:<name>",
41 type => 'string', format => 'pve-ha-resource-or-vm-id',
42});
43
a223f4cc
DM
44PVE::JSONSchema::register_format('pve-ha-group-node', \&pve_verify_ha_group_node);
45sub pve_verify_ha_group_node {
46 my ($node, $noerr) = @_;
47
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";
51 }
52 return $node;
53}
54
55PVE::JSONSchema::register_standard_option('pve-ha-group-node-list', {
63f6a08c 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').",
a223f4cc
DM
57 type => 'string', format => 'pve-ha-group-node-list',
58 typetext => '<node>[:<pri>]{,<node>[:<pri>]}*',
59});
60
61PVE::JSONSchema::register_standard_option('pve-ha-group-id', {
62 description => "The HA group identifier.",
63 type => 'string', format => 'pve-configid',
64});
65
b47a7a1b
DM
66sub parse_sid {
67 my ($sid) = @_;
68
6ca2edcd
DM
69 my ($type, $name);
70
71 if ($sid =~ m/^(\d+)$/) {
72 $name = $1;
427e33b6
AG
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') {
77 $type = 'ct';
78 } elsif ($vm_type eq 'qemu') {
79 $type = 'vm';
80 } else {
81 die "internal error";
82 }
83 $sid = "$type:$name";
84 }
85 else {
86 die "unable do add resource - VM/CT $1 does not exist\n";
87 }
6ca2edcd
DM
88 } elsif ($sid =~m/^(\S+):(\S+)$/) {
89 $name = $2;
90 $type = $1;
91 } else {
92 die "unable to parse service id '$sid'\n";
93 }
b47a7a1b 94
6ca2edcd 95 return wantarray ? ($sid, $type, $name) : $sid;
b47a7a1b
DM
96}
97
54fc75de
DM
98sub read_json_from_file {
99 my ($filename, $default) = @_;
100
101 my $data;
102
103 if (defined($default) && (! -f $filename)) {
104 $data = $default;
105 } else {
3b8cba06
DM
106 my $raw;
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"
112 if !defined($raw);
113 } else {
114 $raw = PVE::Tools::file_get_contents($filename);
115 }
54fc75de
DM
116 $data = decode_json($raw);
117 }
118
119 return $data;
120}
121
122sub write_json_to_file {
123 my ($filename, $data) = @_;
124
125 my $raw = encode_json($data);
a223f4cc 126
54fc75de
DM
127 PVE::Tools::file_set_contents($filename, $raw);
128}
129
49777d09
DM
130sub count_fenced_services {
131 my ($ss, $node) = @_;
132
133 my $count = 0;
134
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') {
142 $count++;
143 next;
144 }
145 }
146
147 return $count;
148}
54fc75de 149
cdf272a0
TL
150# bash auto completion helper
151
152sub complete_sid {
bf119a50 153 my ($cmd, $pname, $cur) = @_;
cdf272a0 154
bf119a50 155 my $cfg = PVE::HA::Config::read_resources_config();
cdf272a0
TL
156
157 my $res = [];
cdf272a0 158
bf119a50 159 if ($cmd eq 'add') {
cdf272a0 160
bf119a50
DM
161 my $vmlist = PVE::Cluster::get_vmlist();
162
163 while (my ($vmid, $info) = each %{$vmlist->{ids}}) {
164
165 my $sid;
166
167 if ($info->{type} eq 'lxc') {
168 $sid = "ct:$vmid";
169 } elsif ($info->{type} eq 'qemu') {
170 $sid = "vm:$vmid";
171 } else {
172 next; # should not happen
173 }
174
175 next if $cfg->{ids}->{$sid};
176
177 push @$res, $sid;
178 }
179
180 } else {
181
182 foreach my $sid (keys %{$cfg->{ids}}) {
183 push @$res, $sid;
cdf272a0 184 }
bf119a50 185 }
cdf272a0 186
bf119a50
DM
187 return $res;
188}
189
190sub complete_enabled_sid {
191
192 my $cfg = PVE::HA::Config::read_resources_config();
cdf272a0 193
bf119a50
DM
194 my $res = [];
195 foreach my $sid (keys %{$cfg->{ids}}) {
196 my $state = $cfg->{ids}->{$sid}->{state} // 'enabled';
197 next if $state ne 'enabled';
cdf272a0 198 push @$res, $sid;
bf119a50 199 }
cdf272a0 200
bf119a50
DM
201 return $res;
202}
203
204sub complete_disabled_sid {
205
206 my $cfg = PVE::HA::Config::read_resources_config();
207
208 my $res = [];
209 foreach my $sid (keys %{$cfg->{ids}}) {
210 my $state = $cfg->{ids}->{$sid}->{state} // 'enabled';
211 next if $state eq 'enabled';
212 push @$res, $sid;
cdf272a0
TL
213 }
214
215 return $res;
216}
217
218sub complete_group {
bc544941 219 my ($cmd, $pname, $cur) = @_;
cdf272a0
TL
220
221 my $cfg = PVE::HA::Config::read_group_config();
222
223 my $res = [];
bc544941
TL
224 if ($cmd ne 'groupadd') {
225
226 foreach my $group (keys %{$cfg->{ids}}) {
227 push @$res, $group;
228 }
229
cdf272a0
TL
230 }
231
232 return $res;
233}
234
235
54fc75de 2361;