]> git.proxmox.com Git - pve-ha-manager.git/blame - src/PVE/HA/Config.pm
factor out resource config check and default set code
[pve-ha-manager.git] / src / PVE / HA / Config.pm
CommitLineData
cc32b737
DM
1package PVE::HA::Config;
2
3use strict;
4use warnings;
139a9b90 5use JSON;
cc32b737 6
139a9b90 7use PVE::HA::Tools;
cc32b737 8use PVE::HA::Groups;
139a9b90 9use PVE::Cluster qw(cfs_register_file cfs_read_file cfs_write_file cfs_lock_file);
d6edb3ea 10use PVE::HA::Resources;
cc32b737
DM
11
12PVE::HA::Groups->register();
13
14PVE::HA::Groups->init();
15
139a9b90
DM
16my $manager_status_filename = "ha/manager_status";
17my $ha_groups_config = "ha/groups.cfg";
18my $ha_resources_config = "ha/resources.cfg";
19my $crm_commands_filename = "ha/crm_commands";
f83e7e6e 20my $ha_fence_config = "ha/fence.cfg";
139a9b90
DM
21
22cfs_register_file($crm_commands_filename,
23 sub { my ($fn, $raw) = @_; return defined($raw) ? $raw : ''; },
24 sub { my ($fn, $raw) = @_; return $raw; });
25cfs_register_file($ha_groups_config,
26 sub { PVE::HA::Groups->parse_config(@_); },
27 sub { PVE::HA::Groups->write_config(@_); });
28cfs_register_file($ha_resources_config,
29 sub { PVE::HA::Resources->parse_config(@_); },
30 sub { PVE::HA::Resources->write_config(@_); });
31cfs_register_file($manager_status_filename,
32 \&json_reader,
33 \&json_writer);
f83e7e6e
TL
34cfs_register_file($ha_fence_config,
35 \&PVE::HA::FenceConfig::parse_config,
36 \&PVE::HA::FenceConfig::write_config);
139a9b90
DM
37
38sub json_reader {
39 my ($filename, $data) = @_;
40
f1817b68 41 return defined($data) && length($data) > 0 ? decode_json($data) : {};
139a9b90
DM
42}
43
44sub json_writer {
45 my ($filename, $data) = @_;
46
47 return encode_json($data);
48}
49
50sub read_lrm_status {
51 my ($node) = @_;
52
53 die "undefined node" if !defined($node);
54
55 my $filename = "/etc/pve/nodes/$node/lrm_status";
56
57 return PVE::HA::Tools::read_json_from_file($filename, {});
58}
59
60sub write_lrm_status {
61 my ($node, $status_obj) = @_;
62
63 die "undefined node" if !defined($node);
64
65 my $filename = "/etc/pve/nodes/$node/lrm_status";
66
67 PVE::HA::Tools::write_json_to_file($filename, $status_obj);
68}
69
cc32b737
DM
70sub parse_groups_config {
71 my ($filename, $raw) = @_;
72
139a9b90 73 return PVE::HA::Groups->parse_config($filename, $raw);
cc32b737
DM
74}
75
ce216792 76sub parse_resources_config {
cc32b737
DM
77 my ($filename, $raw) = @_;
78
79 return PVE::HA::Resources->parse_config($filename, $raw);
80}
81
139a9b90
DM
82sub read_resources_config {
83
84 return cfs_read_file($ha_resources_config);
85}
86
85f6e9ca
TL
87# checks if resource exists and sets defaults for unset values
88sub read_and_check_resources_config {
89
90 my $res = cfs_read_file($ha_resources_config);
91
92 my $vmlist = PVE::Cluster::get_vmlist();
93 my $conf = {};
94
95 foreach my $sid (keys %{$res->{ids}}) {
96 my $d = $res->{ids}->{$sid};
97 my (undef, undef, $name) = PVE::HA::Tools::parse_sid($sid);
98 $d->{state} = 'enabled' if !defined($d->{state});
99 $d->{max_restart} = 1 if !defined($d->{max_restart});
100 $d->{max_relocate} = 1 if !defined($d->{max_relocate});
101 if (PVE::HA::Resources->lookup($d->{type})) {
102 if (my $vmd = $vmlist->{ids}->{$name}) {
103 if (!$vmd) {
104 warn "no such VM '$name'\n";
105 } else {
106 $d->{node} = $vmd->{node};
107 $conf->{$sid} = $d;
108 }
109 } else {
110 if (defined($d->{node})) {
111 $conf->{$sid} = $d;
112 } else {
113 warn "service '$sid' without node\n";
114 }
115 }
116 }
117 }
118
119 return $conf;
120}
121
139a9b90 122sub read_group_config {
139a9b90
DM
123
124 return cfs_read_file($ha_groups_config);
125}
126
9eb0f126
DM
127sub write_group_config {
128 my ($cfg) = @_;
129
130 cfs_write_file($ha_groups_config, $cfg);
131}
132
139a9b90
DM
133sub write_resources_config {
134 my ($cfg) = @_;
135
136 cfs_write_file($ha_resources_config, $cfg);
137}
138
139sub read_manager_status {
140 my () = @_;
141
142 return cfs_read_file($manager_status_filename);
143}
144
145sub write_manager_status {
146 my ($status_obj) = @_;
f83e7e6e 147
139a9b90
DM
148 cfs_write_file($manager_status_filename, $status_obj);
149}
150
f83e7e6e
TL
151sub read_fence_config {
152 my () = @_;
153
154 cfs_read_file($ha_fence_config);
155}
156
b3c07baa
TL
157sub write_fence_config {
158 my ($cfg) = @_;
159
160 cfs_write_file($ha_fence_config, $cfg);
161}
162
66c7e7ef 163sub lock_ha_domain {
139a9b90
DM
164 my ($code, $errmsg) = @_;
165
66c7e7ef 166 my $res = PVE::Cluster::cfs_lock_domain("ha", undef, $code);
139a9b90
DM
167 my $err = $@;
168 if ($err) {
169 $errmsg ? die "$errmsg: $err" : die $err;
170 }
171 return $res;
172}
173
174sub queue_crm_commands {
175 my ($cmd) = @_;
176
177 chomp $cmd;
178
179 my $code = sub {
180 my $data = cfs_read_file($crm_commands_filename);
181 $data .= "$cmd\n";
182 cfs_write_file($crm_commands_filename, $data);
183 };
184
66c7e7ef 185 return lock_ha_domain($code);
139a9b90
DM
186}
187
188sub read_crm_commands {
189
190 my $code = sub {
191 my $data = cfs_read_file($crm_commands_filename);
192 cfs_write_file($crm_commands_filename, '');
193 return $data;
194 };
195
66c7e7ef 196 return lock_ha_domain($code);
139a9b90
DM
197}
198
0e703a14 199my $service_check_ha_state = sub {
e709d3d0
DM
200 my ($conf, $sid, $has_state) = @_;
201
202 if (my $d = $conf->{ids}->{$sid}) {
203 return 1 if !defined($has_state);
204
205 $d->{state} = 'enabled' if !defined($d->{state});
206 return 1 if $d->{state} eq $has_state;
207 }
208
209 return undef;
210};
211
139a9b90 212sub vm_is_ha_managed {
55c82a65 213 my ($vmid, $has_state) = @_;
139a9b90
DM
214
215 my $conf = cfs_read_file($ha_resources_config);
216
8facb786 217 my $types = PVE::HA::Resources->lookup_types();
e709d3d0 218 foreach my $type ('vm', 'ct') {
0e703a14 219 return 1 if &$service_check_ha_state($conf, "$type:$vmid", $has_state);
e709d3d0 220 }
8facb786
TL
221
222 return undef;
139a9b90
DM
223}
224
9e03f787
TL
225sub service_is_ha_managed {
226 my ($sid, $has_state, $noerr) = @_;
227
228 my $conf = cfs_read_file($ha_resources_config);
229
0e703a14 230 return 1 if &$service_check_ha_state($conf, $sid, $has_state);
9e03f787
TL
231
232 die "resource '$sid' is not HA managed\n" if !$noerr;
233
234 return undef;
235}
917ea00c
TL
236
237sub get_service_status {
238 my ($sid) = @_;
239
240 my $status = { managed => 0 };
241
242 my $conf = cfs_read_file($ha_resources_config);
243
0e703a14 244 if (&$service_check_ha_state($conf, $sid)) {
917ea00c
TL
245 my $manager_status = cfs_read_file($manager_status_filename);
246
247 $status->{managed} = 1;
248 $status->{group} = $conf->{ids}->{$sid}->{group};
249 $status->{state} = $manager_status->{service_status}->{$sid}->{state};
250 }
251
252 return $status;
253}
254
cc32b737 2551;