The node affinity and positive resource affinity rule subset is checked
whether the HA resources in a positive resource affinity rule are in
more than one node affinity rule in total.

This check has the assumption that each positive resource affinity
rule's resource set is disjoint from each other, but this is only done
in the later transformation stage when positive resource affinity with
overlapping HA resources in them are merged to one rule.

For example, the following inconsistent rules are not pruned:

- positive resource affinity rule between vm:101 and vm:102
- positive resource affinity rule between vm:102 and vm:103
- node affinity rule for vm:101 on node1
- node affinity rule for vm:103 on node3

Therefore build the same disjoint positive resource affinity resource
sets as the merge_connected_positive_resource_affinity_rules(...)
subroutine, so that the inconsistency check has the necessary
information in advance.

Fixes: c48d9e66 ("rules: restrict inter-plugin resource references to simple 
cases")
Signed-off-by: Daniel Kral <d.k...@proxmox.com>
---
 src/PVE/HA/Rules.pm                           | 10 +++++++---
 ...onsistent-node-resource-affinity-rules.cfg | 19 +++++++++++++++++++
 ...nt-node-resource-affinity-rules.cfg.expect |  6 +++++-
 3 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/src/PVE/HA/Rules.pm b/src/PVE/HA/Rules.pm
index 323ad038..e13769a1 100644
--- a/src/PVE/HA/Rules.pm
+++ b/src/PVE/HA/Rules.pm
@@ -8,6 +8,7 @@ use PVE::Tools;
 
 use PVE::HA::HashTools qw(set_intersect set_union sets_are_disjoint);
 use PVE::HA::Tools;
+use PVE::HA::Rules::Helpers;
 
 use base qw(PVE::SectionConfig);
 
@@ -580,8 +581,11 @@ sub 
check_single_node_affinity_per_positive_resource_affinity_rule {
 
     my @conflicts = ();
 
-    while (my ($positiveid, $positive_rule) = each %$positive_rules) {
-        my $positive_resources = $positive_rule->{resources};
+    my @disjoint_positive_rules =
+        
PVE::HA::Rules::Helpers::find_disjoint_rules_resource_sets($positive_rules);
+
+    for my $entry (@disjoint_positive_rules) {
+        my $positive_resources = $entry->{resources};
         my @paired_node_affinity_rules = ();
 
         while (my ($node_affinity_id, $node_affinity_rule) = each 
%$node_affinity_rules) {
@@ -590,7 +594,7 @@ sub 
check_single_node_affinity_per_positive_resource_affinity_rule {
             push @paired_node_affinity_rules, $node_affinity_id;
         }
         if (@paired_node_affinity_rules > 1) {
-            push @conflicts, ['positive', $positiveid];
+            push @conflicts, ['positive', $_] for $entry->{ruleids}->@*;
             push @conflicts, ['node-affinity', $_] for 
@paired_node_affinity_rules;
         }
     }
diff --git a/src/test/rules_cfgs/inconsistent-node-resource-affinity-rules.cfg 
b/src/test/rules_cfgs/inconsistent-node-resource-affinity-rules.cfg
index 88e6dd0e..52402cd9 100644
--- a/src/test/rules_cfgs/inconsistent-node-resource-affinity-rules.cfg
+++ b/src/test/rules_cfgs/inconsistent-node-resource-affinity-rules.cfg
@@ -52,3 +52,22 @@ node-affinity: vm402-must-be-on-node1
 resource-affinity: vm401-vm402-must-be-kept-separate
        resources vm:401,vm:402
        affinity negative
+
+# Case 5: Remove positive resource affinity rules, which have overlapping HA 
resources, and are restricted with two different node affinity rules.
+node-affinity: vm501-must-be-on-node1
+       resources vm:501
+       nodes node1
+       strict 1
+
+node-affinity: vm503-must-be-on-node2
+       resources vm:503
+       nodes node2
+       strict 1
+
+resource-affinity: vm501-vm502-must-be-kept-together
+       resources vm:501,vm:502
+       affinity positive
+
+resource-affinity: vm502-vm503-must-be-kept-together
+       resources vm:502,vm:503
+       affinity positive
diff --git 
a/src/test/rules_cfgs/inconsistent-node-resource-affinity-rules.cfg.expect 
b/src/test/rules_cfgs/inconsistent-node-resource-affinity-rules.cfg.expect
index e12242ab..80222c86 100644
--- a/src/test/rules_cfgs/inconsistent-node-resource-affinity-rules.cfg.expect
+++ b/src/test/rules_cfgs/inconsistent-node-resource-affinity-rules.cfg.expect
@@ -5,9 +5,13 @@ Drop rule 'vm301-vm302-must-be-kept-together', because 
resources are in multiple
 Drop rule 'vm401-must-be-on-node1', because at least one resource is in a 
negative resource affinity rule and this rule would restrict these to less 
nodes than available to the resources.
 Drop rule 'vm401-vm402-must-be-kept-separate', because two or more resources 
are restricted to less nodes than available to the resources.
 Drop rule 'vm402-must-be-on-node1', because at least one resource is in a 
negative resource affinity rule and this rule would restrict these to less 
nodes than available to the resources.
+Drop rule 'vm501-must-be-on-node1', because at least one resource is in a 
positive resource affinity rule and there are other resources in at least one 
other node affinity rule already.
+Drop rule 'vm501-vm502-must-be-kept-together', because resources are in 
multiple node affinity rules.
+Drop rule 'vm502-vm503-must-be-kept-together', because resources are in 
multiple node affinity rules.
+Drop rule 'vm503-must-be-on-node2', because at least one resource is in a 
positive resource affinity rule and there are other resources in at least one 
other node affinity rule already.
 --- Config ---
 $VAR1 = {
-          'digest' => 'a5d782a442bbe3bf3a4d088db82a575b382a53fe',
+          'digest' => '00a70f4c2bdd41aed16b6e5b9860cd9fb7f0f098',
           'ids' => {
                      'vm101-vm102-must-be-kept-together' => {
                                                               'affinity' => 
'positive',
-- 
2.47.2



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to