]> git.proxmox.com Git - pve-manager.git/blob - www/manager6/lxc/CreateWizard.js
Convert the VMIDSelector to a generic GuestIDSelector
[pve-manager.git] / www / manager6 / lxc / CreateWizard.js
1 /*global
2 FileReader
3 */
4 /*jslint confusion: true */
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 create: true,
62 unused: false,
63 confid: 'rootfs'
64 });
65
66 var networkpanel = Ext.create('PVE.lxc.NetworkInputPanel', {
67 title: gettext('Network'),
68 insideWizard: true,
69 dataCache: {},
70 create: true
71 });
72
73 var passwordfield = Ext.createWidget('textfield', {
74 inputType: 'password',
75 name: 'password',
76 value: '',
77 fieldLabel: gettext('Password'),
78 allowBlank: false,
79 minLength: 5,
80 change: function(f, value) {
81 if (!me.rendered) {
82 return;
83 }
84 me.down('field[name=confirmpw]').validate();
85 }
86 });
87
88 me.sshkeyfield = Ext.createWidget('pvetextfield', {
89 name: 'ssh-public-keys',
90 value: '',
91 fieldLabel: gettext('SSH public key'),
92 allowBlank: true,
93 validator: function(value) {
94 if (value.length) {
95 var key = PVE.Parser.parseSSHKey(value);
96 if (!key) {
97 return "Failed to recognize ssh key";
98 }
99 me.down('field[name=password]').allowBlank = true;
100 } else {
101 me.down('field[name=password]').allowBlank = false;
102 }
103 me.down('field[name=password]').validate();
104 return true;
105 },
106 afterRender: function() {
107 if (!window.FileReader) {
108 // No FileReader support in this browser
109 return;
110 }
111 var cancel = function(ev) {
112 ev = ev.event;
113 if (ev.preventDefault) {
114 ev.preventDefault();
115 }
116 };
117 me.sshkeyfield.inputEl.on('dragover', cancel);
118 me.sshkeyfield.inputEl.on('dragenter', cancel);
119 me.sshkeyfield.inputEl.on('drop', function(ev) {
120 ev = ev.event;
121 if (ev.preventDefault) {
122 ev.preventDefault();
123 }
124 var files = ev.dataTransfer.files;
125 me.loadSSHKeyFromFile(files[0]);
126 });
127 }
128 });
129
130 var column2 = [
131 {
132 xtype: 'pvePoolSelector',
133 fieldLabel: gettext('Resource Pool'),
134 name: 'pool',
135 value: '',
136 allowBlank: true
137 },
138 passwordfield,
139 {
140 xtype: 'textfield',
141 inputType: 'password',
142 name: 'confirmpw',
143 value: '',
144 fieldLabel: gettext('Confirm password'),
145 allowBlank: true,
146 validator: function(value) {
147 var pw = me.down('field[name=password]').getValue();
148 if (pw !== value) {
149 return "Passwords does not match!";
150 }
151 return true;
152 }
153 },
154 me.sshkeyfield
155 ];
156
157 if (window.FileReader) {
158 column2.push({
159 xtype: 'filebutton',
160 name: 'file',
161 text: gettext('Load SSH Key File'),
162 listeners: {
163 change: function(btn, e, value) {
164 e = e.event;
165 me.loadSSHKeyFromFile(e.target.files[0]);
166 btn.reset();
167 }
168 }
169 });
170 }
171
172 Ext.applyIf(me, {
173 subject: gettext('LXC Container'),
174 items: [
175 {
176 xtype: 'inputpanel',
177 title: gettext('General'),
178 onlineHelp: 'pct_general',
179 column1: [
180 {
181 xtype: 'pveNodeSelector',
182 name: 'nodename',
183 selectCurNode: true,
184 fieldLabel: gettext('Node'),
185 allowBlank: false,
186 onlineValidator: true,
187 listeners: {
188 change: function(f, value) {
189 tmplstoragesel.setNodename(value);
190 tmplsel.setStorage(undefined, value);
191 networkpanel.setNodename(value);
192 rootfspanel.setNodename(value);
193 }
194 }
195 },
196 {
197 xtype: 'pveGuestIDSelector',
198 name: 'vmid', // backend only knows vmid
199 guestType: 'lxc',
200 value: '',
201 loadNextFreeID: true,
202 validateExists: false
203 },
204 {
205 xtype: 'pvetextfield',
206 name: 'hostname',
207 vtype: 'DnsName',
208 value: '',
209 fieldLabel: gettext('Hostname'),
210 skipEmptyText: true,
211 allowBlank: true
212 },
213 {
214 xtype: 'pvecheckbox',
215 name: 'unprivileged',
216 value: '',
217 fieldLabel: gettext('Unprivileged container')
218 }
219 ],
220 column2: column2,
221 onGetValues: function(values) {
222 delete values.confirmpw;
223 if (!values.pool) {
224 delete values.pool;
225 }
226 return values;
227 }
228 },
229 {
230 xtype: 'inputpanel',
231 title: gettext('Template'),
232 onlineHelp: 'pct_container_images',
233 column1: [ tmplstoragesel, tmplsel]
234 },
235 rootfspanel,
236 {
237 xtype: 'pveLxcCPUInputPanel',
238 title: gettext('CPU'),
239 insideWizard: true
240 },
241 {
242 xtype: 'pveLxcMemoryInputPanel',
243 title: gettext('Memory'),
244 insideWizard: true
245 },
246 networkpanel,
247 {
248 xtype: 'pveLxcDNSInputPanel',
249 title: gettext('DNS'),
250 insideWizard: true
251 },
252 {
253 title: gettext('Confirm'),
254 layout: 'fit',
255 items: [
256 {
257 title: gettext('Settings'),
258 xtype: 'grid',
259 store: summarystore,
260 columns: [
261 {header: 'Key', width: 150, dataIndex: 'key'},
262 {header: 'Value', flex: 1, dataIndex: 'value'}
263 ]
264 }
265 ],
266 listeners: {
267 show: function(panel) {
268 var form = me.down('form').getForm();
269 var kv = me.getValues();
270 var data = [];
271 Ext.Object.each(kv, function(key, value) {
272 if (key === 'delete' || key === 'tmplstorage') { // ignore
273 return;
274 }
275 if (key === 'password') { // don't show pw
276 return;
277 }
278 var html = Ext.htmlEncode(Ext.JSON.encode(value));
279 data.push({ key: key, value: value });
280 });
281 summarystore.suspendEvents();
282 summarystore.removeAll();
283 summarystore.add(data);
284 summarystore.sort();
285 summarystore.resumeEvents();
286 summarystore.fireEvent('refresh');
287 }
288 },
289 onSubmit: function() {
290 var kv = me.getValues();
291 delete kv['delete'];
292
293 var nodename = kv.nodename;
294 delete kv.nodename;
295 delete kv.tmplstorage;
296
297 if (!kv.password.length && kv['ssh-public-keys']) {
298 delete kv.password;
299 }
300
301 PVE.Utils.API2Request({
302 url: '/nodes/' + nodename + '/lxc',
303 waitMsgTarget: me,
304 method: 'POST',
305 params: kv,
306 success: function(response, opts){
307 var upid = response.result.data;
308
309 var win = Ext.create('PVE.window.TaskViewer', {
310 upid: upid
311 });
312 win.show();
313 me.close();
314 },
315 failure: function(response, opts) {
316 Ext.Msg.alert(gettext('Error'), response.htmlStatus);
317 }
318 });
319 }
320 }
321 ]
322 });
323
324 me.callParent();
325 }
326 });
327
328
329