[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