Signed-off-by: Fabian Ebner <[email protected]>
---

Changes from v2:
    * Adapt to backend changes with explicit action for each drive.

 www/manager6/Makefile                |   1 +
 www/manager6/grid/RestoreDiskGrid.js | 151 +++++++++++++++++++++++++++
 www/manager6/window/Restore.js       |  35 ++++++-
 3 files changed, 186 insertions(+), 1 deletion(-)
 create mode 100644 www/manager6/grid/RestoreDiskGrid.js

diff --git a/www/manager6/Makefile b/www/manager6/Makefile
index 2c7b1e70..93f9f9c6 100644
--- a/www/manager6/Makefile
+++ b/www/manager6/Makefile
@@ -80,6 +80,7 @@ JSSRC=                                                        
\
        grid/PoolMembers.js                             \
        grid/Replication.js                             \
        grid/ResourceGrid.js                            \
+       grid/RestoreDiskGrid.js                         \
        panel/ConfigPanel.js                            \
        panel/BackupJobPrune.js                         \
        panel/HealthWidget.js                           \
diff --git a/www/manager6/grid/RestoreDiskGrid.js 
b/www/manager6/grid/RestoreDiskGrid.js
new file mode 100644
index 00000000..ded8331a
--- /dev/null
+++ b/www/manager6/grid/RestoreDiskGrid.js
@@ -0,0 +1,151 @@
+Ext.define('pve-restore-disk', {
+    extend: 'Ext.data.Model',
+    fields: [
+       { name: 'action', type: 'string' },
+       { name: 'drivename', type: 'string' },
+       { name: 'vm', type: 'string' },
+       { name: 'backup', type: 'string' },
+    ],
+});
+
+Ext.define('PVE.grid.RestoreDiskGrid', {
+    extend: 'Ext.grid.Panel',
+    alias: ['widget.pveRestoreDiskGrid'],
+
+    vmConfig: undefined,
+    backupConfig: undefined,
+
+    setVMConfig: function(config) {
+       let me = this;
+
+       if (me.vmConfig) {
+           throw "vm config already set";
+       }
+       me.vmConfig = config;
+
+       if (me.vmConfig && me.backupConfig) {
+           me.updateData();
+       }
+    },
+
+    setBackupConfig: function(config) {
+       let me = this;
+
+       if (me.backupConfig) {
+           throw "backup config already set";
+       }
+       me.backupConfig = config;
+
+       if (me.vmConfig && me.backupConfig) {
+           me.updateData();
+       }
+    },
+
+    updateData: function() {
+       let me = this;
+
+       let data = [];
+
+       
Object.keys(me.vmConfig).concat(Object.keys(me.backupConfig)).forEach(function(key)
 {
+           if (!key.match(PVE.Utils.bus_match) && 
!key.match(/^(efidisk|tpmstate)\d+$/)) {
+               return;
+           }
+
+           if (data.find(item => item.drivename === key)) {
+               return;
+           }
+
+           data.push({
+               drivename: key,
+               action: me.backupConfig[key] ? 'restore' : 'unused',
+               vm: me.vmConfig[key],
+               backup: me.backupConfig[key],
+           });
+       });
+
+       me.getStore().setData(data);
+    },
+
+    getDriveActionsValue: function() {
+       let actions = [];
+
+       this.getStore().getData().each(item => {
+           let action = `${item.data.drivename}=${item.data.action}`;
+           if (item.data.action === 'restore' && item.data.storage) {
+               action += `:${item.data.storage}`;
+           }
+           actions.push(action);
+       });
+
+       return actions.join(',');
+    },
+
+
+    store: {
+       model: 'pve-restore-disk',
+       sorters: 'drivename',
+    },
+
+    columns: [
+       {
+           xtype: 'widgetcolumn',
+           header: gettext('Action'),
+           dataIndex: 'action',
+           width: 150,
+           widget: {
+               xtype: 'proxmoxKVComboBox',
+               comboItems: [
+                   ['restore', gettext('Restore')],
+                   ['unused', gettext('Keep as unused')],
+                   ['preserve', gettext('Keep configured')],
+               ],
+               listeners: {
+                   change: function(f, value) {
+                       let rec = f.getWidgetRecord();
+
+                       rec.set('action', value);
+
+                       // shouldn't happen, but avoid potential infinite 
recursion below
+                       if (!rec.data.backup && !rec.data.vm) {
+                           return;
+                       }
+
+                       // auto-correct invalid actions
+                       if (value === 'restore' && !rec.data.backup) {
+                           f.setValue('unused');
+                       } else if (value === 'unused' && !rec.data.vm) {
+                           f.setValue('restore');
+                       }
+                   },
+               },
+           },
+       },
+       {
+           header: gettext('Drive'),
+           dataIndex: 'drivename',
+           width: 80,
+       },
+       {
+           header: gettext('Current'),
+           dataIndex: 'vm',
+           flex: 1,
+           renderer: function(drive, metaData, record) {
+               if (record.data.action !== 'restore') {
+                   metaData.tdCls = 'proxmox-good-row';
+               }
+               return drive;
+           },
+       },
+       {
+           header: gettext('Backup'),
+           dataIndex: 'backup',
+           flex: 1,
+           renderer: function(drive, metaData, record) {
+               if (record.data.action === 'restore' && drive) {
+                   metaData.tdCls = 'proxmox-good-row';
+               }
+               return drive;
+           },
+       },
+    ],
+});
diff --git a/www/manager6/window/Restore.js b/www/manager6/window/Restore.js
index 2d78eb56..fb7231c3 100644
--- a/www/manager6/window/Restore.js
+++ b/www/manager6/window/Restore.js
@@ -59,6 +59,11 @@ Ext.define('PVE.window.Restore', {
                delete params.name;
            }
 
+           let diskGrid = view.lookupReference('restoreDiskGrid');
+           if (diskGrid) {
+               params['restore-drive-actions'] = 
diskGrid.getDriveActionsValue();
+           }
+
            let confirmMsg;
            if (view.vmtype === 'lxc') {
                params.ostemplate = view.volid;
@@ -105,6 +110,7 @@ Ext.define('PVE.window.Restore', {
 
        afterRender: function() {
            let view = this.getView();
+           let diskGrid = view.lookupReference('restoreDiskGrid');
 
            Proxmox.Utils.API2Request({
                url: `/nodes/${view.nodename}/vzdump/extractconfig`,
@@ -116,6 +122,7 @@ Ext.define('PVE.window.Restore', {
                failure: response => Ext.Msg.alert('Error', 
response.htmlStatus),
                success: function(response, options) {
                    let allStoragesAvailable = true;
+                   let config = {};
 
                    response.result.data.split('\n').forEach(line => {
                        let [_, key, value] = 
line.match(/^([^:]+):\s*(\S+)\s*$/) ?? [];
@@ -129,7 +136,11 @@ Ext.define('PVE.window.Restore', {
                            // if a /dev/XYZ disk was backed up, ther is no 
storage hint
                            allStoragesAvailable &&= !!match[3] && 
!!PVE.data.ResourceStore.getById(
                                `storage/${view.nodename}/${match[3]}`);
-                       } else if (key === 'name' || key === 'hostname') {
+                       } else {
+                           config[key] = value;
+                       }
+
+                       if (key === 'name' || key === 'hostname') {
                            
view.lookupReference('nameField').setEmptyText(value);
                        } else if (key === 'memory' || key === 'cores' || key 
=== 'sockets') {
                            
view.lookupReference(`${key}Field`).setEmptyText(value);
@@ -141,8 +152,22 @@ Ext.define('PVE.window.Restore', {
                        storagesel.allowBlank = false;
                        storagesel.setEmptyText('');
                    }
+
+                   diskGrid?.setBackupConfig(config);
                },
            });
+
+           if (!diskGrid) {
+               return;
+           }
+
+           Proxmox.Utils.API2Request({
+               url: `/nodes/${view.nodename}/qemu/${view.vmid}/config`,
+               waitMsgTarget: diskGrid,
+               method: 'GET',
+               failure: response => Ext.Msg.alert(gettext('Error'), 
response.htmlStatus),
+               success: response => diskGrid.setVMConfig(response.result.data),
+           });
        },
     },
 
@@ -334,6 +359,13 @@ Ext.define('PVE.window.Restore', {
                maxValue: 4,
                allowBlank: true,
            });
+
+           if (me.vmid) {
+               items.push({
+                   xtype: 'pveRestoreDiskGrid',
+                   reference: 'restoreDiskGrid',
+               });
+           }
        }
 
        let title = gettext('Restore') + ": " + (me.vmtype === 'lxc' ? 'CT' : 
'VM');
@@ -343,6 +375,7 @@ Ext.define('PVE.window.Restore', {
 
        Ext.apply(me, {
            title: title,
+           width: 700,
            items: [
                {
                    xtype: 'form',
-- 
2.30.2



_______________________________________________
pve-devel mailing list
[email protected]
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to