[pve-devel] [RFC manager 2/2] hardware view: Add disk import button

Dominic Jäger d.jaeger at proxmox.com
Fri May 22 12:08:20 CEST 2020


Is it a bad idea to move column2 as I did here? Seems strange to have column1
and 2 so different but I haven't found an easier way to make it available to
the subclass yet.

@Thomas Is this sort of what you had in mind for this feature?

Signed-off-by: Dominic Jäger <d.jaeger at proxmox.com>
---
 www/manager6/Makefile                    |   1 +
 www/manager6/form/DiskStorageSelector.js |   5 +
 www/manager6/qemu/HDEdit.js              |  50 +++++----
 www/manager6/qemu/HDImport.js            | 128 +++++++++++++++++++++++
 www/manager6/qemu/HardwareView.js        |  13 +++
 5 files changed, 176 insertions(+), 21 deletions(-)
 create mode 100644 www/manager6/qemu/HDImport.js

diff --git a/www/manager6/Makefile b/www/manager6/Makefile
index a29e280d..c1645748 100644
--- a/www/manager6/Makefile
+++ b/www/manager6/Makefile
@@ -143,6 +143,7 @@ JSSRC= 				                 	\
 	qemu/Smbios1Edit.js				\
 	qemu/CDEdit.js					\
 	qemu/HDEdit.js					\
+	qemu/HDImport.js				\
 	qemu/HDResize.js				\
 	qemu/HDMove.js					\
 	qemu/HDEfi.js					\
