[pbs-devel] [PATCH proxmox-backup v9 6/6] ui: add option to change the maintenance type

Hannes Laimer h.laimer at proxmox.com
Thu Feb 17 18:14:57 CET 2022


Signed-off-by: Hannes Laimer <h.laimer at proxmox.com>
---
 www/Makefile                     |  1 +
 www/Utils.js                     | 23 ++++++++++
 www/datastore/OptionView.js      | 30 +++++++++++++
 www/window/MaintenanceOptions.js | 77 ++++++++++++++++++++++++++++++++
 4 files changed, 131 insertions(+)
 create mode 100644 www/window/MaintenanceOptions.js

diff --git a/www/Makefile b/www/Makefile
index 455fbeec..0952fb82 100644
--- a/www/Makefile
+++ b/www/Makefile
@@ -61,6 +61,7 @@ JSSRC=							\
 	window/BackupGroupChangeOwner.js		\
 	window/CreateDirectory.js			\
 	window/DataStoreEdit.js				\
+	window/MaintenanceOptions.js			\
 	window/NotesEdit.js				\
 	window/RemoteEdit.js				\
 	window/TrafficControlEdit.js			\
diff --git a/www/Utils.js b/www/Utils.js
index 36a94211..b99bec32 100644
--- a/www/Utils.js
+++ b/www/Utils.js
@@ -640,4 +640,27 @@ Ext.define('PBS.Utils', {
 	return `${icon} ${value}`;
     },
 
+    renderMaintenance: function(mode, activeTasks) {
+	if (!mode) return gettext('None');
+	let [type, _message] = mode.split(",");
+	type = type.split("=").pop();
+
+	const conflictingTasks = activeTasks.write + (type === 'offline' ? activeTasks.read : 0);
+	const checkmarkIcon = '<i class="fa fa-check"></i>';
+	const spinnerIcon = '<i class="fa fa-spinner fa-pulse fa-fw"></i>';
+	const conflictingTasksMessage = `<i>${conflictingTasks} conflicting tasks still active</i>`;
+	const extra = conflictingTasks > 0 ? `| ${spinnerIcon} ${conflictingTasksMessage}` : checkmarkIcon;
+
+	let modeText = Proxmox.Utils.unknownText;
+	switch (type) {
+	    case 'read-only':
+		modeText = gettext("Read-only");
+		break;
+	    case 'offline':
+		modeText = gettext("Offline");
+		break;
+	}
+	return `${modeText} ${extra}`;
+    },
+
 });
diff --git a/www/datastore/OptionView.js b/www/datastore/OptionView.js
index 5a5e85be..25fe71dc 100644
--- a/www/datastore/OptionView.js
+++ b/www/datastore/OptionView.js
@@ -1,3 +1,4 @@
+
 Ext.define('PBS.Datastore.Options', {
     extend: 'Proxmox.grid.ObjectGrid',
     xtype: 'pbsDatastoreOptionView',
@@ -6,6 +7,10 @@ Ext.define('PBS.Datastore.Options', {
     cbindData: function(initial) {
 	let me = this;
 
+	me.maintenanceActiveTasks = {
+	    read: 0,
+	    write: 0,
+	};
 	me.datastore = encodeURIComponent(me.datastore);
 	me.url = `/api2/json/config/datastore/${me.datastore}`;
 	me.editorConfig = {
@@ -18,6 +23,24 @@ Ext.define('PBS.Datastore.Options', {
     controller: {
 	xclass: 'Ext.app.ViewController',
 
+	init: function(view) {
+	    let me = this;
+	    me.callParent();
+	    view.rows['maintenance-mode'].renderer =
+		(value) => PBS.Utils.renderMaintenance(value, view.maintenanceActiveTasks);
+
+	    me.activeOperationsRstore = Ext.create('Proxmox.data.ObjectStore', {
+		url: `/api2/json/admin/datastore/${view.datastore}/active-operations`,
+		interval: 3000,
+	    });
+	    me.activeOperationsRstore.startUpdate();
+
+	    view.mon(me.activeOperationsRstore, 'load', (store, data, success) => {
+		me.view.maintenanceActiveTasks.read = data[0].data.value;
+		me.view.maintenanceActiveTasks.write = data[1].data.value;
+	    });
+	},
+
 	edit: function() {
 	    this.getView().run_editor();
 	},
@@ -111,5 +134,12 @@ Ext.define('PBS.Datastore.Options', {
 		},
 	    },
 	},
+	"maintenance-mode": {
+	    required: true,
+	    header: gettext('Maintenance mode'),
+	    editor: {
+		xtype: 'pbsMaintenanceOptionEdit',
+	    },
+	},
     },
 });
diff --git a/www/window/MaintenanceOptions.js b/www/window/MaintenanceOptions.js
new file mode 100644
index 00000000..1aa03cbd
--- /dev/null
+++ b/www/window/MaintenanceOptions.js
@@ -0,0 +1,77 @@
+Ext.define('PBS.form.maintenanceType', {
+    extend: 'Proxmox.form.KVComboBox',
+    alias: 'widget.pbsMaintenanceType',
+
+    comboItems: [
+	['__default__', gettext('None')],
+	['read-only', gettext('Read only')],
+	['offline', gettext('Offline')],
+    ],
+});
+
+Ext.define('PBS.window.MaintenanceOptions', {
+    extend: 'Proxmox.window.Edit',
+    xtype: 'pbsMaintenanceOptionEdit',
+    mixins: ['Proxmox.Mixin.CBind'],
+
+    subject: gettext('Maintenance mode'),
+
+    width: 450,
+    fieldDefaults: {
+	labelWidth: 120,
+    },
+
+    items: {
+	onGetValues: function(values) {
+	    if (values.delete === 'maintenance-type') {
+		values.delete = 'maintenance-mode';
+	    } else if (values['maintenance-type']) {
+		const escaped_message = values['maintenance-msg']
+		    .replaceAll('\\', '')
+		    .replaceAll('"', '\\"');
+		const maybe_message =
+		    values['maintenance-msg'] ? `,message="${escaped_message}"` : '';
+		values['maintenance-mode'] = `type=${values['maintenance-type']}${maybe_message}`;
+	    }
+	    delete values['maintenance-type'];
+	    delete values['maintenance-msg'];
+	    return values;
+	},
+	xtype: 'inputpanel',
+	items: [
+	    {
+		xtype: 'pbsMaintenanceType',
+		name: 'maintenance-type',
+		fieldLabel: gettext('Maintenance Type'),
+		value: '__default__',
+		deleteEmpty: true,
+	    },
+	    {
+		xtype: 'proxmoxtextfield',
+		name: 'maintenance-msg',
+		fieldLabel: gettext('Description'),
+	    },
+	],
+    },
+    setValues: function(values) {
+	let me = this;
+
+	let options = {
+	    'maintenance-type': '__default__',
+	    'maintenance-msg': '',
+	};
+	if (values['maintenance-mode']) {
+	    let [type, message] = values['maintenance-mode'].split(/,(.+)/);
+	    type = type.split("=").pop();
+	    message = message ? message.split("=")[1]
+		.replace(/^"(.*)"$/, '$1')
+		.replaceAll('\\"', '"') : '';
+	    options = {
+		'maintenance-type': type,
+		'maintenance-msg': message,
+	    };
+	}
+
+	me.callParent([options]);
+    },
+});
-- 
2.30.2






More information about the pbs-devel mailing list