From: "Daniel Kral" <d.kral@proxmox.com>
To: "David Riley" <d.riley@proxmox.com>, <pve-devel@lists.proxmox.com>
Subject: Re: [PATCH manager v2 07/12] ui: ha: node affinity: allow setting affinity for node affinity rules
Date: Tue, 14 Jul 2026 10:39:49 +0200 [thread overview]
Message-ID: <DJY5QLZ5X8GV.1OBLEDMFAX4B2@proxmox.com> (raw)
In-Reply-To: <9d41e54e-4e67-46c7-9df5-90f3aa733eb4@proxmox.com>
On Mon Jul 13, 2026 at 2:43 PM CEST, David Riley wrote:
> Thanks for the patch.
> comments inline.
>
> On 6/2/26 12:02 PM, Daniel Kral wrote:
[ snip ]
>> @@ -56,6 +66,14 @@ Ext.define('PVE.forms.NodePrioritySelector', {
>> minValue: 0,
>> maxValue: 1000,
>> isFormField: false,
>> + bind: {
>> + hidden: '{!showNodePriority}',
>> + disabled: '{!showNodePriority}',
>
> Currently the priority value is not saved/sent to the backend when
> submitting the form. It's always undefined.
> Could it be that you are missing a binding here?
> value: '{record.priority}',
>
> I think that is because you removed the change listener from the
> 'xtype: 'proxmoxintegerfield' (Priority) in Patch 6.
>
Very good catch, thanks! Yeah, I forgot the change listener to add the
priority field to each record as it is changed.
>> + },
>> + },
>> + bind: {
>> + hidden: '{!showNodePriority}',
>> + disabled: '{!showNodePriority}',
>> },
>> },
>> ],
>> @@ -74,6 +92,39 @@ Ext.define('PVE.forms.NodePrioritySelector', {
>> },
>> },
>>
>> + invertCheckboxSelection: function () {
>> + let me = this;
>> +
>> + let sm = me.getSelectionModel();
>> +
>> + let allNodeModels = new Set(sm.getStore().getData().items ?? []);
>
> nit: Would be better to use .getStore().getRange() [0] here instead of accessing the private
> .items field via the collection [1].
> Since getRange() always returns an array you can also remove nullish coalescing
> operator here as well.
>
Nice, will use it in the next revision!
> [0] https://docs.sencha.com/extjs/7.0.0/modern/Ext.data.Store.html#method-getRange
> [1] https://docs.sencha.com/extjs/7.0.0/modern/Ext.util.Collection.html#property-items
>
>> + let selectedNodeModels = new Set(sm.getSelection() ?? []);
>
> nit: getSelection() should always return an array so '?? []' should not be needed
> here as well [2].
>
> [2] https://docs.sencha.com/extjs/7.0.0/classic/Ext.selection.Model.html#method-getSelection
>
ACK here as well
>> +
>> + if (!allNodeModels.size || !selectedNodeModels.size) {
>> + return;
>> + }
>> +
>> + sm.deselectAll();
>> + sm.select([...allNodeModels.difference(selectedNodeModels)]);
>> + },
>> +
>> + applyUseNodePriority: function (newValue) {
>> + let me = this;
>> +
>> + let oldValue = me.getViewModel().get('showNodePriority');
>> +
>> + if (newValue !== oldValue) {
>> + me.getViewModel().set('showNodePriority', newValue);
>> +
>> + // Prevent inverting the selection during component initialization
>> + if (oldValue !== null) {
>
> nit: Using if (oldValue != null) here is would be safer because loose inequality catches
> both null and undefined. This prevents potential initialization failures if the ViewModel's
> default behavior ever changes. Currently you set it to null.
>
Seems good to me as well, thanks!
>> + me.invertCheckboxSelection();
>> + }
>> + }
>> +
>> + return newValue;
>> + },
>> +
>> getSubmitData: function () {
>> let me = this;
>> let res = {};
>> @@ -91,7 +142,15 @@ Ext.define('PVE.forms.NodePrioritySelector', {
>> let sm = me.getSelectionModel();
>> let selectedNodeModels = sm.getSelection() ?? [];
>> let nodes = selectedNodeModels
>> - .map(({ data }) => data.node + (data.priority ? `:${data.priority}` : ''))
>> + .map(({ data }) => {
>> + let nodeEntry = data.node;
>> +
>> + if (me.useNodePriority && data.priority) {
>> + nodeEntry += `:${data.priority}`;
>> + }
>> +
>> + return nodeEntry;
>> + })
>> .join(',');
>>
>> return nodes;
>> diff --git a/www/manager6/ha/rules/NodeAffinityRuleEdit.js b/www/manager6/ha/rules/NodeAffinityRuleEdit.js
>> index 77da18b1..aecaa276 100644
>> --- a/www/manager6/ha/rules/NodeAffinityRuleEdit.js
>> +++ b/www/manager6/ha/rules/NodeAffinityRuleEdit.js
>> @@ -1,6 +1,15 @@
>> Ext.define('PVE.ha.rules.NodeAffinityInputPanel', {
>> extend: 'PVE.ha.RuleInputPanel',
>>
>> + viewModel: {
>> + data: {
>> + affinity: 'positive',
>> + },
>> + formulas: {
>> + isPositiveNodeAffinity: (get) => get('affinity') === 'positive',
>> + },
>> + },
>> +
>> initComponent: function () {
>> let me = this;
>>
>> @@ -18,6 +27,19 @@ Ext.define('PVE.ha.rules.NodeAffinityInputPanel', {
>> uncheckedValue: 0,
>> defaultValue: 0,
>> },
>> + {
>> + xtype: 'proxmoxKVComboBox',
>> + name: 'affinity',
>> + fieldLabel: gettext('Affinity'),
>> + allowBlank: false,
>> + comboItems: [
>> + ['positive', gettext('Prefer Nodes')],
>> + ['negative', gettext('Avoid Nodes')],
>
> The documentation creates a link between the meaning of 'negative' and 'Avoid Nodes'
> but it might be nice to have this link in the WebUI as well because in the CLI one has
> to know what negative and what positive means.
> Example:
> # ha-manager rules add node-affinity ha-rule-negative \
> --affinity negative --resources ct:200,vm:300 --nodes node3
>
> but no hard feelings as this is well documented in Patch 12/12.
> It might be sufficient to introduce a tooltip for this.
>
> Especially because in the grid it shows up as 'positive' but opening the edit form switches
> over to 'Prefer Nodes'. It might be worth adding a renderer to the affinity column so the
> grid displays 'Prefer Nodes' / 'Avoid Nodes' to match the form.
>
Right, I thought about it as well before, but didn't go for it in the
end. I'll do it now though and will slip in a preceding patch which does
the same for the resource affinity rules to be consistent.
>> + ],
>> + bind: {
>> + value: '{affinity}',
>> + },
>> + },
>> ];
>>
>> me.columnB = [
>> @@ -25,6 +47,9 @@ Ext.define('PVE.ha.rules.NodeAffinityInputPanel', {
>> xtype: 'pveNodePrioritySelector',
>> name: 'nodes',
>> allowBlank: false,
>> + bind: {
>> + useNodePriority: '{isPositiveNodeAffinity}',
>> + },
>> },
>> ];
>>
>> diff --git a/www/manager6/ha/rules/NodeAffinityRules.js b/www/manager6/ha/rules/NodeAffinityRules.js
>> index 6fc42799..089dece8 100644
>> --- a/www/manager6/ha/rules/NodeAffinityRules.js
>> +++ b/www/manager6/ha/rules/NodeAffinityRules.js
>> @@ -11,6 +11,11 @@ Ext.define('PVE.ha.NodeAffinityRulesView', {
>> stateId: 'grid-ha-node-affinity-rules',
>>
>> columns: [
>> + {
>> + header: gettext('Affinity'),
>> + width: 75,
>> + dataIndex: 'affinity',
>> + },
>> {
>> header: gettext('Strict'),
>> width: 75,
next prev parent reply other threads:[~2026-07-14 8:39 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-02 10:01 [PATCH-SERIES docs/ha-manager/manager v2 00/12] Negative Node Affinity Rules Daniel Kral
2026-06-02 10:01 ` [PATCH ha-manager v2 01/12] rules: node affinity: add affinity property to node affinity rules Daniel Kral
2026-06-02 10:01 ` [PATCH ha-manager v2 02/12] rules: rename ambiguous argument nodes to cluster nodes Daniel Kral
2026-07-13 12:41 ` David Riley
2026-06-02 10:01 ` [PATCH ha-manager v2 03/12] rules: node affinity: implement negative node affinity rules Daniel Kral
2026-07-13 12:43 ` David Riley
2026-07-14 7:36 ` Daniel Kral
2026-06-02 10:01 ` [PATCH manager v2 04/12] ui: ha: node affinity: handle non-existent nodes Daniel Kral
2026-06-02 10:01 ` [PATCH manager v2 05/12] ui: ha: node affinity: do update node selection all at once Daniel Kral
2026-06-02 10:01 ` [PATCH manager v2 06/12] ui: ha: node affinity: move node priority selector into separate component Daniel Kral
2026-07-13 12:43 ` David Riley
2026-07-14 7:57 ` Daniel Kral
2026-07-14 8:51 ` David Riley
2026-06-02 10:01 ` [PATCH manager v2 07/12] ui: ha: node affinity: allow setting affinity for node affinity rules Daniel Kral
2026-07-13 12:43 ` David Riley
2026-07-14 8:39 ` Daniel Kral [this message]
2026-06-02 10:01 ` [PATCH manager v2 08/12] ui: ha: node affinity: do not send default node affinity rule values Daniel Kral
2026-07-13 12:43 ` David Riley
2026-06-02 10:01 ` [PATCH docs v2 09/12] ha-manager: rules: use the correct article for terms starting with HA Daniel Kral
2026-07-13 12:43 ` David Riley
2026-06-02 10:01 ` [PATCH docs v2 10/12] ha-manager: rules: improve resource affinity rule short description Daniel Kral
2026-07-13 12:44 ` David Riley
2026-06-02 10:01 ` [PATCH docs v2 11/12] ha-manager: rules: adapt rule configuration examples Daniel Kral
2026-07-13 12:44 ` David Riley
2026-06-02 10:01 ` [PATCH docs v2 12/12] ha-manager: rules: add negative node affinity rule descriptions Daniel Kral
2026-07-13 12:44 ` David Riley
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=DJY5QLZ5X8GV.1OBLEDMFAX4B2@proxmox.com \
--to=d.kral@proxmox.com \
--cc=d.riley@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