]>
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: '', | |
f6710aac TL |
9 | unprivileged: true, |
10 | }, | |
7adbc4a4 | 11 | }, |
b1339314 | 12 | |
7adbc4a4 | 13 | cbindData: { |
f6710aac | 14 | nodename: undefined, |
7adbc4a4 | 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}', | |
f6710aac | 30 | preferredValue: '{nodename}', |
7adbc4a4 TL |
31 | }, |
32 | bind: { | |
f6710aac | 33 | value: '{nodename}', |
7adbc4a4 TL |
34 | }, |
35 | fieldLabel: gettext('Node'), | |
36 | allowBlank: false, | |
f6710aac | 37 | onlineValidator: true, |
7adbc4a4 TL |
38 | }, |
39 | { | |
40 | xtype: 'pveGuestIDSelector', | |
41 | name: 'vmid', // backend only knows vmid | |
42 | guestType: 'lxc', | |
43 | value: '', | |
44 | loadNextFreeID: true, | |
f6710aac | 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, | |
f6710aac | 54 | allowBlank: true, |
09358a73 | 55 | }, |
09358a73 | 56 | { |
7adbc4a4 TL |
57 | xtype: 'proxmoxcheckbox', |
58 | name: 'unprivileged', | |
02307282 | 59 | value: true, |
7adbc4a4 | 60 | bind: { |
f6710aac | 61 | value: '{unprivileged}', |
7adbc4a4 | 62 | }, |
f6710aac TL |
63 | fieldLabel: gettext('Unprivileged container'), |
64 | }, | |
7adbc4a4 TL |
65 | ], |
66 | column2: [ | |
67 | { | |
68 | xtype: 'pvePoolSelector', | |
69 | fieldLabel: gettext('Resource Pool'), | |
70 | name: 'pool', | |
7adbc4a4 | 71 | value: '', |
f6710aac | 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 | } | |
f6710aac | 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; | |
f6710aac | 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 | } | |
49aac034 TL |
143 | let files = ev.dataTransfer.files; |
144 | PVE.Utils.loadSSHKeyFromFile(files[0], v => field.setValue(v)); | |
7adbc4a4 | 145 | }); |
f6710aac | 146 | }, |
7adbc4a4 TL |
147 | }, |
148 | { | |
149 | xtype: 'filebutton', | |
150 | name: 'file', | |
151 | hidden: !window.FileReader, | |
152 | text: gettext('Load SSH Key File'), | |
09358a73 | 153 | listeners: { |
7adbc4a4 TL |
154 | change: function(btn, e, value) { |
155 | e = e.event; | |
156 | var field = this.up().down('proxmoxtextfield[name=ssh-public-keys]'); | |
157 | PVE.Utils.loadSSHKeyFromFile(e.target.files[0], function(v) { | |
158 | field.setValue(v); | |
09358a73 | 159 | }); |
7adbc4a4 | 160 | btn.reset(); |
f6710aac TL |
161 | }, |
162 | }, | |
163 | }, | |
164 | ], | |
7adbc4a4 TL |
165 | }, |
166 | { | |
167 | xtype: 'inputpanel', | |
168 | title: gettext('Template'), | |
169 | onlineHelp: 'pct_container_images', | |
170 | column1: [ | |
171 | { | |
172 | xtype: 'pveStorageSelector', | |
173 | name: 'tmplstorage', | |
174 | fieldLabel: gettext('Storage'), | |
175 | storageContent: 'vztmpl', | |
176 | autoSelect: true, | |
177 | allowBlank: false, | |
178 | bind: { | |
179 | value: '{storage}', | |
f6710aac TL |
180 | nodename: '{nodename}', |
181 | }, | |
7adbc4a4 TL |
182 | }, |
183 | { | |
184 | xtype: 'pveFileSelector', | |
185 | name: 'ostemplate', | |
186 | storageContent: 'vztmpl', | |
187 | fieldLabel: gettext('Template'), | |
188 | bind: { | |
189 | storage: '{storage}', | |
f6710aac | 190 | nodename: '{nodename}', |
7adbc4a4 | 191 | }, |
f6710aac TL |
192 | allowBlank: false, |
193 | }, | |
194 | ], | |
7adbc4a4 TL |
195 | }, |
196 | { | |
197 | xtype: 'pveLxcMountPointInputPanel', | |
198 | title: gettext('Root Disk'), | |
199 | insideWizard: true, | |
200 | isCreate: true, | |
201 | unused: false, | |
202 | bind: { | |
203 | nodename: '{nodename}', | |
f6710aac | 204 | unprivileged: '{unprivileged}', |
7adbc4a4 | 205 | }, |
f6710aac | 206 | confid: 'rootfs', |
7adbc4a4 TL |
207 | }, |
208 | { | |
209 | xtype: 'pveLxcCPUInputPanel', | |
210 | title: gettext('CPU'), | |
f6710aac | 211 | insideWizard: true, |
7adbc4a4 TL |
212 | }, |
213 | { | |
214 | xtype: 'pveLxcMemoryInputPanel', | |
215 | title: gettext('Memory'), | |
f6710aac | 216 | insideWizard: true, |
7adbc4a4 TL |
217 | }, |
218 | { | |
219 | xtype: 'pveLxcNetworkInputPanel', | |
220 | title: gettext('Network'), | |
221 | insideWizard: true, | |
222 | bind: { | |
f6710aac | 223 | nodename: '{nodename}', |
7adbc4a4 | 224 | }, |
f6710aac | 225 | isCreate: true, |
7adbc4a4 TL |
226 | }, |
227 | { | |
228 | xtype: 'pveLxcDNSInputPanel', | |
229 | title: gettext('DNS'), | |
f6710aac | 230 | insideWizard: true, |
7adbc4a4 TL |
231 | }, |
232 | { | |
233 | title: gettext('Confirm'), | |
234 | layout: 'fit', | |
235 | items: [ | |
236 | { | |
237 | xtype: 'grid', | |
238 | store: { | |
239 | model: 'KeyValue', | |
240 | sorters: [{ | |
8058410f | 241 | property: 'key', |
f6710aac TL |
242 | direction: 'ASC', |
243 | }], | |
09358a73 | 244 | }, |
7adbc4a4 | 245 | columns: [ |
8058410f TL |
246 | { header: 'Key', width: 150, dataIndex: 'key' }, |
247 | { header: 'Value', flex: 1, dataIndex: 'value' }, | |
f6710aac TL |
248 | ], |
249 | }, | |
7adbc4a4 | 250 | ], |
fe3d3afc TL |
251 | dockedItems: [ |
252 | { | |
253 | xtype: 'proxmoxcheckbox', | |
254 | name: 'start', | |
255 | dock: 'bottom', | |
256 | margin: '5 0 0 0', | |
f6710aac TL |
257 | boxLabel: gettext('Start after created'), |
258 | }, | |
fe3d3afc | 259 | ], |
7adbc4a4 TL |
260 | listeners: { |
261 | show: function(panel) { | |
262 | var wizard = this.up('window'); | |
263 | var kv = wizard.getValues(); | |
264 | var data = []; | |
265 | Ext.Object.each(kv, function(key, value) { | |
266 | if (key === 'delete' || key === 'tmplstorage') { // ignore | |
267 | return; | |
268 | } | |
269 | if (key === 'password') { // don't show pw | |
270 | return; | |
271 | } | |
272 | var html = Ext.htmlEncode(Ext.JSON.encode(value)); | |
273 | data.push({ key: key, value: value }); | |
274 | }); | |
09358a73 | 275 | |
7adbc4a4 TL |
276 | var summarystore = panel.down('grid').getStore(); |
277 | summarystore.suspendEvents(); | |
278 | summarystore.removeAll(); | |
279 | summarystore.add(data); | |
280 | summarystore.sort(); | |
281 | summarystore.resumeEvents(); | |
282 | summarystore.fireEvent('refresh'); | |
f6710aac | 283 | }, |
7adbc4a4 TL |
284 | }, |
285 | onSubmit: function() { | |
286 | var wizard = this.up('window'); | |
287 | var kv = wizard.getValues(); | |
288 | delete kv['delete']; | |
09358a73 | 289 | |
7adbc4a4 TL |
290 | var nodename = kv.nodename; |
291 | delete kv.nodename; | |
292 | delete kv.tmplstorage; | |
b1339314 | 293 | |
4998ae6f AN |
294 | if (!kv.pool.length) { |
295 | delete kv.pool; | |
296 | } | |
297 | ||
7adbc4a4 TL |
298 | if (!kv.password.length && kv['ssh-public-keys']) { |
299 | delete kv.password; | |
300 | } | |
fd776fca | 301 | |
7adbc4a4 TL |
302 | Proxmox.Utils.API2Request({ |
303 | url: '/nodes/' + nodename + '/lxc', | |
304 | waitMsgTarget: wizard, | |
305 | method: 'POST', | |
306 | params: kv, | |
8058410f | 307 | success: function(response, opts) { |
7adbc4a4 TL |
308 | var upid = response.result.data; |
309 | ||
310 | var win = Ext.create('Proxmox.window.TaskViewer', { | |
f6710aac | 311 | upid: upid, |
09358a73 | 312 | }); |
7adbc4a4 TL |
313 | win.show(); |
314 | wizard.close(); | |
315 | }, | |
316 | failure: function(response, opts) { | |
317 | Ext.Msg.alert(gettext('Error'), response.htmlStatus); | |
f6710aac | 318 | }, |
7adbc4a4 | 319 | }); |
f6710aac TL |
320 | }, |
321 | }, | |
322 | ], | |
09358a73 DM |
323 | }); |
324 | ||
325 |