public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: "Daniel Kral" <d.kral@proxmox.com>
To: "Fiona Ebner" <f.ebner@proxmox.com>,
	"Proxmox VE development discussion" <pve-devel@lists.proxmox.com>
Subject: Re: [pve-devel] [RFC PATCH ha-manager 2/2] rules: node affinity: implement negative node affinity rules
Date: Wed, 25 Feb 2026 09:32:59 +0100	[thread overview]
Message-ID: <DGNWJN8ND92A.3KNNXPRSUF75P@proxmox.com> (raw)
In-Reply-To: <4e2babbe-011d-4d08-bd3e-e618f5ed21fd@proxmox.com>

Thanks for the review and testing! Will send a v2 with the changes and
the ui patches as well.

On Tue Feb 24, 2026 at 1:22 PM CET, Fiona Ebner wrote:
> Am 19.12.25 um 2:36 PM schrieb Daniel Kral:
>> Extend the existing node affinity rules plugin to allow users to specify
>> negative node affinity constraints, which specify the nodes where HA
>> resources SHOULD NOT/MUST NOT be placed.
>> 
>> Negative node affinity rules are internally represented as positive node
>> affinity rules, where the positive node affinity rules' nodes set is the
>> set complement of the negative node affinity rules' node set. As this is
>> semantically equivalent, this allows no change in the apply logic.
>
> Nit: 'allows making no change'

Ack!

>
>> As node priority groups do only hold semantic value for positive node
>> affinity rules, add all resulting nodes to the default priority group.
>> 
>> Signed-off-by: Daniel Kral <d.kral@proxmox.com>
>
> [I] root@pve9a1 ~# pvesh create /cluster/ha/rules/ --rule ha-rule-new
> --resources ct:105 --type node-affinity --affinity negative --nodes
> pve9a1:1,pve9a2:2
>
> This currently goes through, but should be rejected, indicating that
> node priorities may not be specified with negative affinity.
>
> Two other smaller comments below, otherwise it looks good to me.

Right, those should be rejected entirely, ack!

>

[ snip ]

>> diff --git a/src/PVE/HA/Rules.pm b/src/PVE/HA/Rules.pm
>> index c4a2ccea..7f9f428d 100644
>> --- a/src/PVE/HA/Rules.pm
>> +++ b/src/PVE/HA/Rules.pm
>> @@ -459,6 +459,8 @@ sub transform {
>>          for my $transform ($transformdef->{$type}->@*) {
>>              my $global_args = $class->get_check_arguments($rules);
>>  
>> +            $global_args->{nodes} = $nodes;
>
> Maybe 'cluster-nodes' as the key to be more explicit?

Good idea, I'll do that for the v2!

>
>> +
>>              $transform->($rules, $global_args);
>>          }
>>      }
>> diff --git a/src/PVE/HA/Rules/NodeAffinity.pm b/src/PVE/HA/Rules/NodeAffinity.pm
>> index 1f15ae2d..cdf67a55 100644

[ snip ]

>> @@ -256,6 +274,43 @@ __PACKAGE__->register_check(
>>      },
>>  );
>>  
>> +=head1 NODE AFFINITY RULE TRANSFORMATION HELPERS
>> +
>> +=cut
>> +
>> +=head3 invert_negative_node_affinity_rules($rules, $node_affinity_rules, $nodes)
>> +
>> +Modifies C<$rules> such that all negative node affinity rules, defined in
>> +C<$node_affinity_rules>, are transformed to positive node affinity rules, where
>> +the nodes set is the complement of the negative node affinity rules' nodes set.
>> +
>> +=cut
>> +
>> +sub invert_negative_node_affinity_rules {
>> +    my ($rules, $node_affinity_rules, $nodes) = @_;
>> +
>> +    my $cluster_nodes = { map { $_ => 1 } @$nodes };
>> +
>> +    while (my ($node_affinity_id, $node_affinity_rule) = each %$node_affinity_rules) {
>> +        next if $node_affinity_rule->{affinity} ne 'negative';
>> +
>> +        my $positive_nodes = { map { $_ => 1 } keys $node_affinity_rule->{nodes}->%* };
>
> I'm confused by the variable name. There is negative affinity towards
> these nodes, so why $positive_nodes?

Right, I'm sorry, this should be $negative_nodes instead, this slipped
right past me. Will change the name in a v2!

If it makes things more clearer, $new_nodes could then take the name of
$positive_nodes.

>
>> +        my $new_nodes = set_difference($cluster_nodes, $positive_nodes);
>> +        $new_nodes->{$_} = { priority => 0 } for keys %$new_nodes;
>> +
>> +        $rules->{ids}->{$node_affinity_id}->{affinity} = 'positive';
>> +        $rules->{ids}->{$node_affinity_id}->{nodes} = $new_nodes;
>> +    }
>> +}
>> +
>> +__PACKAGE__->register_transform(sub {
>> +    my ($rules, $args) = @_;
>> +
>> +    invert_negative_node_affinity_rules(
>> +        $rules, $args->{node_affinity_rules}, $args->{nodes},
>> +    );
>> +});
>> +
>>  =head1 NODE AFFINITY RULE HELPERS
>>  
>>  =cut





  reply	other threads:[~2026-02-25  8:32 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-12-19 13:35 [pve-devel] [RFC PATCH-SERIES ha-manager 0/2] Negative Node Affinity Rules Daniel Kral
2025-12-19 13:35 ` [pve-devel] [RFC PATCH ha-manager 1/2] rules: node affinity: add affinity property to node affinity rules Daniel Kral
2026-02-24 12:22   ` Fiona Ebner
2025-12-19 13:35 ` [pve-devel] [RFC PATCH ha-manager 2/2] rules: node affinity: implement negative " Daniel Kral
2026-02-24 12:22   ` Fiona Ebner
2026-02-25  8:32     ` Daniel Kral [this message]
2026-02-24 12:22 ` [pve-devel] [RFC PATCH-SERIES ha-manager 0/2] Negative Node Affinity Rules Fiona Ebner
2026-02-25  8:46   ` Daniel Kral
2026-02-25  8:58     ` Fiona Ebner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=DGNWJN8ND92A.3KNNXPRSUF75P@proxmox.com \
    --to=d.kral@proxmox.com \
    --cc=f.ebner@proxmox.com \
    --cc=pve-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal