use strict;
use warnings;
-use Data::Dumper;
use PVE::JSONSchema qw(get_standard_option);
use PVE::SectionConfig;
use PVE::HA::Tools;
my $defaultData = {
propertyList => {
type => { description => "Resource type.", optional => 1 },
- sid => get_standard_option('pve-ha-resource-id'),
+ sid => get_standard_option('pve-ha-resource-or-vm-id',
+ { completion => \&PVE::HA::Tools::complete_sid }),
state => {
- description => "Resource state.",
type => 'string',
- enum => ['enabled', 'disabled'],
+ enum => ['started', 'stopped', 'enabled', 'disabled'],
optional => 1,
- default => 'enabled',
+ default => 'started',
+ description => "Requested resource state.",
+ verbose_description => <<EODESC,
+Requested resource state. The CRM reads this state and acts accordingly.
+Please note that `enabled` is just an alias for `started`.
+
+`started`;;
+
+The CRM tries to start the resource. Service state is
+set to `started` after successful start. On node failures, or when start
+fails, it tries to recover the resource. If everything fails, service
+state it set to `error`.
+
+`stopped`;;
+
+The CRM tries to keep the resource in `stopped` state, but it
+still tries to relocate the resources on node failures.
+
+`disabled`;;
+
+The CRM tries to put the resource in `stopped` state, but does not try
+to relocate the resources on node failures. The main purpose of this
+state is error recovery, because it is the only way to move a resource out
+of the `error` state.
+
+EODESC
+ },
+ group => get_standard_option('pve-ha-group-id',
+ { optional => 1,
+ completion => \&PVE::HA::Tools::complete_group }),
+ max_restart => {
+ description => "Maximal number of tries to restart the service on".
+ " a node after its start failed.",
+ type => 'integer',
+ optional => 1,
+ default => 1,
+ minimum => 0,
+ },
+ max_relocate => {
+ description => "Maximal number of service relocate tries when a".
+ " service failes to start.",
+ type => 'integer',
+ optional => 1,
+ default => 1,
+ minimum => 0,
},
- group => get_standard_option('pve-ha-group-id', { optional => 1 }),
comment => {
description => "Description.",
type => 'string',
eval {
if (my $plugin = $defaultData->{plugins}->{$type}) {
$plugin->verify_name($name);
+ } else {
+ die "no such resource type '$type'\n";
}
};
$errmsg = $@ if $@;
return undef;
}
-package PVE::HA::Resources::PVEVM;
+sub start {
+ my ($class, $haenv, $id) = @_;
-use strict;
-use warnings;
+ die "implement in subclass";
+}
-use base qw(PVE::HA::Resources);
+sub shutdown {
+ my ($class, $haenv, $id) = @_;
-sub type {
- return 'vm';
+ die "implement in subclass";
}
-sub verify_name {
- my ($class, $name) = @_;
+sub migrate {
+ my ($class, $haenv, $id, $target, $online) = @_;
- die "invalid VMID\n" if $name !~ m/^[1-9][0-9]+$/;
+ die "implement in subclass";
}
-sub options {
- return {
- state => { optional => 1 },
- group => { optional => 1 },
- comment => { optional => 1 },
- };
+sub config_file {
+ my ($class, $id, $nodename) = @_;
+
+ die "implement in subclass"
}
-package PVE::HA::Resources::IPAddr;
+sub exists {
+ my ($class, $id, $noerr) = @_;
-use strict;
-use warnings;
-use PVE::Tools qw($IPV4RE $IPV6RE);
+ die "implement in subclass"
+}
-use base qw(PVE::HA::Resources);
+sub check_running {
+ my ($class, $haenv, $id) = @_;
-sub type {
- return 'ipaddr';
+ die "implement in subclass";
}
-sub verify_name {
- my ($class, $name) = @_;
+sub remove_locks {
+ my ($self, $haenv, $id, $locks, $service_node) = @_;
- die "invalid IP address\n" if $name !~ m!^$IPV6RE|$IPV4RE$!;
+ die "implement in subclass";
}
-sub options {
- return {
- state => { optional => 1 },
- group => { optional => 1 },
- comment => { optional => 1 },
- };
-}
+
+# package PVE::HA::Resources::IPAddr;
+
+# use strict;
+# use warnings;
+# use PVE::Tools qw($IPV4RE $IPV6RE);
+
+# use base qw(PVE::HA::Resources);
+
+# sub type {
+# return 'ipaddr';
+# }
+
+# sub verify_name {
+# my ($class, $name) = @_;
+
+# die "invalid IP address\n" if $name !~ m!^$IPV6RE|$IPV4RE$!;
+# }
+
+# sub options {
+# return {
+# state => { optional => 1 },
+# group => { optional => 1 },
+# comment => { optional => 1 },
+# };
+# }
1;