]> git.proxmox.com Git - pve-ha-manager.git/blob - src/PVE/HA/Config.pm
Config: add get_service_status method
[pve-ha-manager.git] / src / PVE / HA / Config.pm
1 package PVE::HA::Config;
2
3 use strict;
4 use warnings;
5 use JSON;
6
7 use PVE::HA::Tools;
8 use PVE::HA::Groups;
9 use PVE::Cluster qw(cfs_register_file cfs_read_file cfs_write_file cfs_lock_file);
10 use PVE::HA::Resources;
11
12 PVE::HA::Groups->register();
13
14 PVE::HA::Groups->init();
15
16 my $manager_status_filename = "ha/manager_status";
17 my $ha_groups_config = "ha/groups.cfg";
18 my $ha_resources_config = "ha/resources.cfg";
19 my $crm_commands_filename = "ha/crm_commands";
20 my $ha_fence_config = "ha/fence.cfg";
21
22 cfs_register_file($crm_commands_filename,
23 sub { my ($fn, $raw) = @_; return defined($raw) ? $raw : ''; },
24 sub { my ($fn, $raw) = @_; return $raw; });
25 cfs_register_file($ha_groups_config,
26 sub { PVE::HA::Groups->parse_config(@_); },
27 sub { PVE::HA::Groups->write_config(@_); });
28 cfs_register_file($ha_resources_config,
29 sub { PVE::HA::Resources->parse_config(@_); },
30 sub { PVE::HA::Resources->write_config(@_); });
31 cfs_register_file($manager_status_filename,
32 \&json_reader,
33 \&json_writer);
34 cfs_register_file($ha_fence_config,
35 \&PVE::HA::FenceConfig::parse_config,
36 \&PVE::HA::FenceConfig::write_config);
37
38 sub json_reader {
39 my ($filename, $data) = @_;
40
41 return defined($data) ? decode_json($data) : {};
42 }
43
44 sub json_writer {
45 my ($filename, $data) = @_;
46
47 return encode_json($data);
48 }
49
50 sub 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
60 sub 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
70 sub parse_groups_config {
71 my ($filename, $raw) = @_;
72
73 return PVE::HA::Groups->parse_config($filename, $raw);
74 }
75
76 sub parse_resources_config {
77 my ($filename, $raw) = @_;
78
79 return PVE::HA::Resources->parse_config($filename, $raw);
80 }
81
82 sub read_resources_config {
83
84 return cfs_read_file($ha_resources_config);
85 }
86
87 sub read_group_config {
88
89 return cfs_read_file($ha_groups_config);
90 }
91
92 sub write_group_config {
93 my ($cfg) = @_;
94
95 cfs_write_file($ha_groups_config, $cfg);
96 }
97
98 sub write_resources_config {
99 my ($cfg) = @_;
100
101 cfs_write_file($ha_resources_config, $cfg);
102 }
103
104 sub read_manager_status {
105 my () = @_;
106
107 return cfs_read_file($manager_status_filename);
108 }
109
110 sub write_manager_status {
111 my ($status_obj) = @_;
112
113 cfs_write_file($manager_status_filename, $status_obj);
114 }
115
116 sub read_fence_config {
117 my () = @_;
118
119 cfs_read_file($ha_fence_config);
120 }
121
122 sub lock_ha_domain {
123 my ($code, $errmsg) = @_;
124
125 my $res = PVE::Cluster::cfs_lock_domain("ha", undef, $code);
126 my $err = $@;
127 if ($err) {
128 $errmsg ? die "$errmsg: $err" : die $err;
129 }
130 return $res;
131 }
132
133 sub queue_crm_commands {
134 my ($cmd) = @_;
135
136 chomp $cmd;
137
138 my $code = sub {
139 my $data = cfs_read_file($crm_commands_filename);
140 $data .= "$cmd\n";
141 cfs_write_file($crm_commands_filename, $data);
142 };
143
144 return lock_ha_domain($code);
145 }
146
147 sub read_crm_commands {
148
149 my $code = sub {
150 my $data = cfs_read_file($crm_commands_filename);
151 cfs_write_file($crm_commands_filename, '');
152 return $data;
153 };
154
155 return lock_ha_domain($code);
156 }
157
158 my $servive_check_ha_state = sub {
159 my ($conf, $sid, $has_state) = @_;
160
161 if (my $d = $conf->{ids}->{$sid}) {
162 return 1 if !defined($has_state);
163
164 $d->{state} = 'enabled' if !defined($d->{state});
165 return 1 if $d->{state} eq $has_state;
166 }
167
168 return undef;
169 };
170
171 sub vm_is_ha_managed {
172 my ($vmid, $has_state) = @_;
173
174 my $conf = cfs_read_file($ha_resources_config);
175
176 my $types = PVE::HA::Resources->lookup_types();
177 foreach my $type ('vm', 'ct') {
178 return 1 if &$servive_check_ha_state($conf, "$type:$vmid", $has_state);
179 }
180
181 return undef;
182 }
183
184 sub service_is_ha_managed {
185 my ($sid, $has_state, $noerr) = @_;
186
187 my $conf = cfs_read_file($ha_resources_config);
188
189 return 1 if &$servive_check_ha_state($conf, $sid, $has_state);
190
191 die "resource '$sid' is not HA managed\n" if !$noerr;
192
193 return undef;
194 }
195
196 sub get_service_status {
197 my ($sid) = @_;
198
199 my $status = { managed => 0 };
200
201 my $conf = cfs_read_file($ha_resources_config);
202
203 if (&$servive_check_ha_state($conf, $sid)) {
204 my $manager_status = cfs_read_file($manager_status_filename);
205
206 $status->{managed} = 1;
207 $status->{group} = $conf->{ids}->{$sid}->{group};
208 $status->{state} = $manager_status->{service_status}->{$sid}->{state};
209 }
210
211 return $status;
212 }
213
214 1;