[pve-devel] [RFC v2 pve-container pve-manager 3/3] ui: lxc restore: add selective mountpoint restore

Christian Ebner c.ebner at proxmox.com
Mon Oct 23 13:18:35 CEST 2023


Adds a grid to the lxc backup restore window allowing the user to select
mountpoints which should be included/excluded from a restore.

Signed-off-by: Christian Ebner <c.ebner at proxmox.com>
---

changes since v1:
    not present in v1

 www/manager6/Makefile                     |  1 +
 www/manager6/grid/BackupRestoreTargets.js | 37 +++++++++++++++++++++++
 www/manager6/window/Restore.js            | 34 +++++++++++++++++++++
 3 files changed, 72 insertions(+)
 create mode 100644 www/manager6/grid/BackupRestoreTargets.js

diff --git a/www/manager6/Makefile b/www/manager6/Makefile
index 17e0ad05..c096a8be 100644
--- a/www/manager6/Makefile
+++ b/www/manager6/Makefile
@@ -88,6 +88,7 @@ JSSRC= 							\
 	form/TagEdit.js					\
 	form/MultiFileButton.js				\
 	grid/BackupView.js				\
+	grid/BackupRestoreTargets.js			\
 	grid/FirewallAliases.js				\
 	grid/FirewallOptions.js				\
 	grid/FirewallRules.js				\
diff --git a/www/manager6/grid/BackupRestoreTargets.js b/www/manager6/grid/BackupRestoreTargets.js
new file mode 100644
index 00000000..b811989e
--- /dev/null
+++ b/www/manager6/grid/BackupRestoreTargets.js
@@ -0,0 +1,37 @@
+Ext.define('PVE.BackupRestoreTargets', {
+    extend: 'Ext.grid.Panel',
+    alias: 'widget.pveBackupRestoreTargets',
+    store: {
+	fields: [
+	    {
+		name: 'restore',
+		type: 'boolean',
+	    },
+	    {
+		name: 'target',
+		type: 'string',
+	    },
+	],
+    },
+
+    getMountpoints: function() {
+	return this.store.getData();
+    },
+
+    setMountpoints: function(mountpoints) {
+	this.store.loadData(mountpoints);
+    },
+
+    columns: [
+	{
+	    text: gettext('Mountpoint'),
+	    dataIndex: 'mountpoint',
+	    flex: 1,
+	},
+	{
+	    text: gettext('Restore'),
+	    dataIndex: 'restore',
+	    xtype: 'checkcolumn',
+	},
+    ],
+});
diff --git a/www/manager6/window/Restore.js b/www/manager6/window/Restore.js
index 36aecc39..85e382fb 100644
--- a/www/manager6/window/Restore.js
+++ b/www/manager6/window/Restore.js
@@ -67,6 +67,13 @@ Ext.define('PVE.window.Restore', {
 		    params.unprivileged = values.unprivileged;
 		}
 		confirmMsg = Proxmox.Utils.format_task_description('vzrestore', params.vmid);
+		let viewModel = view.getViewModel();
+		let excludes = viewModel.get('mountpoints')
+		    .filter(mp => mp.restore === false)
+		    .map(mp => mp.mountpoint);
+		if (excludes.length > 0) {
+		    params['exclude-mps'] = excludes.join(',');
+		}
 	    } else if (view.vmtype === 'qemu') {
 		params.archive = view.volid;
 		confirmMsg = Proxmox.Utils.format_task_description('qmrestore', params.vmid);
@@ -111,6 +118,7 @@ Ext.define('PVE.window.Restore', {
 
 	afterRender: function() {
 	    let view = this.getView();
+	    let viewModel = view.getViewModel();
 
 	    Proxmox.Utils.API2Request({
 		url: `/nodes/${view.nodename}/vzdump/extractconfig`,
@@ -123,6 +131,7 @@ Ext.define('PVE.window.Restore', {
 		success: function(response, options) {
 		    let allStoragesAvailable = true;
 
+		    let mountpoints = [];
 		    response.result.data.split('\n').forEach(line => {
 			let [_, key, value] = line.match(/^([^:]+):\s*(\S+)\s*$/) ?? [];
 
@@ -139,8 +148,14 @@ Ext.define('PVE.window.Restore', {
 			    view.lookupReference('nameField').setEmptyText(value);
 			} else if (key === 'memory' || key === 'cores' || key === 'sockets') {
 			    view.lookupReference(`${key}Field`).setEmptyText(value);
+			} else if (key.match(/mp\d+/) && value.includes('backup=1')) {
+			    mountpoints.push({
+				'mountpoint': key,
+				'restore': true,
+			    });
 			}
 		    });
+		    viewModel.set('mountpoints', mountpoints);
 
 		    if (!allStoragesAvailable) {
 			let storagesel = view.down('pveStorageSelector[name=storage]');
@@ -152,6 +167,12 @@ Ext.define('PVE.window.Restore', {
 	},
     },
 
+    viewModel: {
+	config: {
+	    mountpoints: [],
+	},
+    },
+
     initComponent: function() {
 	let me = this;
 
@@ -354,6 +375,19 @@ Ext.define('PVE.window.Restore', {
 	    ],
 	});
 
+	if (me.vmtype === 'lxc') {
+	    items.push({
+		title: `${gettext('Restore Mountpoints')}:`,
+		name: 'mountpointRestoreTargets',
+		xtype: 'pveBackupRestoreTargets',
+		hidden: true, // Hide until config loaded
+		bind: {
+		    mountpoints: '{mountpoints}',
+		    hidden: '{!mountpoints.length}',
+		},
+	    });
+	}
+
 	let title = gettext('Restore') + ": " + (me.vmtype === 'lxc' ? 'CT' : 'VM');
 	if (me.vmid) {
 	    title = `${gettext('Overwrite')} ${title} ${me.vmid}`;
-- 
2.39.2






More information about the pve-devel mailing list