[pve-devel] [PATCH ha-manager v3 05/15] config, env, hw: add rules read and parse methods

Daniel Kral d.kral at proxmox.com
Fri Jul 4 20:16:45 CEST 2025


Adds methods to the HA environment to read and write the rules
configuration file for the different environment implementations.

The HA Rules are initialized with property isolation since it is
expected that other rule types will use similar property names with
different semantic meanings and/or possible values.

Signed-off-by: Daniel Kral <d.kral at proxmox.com>
---
 src/PVE/HA/Config.pm       | 30 ++++++++++++++++++++++++++++++
 src/PVE/HA/Env.pm          |  6 ++++++
 src/PVE/HA/Env/PVE2.pm     | 12 ++++++++++++
 src/PVE/HA/Sim/Env.pm      | 14 ++++++++++++++
 src/PVE/HA/Sim/Hardware.pm | 21 +++++++++++++++++++++
 5 files changed, 83 insertions(+)

diff --git a/src/PVE/HA/Config.pm b/src/PVE/HA/Config.pm
index ec9360e..012ae16 100644
--- a/src/PVE/HA/Config.pm
+++ b/src/PVE/HA/Config.pm
@@ -7,12 +7,14 @@ use JSON;
 
 use PVE::HA::Tools;
 use PVE::HA::Groups;
+use PVE::HA::Rules;
 use PVE::Cluster qw(cfs_register_file cfs_read_file cfs_write_file cfs_lock_file);
 use PVE::HA::Resources;
 
 my $manager_status_filename = "ha/manager_status";
 my $ha_groups_config = "ha/groups.cfg";
 my $ha_resources_config = "ha/resources.cfg";
+my $ha_rules_config = "ha/rules.cfg";
 my $crm_commands_filename = "ha/crm_commands";
 my $ha_fence_config = "ha/fence.cfg";
 
@@ -31,6 +33,11 @@ cfs_register_file(
     sub { PVE::HA::Resources->parse_config(@_); },
     sub { PVE::HA::Resources->write_config(@_); },
 );
