add setNodename method to FileSelector and a setUnprivileged to
MPEdit, this allows to make those properties bindable

Reset MPEdits quota checkbox when it gets disabled

Move the loadSSHKeyFromFile helper to the PVE.Utils singleton

And then, with all those changes transform the LXC Create wizard to
a declarative style, in one go. Maybe it's better to just look at the
end result than the diff...

Signed-off-by: Thomas Lamprecht <t.lampre...@proxmox.com>
---

I did not see easy intermediate steps that make sense from a git
history POV, so just sending ti as one change...

 www/manager6/Utils.js             |  19 ++
 www/manager6/form/FileSelector.js |   4 +
 www/manager6/lxc/CreateWizard.js  | 597 ++++++++++++++++++--------------------
 www/manager6/lxc/MPEdit.js        |  13 +-
 www/manager6/lxc/Network.js       |  11 +-
 5 files changed, 325 insertions(+), 319 deletions(-)

diff --git a/www/manager6/Utils.js b/www/manager6/Utils.js
index 8f80c76a..87699e56 100644
--- a/www/manager6/Utils.js
+++ b/www/manager6/Utils.js
@@ -875,6 +875,25 @@ Ext.define('PVE.Utils', { utilities: {
 
            delete values[fieldname];
        }
+    },
+
+    loadSSHKeyFromFile: function(file, callback) {
+       // ssh-keygen produces 740 bytes for an average 4096 bit rsa key, with
+       // a user@host comment, 1420 for 8192 bits; current max is 16kbit
+       // assume: 740*8 for max. 32kbit (5920 byte file)
+       // round upwards to nearest nice number => 8192 bytes, leaves lots of 
comment space
+       if (file.size > 8192) {
+           Ext.Msg.alert(gettext('Error'), gettext("Invalid file size: ") + 
file.size);
+           return;
+       }
+       /*global
+         FileReader
+       */
+       var reader = new FileReader();
+       reader.onload = function(evt) {
+           callback(evt.target.result);
+       };
+       reader.readAsText(file);
     }
 },
 
