* [PATCH manager v2] ui: ha: add disarm/re-arm button
@ 2026-04-15 6:41 Dominik Rusovac
2026-04-15 7:34 ` Daniel Kral
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Dominik Rusovac @ 2026-04-15 6:41 UTC (permalink / raw)
To: pve-devel
The button to disarm HA in either of the resource modes ('freeze' or
'ignore') is disabled as long as HA is disarmed. Analogously, the button
to arm HA is disabled as long as HA is not disarmed.
The icons ('unlink' and 'link') are chosen to emphasize that "Disarm HA"
and "Arm HA" are complements. There may be more suitable pairs of icons
though.
Signed-off-by: Dominik Rusovac <d.rusovac@proxmox.com>
---
changes since v1:
* use camel case for function names
* choose clearer parameter: 'comp' -> 'menuItem'
* choose clearer function names:
- 'disarm' -> 'handleDisarmButton'
- 'rearm' -> 'handleArmButton'
* deduplicate translation keys
* use same translation keys as for menu items
* remove obsolete 'params'
* change button text "Re-arm HA" to "Arm HA"
* remove extra new-line
www/manager6/ha/Status.js | 104 ++++++++++++++++++++++++++++++++++
www/manager6/ha/StatusView.js | 8 +++
2 files changed, 112 insertions(+)
diff --git a/www/manager6/ha/Status.js b/www/manager6/ha/Status.js
index b0b0feb9..5c65d52d 100644
--- a/www/manager6/ha/Status.js
+++ b/www/manager6/ha/Status.js
@@ -8,6 +8,105 @@ Ext.define('PVE.ha.Status', {
align: 'stretch',
},
+ viewModel: {
+ data: {
+ haDisarmed: false,
+ },
+ },
+
+ controller: {
+ xclass: 'Ext.app.ViewController',
+
+ checkHaStatus: function (isDisarmed) {
+ let vm = this.getViewModel();
+ vm.set('haDisarmed', isDisarmed);
+ },
+
+ handleDisarmButton: function (menuItem) {
+ let me = this;
+ let view = me.getView();
+
+ Ext.Msg.confirm(
+ gettext('Confirm'),
+ Ext.String.format(
+ gettext("Are you sure you want to disarm HA with resource mode '{0}'?"),
+ menuItem.text,
+ ),
+ function (btn) {
+ if (btn !== 'yes') {
+ return;
+ }
+ Proxmox.Utils.API2Request({
+ url: '/cluster/ha/status/disarm-ha',
+ params: { 'resource-mode': menuItem.mode },
+ method: 'POST',
+ waitMsgTarget: view,
+ failure: (response) => Ext.Msg.alert(gettext('Error'), response.htmlStatus),
+ });
+ },
+ );
+ },
+
+ handleArmButton: function () {
+ let me = this;
+ let view = me.getView();
+
+ Ext.Msg.confirm(
+ gettext('Confirm'),
+ gettext('Are you sure you want to arm HA?'),
+ function (btn) {
+ if (btn !== 'yes') {
+ return;
+ }
+ Proxmox.Utils.API2Request({
+ url: '/cluster/ha/status/arm-ha',
+ method: 'POST',
+ waitMsgTarget: view,
+ failure: (response) => Ext.Msg.alert(gettext('Error'), response.htmlStatus),
+ });
+ },
+ );
+ },
+ },
+
+ dockedItems: [
+ {
+ xtype: 'toolbar',
+ dock: 'top',
+ items: [
+ {
+ text: gettext('Disarm HA'),
+ iconCls: 'fa fa-unlink',
+ bind: {
+ disabled: '{haDisarmed}',
+ },
+ menu: [
+ {
+ text: gettext('Freeze'),
+ iconCls: 'fa fa-snowflake-o',
+ mode: 'freeze',
+ handler: 'handleDisarmButton',
+ },
+ {
+ text: gettext('Ignore'),
+ iconCls: 'fa fa-eye-slash',
+ mode: 'ignore',
+ handler: 'handleDisarmButton',
+ },
+ ],
+ },
+ {
+ text: gettext('Arm HA'),
+ iconCls: 'fa fa-link',
+ bind: {
+ disabled: '{!haDisarmed}',
+ },
+ handler: 'handleArmButton',
+ },
+ ],
+ },
+ ],
+
initComponent: function () {
var me = this;
@@ -30,6 +129,11 @@ Ext.define('PVE.ha.Status', {
border: 0,
collapsible: true,
padding: '0 0 20 0',
+ listeners: {
+ hastatuschange: function (isDisarmed) {
+ me.getController().checkHaStatus(isDisarmed);
+ },
+ },
},
{
xtype: 'pveHAResourcesView',
diff --git a/www/manager6/ha/StatusView.js b/www/manager6/ha/StatusView.js
index bc2da71f..4cbe85a1 100644
--- a/www/manager6/ha/StatusView.js
+++ b/www/manager6/ha/StatusView.js
@@ -42,6 +42,13 @@ Ext.define(
},
});
+ me.rstore.on('load', function () {
+ let fencing = store.findRecord('type', 'fencing');
+ let disarmed = fencing && fencing.get('armed-state') === 'disarmed';
+
+ me.fireEvent('hastatuschange', disarmed);
+ });
+
Ext.apply(me, {
store: store,
stateful: false,
@@ -105,6 +112,7 @@ Ext.define(
return PVE.data.ResourceStore.guestName(vmid);
},
},
+ 'armed-state',
],
idProperty: 'id',
});
--
2.47.3
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH manager v2] ui: ha: add disarm/re-arm button 2026-04-15 6:41 [PATCH manager v2] ui: ha: add disarm/re-arm button Dominik Rusovac @ 2026-04-15 7:34 ` Daniel Kral 2026-04-15 12:32 ` Dominik Csapak 2026-04-16 11:21 ` Dominik Rusovac 2 siblings, 0 replies; 10+ messages in thread From: Daniel Kral @ 2026-04-15 7:34 UTC (permalink / raw) To: Dominik Rusovac, pve-devel On Wed Apr 15, 2026 at 8:41 AM CEST, Dominik Rusovac wrote: > The button to disarm HA in either of the resource modes ('freeze' or > 'ignore') is disabled as long as HA is disarmed. Analogously, the button > to arm HA is disabled as long as HA is not disarmed. > > The icons ('unlink' and 'link') are chosen to emphasize that "Disarm HA" > and "Arm HA" are complements. There may be more suitable pairs of icons > though. > > Signed-off-by: Dominik Rusovac <d.rusovac@proxmox.com> > --- > changes since v1: > * use camel case for function names > * choose clearer parameter: 'comp' -> 'menuItem' > * choose clearer function names: > - 'disarm' -> 'handleDisarmButton' > - 'rearm' -> 'handleArmButton' > * deduplicate translation keys > * use same translation keys as for menu items > * remove obsolete 'params' > * change button text "Re-arm HA" to "Arm HA" > * remove extra new-line Thanks for the swift v2! Tested in a 3-node cluster and a single node setup and also checked the error handling with some die's in the API handlers, looks good to me! Consider this as: Reviewed-by: Daniel Kral <d.kral@proxmox.com> Tested-by: Daniel Kral <d.kral@proxmox.com> ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH manager v2] ui: ha: add disarm/re-arm button 2026-04-15 6:41 [PATCH manager v2] ui: ha: add disarm/re-arm button Dominik Rusovac 2026-04-15 7:34 ` Daniel Kral @ 2026-04-15 12:32 ` Dominik Csapak 2026-04-15 13:32 ` Dominik Rusovac 2026-04-16 11:21 ` Dominik Rusovac 2 siblings, 1 reply; 10+ messages in thread From: Dominik Csapak @ 2026-04-15 12:32 UTC (permalink / raw) To: Dominik Rusovac, pve-devel what i miss with using these is some feedback when i activated them. This is probably more due to the backend decision, but when clicking arm/disarm, there is nothing happening in the gui at first, no spinning icon, no change in state.. I think there are a few possible solutions on this, but i'm not super deep in the ha stack, so sorry in advance if some can't work: * use a worker that waits for the change of the ha state, e.g. via polling. this could directly be shown in the gui * mark the requested state immediately somewhere and return it with the overall ha state, so we see in the gui what is happening * 'fake' the progress until we see a status change (i don't really like this, since it's prone to errors when e.g. one admin disarms, the other arms again, but the gui does not get an updated state in the meantime) other comments inline On 4/15/26 8:40 AM, Dominik Rusovac wrote: > The button to disarm HA in either of the resource modes ('freeze' or > 'ignore') is disabled as long as HA is disarmed. Analogously, the button > to arm HA is disabled as long as HA is not disarmed. > > The icons ('unlink' and 'link') are chosen to emphasize that "Disarm HA" > and "Arm HA" are complements. There may be more suitable pairs of icons > though. > > Signed-off-by: Dominik Rusovac <d.rusovac@proxmox.com> > --- > changes since v1: > * use camel case for function names > * choose clearer parameter: 'comp' -> 'menuItem' > * choose clearer function names: > - 'disarm' -> 'handleDisarmButton' > - 'rearm' -> 'handleArmButton' > * deduplicate translation keys > * use same translation keys as for menu items > * remove obsolete 'params' > * change button text "Re-arm HA" to "Arm HA" > * remove extra new-line > > www/manager6/ha/Status.js | 104 ++++++++++++++++++++++++++++++++++ > www/manager6/ha/StatusView.js | 8 +++ > 2 files changed, 112 insertions(+) > > diff --git a/www/manager6/ha/Status.js b/www/manager6/ha/Status.js > index b0b0feb9..5c65d52d 100644 > --- a/www/manager6/ha/Status.js > +++ b/www/manager6/ha/Status.js > @@ -8,6 +8,105 @@ Ext.define('PVE.ha.Status', { > align: 'stretch', > }, > > + viewModel: { > + data: { > + haDisarmed: false, > + }, > + }, > + > + controller: { > + xclass: 'Ext.app.ViewController', > + > + checkHaStatus: function (isDisarmed) { > + let vm = this.getViewModel(); > + vm.set('haDisarmed', isDisarmed); > + }, > + this method does not 'check' it 'sets' the HA status? IMHO a better name would be: setHaStatus or similar also, this is only used once, so it's probably better to just call the vm.set inline > + handleDisarmButton: function (menuItem) { > + let me = this; > + let view = me.getView(); > + > + Ext.Msg.confirm( > + gettext('Confirm'), > + Ext.String.format( > + gettext("Are you sure you want to disarm HA with resource mode '{0}'?"), > + menuItem.text, > + ), > + function (btn) { > + if (btn !== 'yes') { > + return; > + } > + Proxmox.Utils.API2Request({ > + url: '/cluster/ha/status/disarm-ha', > + params: { 'resource-mode': menuItem.mode }, > + method: 'POST', > + waitMsgTarget: view, > + failure: (response) => Ext.Msg.alert(gettext('Error'), response.htmlStatus), > + }); > + }, > + ); > + }, > + > + handleArmButton: function () { > + let me = this; > + let view = me.getView(); > + > + Ext.Msg.confirm( > + gettext('Confirm'), > + gettext('Are you sure you want to arm HA?'), > + function (btn) { > + if (btn !== 'yes') { > + return; > + } > + Proxmox.Utils.API2Request({ > + url: '/cluster/ha/status/arm-ha', > + method: 'POST', > + waitMsgTarget: view, > + failure: (response) => Ext.Msg.alert(gettext('Error'), response.htmlStatus), > + }); > + }, > + ); > + }, > + }, > + > + dockedItems: [ > + { > + xtype: 'toolbar', > + dock: 'top', > + items: [ it should be able to shorten that to just using 'tbar' tbar: [ { ... }, // button 1 { ... }, // button 2 ], > + { > + text: gettext('Disarm HA'), > + iconCls: 'fa fa-unlink', > + bind: { > + disabled: '{haDisarmed}', > + }, > + menu: [ > + { > + text: gettext('Freeze'), > + iconCls: 'fa fa-snowflake-o', > + mode: 'freeze', > + handler: 'handleDisarmButton', > + }, > + { > + text: gettext('Ignore'), > + iconCls: 'fa fa-eye-slash', > + mode: 'ignore', > + handler: 'handleDisarmButton', > + }, > + ], > + }, > + { > + text: gettext('Arm HA'), > + iconCls: 'fa fa-link', > + bind: { > + disabled: '{!haDisarmed}', > + }, > + handler: 'handleArmButton', > + }, > + ], i'm not totally against having two buttons here, but since there is always only one or the other active, wouldn't it make more sense to hide the button that can't do anything? (though i admit we do most often show the unusable buttons across our gui, so it's fine too) At least i would probably switch the position of these, since the more (for the lack of a better word) 'affirming' action is usually at the beginning (like 'add' or 'start') and the other options comes later (like 'remove' or 'shutdown') so | Arm | Disarm | reads more logical to me than | Disarm | Arm | > + }, > + ], > + > initComponent: function () { > var me = this; > > @@ -30,6 +129,11 @@ Ext.define('PVE.ha.Status', { > border: 0, > collapsible: true, > padding: '0 0 20 0', > + listeners: { > + hastatuschange: function (isDisarmed) { > + me.getController().checkHaStatus(isDisarmed); > + }, > + }, > }, > { > xtype: 'pveHAResourcesView', > diff --git a/www/manager6/ha/StatusView.js b/www/manager6/ha/StatusView.js > index bc2da71f..4cbe85a1 100644 > --- a/www/manager6/ha/StatusView.js > +++ b/www/manager6/ha/StatusView.js > @@ -42,6 +42,13 @@ Ext.define( > }, > }); > > + me.rstore.on('load', function () { > + let fencing = store.findRecord('type', 'fencing'); > + let disarmed = fencing && fencing.get('armed-state') === 'disarmed'; > + > + me.fireEvent('hastatuschange', disarmed); just a remark, not even a nit: the usual convention in extjs is that the first parameter of an event is the component itself, so it would usually be me.fireEvent('foo', me, <remaining arguments>); we (and extjs itself) don't always adhere to that, so it's fine here, but wanted to note it anyway > + }); > + > Ext.apply(me, { > store: store, > stateful: false, > @@ -105,6 +112,7 @@ Ext.define( > return PVE.data.ResourceStore.guestName(vmid); > }, > }, > + 'armed-state', > ], > idProperty: 'id', > }); ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH manager v2] ui: ha: add disarm/re-arm button 2026-04-15 12:32 ` Dominik Csapak @ 2026-04-15 13:32 ` Dominik Rusovac 2026-04-15 14:18 ` Dominik Csapak 2026-04-16 7:33 ` Daniel Kral 0 siblings, 2 replies; 10+ messages in thread From: Dominik Rusovac @ 2026-04-15 13:32 UTC (permalink / raw) To: Dominik Csapak, pve-devel thx for the comments! I will send a v3 On Wed Apr 15, 2026 at 2:32 PM CEST, Dominik Csapak wrote: > what i miss with using these is some feedback when i activated them. > > This is probably more due to the backend decision, but > when clicking arm/disarm, there is nothing happening in the gui at > first, no spinning icon, no change in state.. regarding feedback after activating either of them: one can see the Status changing in the Status panel, which exactly traces what's going on for every node, in particular it reveals the armed-state in the Status of fencing if that's not enough feedback, I'd look into other possible solutions in more detail > > I think there are a few possible solutions on this, but > i'm not super deep in the ha stack, so sorry in advance if > some can't work: > * use a worker that waits for the change of the ha state, e.g. > via polling. this could directly be shown in the gui > * mark the requested state immediately somewhere and return > it with the overall ha state, so we see in the gui what is happening > * 'fake' the progress until we see a status change > (i don't really like this, since it's prone to errors when e.g. > one admin disarms, the other arms again, but the gui does not > get an updated state in the meantime) > > > other comments inline > > On 4/15/26 8:40 AM, Dominik Rusovac wrote: >> The button to disarm HA in either of the resource modes ('freeze' or >> 'ignore') is disabled as long as HA is disarmed. Analogously, the button >> to arm HA is disabled as long as HA is not disarmed. >> >> The icons ('unlink' and 'link') are chosen to emphasize that "Disarm HA" >> and "Arm HA" are complements. There may be more suitable pairs of icons >> though. >> >> Signed-off-by: Dominik Rusovac <d.rusovac@proxmox.com> >> --- >> changes since v1: >> * use camel case for function names >> * choose clearer parameter: 'comp' -> 'menuItem' >> * choose clearer function names: >> - 'disarm' -> 'handleDisarmButton' >> - 'rearm' -> 'handleArmButton' >> * deduplicate translation keys >> * use same translation keys as for menu items >> * remove obsolete 'params' >> * change button text "Re-arm HA" to "Arm HA" >> * remove extra new-line >> >> www/manager6/ha/Status.js | 104 ++++++++++++++++++++++++++++++++++ >> www/manager6/ha/StatusView.js | 8 +++ >> 2 files changed, 112 insertions(+) >> [snip] >> + controller: { >> + xclass: 'Ext.app.ViewController', >> + >> + checkHaStatus: function (isDisarmed) { >> + let vm = this.getViewModel(); >> + vm.set('haDisarmed', isDisarmed); >> + }, >> + > > this method does not 'check' it 'sets' the HA status? > > IMHO a better name would be: > > setHaStatus > or similar > > > also, this is only used once, so it's probably better > to just call the vm.set inline > thx, I will inline it [snip] >> + >> + dockedItems: [ >> + { >> + xtype: 'toolbar', >> + dock: 'top', >> + items: [ > > it should be able to shorten that to just using 'tbar' > > tbar: [ > { ... }, // button 1 > { ... }, // button 2 > ], > indeed, thx, will use 'tbar' instead >> + { >> + text: gettext('Disarm HA'), >> + iconCls: 'fa fa-unlink', >> + bind: { >> + disabled: '{haDisarmed}', >> + }, >> + menu: [ >> + { >> + text: gettext('Freeze'), >> + iconCls: 'fa fa-snowflake-o', >> + mode: 'freeze', >> + handler: 'handleDisarmButton', >> + }, >> + { >> + text: gettext('Ignore'), >> + iconCls: 'fa fa-eye-slash', >> + mode: 'ignore', >> + handler: 'handleDisarmButton', >> + }, >> + ], >> + }, >> + { >> + text: gettext('Arm HA'), >> + iconCls: 'fa fa-link', >> + bind: { >> + disabled: '{!haDisarmed}', >> + }, >> + handler: 'handleArmButton', >> + }, >> + ], > > i'm not totally against having two buttons here, but since > there is always only one or the other active, wouldn't > it make more sense to hide the button that > can't do anything? (though i admit we do most often show the > unusable buttons across our gui, so it's fine too) > tbh, I just tried to adhere to what I found in other places of the gui if hiding the unusable button is more desirable, I can go for that option instead > At least i would probably switch the position of these, > since the more (for the lack of a better word) 'affirming' action > is usually at the beginning (like 'add' or 'start') and the other > options comes later (like 'remove' or 'shutdown') > > so > > | Arm | Disarm | > > reads more logical to me than > > | Disarm | Arm | > in retrospect, I think my reasoning behind this positioning was rather about the more 'obvious' or 'natural' action, that is: HA is from the get-go (and also usually) armed and can only be (re-)armed, once it's been disarmed - just like stopping something is only possible once this very something's started I see your reasoning though, and if we do not go for hiding either of the buttons, I do not mind changing the positioning >> + }, >> + ], >> + [snip] >> + me.rstore.on('load', function () { >> + let fencing = store.findRecord('type', 'fencing'); >> + let disarmed = fencing && fencing.get('armed-state') === 'disarmed'; >> + >> + me.fireEvent('hastatuschange', disarmed); > > just a remark, not even a nit: > > the usual convention in extjs is that the first parameter of an event is > the component itself, so it would usually be > > me.fireEvent('foo', me, <remaining arguments>); > > we (and extjs itself) don't always adhere to that, so it's fine > here, but wanted to note it anyway > thx for this informative remark [snip] ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH manager v2] ui: ha: add disarm/re-arm button 2026-04-15 13:32 ` Dominik Rusovac @ 2026-04-15 14:18 ` Dominik Csapak 2026-04-16 5:58 ` Dominik Rusovac 2026-04-16 7:33 ` Daniel Kral 1 sibling, 1 reply; 10+ messages in thread From: Dominik Csapak @ 2026-04-15 14:18 UTC (permalink / raw) To: Dominik Rusovac, pve-devel On 4/15/26 3:30 PM, Dominik Rusovac wrote: > thx for the comments! I will send a v3 > > On Wed Apr 15, 2026 at 2:32 PM CEST, Dominik Csapak wrote: >> what i miss with using these is some feedback when i activated them. >> >> This is probably more due to the backend decision, but >> when clicking arm/disarm, there is nothing happening in the gui at >> first, no spinning icon, no change in state.. > > regarding feedback after activating either of them: one can see the > Status changing in the Status panel, which exactly traces what's going > on for every node, in particular it reveals the armed-state in the > Status of fencing > > if that's not enough feedback, I'd look into other possible solutions in > more detail on my test machine, it multiple seconds from clicking ok to the status actually changing, so this might be confusing, especially if the cluster/connection is not the fastest and the updates take longer to arrive. > >> >> I think there are a few possible solutions on this, but >> i'm not super deep in the ha stack, so sorry in advance if >> some can't work: >> * use a worker that waits for the change of the ha state, e.g. >> via polling. this could directly be shown in the gui >> * mark the requested state immediately somewhere and return >> it with the overall ha state, so we see in the gui what is happening >> * 'fake' the progress until we see a status change >> (i don't really like this, since it's prone to errors when e.g. >> one admin disarms, the other arms again, but the gui does not >> get an updated state in the meantime) >> >> >> other comments inline >> >> On 4/15/26 8:40 AM, Dominik Rusovac wrote: >>> The button to disarm HA in either of the resource modes ('freeze' or >>> 'ignore') is disabled as long as HA is disarmed. Analogously, the button >>> to arm HA is disabled as long as HA is not disarmed. >>> >>> The icons ('unlink' and 'link') are chosen to emphasize that "Disarm HA" >>> and "Arm HA" are complements. There may be more suitable pairs of icons >>> though. >>> >>> Signed-off-by: Dominik Rusovac <d.rusovac@proxmox.com> >>> --- >>> changes since v1: >>> * use camel case for function names >>> * choose clearer parameter: 'comp' -> 'menuItem' >>> * choose clearer function names: >>> - 'disarm' -> 'handleDisarmButton' >>> - 'rearm' -> 'handleArmButton' >>> * deduplicate translation keys >>> * use same translation keys as for menu items >>> * remove obsolete 'params' >>> * change button text "Re-arm HA" to "Arm HA" >>> * remove extra new-line >>> >>> www/manager6/ha/Status.js | 104 ++++++++++++++++++++++++++++++++++ >>> www/manager6/ha/StatusView.js | 8 +++ >>> 2 files changed, 112 insertions(+) >>> > > [snip] > >>> + controller: { >>> + xclass: 'Ext.app.ViewController', >>> + >>> + checkHaStatus: function (isDisarmed) { >>> + let vm = this.getViewModel(); >>> + vm.set('haDisarmed', isDisarmed); >>> + }, >>> + >> >> this method does not 'check' it 'sets' the HA status? >> >> IMHO a better name would be: >> >> setHaStatus >> or similar >> >> >> also, this is only used once, so it's probably better >> to just call the vm.set inline >> > > thx, I will inline it > > [snip] > >>> + >>> + dockedItems: [ >>> + { >>> + xtype: 'toolbar', >>> + dock: 'top', >>> + items: [ >> >> it should be able to shorten that to just using 'tbar' >> >> tbar: [ >> { ... }, // button 1 >> { ... }, // button 2 >> ], >> > > indeed, thx, will use 'tbar' instead > >>> + { >>> + text: gettext('Disarm HA'), >>> + iconCls: 'fa fa-unlink', >>> + bind: { >>> + disabled: '{haDisarmed}', >>> + }, >>> + menu: [ >>> + { >>> + text: gettext('Freeze'), >>> + iconCls: 'fa fa-snowflake-o', >>> + mode: 'freeze', >>> + handler: 'handleDisarmButton', >>> + }, >>> + { >>> + text: gettext('Ignore'), >>> + iconCls: 'fa fa-eye-slash', >>> + mode: 'ignore', >>> + handler: 'handleDisarmButton', >>> + }, >>> + ], >>> + }, >>> + { >>> + text: gettext('Arm HA'), >>> + iconCls: 'fa fa-link', >>> + bind: { >>> + disabled: '{!haDisarmed}', >>> + }, >>> + handler: 'handleArmButton', >>> + }, >>> + ], >> >> i'm not totally against having two buttons here, but since >> there is always only one or the other active, wouldn't >> it make more sense to hide the button that >> can't do anything? (though i admit we do most often show the >> unusable buttons across our gui, so it's fine too) >> > > tbh, I just tried to adhere to what I found in other places of the gui > > if hiding the unusable button is more desirable, I can go for that > option instead > >> At least i would probably switch the position of these, >> since the more (for the lack of a better word) 'affirming' action >> is usually at the beginning (like 'add' or 'start') and the other >> options comes later (like 'remove' or 'shutdown') >> >> so >> >> | Arm | Disarm | >> >> reads more logical to me than >> >> | Disarm | Arm | >> > > in retrospect, I think my reasoning behind this positioning was rather > about the more 'obvious' or 'natural' action, that is: HA is > from the get-go (and also usually) armed and can only be (re-)armed, > once it's been disarmed - just like stopping something is only possible > once this very something's started > > I see your reasoning though, and if we do not go for hiding either of > the buttons, I do not mind changing the positioning > >>> + }, >>> + ], >>> + > > [snip] > >>> + me.rstore.on('load', function () { >>> + let fencing = store.findRecord('type', 'fencing'); >>> + let disarmed = fencing && fencing.get('armed-state') === 'disarmed'; >>> + >>> + me.fireEvent('hastatuschange', disarmed); >> >> just a remark, not even a nit: >> >> the usual convention in extjs is that the first parameter of an event is >> the component itself, so it would usually be >> >> me.fireEvent('foo', me, <remaining arguments>); >> >> we (and extjs itself) don't always adhere to that, so it's fine >> here, but wanted to note it anyway >> > > thx for this informative remark > > [snip] ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH manager v2] ui: ha: add disarm/re-arm button 2026-04-15 14:18 ` Dominik Csapak @ 2026-04-16 5:58 ` Dominik Rusovac 0 siblings, 0 replies; 10+ messages in thread From: Dominik Rusovac @ 2026-04-16 5:58 UTC (permalink / raw) To: Dominik Csapak, pve-devel On Wed Apr 15, 2026 at 4:18 PM CEST, Dominik Csapak wrote: > > > On 4/15/26 3:30 PM, Dominik Rusovac wrote: >> thx for the comments! I will send a v3 >> >> On Wed Apr 15, 2026 at 2:32 PM CEST, Dominik Csapak wrote: >>> what i miss with using these is some feedback when i activated them. >>> >>> This is probably more due to the backend decision, but >>> when clicking arm/disarm, there is nothing happening in the gui at >>> first, no spinning icon, no change in state.. >> >> regarding feedback after activating either of them: one can see the >> Status changing in the Status panel, which exactly traces what's going >> on for every node, in particular it reveals the armed-state in the >> Status of fencing >> >> if that's not enough feedback, I'd look into other possible solutions in >> more detail > > on my test machine, it multiple seconds from clicking ok to > the status actually changing, so this might be confusing, especially > if the cluster/connection is not the fastest and the updates > take longer to arrive. > ok, I see your point. I will try to come up with a solution >> >>> >>> I think there are a few possible solutions on this, but >>> i'm not super deep in the ha stack, so sorry in advance if >>> some can't work: >>> * use a worker that waits for the change of the ha state, e.g. >>> via polling. this could directly be shown in the gui >>> * mark the requested state immediately somewhere and return >>> it with the overall ha state, so we see in the gui what is happening >>> * 'fake' the progress until we see a status change >>> (i don't really like this, since it's prone to errors when e.g. >>> one admin disarms, the other arms again, but the gui does not >>> get an updated state in the meantime) >>> [snip] ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH manager v2] ui: ha: add disarm/re-arm button 2026-04-15 13:32 ` Dominik Rusovac 2026-04-15 14:18 ` Dominik Csapak @ 2026-04-16 7:33 ` Daniel Kral 2026-04-16 9:20 ` Thomas Lamprecht 1 sibling, 1 reply; 10+ messages in thread From: Daniel Kral @ 2026-04-16 7:33 UTC (permalink / raw) To: Dominik Rusovac, Dominik Csapak, pve-devel On Wed Apr 15, 2026 at 3:32 PM CEST, Dominik Rusovac wrote: > thx for the comments! I will send a v3 > > On Wed Apr 15, 2026 at 2:32 PM CEST, Dominik Csapak wrote: >> what i miss with using these is some feedback when i activated them. >> >> This is probably more due to the backend decision, but >> when clicking arm/disarm, there is nothing happening in the gui at >> first, no spinning icon, no change in state.. > > regarding feedback after activating either of them: one can see the > Status changing in the Status panel, which exactly traces what's going > on for every node, in particular it reveals the armed-state in the > Status of fencing > > if that's not enough feedback, I'd look into other possible solutions in > more detail > >> >> I think there are a few possible solutions on this, but >> i'm not super deep in the ha stack, so sorry in advance if >> some can't work: >> * use a worker that waits for the change of the ha state, e.g. >> via polling. this could directly be shown in the gui >> * mark the requested state immediately somewhere and return >> it with the overall ha state, so we see in the gui what is happening >> * 'fake' the progress until we see a status change >> (i don't really like this, since it's prone to errors when e.g. >> one admin disarms, the other arms again, but the gui does not >> get an updated state in the meantime) Good catch! Hm, we also more-or-less fake the instant state change of the HA resources: If the HA resource's state is changed in the web interface, which is written to the resources.cfg file, we reload the HA status model right after it. The status API then returns some interleaved version, which instantly respects the requested state from the config (see PVE::HA::Tools::get_verbose_service_state()). The reason this doesn't happen for the disarm/arm state is because these need to wait to be processed by the HA Manager first... The same goes for other things handled with CRM commands, such things as migrating HA resources or putting nodes in maintenance mode. But for these things we can't really fake it because whether these actions are accepted at all depend on the HA Manager entirely. Ideally, we would have some callback mechanism here (would benefit some other things for the HA stack as well). In the meantime I think a worker polling the ha state for the requested condition would do good here to give users feedback when the disarming process is finished. This should also handle if the HA Manager doesn't process the command at all for some reason. [snip] >>> + { >>> + text: gettext('Disarm HA'), >>> + iconCls: 'fa fa-unlink', >>> + bind: { >>> + disabled: '{haDisarmed}', >>> + }, >>> + menu: [ >>> + { >>> + text: gettext('Freeze'), >>> + iconCls: 'fa fa-snowflake-o', >>> + mode: 'freeze', >>> + handler: 'handleDisarmButton', >>> + }, >>> + { >>> + text: gettext('Ignore'), >>> + iconCls: 'fa fa-eye-slash', >>> + mode: 'ignore', >>> + handler: 'handleDisarmButton', >>> + }, >>> + ], >>> + }, >>> + { >>> + text: gettext('Arm HA'), >>> + iconCls: 'fa fa-link', >>> + bind: { >>> + disabled: '{!haDisarmed}', >>> + }, >>> + handler: 'handleArmButton', >>> + }, >>> + ], >> >> i'm not totally against having two buttons here, but since >> there is always only one or the other active, wouldn't >> it make more sense to hide the button that >> can't do anything? (though i admit we do most often show the >> unusable buttons across our gui, so it's fine too) >> > > tbh, I just tried to adhere to what I found in other places of the gui > > if hiding the unusable button is more desirable, I can go for that > option instead > IMO this should be consistent with the other panels (e.g. OSD where we also have mutually exclusive buttons like 'Start'/'Stop' and 'In'/'Out'). I think the nice thing about having both visible at the same time is that users can immediately see where they have to click when they want to arm the HA stack again and vice versa and don't have to find out by a rather 'dangerous' action. Especially since the buttons have different behaviors with disarming having two modes while arming being a single, simple button. >> At least i would probably switch the position of these, >> since the more (for the lack of a better word) 'affirming' action >> is usually at the beginning (like 'add' or 'start') and the other >> options comes later (like 'remove' or 'shutdown') >> >> so >> >> | Arm | Disarm | >> >> reads more logical to me than >> >> | Disarm | Arm | >> Nice! +1 ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH manager v2] ui: ha: add disarm/re-arm button 2026-04-16 7:33 ` Daniel Kral @ 2026-04-16 9:20 ` Thomas Lamprecht 2026-04-16 9:59 ` Daniel Kral 0 siblings, 1 reply; 10+ messages in thread From: Thomas Lamprecht @ 2026-04-16 9:20 UTC (permalink / raw) To: Daniel Kral, Dominik Rusovac, Dominik Csapak, pve-devel On 16/04/2026 09:32, Daniel Kral wrote: > On Wed Apr 15, 2026 at 3:32 PM CEST, Dominik Rusovac wrote: >> thx for the comments! I will send a v3 >> >> On Wed Apr 15, 2026 at 2:32 PM CEST, Dominik Csapak wrote: >>> what i miss with using these is some feedback when i activated them. >>> >>> This is probably more due to the backend decision, but >>> when clicking arm/disarm, there is nothing happening in the gui at >>> first, no spinning icon, no change in state.. >> >> regarding feedback after activating either of them: one can see the >> Status changing in the Status panel, which exactly traces what's going >> on for every node, in particular it reveals the armed-state in the >> Status of fencing >> >> if that's not enough feedback, I'd look into other possible solutions in >> more detail >> >>> >>> I think there are a few possible solutions on this, but >>> i'm not super deep in the ha stack, so sorry in advance if >>> some can't work: >>> * use a worker that waits for the change of the ha state, e.g. >>> via polling. this could directly be shown in the gui >>> * mark the requested state immediately somewhere and return >>> it with the overall ha state, so we see in the gui what is happening >>> * 'fake' the progress until we see a status change >>> (i don't really like this, since it's prone to errors when e.g. >>> one admin disarms, the other arms again, but the gui does not >>> get an updated state in the meantime) > > Good catch! > > Hm, we also more-or-less fake the instant state change of the HA > resources: If the HA resource's state is changed in the web interface, > which is written to the resources.cfg file, we reload the HA status > model right after it. The status API then returns some interleaved > version, which instantly respects the requested state from the config > (see PVE::HA::Tools::get_verbose_service_state()). > > The reason this doesn't happen for the disarm/arm state is because these > need to wait to be processed by the HA Manager first... The same goes > for other things handled with CRM commands, such things as migrating HA > resources or putting nodes in maintenance mode. But for these things we > can't really fake it because whether these actions are accepted at all > depend on the HA Manager entirely. > > Ideally, we would have some callback mechanism here (would benefit some > other things for the HA stack as well). We could compare the request state (config + queued CRM commands) with the current status and show pending states, with that we should be able to solve better relaying any such queued changes, be it resource level ones or HA LRM/CRM ones. > In the meantime I think a worker polling the ha state for the requested > condition would do good here to give users feedback when the disarming > process is finished. This should also handle if the HA Manager doesn't > process the command at all for some reason. can be OK, but rather more work and also "just" a entry in the task log, if a lot is going on in a cluster, i.e. multiple tasks are running, this might be easily missed as well. Biggest benefit of it would be actually having some more visible task log of whom triggered a HA change when, as the system log is not fully complete (missing user) and as much more gets logged there from the whole system it's also more crowded. Such a task log would IMO a orthogonal change to the showing pending changes one though, and might be better solved with a targeted audit system/log, as adding a task log just for that might be a bit overkill and slightly misusing the task log system for something it wasn't exactly designed for (one can squint and it will seem appropriate, but a structured audit log would be much better and solve some other pain points and user requests). Would be nice to have, but not a blocker for this. The pending changes is blowing up scope a bit and given that we already have the pattern for resource request state changes, I'd also not see that as blocker here, but definitively should get improved soon. > > [snip] > >>>> + { >>>> + text: gettext('Disarm HA'), >>>> + iconCls: 'fa fa-unlink', >>>> + bind: { >>>> + disabled: '{haDisarmed}', >>>> + }, >>>> + menu: [ >>>> + { >>>> + text: gettext('Freeze'), >>>> + iconCls: 'fa fa-snowflake-o', >>>> + mode: 'freeze', >>>> + handler: 'handleDisarmButton', >>>> + }, >>>> + { >>>> + text: gettext('Ignore'), >>>> + iconCls: 'fa fa-eye-slash', >>>> + mode: 'ignore', >>>> + handler: 'handleDisarmButton', >>>> + }, >>>> + ], >>>> + }, >>>> + { >>>> + text: gettext('Arm HA'), >>>> + iconCls: 'fa fa-link', >>>> + bind: { >>>> + disabled: '{!haDisarmed}', >>>> + }, >>>> + handler: 'handleArmButton', >>>> + }, >>>> + ], >>> >>> i'm not totally against having two buttons here, but since >>> there is always only one or the other active, wouldn't >>> it make more sense to hide the button that >>> can't do anything? (though i admit we do most often show the >>> unusable buttons across our gui, so it's fine too) >>> >> >> tbh, I just tried to adhere to what I found in other places of the gui >> >> if hiding the unusable button is more desirable, I can go for that >> option instead >> > > IMO this should be consistent with the other panels (e.g. OSD where we > also have mutually exclusive buttons like 'Start'/'Stop' and > 'In'/'Out'). +1 w.r.t. consistency with other panels. > I think the nice thing about having both visible at the same time is > that users can immediately see where they have to click when they want > to arm the HA stack again and vice versa and don't have to find out by a > rather 'dangerous' action. Especially since the buttons have different > behaviors with disarming having two modes while arming being a single, > simple button. I mean, both have a confirmation prompt, so IMO OK as is w.r.t. basic UI/UX safety. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH manager v2] ui: ha: add disarm/re-arm button 2026-04-16 9:20 ` Thomas Lamprecht @ 2026-04-16 9:59 ` Daniel Kral 0 siblings, 0 replies; 10+ messages in thread From: Daniel Kral @ 2026-04-16 9:59 UTC (permalink / raw) To: Thomas Lamprecht, Dominik Rusovac, Dominik Csapak, pve-devel On Thu Apr 16, 2026 at 11:20 AM CEST, Thomas Lamprecht wrote: > On 16/04/2026 09:32, Daniel Kral wrote: >> Good catch! >> >> Hm, we also more-or-less fake the instant state change of the HA >> resources: If the HA resource's state is changed in the web interface, >> which is written to the resources.cfg file, we reload the HA status >> model right after it. The status API then returns some interleaved >> version, which instantly respects the requested state from the config >> (see PVE::HA::Tools::get_verbose_service_state()). >> >> The reason this doesn't happen for the disarm/arm state is because these >> need to wait to be processed by the HA Manager first... The same goes >> for other things handled with CRM commands, such things as migrating HA >> resources or putting nodes in maintenance mode. But for these things we >> can't really fake it because whether these actions are accepted at all >> depend on the HA Manager entirely. >> >> Ideally, we would have some callback mechanism here (would benefit some >> other things for the HA stack as well). > > We could compare the request state (config + queued CRM commands) with > the current status and show pending states, with that we should be able > to solve better relaying any such queued changes, be it resource level > ones or HA LRM/CRM ones. > Right, now that you say it, most of the queued CRM commands do not have much logic we would need to 'emulate' for the Status API so those queued changes can be relayed quicker to the user, good idea! >> In the meantime I think a worker polling the ha state for the requested >> condition would do good here to give users feedback when the disarming >> process is finished. This should also handle if the HA Manager doesn't >> process the command at all for some reason. > > can be OK, but rather more work and also "just" a entry in the task log, > if a lot is going on in a cluster, i.e. multiple tasks are running, this > might be easily missed as well. Biggest benefit of it would be actually > having some more visible task log of whom triggered a HA change when, as > the system log is not fully complete (missing user) and as much more gets > logged there from the whole system it's also more crowded. > > Such a task log would IMO a orthogonal change to the showing pending > changes one though, and might be better solved with a targeted audit > system/log, as adding a task log just for that might be a bit overkill and > slightly misusing the task log system for something it wasn't exactly > designed for (one can squint and it will seem appropriate, but a structured > audit log would be much better and solve some other pain points and user > requests). Would be nice to have, but not a blocker for this. The pending > changes is blowing up scope a bit and given that we already have the > pattern for resource request state changes, I'd also not see that as > blocker here, but definitively should get improved soon. I could have phrased my response a little better as I meant polling in the web interface here. The tasks could be nice too as you said but should not block this patch here at all and I fully agree that such a feature should be handled in another series. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH manager v2] ui: ha: add disarm/re-arm button 2026-04-15 6:41 [PATCH manager v2] ui: ha: add disarm/re-arm button Dominik Rusovac 2026-04-15 7:34 ` Daniel Kral 2026-04-15 12:32 ` Dominik Csapak @ 2026-04-16 11:21 ` Dominik Rusovac 2 siblings, 0 replies; 10+ messages in thread From: Dominik Rusovac @ 2026-04-16 11:21 UTC (permalink / raw) To: Dominik Rusovac, pve-devel Superseded-by: https://lore.proxmox.com/pve-devel/20260416112033.148589-1-d.rusovac@proxmox.com/T/#u On Wed Apr 15, 2026 at 8:41 AM CEST, Dominik Rusovac wrote: > The button to disarm HA in either of the resource modes ('freeze' or > 'ignore') is disabled as long as HA is disarmed. Analogously, the button > to arm HA is disabled as long as HA is not disarmed. > > The icons ('unlink' and 'link') are chosen to emphasize that "Disarm HA" > and "Arm HA" are complements. There may be more suitable pairs of icons > though. > > Signed-off-by: Dominik Rusovac <d.rusovac@proxmox.com> > --- > changes since v1: > * use camel case for function names > * choose clearer parameter: 'comp' -> 'menuItem' > * choose clearer function names: > - 'disarm' -> 'handleDisarmButton' > - 'rearm' -> 'handleArmButton' > * deduplicate translation keys > * use same translation keys as for menu items > * remove obsolete 'params' > * change button text "Re-arm HA" to "Arm HA" > * remove extra new-line > > www/manager6/ha/Status.js | 104 ++++++++++++++++++++++++++++++++++ > www/manager6/ha/StatusView.js | 8 +++ > 2 files changed, 112 insertions(+) > [snip] ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-04-16 11:21 UTC | newest] Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2026-04-15 6:41 [PATCH manager v2] ui: ha: add disarm/re-arm button Dominik Rusovac 2026-04-15 7:34 ` Daniel Kral 2026-04-15 12:32 ` Dominik Csapak 2026-04-15 13:32 ` Dominik Rusovac 2026-04-15 14:18 ` Dominik Csapak 2026-04-16 5:58 ` Dominik Rusovac 2026-04-16 7:33 ` Daniel Kral 2026-04-16 9:20 ` Thomas Lamprecht 2026-04-16 9:59 ` Daniel Kral 2026-04-16 11:21 ` Dominik Rusovac
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox