]>
Commit | Line | Data |
---|---|---|
09358a73 DM |
1 | Ext.define('PVE.lxc.CreateWizard', { |
2 | extend: 'PVE.window.Wizard', | |
7adbc4a4 | 3 | mixins: ['Proxmox.Mixin.CBind'], |
09358a73 | 4 | |
7adbc4a4 TL |
5 | viewModel: { |
6 | data: { | |
7 | nodename: '', | |
8 | storage: '', | |
02307282 | 9 | unprivileged: true |
7adbc4a4 TL |
10 | } |
11 | }, | |
b1339314 | 12 | |
7adbc4a4 TL |
13 | cbindData: { |
14 | nodename: undefined | |
15 | }, | |
b1339314 | 16 | |
7adbc4a4 | 17 | subject: gettext('LXC Container'), |
b1339314 | 18 | |
7adbc4a4 TL |
19 | items: [ |
20 | { | |
21 | xtype: 'inputpanel', | |
22 | title: gettext('General'), | |
23 | onlineHelp: 'pct_general', | |
24 | column1: [ | |
09358a73 | 25 | { |
7adbc4a4 TL |
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 | |
09358a73 DM |
46 | }, |
47 | { | |
7adbc4a4 TL |
48 | xtype: 'proxmoxtextfield', |
49 | name: 'hostname', | |
50 | vtype: 'DnsName', | |
51 | value: '', | |
52 | fieldLabel: gettext('Hostname'), | |
53 | skipEmptyText: true, | |
54 | allowBlank: true | |
09358a73 | 55 | }, |
09358a73 | 56 | { |
7adbc4a4 TL |
57 | xtype: 'proxmoxcheckbox', |
58 | name: 'unprivileged', | |
02307282 | 59 | value: true, |
7adbc4a4 TL |
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', | |
7adbc4a4 TL |
71 | value: '', |
72 | allowBlank: true | |
09358a73 DM |
73 | }, |
74 | { | |
7adbc4a4 TL |
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 | } | |
09358a73 | 87 | }, |
09358a73 | 88 | { |
7adbc4a4 TL |
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 | } | |
09358a73 DM |
103 | }, |
104 | { | |
7adbc4a4 TL |
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; | |
09358a73 | 128 | } |
7adbc4a4 TL |
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'), | |
09358a73 | 155 | listeners: { |
7adbc4a4 TL |
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); | |
09358a73 | 161 | }); |
7adbc4a4 | 162 | btn.reset(); |
09358a73 | 163 | } |
7adbc4a4 TL |
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 | }] | |
09358a73 | 246 | }, |
7adbc4a4 TL |
247 | columns: [ |
248 | {header: 'Key', width: 150, dataIndex: 'key'}, | |
249 | {header: 'Value', flex: 1, dataIndex: 'value'} | |
250 | ] | |
251 | } | |
252 | ], | |
fe3d3afc TL |
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 | ], | |
7adbc4a4 TL |
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 | }); | |
09358a73 | 277 | |
7adbc4a4 TL |
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']; | |
09358a73 | 291 | |
7adbc4a4 TL |
292 | var nodename = kv.nodename; |
293 | delete kv.nodename; | |
294 | delete kv.tmplstorage; | |
b1339314 | 295 | |
4998ae6f AN |
296 | if (!kv.pool.length) { |
297 | delete kv.pool; | |
298 | } | |
299 | ||
7adbc4a4 TL |
300 | if (!kv.password.length && kv['ssh-public-keys']) { |
301 | delete kv.password; | |
302 | } | |
fd776fca | 303 | |
7adbc4a4 TL |
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 | |
09358a73 | 314 | }); |
7adbc4a4 TL |
315 | win.show(); |
316 | wizard.close(); | |
317 | }, | |
318 | failure: function(response, opts) { | |
319 | Ext.Msg.alert(gettext('Error'), response.htmlStatus); | |
09358a73 | 320 | } |
7adbc4a4 TL |
321 | }); |
322 | } | |
323 | } | |
324 | ] | |
09358a73 DM |
325 | }); |
326 | ||
327 | ||
328 |