diff --git a/www/manager6/form/DiskStorageSelector.js b/www/manager6/form/DiskStorageSelector.js
index 445e3ac0..2c1555e1 100644
--- a/www/manager6/form/DiskStorageSelector.js
+++ b/www/manager6/form/DiskStorageSelector.js
@@ -32,6 +32,11 @@ Ext.define('PVE.form.DiskStorageSelector', {
     // string because else we get a type confusion
     defaultSize: '32',
 
+    setDiskSize: function(newSize) {
+	    let field = this.getComponent('disksize');
+	    field.setValue(newSize);
+    },
+
     changeStorage: function(f, value) {
 	var me = this;
 	var formatsel = me.getComponent('diskformat');
diff --git a/www/manager6/qemu/HDEdit.js b/www/manager6/qemu/HDEdit.js
index fd890600..5d6c12e9 100644
--- a/www/manager6/qemu/HDEdit.js
+++ b/www/manager6/qemu/HDEdit.js
@@ -13,6 +13,28 @@ Ext.define('PVE.qemu.HDInputPanel', {
 
     viewModel: {},
 
+    diskStorageSelector: {
+	xtype: 'pveDiskStorageSelector',
+	storageContent: 'images',
+	name: 'disk',
+	reference: 'storageSelector',
+    },
+
+    column2: [
+	    {
+		xtype: 'CacheTypeSelector',
+		name: 'cache',
+		value: '__default__',
+		fieldLabel: gettext('Cache')
+	    },
+	    {
+		xtype: 'proxmoxcheckbox',
+		fieldLabel: gettext('Discard'),
+		reference: 'discard',
+		name: 'discard'
+	    },
+    ],
+
     controller: {
 
 	xclass: 'Ext.app.ViewController',
@@ -164,7 +186,6 @@ Ext.define('PVE.qemu.HDInputPanel', {
 	me.drive = {};
 
 	me.column1 = [];
-	me.column2 = [];
 
 	me.advancedColumn1 = [];
 	me.advancedColumn2 = [];
@@ -188,6 +209,8 @@ Ext.define('PVE.qemu.HDInputPanel', {
 	    me.column1.push(me.scsiController);
 	}
 
+	me.diskStorageSelector.nodename = me.nodename;
+	me.diskStorageSelector.autoSelect = me.insideWizard;
 	if (me.unused) {
 	    me.unusedDisks = Ext.create('Proxmox.form.KVComboBox', {
 		name: 'unusedId',
@@ -201,13 +224,7 @@ Ext.define('PVE.qemu.HDInputPanel', {
 	    });
 	    me.column1.push(me.unusedDisks);
 	} else if (me.isCreate) {
-	    me.column1.push({
-		xtype: 'pveDiskStorageSelector',
-		storageContent: 'images',
-		name: 'disk',
-		nodename: me.nodename,
-		autoSelect: me.insideWizard
-	    });
+	    me.column1.push(me.diskStorageSelector);
 	} else {
 	    me.column1.push({
 		xtype: 'textfield',
@@ -219,18 +236,6 @@ Ext.define('PVE.qemu.HDInputPanel', {
 	}
 
 	me.column2.push(
-	    {
-		xtype: 'CacheTypeSelector',
-		name: 'cache',
-		value: '__default__',
-		fieldLabel: gettext('Cache')
-	    },
-	    {
-		xtype: 'proxmoxcheckbox',
-		fieldLabel: gettext('Discard'),
-		reference: 'discard',
-		name: 'discard'
-	    }
 	);
 
 	me.advancedColumn1.push(
@@ -358,7 +363,9 @@ Ext.define('PVE.qemu.HDEdit', {
 
     backgroundDelay: 5,
 
-    initComponent : function() {
+    isImport: false,
+
+    initComponent: function() {
 	var me = this;
 
 	var nodename = me.pveSelNode.data.node;
@@ -374,6 +381,7 @@ Ext.define('PVE.qemu.HDEdit', {
 	    confid: me.confid,
 	    nodename: nodename,
 	    unused: unused,
+	    isImport: me.isImport,
 	    isCreate: me.isCreate
 	});
 
diff --git a/www/manager6/qemu/HDImport.js b/www/manager6/qemu/HDImport.js
new file mode 100644
index 00000000..16e08ff2
--- /dev/null
+++ b/www/manager6/qemu/HDImport.js
@@ -0,0 +1,128 @@
+Ext.define('PVE.qemu.HDImportInputPanel', {
+    extend: 'PVE.qemu.HDInputPanel',
+    alias: 'widget.pveQemuHDImportInputPanel',
+
+    constructor: function(config) {
+	let me = this;
+	this.callParent([config]);
+    },
+
+    column2: [
+	{
+	    xtype: 'textfield',
+	    fieldLabel: gettext('Source image'),
+	    name: 'inputImage',
+	    emptyText: '/home/user/disk.qcow2',
+	    submitValue: true,
+	},
+    ],
+
+    initComponent: function() {
+	let me = this;
+	this.column2 = this.superclass.column2.concat(this.column2);
+	Object.assign(this.diskStorageSelector, this.superclass.diskStorageSelector );
+	let inputField = this.column2.find(el => el.name == 'inputImage');
+	if (typeof inputField !== 'undefined') {
+	    inputField.listeners = {
+	        focusleave: function() {
+		    // TODO get size of source image
+		    let newSize = Math.floor(Math.random()*100);
+		    me.lookup('storageSelector').setDiskSize(newSize);
+	        },
+	    };
+	}
+	this.callParent();
+	let selector = this.lookup('storageSelector');
+    },
+    onGetValues: function(values) {
+	let params = this.callParent([values]);
+	params['source'] = values.inputImage;
+	return params;
+    },
+});
+
+Ext.define('PVE.qemu.HDImport', {
+    extend: 'Proxmox.window.Edit',
+
+    isImport: true,
+    isCreate: true,
+    subject: gettext('Import Hard Disk'),
+    submitText: gettext('Import'),
+    submit: function() {
+	let submitObject = this;
+	let params = submitObject.getValues();
+	let importParams = {};
+	let addParams = {};
+	Ext.Object.each(params, function(name, val) {
+	    if (name === 'storage' || name === 'source') {
+		importParams[name] = val;
+	    } else {
+	       addParams[name] = val;
+	    }
+	});
+	let me = this;
+	var form = me.formPanel.getForm();
+	Proxmox.Utils.API2Request({
+	    url: submitObject.url.replace(/config/, 'importdisk'),
+	    backgroundDelay: 0,
+	    method: 'POST',
+	    params: params,
+	    failure: function(response, options) {
+		me.apiCallDone(false, response, options);
+
+		if (response.result && response.result.errors) {
+		    form.markInvalid(response.result.errors);
+		}
+		Ext.Msg.alert(gettext('Error'), response.htmlStatus);
+	    },
+	    success: function(response, options) {
+		var hasProgressBar = (me.backgroundDelay || me.showProgress || me.showTaskViewer) &&
+		    response.result.data ? true : false;
+
+		me.apiCallDone(true, response, options);
+
+		if (hasProgressBar) {
+		    // stay around so we can trigger our close events
+		    // when background action is completed
+		    me.hide();
+
+		    var upid = response.result.data;
+		    var viewerClass = me.showTaskViewer ? 'Viewer' : 'Progress';
+		    var win = Ext.create('Proxmox.window.Task' + viewerClass, {
+			upid: upid,
+			taskDone: me.taskDone,
+			listeners: {
+			    destroy: function () {
+				me.close();
+			    }
+			}
+		    });
+		    win.show();
+		} else {
+		    me.close();
+		}
+	    }
+	});
+    },
+    constructor: function(config) {
+	this.callParent([config]);
+    },
+
+    initComponent: function() {
+	let nodename = this.pveSelNode.data.node;
+	if (!nodename) { throw 'no node name specified'; }
+
+	this.items = [ Ext.create('PVE.qemu.HDImportInputPanel', {
+	    confid: this.confid,
+	    nodename: nodename,
+	    isImport: true,
+	    isCreate: true,
+	})];
+
+	this.callParent(); 
+    },
+
+    onGetValues: function(values) {
+	this.callParent();
+    },
+});
diff --git a/www/manager6/qemu/HardwareView.js b/www/manager6/qemu/HardwareView.js
index 6c831ad6..47fb5cea 100644
--- a/www/manager6/qemu/HardwareView.js
+++ b/www/manager6/qemu/HardwareView.js
@@ -438,6 +438,18 @@ Ext.define('PVE.qemu.HardwareView', {
 	    handler: run_move
 	});
 
+	var import_btn = new Proxmox.button.Button({
+	    text: gettext('Import disk'),
+	    handler: function() {
+		var win = Ext.create('PVE.qemu.HDImport', {
+		    url: '/api2/extjs/' + baseurl,
+		    pveSelNode: me.pveSelNode,
+		});
+		win.on('destroy', me.reload, me);
+		win.show();
+	    },
+	});
+
 	var remove_btn = new Proxmox.button.Button({
 	    text: gettext('Remove'),
 	    defaultText: gettext('Remove'),
@@ -754,6 +766,7 @@ Ext.define('PVE.qemu.HardwareView', {
 		edit_btn,
 		resize_btn,
 		move_btn,
+		import_btn,
 		revert_btn
 	    ],
 	    rows: rows,
-- 
2.20.1




More information about the pve-devel mailing list