]> git.proxmox.com Git - pve-ha-manager.git/blob - src/PVE/HA/Resources.pm
clean up 'Data::Dumper' usage tree wide
[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'],
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 EODESC
47 },
48 group => get_standard_option('pve-ha-group-id',
49 { optional => 1,
50 completion => \&PVE::HA::Tools::complete_group }),
51 max_restart => {
52 description => "Maximal number of tries to restart the service on".
53 " a node after its start failed.",
54 type => 'integer',
55 optional => 1,
56 default => 1,
57 minimum => 0,
58 },
59 max_relocate => {
60 description => "Maximal number of service relocate tries when a".
61 " service failes to start.",
62 type => 'integer',
63 optional => 1,
64 default => 1,
65 minimum => 0,
66 },
67 comment => {
68 description => "Description.",
69 type => 'string',
70 optional => 1,
71 maxLength => 4096,
72 },
73 },
74 };
75
76 sub verify_name {
77 my ($class, $name) = @_;
78
79 die "implement this in subclass";
80 }
81
82 sub private {
83 return $defaultData;
84 }
85
86 sub format_section_header {
87 my ($class, $type, $sectionId) = @_;
88
89 my (undef, $name) = split(':', $sectionId, 2);
90
91 return "$type: $name\n";
92 }
93
94 sub parse_section_header {
95 my ($class, $line) = @_;
96
97 if ($line =~ m/^(\S+):\s*(\S+)\s*$/) {
98 my ($type, $name) = (lc($1), $2);
99 my $errmsg = undef; # set if you want to skip whole section
100 eval {
101 if (my $plugin = $defaultData->{plugins}->{$type}) {
102 $plugin->verify_name($name);
103 } else {
104 die "no such resource type '$type'\n";
105 }
106 };
107 $errmsg = $@ if $@;
108 my $config = {}; # to return additional attributes
109 return ($type, "$type:$name", $errmsg, $config);
110 }
111 return undef;
112 }
113
114 sub start {
115 my ($class, $haenv, $id) = @_;
116
117 die "implement in subclass";
118 }
119
120 sub shutdown {
121 my ($class, $haenv, $id) = @_;
122
123 die "implement in subclass";
124 }
125
126 sub migrate {
127 my ($class, $haenv, $id, $target, $online) = @_;
128
129 die "implement in subclass";
130 }
131
132 sub config_file {
133 my ($class, $id, $nodename) = @_;
134
135 die "implement in subclass"
136 }
137
138 sub exists {
139 my ($class, $id, $noerr) = @_;
140
141 die "implement in subclass"
142 }
143
144 sub check_running {
145 my ($class, $haenv, $id) = @_;
146
147 die "implement in subclass";
148 }
149
150 sub remove_locks {
151 my ($self, $haenv, $id, $locks, $service_node) = @_;
152
153 die "implement in subclass";
154 }
155
156
157 # package PVE::HA::Resources::IPAddr;
158
159 # use strict;
160 # use warnings;
161 # use PVE::Tools qw($IPV4RE $IPV6RE);
162
163 # use base qw(PVE::HA::Resources);
164
165 # sub type {
166 # return 'ipaddr';
167 # }
168
169 # sub verify_name {
170 # my ($class, $name) = @_;
171
172 # die "invalid IP address\n" if $name !~ m!^$IPV6RE|$IPV4RE$!;
173 # }
174
175 # sub options {
176 # return {
177 # state => { optional => 1 },
178 # group => { optional => 1 },
179 # comment => { optional => 1 },
180 # };
181 # }
182
183 1;