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

Dominik Csapak d.csapak at proxmox.com
Wed May 27 08:51:37 CEST 2020


sry for the delay of the review....

a few comments inline

On 5/22/20 12:08 PM, Dominic Jäger wrote:
> 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?

i do not know what you're talked about, but seeing this
i would rather put the 'importing' code directly
into the hdedit panel, and make the 'mode' configurable

since most of the logic is in the window anyway.
that would avoid the whole issue of the accessing
columns of the superclass etc.

> 
> 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');

i guess this is leftover? (since its not used)

> +    },
> +    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;
> +	    }
> +	});

its ok but we can use

for (const [key,val] of Object.entries(someObj)) {
}

now ;)

also, neither addParams, nor importParams are actually used?


> +	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,
> 





More information about the pve-devel mailing list