[pve-devel] [RFC rebased manager] lxc: wizard: ssh key

Dominik Csapak d.csapak at proxmox.com
Mon Aug 8 16:49:26 CEST 2016


the only thing i want to mention:

if you select a big file, the browser hangs (no wonder, since it tries 
to fill a textbox with the content of the file),
can we check if the file has a sane size beforehand?
(anything over a few kb should be rejected

rest looks good to me,
tested in chromium, firefox, ie11 (win10), edge (win10)

On 08/08/2016 01:00 PM, Wolfgang Bumiller wrote:
> ---
> @Dominic: can you look over this please?
>
>  www/manager6/Parser.js           |  30 ++++++++
>  www/manager6/lxc/CreateWizard.js | 155 +++++++++++++++++++++++++++++----------
>  2 files changed, 146 insertions(+), 39 deletions(-)
>
> diff --git a/www/manager6/Parser.js b/www/manager6/Parser.js
> index c049d06..c796d35 100644
> --- a/www/manager6/Parser.js
> +++ b/www/manager6/Parser.js
> @@ -493,5 +493,35 @@ Ext.define('PVE.Parser', { statics: {
>  	}
>
>  	return cpustr + optstr;
> +    },
> +
> +    parseSSHKey: function(key) {
> +	//                |--- options can have quotes--|     type    key        comment
> +	var keyre = /^(?:((?:[^\s"]|\"(?:\\.|[^"\\])*")+)\s+)?(\S+)\s+(\S+)(?:\s+(.*))?$/;
> +	var typere = /^(?:ssh-(?:dss|rsa|ed25519)|ecdsa-sha2-nistp\d+)$/;
> +
> +	var m = key.match(keyre);
> +	if (!m) {
> +	    return null;
> +	}
> +	if (m.length < 3 || !m[2]) { // [2] is always either type or key
> +	    return null;
> +	}
> +	if (m[1] && m[1].match(typere)) {
> +	    return {
> +		type: m[1],
> +		key: m[2],
> +		comment: m[3]
> +	    };
> +	}
> +	if (m[2].match(typere)) {
> +	    return {
> +		options: m[1],
> +		type: m[2],
> +		key: m[3],
> +		comment: m[4]
> +	    };
> +	}
> +	return null;
>      }
>  }});
> diff --git a/www/manager6/lxc/CreateWizard.js b/www/manager6/lxc/CreateWizard.js
> index a1a7b57..ad4a100 100644
> --- a/www/manager6/lxc/CreateWizard.js
> +++ b/www/manager6/lxc/CreateWizard.js
> @@ -2,6 +2,15 @@
>  Ext.define('PVE.lxc.CreateWizard', {
>      extend: 'PVE.window.Wizard',
>
> +    loadSSHKeyFromFile: function(file) {
> +	var me = this;
> +	var reader = new FileReader();
> +	reader.onload = function(evt) {
> +	    me.sshkeyfield.setValue(evt.target.result);
> +	};
> +	reader.readAsText(file);
> +    },
> +
>      initComponent: function() {
>  	var me = this;
>
> @@ -50,6 +59,106 @@ Ext.define('PVE.lxc.CreateWizard', {
>  	    create: true
>  	});
>
> +	var passwordfield = Ext.createWidget('textfield', {
> +	    inputType: 'password',
> +	    name: 'password',
> +	    value: '',
> +	    fieldLabel: gettext('Password'),
> +	    allowBlank: false,
> +	    minLength: 5,
> +	    change: function(f, value) {
> +		if (!me.rendered) {
> +		    return;
> +		}
> +		me.down('field[name=confirmpw]').validate();
> +	    }
> +	});
> +
> +	me.sshkeyfield = Ext.createWidget('textfield', {
> +	    xtype: 'textfield',
> +	    name: 'ssh-public-keys',
> +	    value: '',
> +	    fieldLabel: gettext('SSH public key'),
> +	    allowBlank: true,
> +	    validator: function(value) {
> +		if (value.length) {
> +		    var key = PVE.Parser.parseSSHKey(value);
> +		    if (!key) {
> +			return "Failed to recognize ssh key";
> +		    }
> +		    me.down('field[name=password]').allowBlank = true;
> +		} else {
> +		    me.down('field[name=password]').allowBlank = false;
> +		}
> +		me.down('field[name=password]').validate();
> +		return true;
> +	    },
> +	    afterRender: function() {
> +		if (!window.FileReader) {
> +		    // No FileReader support in this browser
> +		    return;
> +		}
> +		var cancel = function(ev) {
> +		    ev = ev.event;
> +		    if (ev.preventDefault) {
> +			ev.preventDefault();
> +		    }
> +		};
> +		me.sshkeyfield.inputEl.on('dragover', cancel);
> +		me.sshkeyfield.inputEl.on('dragenter', cancel);
> +		me.sshkeyfield.inputEl.on('drop', function(ev) {
> +		    ev = ev.event;
> +		    if (ev.preventDefault) {
> +			ev.preventDefault();
> +		    }
> +		    var files = ev.dataTransfer.files;
> +		    me.loadSSHKeyFromFile(files[0]);
> +		});
> +	    },
> +	});
> +
> +	var column2 = [
> +	    {
> +		xtype: 'pvePoolSelector',
> +		fieldLabel: gettext('Resource Pool'),
> +		name: 'pool',
> +		value: '',
> +		allowBlank: true
> +	    },
> +	    passwordfield,
> +	    {
> +		xtype: 'textfield',
> +		inputType: 'password',
> +		name: 'confirmpw',
> +		value: '',
> +		fieldLabel: gettext('Confirm password'),
> +		allowBlank: true,
> +		validator: function(value) {
> +		    var pw = me.down('field[name=password]').getValue();
> +		    if (pw !== value) {
> +			return "Passwords does not match!";
> +		    }
> +		    return true;
> +		}
> +	    },
> +	    me.sshkeyfield
> +	];
> +
> +	if (window.FileReader) {
> +	    column2.push({
> +		xtype: 'filebutton',
> +		name: 'file',
> +		text: gettext('Load SSH Key File'),
> +		listeners: {
> +		    change: function(btn, e, value) {
> +			e = e.event;
> +			me.loadSSHKeyFromFile(e.target.files[0]);
> +			btn.reset();
> +		    }
> +		}
> +	    });
> +	}
> +
>  	Ext.applyIf(me, {
>  	    subject: gettext('LXC Container'),
>  	    items: [
> @@ -89,45 +198,7 @@ Ext.define('PVE.lxc.CreateWizard', {
>  			    allowBlank: true
>  			}
>  		    ],
> -		    column2: [
> -			{
> -			    xtype: 'pvePoolSelector',
> -			    fieldLabel: gettext('Resource Pool'),
> -			    name: 'pool',
> -			    value: '',
> -			    allowBlank: true
> -			},
> -			{
> -			    xtype: 'textfield',
> -			    inputType: 'password',
> -			    name: 'password',
> -			    value: '',
> -			    fieldLabel: gettext('Password'),
> -			    allowBlank: false,
> -			    minLength: 5,
> -			    change: function(f, value) {
> -				if (!me.rendered) {
> -				    return;
> -				}
> -				me.down('field[name=confirmpw]').validate();
> -			    }
> -			},
> -			{
> -			    xtype: 'textfield',
> -			    inputType: 'password',
> -			    name: 'confirmpw',
> -			    value: '',
> -			    fieldLabel: gettext('Confirm password'),
> -			    allowBlank: false,
> -			    validator: function(value) {
> -				var pw = me.down('field[name=password]').getValue();
> -				if (pw !== value) {
> -				    return "Passwords does not match!";
> -				}
> -				return true;
> -			    }
> -			}
> -		    ],
> +		    column2: column2,
>  		    onGetValues: function(values) {
>  			delete values.confirmpw;
>  			if (!values.pool) {
> @@ -203,6 +274,12 @@ Ext.define('PVE.lxc.CreateWizard', {
>  			delete kv.nodename;
>  			delete kv.tmplstorage;
>
> +			if (!kv['ssh-public-keys'].length) {
> +			    delete kv['ssh-public-keys'];
> +			} else if (!kv['password'].length) {
> +			    delete kv['password'];
> +			}
> +
>  			PVE.Utils.API2Request({
>  			    url: '/nodes/' + nodename + '/lxc',
>  			    waitMsgTarget: me,
>





More information about the pve-devel mailing list