[pve-devel] [PATCH ha-manager 04/15] add rules section config base plugin
Daniel Kral
d.kral at proxmox.com
Tue Mar 25 16:12:43 CET 2025
Add a rules section config base plugin to allow users to specify
different kinds of rules in a single configuration file.
The interface is designed to allow sub plugins to implement their own
{decode,encode}_value() methods and also offer a canonicalized version
of their rules with canonicalize(), i.e. with any inconsistencies
removed and ambiguities resolved. There is also a are_satisfiable()
method for anticipation of the verification of additions or changes to
the rules config via the API.
Signed-off-by: Daniel Kral <d.kral at proxmox.com>
---
debian/pve-ha-manager.install | 1 +
src/PVE/HA/Makefile | 2 +-
src/PVE/HA/Rules.pm | 118 ++++++++++++++++++++++++++++++++++
src/PVE/HA/Tools.pm | 5 ++
4 files changed, 125 insertions(+), 1 deletion(-)
create mode 100644 src/PVE/HA/Rules.pm
diff --git a/debian/pve-ha-manager.install b/debian/pve-ha-manager.install
index 0ffbd8d..9bbd375 100644
--- a/debian/pve-ha-manager.install
+++ b/debian/pve-ha-manager.install
@@ -32,6 +32,7 @@
/usr/share/perl5/PVE/HA/Resources.pm
/usr/share/perl5/PVE/HA/Resources/PVECT.pm
/usr/share/perl5/PVE/HA/Resources/PVEVM.pm
+/usr/share/perl5/PVE/HA/Rules.pm
/usr/share/perl5/PVE/HA/Tools.pm
/usr/share/perl5/PVE/HA/Usage.pm
/usr/share/perl5/PVE/HA/Usage/Basic.pm
diff --git a/src/PVE/HA/Makefile b/src/PVE/HA/Makefile
index 8c91b97..489cbc0 100644
--- a/src/PVE/HA/Makefile
+++ b/src/PVE/HA/Makefile
@@ -1,4 +1,4 @@
-SIM_SOURCES=CRM.pm Env.pm Groups.pm Resources.pm LRM.pm Manager.pm \
+SIM_SOURCES=CRM.pm Env.pm Groups.pm Rules.pm Resources.pm LRM.pm Manager.pm \
NodeStatus.pm Tools.pm FenceConfig.pm Fence.pm Usage.pm
SOURCES=${SIM_SOURCES} Config.pm
diff --git a/src/PVE/HA/Rules.pm b/src/PVE/HA/Rules.pm
new file mode 100644
index 0000000..bff3375
--- /dev/null
+++ b/src/PVE/HA/Rules.pm
@@ -0,0 +1,118 @@
+package PVE::HA::Rules;
+
+use strict;
+use warnings;
+
+use PVE::JSONSchema qw(get_standard_option);
+use PVE::SectionConfig;
+use PVE::HA::Tools;
+
+use base qw(PVE::SectionConfig);
+
+# TODO Add descriptions, completions, etc.
+my $defaultData = {
+ propertyList => {
+ type => { description => "Rule type." },
+ ruleid => get_standard_option('pve-ha-rule-id'),
+ comment => {
+ type => 'string',
+ maxLength => 4096,
+ description => "Rule description.",
+ },
+ },
+};
+
+sub private {
+ return $defaultData;
+}
+
+sub options {
+ return {
+ type => { optional => 0 },
+ ruleid => { optional => 0 },
+ comment => { optional => 1 },
+ };
+};
+
+sub decode_value {
+ my ($class, $type, $key, $value) = @_;
+
+ if ($key eq 'comment') {
+ return PVE::Tools::decode_text($value);
+ }
+
+ my $plugin = __PACKAGE__->lookup($type);
+ return $plugin->decode_value($type, $key, $value);
+}
+
+sub encode_value {
+ my ($class, $type, $key, $value) = @_;
+
+ if ($key eq 'comment') {
+ return PVE::Tools::encode_text($value);
+ }
+
+ my $plugin = __PACKAGE__->lookup($type);
+ return $plugin->encode_value($type, $key, $value);
+}
+
+sub parse_section_header {
+ my ($class, $line) = @_;
+
+ if ($line =~ m/^(\S+):\s*(\S+)\s*$/) {
+ my ($type, $ruleid) = (lc($1), $2);
+ my $errmsg = undef; # set if you want to skip whole section
+ eval { PVE::JSONSchema::pve_verify_configid($ruleid); };
+ $errmsg = $@ if $@;
+ my $config = {}; # to return additional attributes
+ return ($type, $ruleid, $errmsg, $config);
+ }
+ return undef;
+}
+
+sub foreach_service_rule {
+ my ($rules, $func, $opts) = @_;
+
+ my $sid = $opts->{sid};
+ my $type = $opts->{type};
+
+ my @ruleids = sort {
+ $rules->{order}->{$a} <=> $rules->{order}->{$b}
+ } keys %{$rules->{ids}};
+
+ for my $ruleid (@ruleids) {
+ my $rule = $rules->{ids}->{$ruleid};
+
+ next if !$rule; # invalid rules are kept undef in section config, delete them
+ next if $type && $rule->{type} ne $type;
+ next if $sid && !defined($rule->{services}->{$sid});
+
+ $func->($rule, $ruleid);
+ }
+}
+
+sub canonicalize {
+ my ($class, $rules, $groups, $services) = @_;
+
+ die "implement in subclass";
+}
+
+sub are_satisfiable {
+ my ($class, $rules, $groups, $services) = @_;
+
+ die "implement in subclass";
+}
+
+sub checked_config {
+ my ($rules, $groups, $services) = @_;
+
+ my $types = __PACKAGE__->lookup_types();
+
+ for my $type (@$types) {
+ my $plugin = __PACKAGE__->lookup($type);
+
+ $plugin->canonicalize($rules, $groups, $services);
+ }
+}
+
+1;
diff --git a/src/PVE/HA/Tools.pm b/src/PVE/HA/Tools.pm
index fc3282c..35107c9 100644
--- a/src/PVE/HA/Tools.pm
+++ b/src/PVE/HA/Tools.pm
@@ -92,6 +92,11 @@ PVE::JSONSchema::register_standard_option('pve-ha-group-id', {
type => 'string', format => 'pve-configid',
});
+PVE::JSONSchema::register_standard_option('pve-ha-rule-id', {
+ description => "The HA rule identifier.",
+ type => 'string', format => 'pve-configid',
+});
+
sub read_json_from_file {
my ($filename, $default) = @_;
--
2.39.5
More information about the pve-devel
mailing list