diff --git a/www/manager6/form/FileSelector.js 
b/www/manager6/form/FileSelector.js
index 9afbf821..3dc50720 100644
--- a/www/manager6/form/FileSelector.js
+++ b/www/manager6/form/FileSelector.js
@@ -47,6 +47,10 @@ Ext.define('PVE.form.FileSelector', {
        me.store.load();
     },
 
+    setNodename: function(nodename) {
+       this.setStorage(undefined, nodename);
+    },
+
     store: {
        model: 'pve-storage-content'
     },
diff --git a/www/manager6/lxc/CreateWizard.js b/www/manager6/lxc/CreateWizard.js
index 5b069317..9abe7887 100644
--- a/www/manager6/lxc/CreateWizard.js
+++ b/www/manager6/lxc/CreateWizard.js
@@ -1,342 +1,317 @@
-/*global
-  FileReader
-*/
-
+/*jslint confusion: true*/
 Ext.define('PVE.lxc.CreateWizard', {
     extend: 'PVE.window.Wizard',
+    mixins: ['Proxmox.Mixin.CBind'],
 
-    loadSSHKeyFromFile: function(file) {
-       var me = this;
-       // ssh-keygen produces 740 bytes for an average 4096 bit rsa key, with
-       // a user@host comment, 1420 for 8192 bits; current max is 16kbit
-       // assume: 740*8 for max. 32kbit (5920 byte file)
-       // round upwards to nearest nice number => 8192 bytes, leaves lots of 
comment space
-       if (file.size > 8192) {
-           Ext.Msg.alert(gettext('Error'), gettext("Invalid file size: ") + 
file.size);
-           return;
+    viewModel: {
+       data: {
+           nodename: '',
+           storage: '',
+           unprivileged: false
        }
-       var reader = new FileReader();
-       reader.onload = function(evt) {
-           me.sshkeyfield.setValue(evt.target.result);
-       };
-       reader.readAsText(file);
     },
 
-    initComponent: function() {
-       var me = this;
+    cbindData: {
+       nodename: undefined
+    },
+
+    subject: gettext('LXC Container'),
 
-       var summarystore = Ext.create('Ext.data.Store', {
-           model: 'KeyValue',
-           sorters: [
+    items: [
+       {
+           xtype: 'inputpanel',
+           title: gettext('General'),
+           onlineHelp: 'pct_general',
+           column1: [
+               {
+                   xtype: 'pveNodeSelector',
+                   name: 'nodename',
+                   cbind: {
+                       selectCurNode: '{!nodename}',
+                       preferredValue: '{nodename}'
+                   },
+                   bind: {
+                       value: '{nodename}'
+                   },
+                   fieldLabel: gettext('Node'),
+                   allowBlank: false,
+                   onlineValidator: true
+               },
+               {
+                   xtype: 'pveGuestIDSelector',
+                   name: 'vmid', // backend only knows vmid
+                   guestType: 'lxc',
+                   value: '',
+                   loadNextFreeID: true,
+                   validateExists: false
+               },
+               {
+                   xtype: 'proxmoxtextfield',
+                   name: 'hostname',
+                   vtype: 'DnsName',
+                   value: '',
+                   fieldLabel: gettext('Hostname'),
+                   skipEmptyText: true,
+                   allowBlank: true
+               },
                {
-                   property : 'key',
-                   direction: 'ASC'
+                   xtype: 'proxmoxcheckbox',
+                   name: 'unprivileged',
+                   value: false,
+                   bind: {
+                       value: '{unprivileged}'
+                   },
+                   fieldLabel: gettext('Unprivileged container')
+               }
+           ],
+           column2: [
+               {
+                   xtype: 'pvePoolSelector',
+                   fieldLabel: gettext('Resource Pool'),
+                   name: 'pool',
+                   submitValue: false,
+                   value: '',
+                   allowBlank: true
+               },
+               {
+                   xtype: 'textfield',
+                   inputType: 'password',
+                   name: 'password',
+                   value: '',
+                   fieldLabel: gettext('Password'),
+                   allowBlank: false,
+                   minLength: 5,
+                   change: function(f, value) {
+                       if (!f.rendered) {
+                           return;
+                       }
+                       f.uo().down('field[name=confirmpw]').validate();
+                   }
+               },
+               {
+                   xtype: 'textfield',
+                   inputType: 'password',
+                   name: 'confirmpw',
+                   value: '',
+                   fieldLabel: gettext('Confirm password'),
+                   allowBlank: true,
+                   submitValue: false,
+                   validator: function(value) {
+                       var pw = 
this.up().down('field[name=password]').getValue();
+                       if (pw !== value) {
+                           return "Passwords do not match!";
+                       }
+                       return true;
+                   }
+               },
+               {
+                   xtype: 'proxmoxtextfield',
+                   name: 'ssh-public-keys',
+                   value: '',
+                   fieldLabel: gettext('SSH public key'),
+                   allowBlank: true,
+                   validator: function(value) {
+                       var pwfield = this.up().down('field[name=password]');
+                       if (value.length) {
+                           var key = PVE.Parser.parseSSHKey(value);
+                           if (!key) {
+                               return "Failed to recognize ssh key";
+                           }
+                           pwfield.allowBlank = true;
+                       } else {
+                           pwfield.allowBlank = false;
+                       }
+                       pwfield.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();
+                           }
+                       };
+                       var field = this;
+                       field.inputEl.on('dragover', cancel);
+                       field.inputEl.on('dragenter', cancel);
+                       field.inputEl.on('drop', function(ev) {
+                           ev = ev.event;
+                           if (ev.preventDefault) {
+                               ev.preventDefault();
+                           }
+                           var files = ev.dataTransfer.files;
+                           PVE.Utils.loadSSHKeyFromFile(files[0], function(v) {
+                               field.setValue(v);
+                           });
+                       });
+                   }
+               },
+               {
+                   xtype: 'filebutton',
+                   name: 'file',
+                   hidden: !window.FileReader,
+                   text: gettext('Load SSH Key File'),
+                   listeners: {
+                       change: function(btn, e, value) {
+                           e = e.event;
+                           var field = 
this.up().down('proxmoxtextfield[name=ssh-public-keys]');
+                           PVE.Utils.loadSSHKeyFromFile(e.target.files[0], 
function(v) {
+                               field.setValue(v);
+                           });
+                           btn.reset();
+                       }
+                   }
                }
            ]
-       });
-
-       var tmplsel = Ext.create('PVE.form.FileSelector', {
-           name: 'ostemplate',
-           storageContent: 'vztmpl',
-           fieldLabel: gettext('Template'),
-           allowBlank: false
-       });
-
-       var tmplstoragesel = Ext.create('PVE.form.StorageSelector', {
-           name: 'tmplstorage',
-           fieldLabel: gettext('Storage'),
-           storageContent: 'vztmpl',
-           autoSelect: true,
-           allowBlank: false,
-           listeners: {
-               change: function(f, value) {
-                   tmplsel.setStorage(value);
+       },
+       {
+           xtype: 'inputpanel',
+           title: gettext('Template'),
+           onlineHelp: 'pct_container_images',
+           column1: [
+               {
+                   xtype: 'pveStorageSelector',
+                   name: 'tmplstorage',
+                   fieldLabel: gettext('Storage'),
+                   storageContent: 'vztmpl',
+                   autoSelect: true,
+                   allowBlank: false,
+                   bind: {
+                       value: '{storage}',
+                       nodename: '{nodename}'
+                   }
+               },
+               {
+                   xtype: 'pveFileSelector',
+                   name: 'ostemplate',
+                   storageContent: 'vztmpl',
+                   fieldLabel: gettext('Template'),
+                   bind: {
+                       storage: '{storage}',
+                       nodename: '{nodename}'
+                   },
+                   allowBlank: false
                }
-           }
-       });
-
-       var rootfspanel = Ext.create('PVE.lxc.MountPointInputPanel', {
+           ]
+       },
+       {
+           xtype: 'pveLxcMountPointInputPanel',
            title: gettext('Root Disk'),
            insideWizard: true,
            isCreate: true,
            unused: false,
-           unprivileged: false,
+           bind: {
+               nodename: '{nodename}',
+               unprivileged: '{unprivileged}'
+           },
            confid: 'rootfs'
-       });
-
-       var networkpanel = Ext.create('PVE.lxc.NetworkInputPanel', {
+       },
+       {
+           xtype: 'pveLxcCPUInputPanel',
+           title: gettext('CPU'),
+           insideWizard: true
+       },
+       {
+           xtype: 'pveLxcMemoryInputPanel',
+           title: gettext('Memory'),
+           insideWizard: true
+       },
+       {
+           xtype: 'pveLxcNetworkInputPanel',
            title: gettext('Network'),
            insideWizard: true,
-           dataCache: {},
+           bind: {
+               nodename: '{nodename}'
+           },
            isCreate: 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();
-           }
-       });
-
-       /*jslint confusion: true */
-       /* the validator function can return either a string or a boolean */
-       me.sshkeyfield = Ext.createWidget('proxmoxtextfield', {
-           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 do not match!";
-                   }
-                   return true;
-               }
-           },
-           me.sshkeyfield
-       ];
-       /*jslint confusion: false */
-
-       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'),
+       },
+       {
+           xtype: 'pveLxcDNSInputPanel',
+           title: gettext('DNS'),
+           insideWizard: true
+       },
+       {
+           title: gettext('Confirm'),
+           layout: 'fit',
            items: [
                {
-                   xtype: 'inputpanel',
-                   title: gettext('General'),
-                   onlineHelp: 'pct_general',
-                   column1: [
-                       {
-                           xtype: 'pveNodeSelector',
-                           name: 'nodename',
-                           selectCurNode: !me.nodename,
-                           preferredValue: me.nodename,
-                           fieldLabel: gettext('Node'),
-                           allowBlank: false,
-                           onlineValidator: true,
-                           listeners: {
-                               change: function(f, value) {
-                                   tmplstoragesel.setNodename(value);
-                                   tmplsel.setStorage(undefined, value);
-                                   networkpanel.setNodename(value);
-                                   rootfspanel.setNodename(value);
-                               }
-                           }
-                       },
-                       {
-                           xtype: 'pveGuestIDSelector',
-                           name: 'vmid', // backend only knows vmid
-                           guestType: 'lxc',
-                           value: '',
-                           loadNextFreeID: true,
-                           validateExists: false
-                       },
-                       {
-                           xtype: 'proxmoxtextfield',
-                           name: 'hostname',
-                           vtype: 'DnsName',
-                           value: '',
-                           fieldLabel: gettext('Hostname'),
-                           skipEmptyText: true,
-                           allowBlank: true
-                       },
-                       {
-                           xtype: 'proxmoxcheckbox',
-                           name: 'unprivileged',
-                           value: '',
-                           listeners: {
-                               change: function(f, value) {
-                                   if (value) {
-                                       
rootfspanel.down('field[name=quota]').setValue(false);
-                                   }
-                                   rootfspanel.unprivileged = value;
-                                   var hdsel = rootfspanel.down('#hdstorage');
-                                   hdsel.fireEvent('change', hdsel, 
hdsel.getValue());
-                               }
-                           },
-                           fieldLabel: gettext('Unprivileged container')
-                       }
-                   ],
-                   column2: column2,
-                   onGetValues: function(values) {
-                       delete values.confirmpw;
-                       if (!values.pool) {
-                           delete values.pool;
-                       }
-                       return values;
-                   }
-               },
-               {
-                   xtype: 'inputpanel',
-                   title: gettext('Template'),
-                   onlineHelp: 'pct_container_images',
-                   column1: [ tmplstoragesel, tmplsel]
-               },
-               rootfspanel,
-               {
-                   xtype: 'pveLxcCPUInputPanel',
-                   title: gettext('CPU'),
-                   insideWizard: true
-               },
-               {
-                   xtype: 'pveLxcMemoryInputPanel',
-                   title: gettext('Memory'),
-                   insideWizard: true
-               },
-               networkpanel,
-               {
-                   xtype: 'pveLxcDNSInputPanel',
-                   title: gettext('DNS'),
-                   insideWizard: true
-               },
-               {
-                   title: gettext('Confirm'),
-                   layout: 'fit',
-                   items: [
-                       {
-                           xtype: 'grid',
-                           store: summarystore,
-                           columns: [
-                               {header: 'Key', width: 150, dataIndex: 'key'},
-                               {header: 'Value', flex: 1, dataIndex: 'value'}
-                           ]
-                       }
-                   ],
-                   listeners: {
-                       show: function(panel) {
-                           var form = me.down('form').getForm();
-                           var kv = me.getValues();
-                           var data = [];
-                           Ext.Object.each(kv, function(key, value) {
-                               if (key === 'delete' || key === 'tmplstorage') 
{ // ignore
-                                   return;
-                               }
-                               if (key === 'password') { // don't show pw
-                                   return;
-                               }
-                               var html = 
Ext.htmlEncode(Ext.JSON.encode(value));
-                               data.push({ key: key, value: value });
-                           });
-                           summarystore.suspendEvents();
-                           summarystore.removeAll();
-                           summarystore.add(data);
-                           summarystore.sort();
-                           summarystore.resumeEvents();
-                           summarystore.fireEvent('refresh');
-                       }
+                   xtype: 'grid',
+                   store: {
+                       model: 'KeyValue',
+                       sorters: [{
+                               property : 'key',
+                               direction: 'ASC'
+                       }]
                    },
-                   onSubmit: function() {
-                       var kv = me.getValues();
-                       delete kv['delete'];
+                   columns: [
+                       {header: 'Key', width: 150, dataIndex: 'key'},
+                       {header: 'Value', flex: 1, dataIndex: 'value'}
+                   ]
+               }
+           ],
+           listeners: {
+               show: function(panel) {
+                   var wizard = this.up('window');
+                   var kv = wizard.getValues();
+                   var data = [];
+                   Ext.Object.each(kv, function(key, value) {
+                       if (key === 'delete' || key === 'tmplstorage') { // 
ignore
+                           return;
+                       }
+                       if (key === 'password') { // don't show pw
+                           return;
+                       }
+                       var html = Ext.htmlEncode(Ext.JSON.encode(value));
+                       data.push({ key: key, value: value });
+                   });
 
-                       var nodename = kv.nodename;
-                       delete kv.nodename;
-                       delete kv.tmplstorage;
+                   var summarystore = panel.down('grid').getStore();
+                   summarystore.suspendEvents();
+                   summarystore.removeAll();
+                   summarystore.add(data);
+                   summarystore.sort();
+                   summarystore.resumeEvents();
+                   summarystore.fireEvent('refresh');
+               }
+           },
+           onSubmit: function() {
+               var wizard = this.up('window');
+               var kv = wizard.getValues();
+               delete kv['delete'];
 
-                       if (!kv.password.length && kv['ssh-public-keys']) {
-                           delete kv.password;
-                       }
+               var nodename = kv.nodename;
+               delete kv.nodename;
+               delete kv.tmplstorage;
+
+               if (!kv.password.length && kv['ssh-public-keys']) {
+                   delete kv.password;
+               }
 
-                       Proxmox.Utils.API2Request({
-                           url: '/nodes/' + nodename + '/lxc',
-                           waitMsgTarget: me,
-                           method: 'POST',
-                           params: kv,
-                           success: function(response, opts){
-                               var upid = response.result.data;
+               Proxmox.Utils.API2Request({
+                   url: '/nodes/' + nodename + '/lxc',
+                   waitMsgTarget: wizard,
+                   method: 'POST',
+                   params: kv,
+                   success: function(response, opts){
+                       var upid = response.result.data;
 
-                               var win = 
Ext.create('Proxmox.window.TaskViewer', {
-                                   upid: upid
-                               });
-                               win.show();
-                               me.close();
-                           },
-                           failure: function(response, opts) {
-                               Ext.Msg.alert(gettext('Error'), 
response.htmlStatus);
-                           }
+                       var win = Ext.create('Proxmox.window.TaskViewer', {
+                           upid: upid
                        });
+                       win.show();
+                       wizard.close();
+                   },
+                   failure: function(response, opts) {
+                       Ext.Msg.alert(gettext('Error'), response.htmlStatus);
                    }
-               }
-           ]
-       });
-
-       me.callParent();
-    }
+               });
+           }
+       }
+    ]
 });
 
 
