]> git.proxmox.com Git - pve-ha-manager.git/blob - src/PVE/HA/Resources.pm
add ignore state for resources
[pve-ha-manager.git] / src / PVE / HA / Resources.pm
1 package PVE::HA::Resources;
2
3 use strict;
4 use warnings;
5
6 use PVE::JSONSchema qw(get_standard_option);
7 use PVE::SectionConfig;
8 use PVE::HA::Tools;
9
10 use base qw(PVE::SectionConfig);
11
12 my $defaultData = {
13 propertyList => {
14 type => { description => "Resource type.", optional => 1 },
15 sid => get_standard_option('pve-ha-resource-or-vm-id',
16 { completion => \&PVE::HA::Tools::complete_sid }),
17 state => {
18 type => 'string',
19 enum => ['started', 'stopped', 'enabled', 'disabled', 'ignored'],
20 optional => 1,
21 default => 'started',
22 description => "Requested resource state.",
23 verbose_description => <<EODESC,
24 Requested resource state. The CRM reads this state and acts accordingly.
25 Please note that `enabled` is just an alias for `started`.
26
27 `started`;;
28
29 The CRM tries to start the resource. Service state is
30 set to `started` after successful start. On node failures, or when start
31 fails, it tries to recover the resource. If everything fails, service
32 state it set to `error`.
33
34 `stopped`;;
35
36 The CRM tries to keep the resource in `stopped` state, but it
37 still tries to relocate the resources on node failures.
38
39 `disabled`;;
40
41 The CRM tries to put the resource in `stopped` state, but does not try
42 to relocate the resources on node failures. The main purpose of this
43 state is error recovery, because it is the only way to move a resource out
44 of the `error` state.
45
46 `ignored`;;
47
48 The resource gets removed from the manager status and so the CRM and the LRM do
49 not touch the resource anymore. All {pve} API calls affecting this resource
50 will be executed, directly bypassing the HA stack. CRM commands will be thrown
51 away while there source is in this state. The resource will not get relocated
52 on node failures.
53
54 EODESC
55 },
56 group => get_standard_option('pve-ha-group-id',
57 { optional => 1,
58 completion => \&PVE::HA::Tools::complete_group }),
59 max_restart => {
60 description => "Maximal number of tries to restart the service on".
61 " a node after its start failed.",
62 type => 'integer',
63 optional => 1,
64 default => 1,
65 minimum => 0,
66 },
67 max_relocate => {
68 description => "Maximal number of service relocate tries when a".
69 " service failes to start.",
70 type => 'integer',
71 optional => 1,
72 default => 1,
73 minimum => 0,
74 },
75 comment => {
76 description => "Description.",
77 type => 'string',
78 optional => 1,
79 maxLength => 4096,
80 },
81 },
82 };
83
84 sub verify_name {
85 my ($class, $name) = @_;
86
87 die "implement this in subclass";
88 }
89
90 sub private {
91 return $defaultData;
92 }
93
94 sub format_section_header {
95 my ($class, $type, $sectionId) = @_;
96
97 my (undef, $name) = split(':', $sectionId, 2);
98
99 return "$type: $name\n";
100 }
101
102 sub parse_section_header {
103 my ($class, $line) = @_;
104
105 if ($line =~ m/^(\S+):\s*(\S+)\s*$/) {
106 my ($type, $name) = (lc($1), $2);
107 my $errmsg = undef; # set if you want to skip whole section
108 eval {
109 if (my $plugin = $defaultData->{plugins}->{$type}) {
110 $plugin->verify_name($name);
111 } else {
112 die "no such resource type '$type'\n";
113 }
114 };
115 $errmsg = $@ if $@;
116 my $config = {}; # to return additional attributes
117 return ($type, "$type:$name", $errmsg, $config);
118 }
119 return undef;
120 }
121
122 sub start {
123 my ($class, $haenv, $id) = @_;
124
125 die "implement in subclass";
126 }
127
128 sub shutdown {
129 my ($class, $haenv, $id) = @_;
130
131 die "implement in subclass";
132 }
133
134 sub migrate {
135 my ($class, $haenv, $id, $target, $online) = @_;
136
137 die "implement in subclass";
138 }
139
140 sub config_file {
141 my ($class, $id, $nodename) = @_;
142
143 die "implement in subclass"
144 }
145
146 sub exists {
147 my ($class, $id, $noerr) = @_;
148
149 die "implement in subclass"
150 }
151
152 sub check_running {
153 my ($class, $haenv, $id) = @_;
154
155 die "implement in subclass";
156 }
157
158 sub remove_locks {
159 my ($self, $haenv, $id, $locks, $service_node) = @_;
160
161 die "implement in subclass";
162 }
163
164
165 # package PVE::HA::Resources::IPAddr;
166
167 # use strict;
168 # use warnings;
169 # use PVE::Tools qw($IPV4RE $IPV6RE);
170
171 # use base qw(PVE::HA::Resources);
172
173 # sub type {
174 # return 'ipaddr';
175 # }
176
177 # sub verify_name {
178 # my ($class, $name) = @_;
179
180 # die "invalid IP address\n" if $name !~ m!^$IPV6RE|$IPV4RE$!;
181 # }
182
183 # sub options {
184 # return {
185 # state => { optional => 1 },
186 # group => { optional => 1 },
187 # comment => { optional => 1 },
188 # };
189 # }
190
191 1;