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