diff --git a/www/manager6/lxc/MPEdit.js b/www/manager6/lxc/MPEdit.js
index 827869e8..3f84ed5f 100644
--- a/www/manager6/lxc/MPEdit.js
+++ b/www/manager6/lxc/MPEdit.js
@@ -12,6 +12,10 @@ Ext.define('PVE.lxc.MountPointInputPanel', {
 
     vmconfig: {}, // used to select unused disks
 
+    setUnprivileged: function(unprivileged) {
+       this.unprivileged = unprivileged;
+    },
+
     onGetValues: function(values) {
        var me = this;
 
@@ -77,7 +81,6 @@ Ext.define('PVE.lxc.MountPointInputPanel', {
 
        if (mp.type === 'bind') {
            me.quota.setDisabled(true);
-           me.quota.setValue(false);
            me.acl.setDisabled(true);
            me.acl.setValue('Default');
            me.down('#hdstorage').setDisabled(true);
@@ -222,7 +225,12 @@ Ext.define('PVE.lxc.MountPointInputPanel', {
            name: 'quota',
            defaultValue: 0,
            disabled: me.unprivileged,
-           fieldLabel: gettext('Enable quota')
+           fieldLabel: gettext('Enable quota'),
+           listeners: {
+               disable: function() {
+                   this.reset();
+               }
+           }
        });
 
        me.column2 = [
@@ -276,7 +284,6 @@ Ext.define('PVE.lxc.MountPointInputPanel', {
                }
                if (rec.data.type === 'zfs' || rec.data.type === 'zfspool') {
                    me.quota.setDisabled(true);
-                   me.quota.setValue(false);
                } else {
                    me.quota.setDisabled(me.unprivileged);
                }
diff --git a/www/manager6/lxc/Network.js b/www/manager6/lxc/Network.js
index 1b574239..22d30055 100644
--- a/www/manager6/lxc/Network.js
+++ b/www/manager6/lxc/Network.js
@@ -49,17 +49,18 @@ Ext.define('PVE.lxc.NetworkInputPanel', {
     initComponent : function() {
        var me = this;
 
-       if (!me.dataCache) {
-           throw "no dataCache specified";
-       }
-       
        var cdata = {};
 
        if (me.insideWizard) {
            me.ifname = 'net0';
            cdata.name = 'eth0';
+           me.dataCache = {};
        }
-       
+
+       if (!me.dataCache) {
+           throw "no dataCache specified";
+       }
+
        if (!me.isCreate) {
            if (!me.ifname) {
                throw "no interface name specified";
-- 
2.14.2


_______________________________________________
pve-devel mailing list
pve-devel@pve.proxmox.com
https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to