From 4e0e6b77e9faff9fb6616d16a9a2a74b47921fdf Mon Sep 17 00:00:00 2001 From: Dominik Csapak Date: Thu, 30 Jan 2020 16:58:51 +0100 Subject: [PATCH] gui: refactor snapshot window using an Proxmox.window.Edit, which does many of the things we did manually, also rewrite is in such way that we can use it for qemu and lxc Signed-off-by: Dominik Csapak --- www/manager6/Makefile | 3 +- www/manager6/lxc/Snapshot.js | 206 ---------------------------- www/manager6/lxc/SnapshotTree.js | 4 + www/manager6/qemu/Snapshot.js | 215 ------------------------------ www/manager6/qemu/SnapshotTree.js | 4 + www/manager6/window/Snapshot.js | 131 ++++++++++++++++++ 6 files changed, 140 insertions(+), 423 deletions(-) delete mode 100644 www/manager6/lxc/Snapshot.js delete mode 100644 www/manager6/qemu/Snapshot.js create mode 100644 www/manager6/window/Snapshot.js diff --git a/www/manager6/Makefile b/www/manager6/Makefile index d232e635..3c99ec6c 100644 --- a/www/manager6/Makefile +++ b/www/manager6/Makefile @@ -127,6 +127,7 @@ JSSRC= \ window/Migrate.js \ window/BulkAction.js \ window/Clone.js \ + window/Snapshot.js \ qemu/Monitor.js \ qemu/OSTypeEdit.js \ qemu/OSDefaults.js \ @@ -146,7 +147,6 @@ JSSRC= \ qemu/ScsiHwEdit.js \ qemu/QemuBiosEdit.js \ qemu/Options.js \ - qemu/Snapshot.js \ qemu/SnapshotTree.js \ qemu/Config.js \ qemu/CreateWizard.js \ @@ -168,7 +168,6 @@ JSSRC= \ lxc/Config.js \ lxc/CreateWizard.js \ lxc/SnapshotTree.js \ - lxc/Snapshot.js \ lxc/ResourceEdit.js \ lxc/MPResize.js \ lxc/MPEdit.js \ diff --git a/www/manager6/lxc/Snapshot.js b/www/manager6/lxc/Snapshot.js deleted file mode 100644 index bdb99018..00000000 --- a/www/manager6/lxc/Snapshot.js +++ /dev/null @@ -1,206 +0,0 @@ -Ext.define('PVE.window.LxcSnapshot', { - extend: 'Ext.window.Window', - - resizable: false, - - // needed for finding the reference to submitbutton - // because we do not have a controller - referenceHolder: true, - defaultButton: 'submitbutton', - defaultFocus: 'field', - - take_snapshot: function(snapname, descr, vmstate) { - var me = this; - var params = { snapname: snapname }; - if (descr) { - params.description = descr; - } - - Proxmox.Utils.API2Request({ - params: params, - url: '/nodes/' + me.nodename + '/lxc/' + me.vmid + "/snapshot", - waitMsgTarget: me, - method: 'POST', - failure: function(response, opts) { - Ext.Msg.alert(gettext('Error'), response.htmlStatus); - }, - success: function(response, options) { - var upid = response.result.data; - var win = Ext.create('Proxmox.window.TaskProgress', { upid: upid }); - win.show(); - me.close(); - } - }); - }, - - update_snapshot: function(snapname, descr) { - var me = this; - Proxmox.Utils.API2Request({ - params: { description: descr }, - url: '/nodes/' + me.nodename + '/lxc/' + me.vmid + "/snapshot/" + - snapname + '/config', - waitMsgTarget: me, - method: 'PUT', - failure: function(response, opts) { - Ext.Msg.alert(gettext('Error'), response.htmlStatus); - }, - success: function(response, options) { - me.close(); - } - }); - }, - - initComponent : function() { - var me = this; - - if (!me.nodename) { - throw "no node name specified"; - } - - if (!me.vmid) { - throw "no VM ID specified"; - } - - var summarystore = Ext.create('Ext.data.Store', { - model: 'KeyValue', - sorters: [ - { - property : 'key', - direction: 'ASC' - } - ] - }); - - var items = [ - { - xtype: me.snapname ? 'displayfield' : 'textfield', - name: 'snapname', - value: me.snapname, - fieldLabel: gettext('Name'), - vtype: 'ConfigId', - allowBlank: false - } - ]; - - if (me.snapname) { - items.push({ - xtype: 'displayfield', - name: 'snaptime', - renderer: PVE.Utils.render_timestamp_human_readable, - fieldLabel: gettext('Timestamp') - }); - } - - items.push({ - xtype: 'textareafield', - grow: true, - name: 'description', - fieldLabel: gettext('Description') - }); - - if (me.snapname) { - items.push({ - title: gettext('Settings'), - xtype: 'grid', - height: 200, - store: summarystore, - columns: [ - {header: gettext('Key'), width: 150, dataIndex: 'key'}, - {header: gettext('Value'), flex: 1, dataIndex: 'value'} - ] - }); - } - - me.formPanel = Ext.create('Ext.form.Panel', { - bodyPadding: 10, - border: false, - fieldDefaults: { - labelWidth: 100, - anchor: '100%' - }, - items: items - }); - - var form = me.formPanel.getForm(); - - var submitBtn; - - if (me.snapname) { - me.title = gettext('Edit') + ': ' + gettext('Snapshot'); - submitBtn = Ext.create('Ext.Button', { - text: gettext('Update'), - handler: function() { - if (form.isValid()) { - var values = form.getValues(); - me.update_snapshot(me.snapname, values.description); - } - } - }); - } else { - me.title ="VM " + me.vmid + ': ' + gettext('Take Snapshot'); - submitBtn = Ext.create('Ext.Button', { - text: gettext('Take Snapshot'), - reference: 'submitbutton', - handler: function() { - if (form.isValid()) { - var values = form.getValues(); - me.take_snapshot(values.snapname, values.description); - } - } - }); - } - - Ext.apply(me, { - modal: true, - width: 450, - border: false, - layout: 'fit', - buttons: [ submitBtn ], - items: [ me.formPanel ] - }); - - if (me.snapname) { - Ext.apply(me, { - width: 620, - height: 420 - }); - } - - me.callParent(); - - if (!me.snapname) { - return; - } - - // else load data - Proxmox.Utils.API2Request({ - url: '/nodes/' + me.nodename + '/lxc/' + me.vmid + "/snapshot/" + - me.snapname + '/config', - waitMsgTarget: me, - method: 'GET', - failure: function(response, opts) { - Ext.Msg.alert(gettext('Error'), response.htmlStatus); - me.close(); - }, - success: function(response, options) { - var data = response.result.data; - var kvarray = []; - Ext.Object.each(data, function(key, value) { - if (key === 'description' || key === 'snaptime') { - return; - } - kvarray.push({ key: key, value: value }); - }); - - summarystore.suspendEvents(); - summarystore.add(kvarray); - summarystore.sort(); - summarystore.resumeEvents(); - summarystore.fireEvent('refresh', summarystore); - - form.findField('snaptime').setValue(data.snaptime); - form.findField('description').setValue(data.description); - } - }); - } -}); diff --git a/www/manager6/lxc/SnapshotTree.js b/www/manager6/lxc/SnapshotTree.js index d9414fef..0c1d9a6b 100644 --- a/www/manager6/lxc/SnapshotTree.js +++ b/www/manager6/lxc/SnapshotTree.js @@ -136,6 +136,7 @@ Ext.define('PVE.lxc.SnapshotTree', { var rec = sm.getSelection()[0]; if (valid_snapshot(rec)) { var win = Ext.create('PVE.window.LxcSnapshot', { + type: 'lxc', snapname: rec.data.name, nodename: me.nodename, vmid: me.vmid @@ -238,6 +239,9 @@ Ext.define('PVE.lxc.SnapshotTree', { disabled: true, handler: function() { var win = Ext.create('PVE.window.LxcSnapshot', { + type: 'lxc', + isCreate: true, + submitText: gettext('Take Snapshot'), nodename: me.nodename, vmid: me.vmid }); diff --git a/www/manager6/qemu/Snapshot.js b/www/manager6/qemu/Snapshot.js deleted file mode 100644 index 59fae1a2..00000000 --- a/www/manager6/qemu/Snapshot.js +++ /dev/null @@ -1,215 +0,0 @@ -Ext.define('PVE.window.Snapshot', { - extend: 'Ext.window.Window', - - resizable: false, - - // needed for finding the reference to submitbutton - // because we do not have a controller - referenceHolder: true, - defaultButton: 'submitbutton', - defaultFocus: 'field', - - take_snapshot: function(snapname, descr, vmstate) { - var me = this; - var params = { snapname: snapname, vmstate: vmstate ? 1 : 0 }; - if (descr) { - params.description = descr; - } - - Proxmox.Utils.API2Request({ - params: params, - url: '/nodes/' + me.nodename + '/qemu/' + me.vmid + "/snapshot", - waitMsgTarget: me, - method: 'POST', - failure: function(response, opts) { - Ext.Msg.alert(gettext('Error'), response.htmlStatus); - }, - success: function(response, options) { - var upid = response.result.data; - var win = Ext.create('Proxmox.window.TaskProgress', { upid: upid }); - win.show(); - me.close(); - } - }); - }, - - update_snapshot: function(snapname, descr) { - var me = this; - Proxmox.Utils.API2Request({ - params: { description: descr }, - url: '/nodes/' + me.nodename + '/qemu/' + me.vmid + "/snapshot/" + - snapname + '/config', - waitMsgTarget: me, - method: 'PUT', - failure: function(response, opts) { - Ext.Msg.alert(gettext('Error'), response.htmlStatus); - }, - success: function(response, options) { - me.close(); - } - }); - }, - - initComponent : function() { - var me = this; - - if (!me.nodename) { - throw "no node name specified"; - } - - if (!me.vmid) { - throw "no VM ID specified"; - } - - var summarystore = Ext.create('Ext.data.Store', { - model: 'KeyValue', - sorters: [ - { - property : 'key', - direction: 'ASC' - } - ] - }); - - var items = [ - { - xtype: me.snapname ? 'displayfield' : 'textfield', - name: 'snapname', - value: me.snapname, - fieldLabel: gettext('Name'), - vtype: 'ConfigId', - allowBlank: false - } - ]; - - if (me.snapname) { - items.push({ - xtype: 'displayfield', - name: 'snaptime', - renderer: PVE.Utils.render_timestamp_human_readable, - fieldLabel: gettext('Timestamp') - }); - } else { - items.push({ - xtype: 'proxmoxcheckbox', - name: 'vmstate', - uncheckedValue: 0, - defaultValue: 0, - checked: 1, - fieldLabel: gettext('Include RAM') - }); - } - - items.push({ - xtype: 'textareafield', - grow: true, - name: 'description', - fieldLabel: gettext('Description') - }); - - if (me.snapname) { - items.push({ - title: gettext('Settings'), - xtype: 'grid', - height: 200, - store: summarystore, - columns: [ - {header: gettext('Key'), width: 150, dataIndex: 'key'}, - {header: gettext('Value'), flex: 1, dataIndex: 'value'} - ] - }); - } - - me.formPanel = Ext.create('Ext.form.Panel', { - bodyPadding: 10, - border: false, - fieldDefaults: { - labelWidth: 100, - anchor: '100%' - }, - items: items - }); - - var form = me.formPanel.getForm(); - - var submitBtn; - - if (me.snapname) { - me.title = gettext('Edit') + ': ' + gettext('Snapshot'); - submitBtn = Ext.create('Ext.Button', { - text: gettext('Update'), - handler: function() { - if (form.isValid()) { - var values = form.getValues(); - me.update_snapshot(me.snapname, values.description); - } - } - }); - } else { - me.title ="VM " + me.vmid + ': ' + gettext('Take Snapshot'); - submitBtn = Ext.create('Ext.Button', { - text: gettext('Take Snapshot'), - reference: 'submitbutton', - handler: function() { - if (form.isValid()) { - var values = form.getValues(); - me.take_snapshot(values.snapname, values.description, values.vmstate); - } - } - }); - } - - Ext.apply(me, { - modal: true, - width: 450, - border: false, - layout: 'fit', - buttons: [ submitBtn ], - items: [ me.formPanel ] - }); - - if (me.snapname) { - Ext.apply(me, { - width: 620, - height: 420 - }); - } - - me.callParent(); - - if (!me.snapname) { - return; - } - - // else load data - Proxmox.Utils.API2Request({ - url: '/nodes/' + me.nodename + '/qemu/' + me.vmid + "/snapshot/" + - me.snapname + '/config', - waitMsgTarget: me, - method: 'GET', - failure: function(response, opts) { - Ext.Msg.alert(gettext('Error'), response.htmlStatus); - me.close(); - }, - success: function(response, options) { - var data = response.result.data; - var kvarray = []; - Ext.Object.each(data, function(key, value) { - if (key === 'description' || key === 'snaptime') { - return; - } - kvarray.push({ key: key, value: value }); - }); - - summarystore.suspendEvents(); - summarystore.add(kvarray); - summarystore.sort(); - summarystore.resumeEvents(); - summarystore.fireEvent('refresh', summarystore); - - form.findField('snaptime').setValue(data.snaptime); - form.findField('description').setValue(data.description); - } - }); - } -}); diff --git a/www/manager6/qemu/SnapshotTree.js b/www/manager6/qemu/SnapshotTree.js index 9b7c1fb6..a3891433 100644 --- a/www/manager6/qemu/SnapshotTree.js +++ b/www/manager6/qemu/SnapshotTree.js @@ -134,6 +134,7 @@ Ext.define('PVE.qemu.SnapshotTree', { var rec = sm.getSelection()[0]; if (valid_snapshot(rec)) { var win = Ext.create('PVE.window.Snapshot', { + type: 'qemu', snapname: rec.data.name, nodename: me.nodename, vmid: me.vmid @@ -228,6 +229,9 @@ Ext.define('PVE.qemu.SnapshotTree', { disabled: true, handler: function() { var win = Ext.create('PVE.window.Snapshot', { + isCreate: true, + type: 'qemu', + submitText: gettext('Take Snapshot'), nodename: me.nodename, vmid: me.vmid }); diff --git a/www/manager6/window/Snapshot.js b/www/manager6/window/Snapshot.js new file mode 100644 index 00000000..64de9293 --- /dev/null +++ b/www/manager6/window/Snapshot.js @@ -0,0 +1,131 @@ +Ext.define('PVE.window.Snapshot', { + extend: 'Proxmox.window.Edit', + + onGetValues: function(values) { + let me = this; + + if (me.type === 'lxc') { + delete values.vmstate; + } + + return values; + }, + + initComponent : function() { + var me = this; + + if (!me.nodename) { + throw "no node name specified"; + } + + if (!me.vmid) { + throw "no VM ID specified"; + } + + if (!me.type) { + throw "no VM ID specified"; + } + + me.items = [ + { + xtype: me.snapname ? 'displayfield' : 'textfield', + name: 'snapname', + value: me.snapname, + fieldLabel: gettext('Name'), + vtype: 'ConfigId', + allowBlank: false + }, + { + xtype: 'displayfield', + hidden: !me.snapname, + disabled: !me.snapname, + name: 'snaptime', + renderer: PVE.Utils.render_timestamp_human_readable, + fieldLabel: gettext('Timestamp') + }, + { + xtype: 'proxmoxcheckbox', + hidden: me.type !== 'qemu' || me.snapname, + disabled: me.type !== 'qemu' || me.snapname, + name: 'vmstate', + uncheckedValue: 0, + defaultValue: 0, + checked: 1, + fieldLabel: gettext('Include RAM') + }, + { + xtype: 'textareafield', + grow: true, + editable: !me.viewonly, + name: 'description', + fieldLabel: gettext('Description') + }, + { + title: gettext('Settings'), + hidden: !me.snapname, + xtype: 'grid', + itemId: 'summary', + border: true, + height: 200, + store: { + model: 'KeyValue', + sorters: [ + { + property : 'key', + direction: 'ASC' + } + ] + }, + columns: [ + {header: gettext('Key'), width: 150, dataIndex: 'key'}, + {header: gettext('Value'), flex: 1, dataIndex: 'value'} + ] + } + ]; + + me.url = `/nodes/${me.nodename}/${me.type}/${me.vmid}/snapshot`; + + let subject; + if (me.snapname) { + subject = gettext('Snapshot') + ` ${me.snapname}`; + me.url += `/${me.snapname}/config`; + } else { + subject = (me.type === 'qemu' ? 'VM' : 'CT') + me.vmid + ' ' + gettext('Snapshot'); + me.method = 'POST'; + me.showProgress = true; + } + + Ext.apply(me, { + subject: subject, + width: me.snapname ? 620 : 450, + height: me.snapname ? 420 : undefined, + }); + + me.callParent(); + + if (!me.snapname) { + return; + } + + me.load({ + success: function(response) { + let kvarray = []; + Ext.Object.each(response.result.data, function(key, value) { + if (key === 'description' || key === 'snaptime') { + return; + } + kvarray.push({ key: key, value: value }); + }); + + let summarystore = me.down('#summary').getStore(); + summarystore.suspendEvents(); + summarystore.add(kvarray); + summarystore.sort(); + summarystore.resumeEvents(); + summarystore.fireEvent('refresh', summarystore); + + me.setValues(response.result.data); + } + }); + } +}); -- 2.39.5