]> git.proxmox.com Git - pve-manager.git/blob - www/manager6/lxc/CreateWizard.js
use Checkbox from widget toolkit
[pve-manager.git] / www / manager6 / lxc / CreateWizard.js
1 /*global
2 FileReader
3 */
4
5 Ext.define('PVE.lxc.CreateWizard', {
6 extend: 'PVE.window.Wizard',
7
8 loadSSHKeyFromFile: function(file) {
9 var me = this;
10 // ssh-keygen produces 740 bytes for an average 4096 bit rsa key, with
11 // a user@host comment, 1420 for 8192 bits; current max is 16kbit
12 // assume: 740*8 for max. 32kbit (5920 byte file)
13 // round upwards to nearest nice number => 8192 bytes, leaves lots of comment space
14 if (file.size > 8192) {
15 Ext.Msg.alert(gettext('Error'), gettext("Invalid file size: ") + file.size);
16 return;
17 }
18 var reader = new FileReader();
19 reader.onload = function(evt) {
20 me.sshkeyfield.setValue(evt.target.result);
21 };
22 reader.readAsText(file);
23 },
24
25 initComponent: function() {
26 var me = this;
27
28 var summarystore = Ext.create('Ext.data.Store', {
29 model: 'KeyValue',
30 sorters: [
31 {
32 property : 'key',
33 direction: 'ASC'
34 }
35 ]
36 });
37
38 var tmplsel = Ext.create('PVE.form.FileSelector', {
39 name: 'ostemplate',
40 storageContent: 'vztmpl',
41 fieldLabel: gettext('Template'),
42 allowBlank: false
43 });
44
45 var tmplstoragesel = Ext.create('PVE.form.StorageSelector', {
46 name: 'tmplstorage',
47 fieldLabel: gettext('Storage'),
48 storageContent: 'vztmpl',
49 autoSelect: true,
50 allowBlank: false,
51 listeners: {
52 change: function(f, value) {
53 tmplsel.setStorage(value);
54 }
55 }
56 });
57
58 var rootfspanel = Ext.create('PVE.lxc.MountPointInputPanel', {
59 title: gettext('Root Disk'),
60 insideWizard: true,
61 isCreate: true,
62 unused: false,
63 unprivileged: false,
64 confid: 'rootfs'
65 });
66
67 var networkpanel = Ext.create('PVE.lxc.NetworkInputPanel', {
68 title: gettext('Network'),
69 insideWizard: true,
70 dataCache: {},
71 isCreate: true
72 });
73
74 var passwordfield = Ext.createWidget('textfield', {
75 inputType: 'password',
76 name: 'password',
77 value: '',
78 fieldLabel: gettext('Password'),
79 allowBlank: false,
80 minLength: 5,
81 change: function(f, value) {
82 if (!me.rendered) {
83 return;
84 }
85 me.down('field[name=confirmpw]').validate();
86 }
87 });
88
89 /*jslint confusion: true */
90 /* the validator function can return either a string or a boolean */
91 me.sshkeyfield = Ext.createWidget('proxmoxtextfield', {
92 name: 'ssh-public-keys',
93 value: '',
94 fieldLabel: gettext('SSH public key'),
95 allowBlank: true,
96 validator: function(value) {
97 if (value.length) {
98 var key = PVE.Parser.parseSSHKey(value);
99 if (!key) {
100 return "Failed to recognize ssh key";
101 }
102 me.down('field[name=password]').allowBlank = true;
103 } else {
104 me.down('field[name=password]').allowBlank = false;
105 }
106 me.down('field[name=password]').validate();
107 return true;
108 },
109 afterRender: function() {
110 if (!window.FileReader) {
111 // No FileReader support in this browser
112 return;
113 }
114 var cancel = function(ev) {
115 ev = ev.event;
116 if (ev.preventDefault) {
117 ev.preventDefault();
118 }
119 };
120 me.sshkeyfield.inputEl.on('dragover', cancel);
121 me.sshkeyfield.inputEl.on('dragenter', cancel);
122 me.sshkeyfield.inputEl.on('drop', function(ev) {
123 ev = ev.event;
124 if (ev.preventDefault) {
125 ev.preventDefault();
126 }
127 var files = ev.dataTransfer.files;
128 me.loadSSHKeyFromFile(files[0]);
129 });
130 }
131 });
132
133 var column2 = [
134 {
135 xtype: 'pvePoolSelector',
136 fieldLabel: gettext('Resource Pool'),
137 name: 'pool',
138 value: '',
139 allowBlank: true
140 },
141 passwordfield,
142 {
143 xtype: 'textfield',
144 inputType: 'password',
145 name: 'confirmpw',
146 value: '',
147 fieldLabel: gettext('Confirm password'),
148 allowBlank: true,
149 validator: function(value) {
150 var pw = me.down('field[name=password]').getValue();
151 if (pw !== value) {
152 return "Passwords do not match!";
153 }
154 return true;
155 }
156 },
157 me.sshkeyfield
158 ];
159 /*jslint confusion: false */
160
161 if (window.FileReader) {
162 column2.push({
163 xtype: 'filebutton',
164 name: 'file',
165 text: gettext('Load SSH Key File'),
166 listeners: {
167 change: function(btn, e, value) {
168 e = e.event;
169 me.loadSSHKeyFromFile(e.target.files[0]);
170 btn.reset();
171 }
172 }
173 });
174 }
175
176 Ext.applyIf(me, {
177 subject: gettext('LXC Container'),
178 items: [
179 {
180 xtype: 'inputpanel',
181 title: gettext('General'),
182 onlineHelp: 'pct_general',
183 column1: [
184 {
185 xtype: 'pveNodeSelector',
186 name: 'nodename',
187 selectCurNode: !me.nodename,
188 preferredValue: me.nodename,
189 fieldLabel: gettext('Node'),
190 allowBlank: false,
191 onlineValidator: true,
192 listeners: {
193 change: function(f, value) {
194 tmplstoragesel.setNodename(value);
195 tmplsel.setStorage(undefined, value);
196 networkpanel.setNodename(value);
197 rootfspanel.setNodename(value);
198 }
199 }
200 },
201 {
202 xtype: 'pveGuestIDSelector',
203 name: 'vmid', // backend only knows vmid
204 guestType: 'lxc',
205 value: '',
206 loadNextFreeID: true,
207 validateExists: false
208 },
209 {
210 xtype: 'proxmoxtextfield',
211 name: 'hostname',
212 vtype: 'DnsName',
213 value: '',
214 fieldLabel: gettext('Hostname'),
215 skipEmptyText: true,
216 allowBlank: true
217 },
218 {
219 xtype: 'proxmoxcheckbox',
220 name: 'unprivileged',
221 value: '',
222 listeners: {
223 change: function(f, value) {
224 if (value) {
225 rootfspanel.down('field[name=quota]').setValue(false);
226 }
227 rootfspanel.unprivileged = value;
228 var hdsel = rootfspanel.down('#hdstorage');
229 hdsel.fireEvent('change', hdsel, hdsel.getValue());
230 }
231 },
232 fieldLabel: gettext('Unprivileged container')
233 }
234 ],
235 column2: column2,
236 onGetValues: function(values) {
237 delete values.confirmpw;
238 if (!values.pool) {
239 delete values.pool;
240 }
241 return values;
242 }
243 },
244 {
245 xtype: 'inputpanel',
246 title: gettext('Template'),
247 onlineHelp: 'pct_container_images',
248 column1: [ tmplstoragesel, tmplsel]
249 },
250 rootfspanel,
251 {
252 xtype: 'pveLxcCPUInputPanel',
253 title: gettext('CPU'),
254 insideWizard: true
255 },
256 {
257 xtype: 'pveLxcMemoryInputPanel',
258 title: gettext('Memory'),
259 insideWizard: true
260 },
261 networkpanel,
262 {
263 xtype: 'pveLxcDNSInputPanel',
264 title: gettext('DNS'),
265 insideWizard: true
266 },
267 {
268 title: gettext('Confirm'),
269 layout: 'fit',
270 items: [
271 {
272 xtype: 'grid',
273 store: summarystore,
274 columns: [
275 {header: 'Key', width: 150, dataIndex: 'key'},
276 {header: 'Value', flex: 1, dataIndex: 'value'}
277 ]
278 }
279 ],
280 listeners: {
281 show: function(panel) {
282 var form = me.down('form').getForm();
283 var kv = me.getValues();
284 var data = [];
285 Ext.Object.each(kv, function(key, value) {
286 if (key === 'delete' || key === 'tmplstorage') { // ignore
287 return;
288 }
289 if (key === 'password') { // don't show pw
290 return;
291 }
292 var html = Ext.htmlEncode(Ext.JSON.encode(value));
293 data.push({ key: key, value: value });
294 });
295 summarystore.suspendEvents();
296 summarystore.removeAll();
297 summarystore.add(data);
298 summarystore.sort();
299 summarystore.resumeEvents();
300 summarystore.fireEvent('refresh');
301 }
302 },
303 onSubmit: function() {
304 var kv = me.getValues();
305 delete kv['delete'];
306
307 var nodename = kv.nodename;
308 delete kv.nodename;
309 delete kv.tmplstorage;
310
311 if (!kv.password.length && kv['ssh-public-keys']) {
312 delete kv.password;
313 }
314
315 Proxmox.Utils.API2Request({
316 url: '/nodes/' + nodename + '/lxc',
317 waitMsgTarget: me,
318 method: 'POST',
319 params: kv,
320 success: function(response, opts){
321 var upid = response.result.data;
322
323 var win = Ext.create('PVE.window.TaskViewer', {
324 upid: upid
325 });
326 win.show();
327 me.close();
328 },
329 failure: function(response, opts) {
330 Ext.Msg.alert(gettext('Error'), response.htmlStatus);
331 }
332 });
333 }
334 }
335 ]
336 });
337
338 me.callParent();
339 }
340 });
341
342
343