+cfs_register_file(
+    $ha_rules_config,
+    sub { PVE::HA::Rules->parse_config(@_); },
+    sub { PVE::HA::Rules->write_config(@_); },
+);
 cfs_register_file($manager_status_filename, \&json_reader, \&json_writer);
 cfs_register_file(
     $ha_fence_config,
@@ -197,6 +204,29 @@ sub parse_sid {
     return wantarray ? ($sid, $type, $name) : $sid;
 }
 
+sub read_rules_config {
+
+    return cfs_read_file($ha_rules_config);
+}
+
+sub read_and_check_rules_config {
+
+    my $rules = cfs_read_file($ha_rules_config);
+
+    # set optional rule parameter's default values
+    for my $rule (values %{ $rules->{ids} }) {
+        PVE::HA::Rules->set_rule_defaults($rule);
+    }
+
+    return $rules;
+}
+
+sub write_rules_config {
+    my ($cfg) = @_;
+
+    cfs_write_file($ha_rules_config, $cfg);
+}
+
 sub read_group_config {
 
     return cfs_read_file($ha_groups_config);
diff --git a/src/PVE/HA/Env.pm b/src/PVE/HA/Env.pm
index 285e440..5cee7b3 100644
--- a/src/PVE/HA/Env.pm
+++ b/src/PVE/HA/Env.pm
@@ -131,6 +131,12 @@ sub steal_service {
     return $self->{plug}->steal_service($sid, $current_node, $new_node);
 }
 
+sub read_rules_config {
+    my ($self) = @_;
+
+    return $self->{plug}->read_rules_config();
+}
+
 sub read_group_config {
     my ($self) = @_;
 
diff --git a/src/PVE/HA/Env/PVE2.pm b/src/PVE/HA/Env/PVE2.pm
index b709f30..58fd36e 100644
--- a/src/PVE/HA/Env/PVE2.pm
+++ b/src/PVE/HA/Env/PVE2.pm
@@ -22,12 +22,18 @@ use PVE::HA::FenceConfig;
 use PVE::HA::Resources;
 use PVE::HA::Resources::PVEVM;
 use PVE::HA::Resources::PVECT;
+use PVE::HA::Rules;
+use PVE::HA::Rules::NodeAffinity;
 
 PVE::HA::Resources::PVEVM->register();
 PVE::HA::Resources::PVECT->register();
 
 PVE::HA::Resources->init();
 
+PVE::HA::Rules::NodeAffinity->register();
+
+PVE::HA::Rules->init(property_isolation => 1);
+
 my $lockdir = "/etc/pve/priv/lock";
 
 sub new {
@@ -189,6 +195,12 @@ sub steal_service {
     $self->cluster_state_update();
 }
 
+sub read_rules_config {
+    my ($self) = @_;
+
+    return PVE::HA::Config::read_and_check_rules_config();
+}
+
 sub read_group_config {
     my ($self) = @_;
 
diff --git a/src/PVE/HA/Sim/Env.pm b/src/PVE/HA/Sim/Env.pm
index d892a00..bb76b7f 100644
--- a/src/PVE/HA/Sim/Env.pm
+++ b/src/PVE/HA/Sim/Env.pm
@@ -10,6 +10,8 @@ use Fcntl qw(:DEFAULT :flock);
 use PVE::HA::Tools;
 use PVE::HA::Env;
 use PVE::HA::Resources;
+use PVE::HA::Rules;
+use PVE::HA::Rules::NodeAffinity;
 use PVE::HA::Sim::Resources::VirtVM;
 use PVE::HA::Sim::Resources::VirtCT;
 use PVE::HA::Sim::Resources::VirtFail;
@@ -20,6 +22,10 @@ PVE::HA::Sim::Resources::VirtFail->register();
 
 PVE::HA::Resources->init();
 
+PVE::HA::Rules::NodeAffinity->register();
+
+PVE::HA::Rules->init(property_isolation => 1);
+
 sub new {
     my ($this, $nodename, $hardware, $log_id) = @_;
 
@@ -245,6 +251,14 @@ sub exec_fence_agent {
     return $self->{hardware}->exec_fence_agent($agent, $node, @param);
 }
 
+sub read_rules_config {
+    my ($self) = @_;
+
+    $assert_cfs_can_rw->($self);
+
+    return $self->{hardware}->read_rules_config();
+}
+
 sub read_group_config {
     my ($self) = @_;
 
diff --git a/src/PVE/HA/Sim/Hardware.pm b/src/PVE/HA/Sim/Hardware.pm
index 576527d..89dbdfa 100644
--- a/src/PVE/HA/Sim/Hardware.pm
+++ b/src/PVE/HA/Sim/Hardware.pm
@@ -28,6 +28,7 @@ my $watchdog_timeout = 60;
 # $testdir/cmdlist                    Command list for simulation
 # $testdir/hardware_status            Hardware description (number of nodes, ...)
 # $testdir/manager_status             CRM status (start with {})
+# $testdir/rules_config               Contraints / Rules configuration
 # $testdir/service_config             Service configuration
 # $testdir/static_service_stats       Static service usage information (cpu, memory)
 # $testdir/groups                     HA groups configuration
@@ -319,6 +320,22 @@ sub read_crm_commands {
     return $self->global_lock($code);
 }
 
+sub read_rules_config {
+    my ($self) = @_;
+
+    my $filename = "$self->{statusdir}/rules_config";
+    my $raw = '';
+    $raw = PVE::Tools::file_get_contents($filename) if -f $filename;
+    my $rules = PVE::HA::Rules->parse_config($filename, $raw);
+
+    # set optional rule parameter's default values
+    for my $rule (values %{ $rules->{ids} }) {
+        PVE::HA::Rules->set_rule_defaults($rule);
+    }
+
+    return $rules;
+}
+
 sub read_group_config {
     my ($self) = @_;
 
@@ -391,6 +408,10 @@ sub new {
     # copy initial configuartion
     copy("$testdir/manager_status", "$statusdir/manager_status"); # optional
 
+    if (-f "$testdir/rules_config") {
+        copy("$testdir/rules_config", "$statusdir/rules_config");
+    }
+
     if (-f "$testdir/groups") {
         copy("$testdir/groups", "$statusdir/groups");
     } else {
-- 
2.39.5





More information about the pve-devel mailing list