]> git.proxmox.com Git - pve-manager.git/blame - www/manager6/lxc/CreateWizard.js
ui: add lxc/MultiMPEdit and use in lxc/CreateWizard
[pve-manager.git] / www / manager6 / lxc / CreateWizard.js
CommitLineData
09358a73
DM
1Ext.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 },
75b0b132
DC
65 {
66 xtype: 'proxmoxcheckbox',
67 name: 'features',
68 inputValue: 'nesting=1',
69 value: true,
70 bind: {
71 disabled: '{!unprivileged}',
72 },
73 fieldLabel: gettext('Nesting'),
74 },
7adbc4a4
TL
75 ],
76 column2: [
77 {
78 xtype: 'pvePoolSelector',
79 fieldLabel: gettext('Resource Pool'),
80 name: 'pool',
7adbc4a4 81 value: '',
f6710aac 82 allowBlank: true,
09358a73
DM
83 },
84 {
7adbc4a4
TL
85 xtype: 'textfield',
86 inputType: 'password',
87 name: 'password',
88 value: '',
89 fieldLabel: gettext('Password'),
90 allowBlank: false,
91 minLength: 5,
92 change: function(f, value) {
93 if (f.rendered) {
94 f.up().down('field[name=confirmpw]').validate();
95 }
f6710aac 96 },
09358a73 97 },
09358a73 98 {
7adbc4a4
TL
99 xtype: 'textfield',
100 inputType: 'password',
101 name: 'confirmpw',
102 value: '',
103 fieldLabel: gettext('Confirm password'),
104 allowBlank: true,
105 submitValue: false,
106 validator: function(value) {
107 var pw = this.up().down('field[name=password]').getValue();
108 if (pw !== value) {
109 return "Passwords do not match!";
110 }
111 return true;
f6710aac 112 },
09358a73
DM
113 },
114 {
7adbc4a4
TL
115 xtype: 'proxmoxtextfield',
116 name: 'ssh-public-keys',
117 value: '',
118 fieldLabel: gettext('SSH public key'),
119 allowBlank: true,
120 validator: function(value) {
4fd034b1 121 let pwfield = this.up().down('field[name=password]');
7adbc4a4 122 if (value.length) {
4fd034b1 123 let key = PVE.Parser.parseSSHKey(value);
7adbc4a4
TL
124 if (!key) {
125 return "Failed to recognize ssh key";
126 }
127 pwfield.allowBlank = true;
128 } else {
129 pwfield.allowBlank = false;
130 }
131 pwfield.validate();
132 return true;
133 },
134 afterRender: function() {
135 if (!window.FileReader) {
4fd034b1 136 return; // No FileReader support in this browser
09358a73 137 }
4fd034b1 138 let cancelEvent = ev => {
7adbc4a4
TL
139 ev = ev.event;
140 if (ev.preventDefault) {
141 ev.preventDefault();
142 }
143 };
4fd034b1
TL
144 this.inputEl.on('dragover', cancelEvent);
145 this.inputEl.on('dragenter', cancelEvent);
146 this.inputEl.on('drop', ev => {
147 cancelEvent(ev);
148 let files = ev.event.dataTransfer.files;
149 PVE.Utils.loadSSHKeyFromFile(files[0], v => this.setValue(v));
7adbc4a4 150 });
f6710aac 151 },
7adbc4a4
TL
152 },
153 {
154 xtype: 'filebutton',
155 name: 'file',
156 hidden: !window.FileReader,
157 text: gettext('Load SSH Key File'),
09358a73 158 listeners: {
7adbc4a4
TL
159 change: function(btn, e, value) {
160 e = e.event;
4fd034b1
TL
161 let field = this.up().down('proxmoxtextfield[name=ssh-public-keys]');
162 PVE.Utils.loadSSHKeyFromFile(e.target.files[0], v => field.setValue(v));
7adbc4a4 163 btn.reset();
f6710aac
TL
164 },
165 },
166 },
167 ],
7adbc4a4
TL
168 },
169 {
170 xtype: 'inputpanel',
171 title: gettext('Template'),
172 onlineHelp: 'pct_container_images',
173 column1: [
174 {
175 xtype: 'pveStorageSelector',
176 name: 'tmplstorage',
177 fieldLabel: gettext('Storage'),
178 storageContent: 'vztmpl',
179 autoSelect: true,
180 allowBlank: false,
181 bind: {
182 value: '{storage}',
f6710aac
TL
183 nodename: '{nodename}',
184 },
7adbc4a4
TL
185 },
186 {
187 xtype: 'pveFileSelector',
188 name: 'ostemplate',
189 storageContent: 'vztmpl',
190 fieldLabel: gettext('Template'),
191 bind: {
192 storage: '{storage}',
f6710aac 193 nodename: '{nodename}',
7adbc4a4 194 },
f6710aac
TL
195 allowBlank: false,
196 },
197 ],
7adbc4a4
TL
198 },
199 {
af07d3d3
DC
200 xtype: 'pveMultiMPPanel',
201 title: gettext('Disks'),
7adbc4a4
TL
202 insideWizard: true,
203 isCreate: true,
204 unused: false,
f6710aac 205 confid: 'rootfs',
7adbc4a4
TL
206 },
207 {
208 xtype: 'pveLxcCPUInputPanel',
209 title: gettext('CPU'),
f6710aac 210 insideWizard: true,
7adbc4a4
TL
211 },
212 {
213 xtype: 'pveLxcMemoryInputPanel',
214 title: gettext('Memory'),
f6710aac 215 insideWizard: true,
7adbc4a4
TL
216 },
217 {
218 xtype: 'pveLxcNetworkInputPanel',
219 title: gettext('Network'),
220 insideWizard: true,
221 bind: {
f6710aac 222 nodename: '{nodename}',
7adbc4a4 223 },
f6710aac 224 isCreate: true,
7adbc4a4
TL
225 },
226 {
227 xtype: 'pveLxcDNSInputPanel',
228 title: gettext('DNS'),
f6710aac 229 insideWizard: true,
7adbc4a4
TL
230 },
231 {
232 title: gettext('Confirm'),
233 layout: 'fit',
234 items: [
235 {
236 xtype: 'grid',
237 store: {
238 model: 'KeyValue',
239 sorters: [{
8058410f 240 property: 'key',
f6710aac
TL
241 direction: 'ASC',
242 }],
09358a73 243 },
7adbc4a4 244 columns: [
8058410f
TL
245 { header: 'Key', width: 150, dataIndex: 'key' },
246 { header: 'Value', flex: 1, dataIndex: 'value' },
f6710aac
TL
247 ],
248 },
7adbc4a4 249 ],
fe3d3afc
TL
250 dockedItems: [
251 {
252 xtype: 'proxmoxcheckbox',
253 name: 'start',
254 dock: 'bottom',
255 margin: '5 0 0 0',
f6710aac
TL
256 boxLabel: gettext('Start after created'),
257 },
fe3d3afc 258 ],
7adbc4a4
TL
259 listeners: {
260 show: function(panel) {
4fd034b1
TL
261 let wizard = this.up('window');
262 let kv = wizard.getValues();
263 let data = [];
7adbc4a4
TL
264 Ext.Object.each(kv, function(key, value) {
265 if (key === 'delete' || key === 'tmplstorage') { // ignore
266 return;
267 }
268 if (key === 'password') { // don't show pw
269 return;
270 }
7adbc4a4
TL
271 data.push({ key: key, value: value });
272 });
09358a73 273
4fd034b1
TL
274 let summaryStore = panel.down('grid').getStore();
275 summaryStore.suspendEvents();
276 summaryStore.removeAll();
277 summaryStore.add(data);
278 summaryStore.sort();
279 summaryStore.resumeEvents();
280 summaryStore.fireEvent('refresh');
f6710aac 281 },
7adbc4a4
TL
282 },
283 onSubmit: function() {
4fd034b1
TL
284 let wizard = this.up('window');
285 let kv = wizard.getValues();
399ffa76 286 delete kv.delete;
09358a73 287
4fd034b1 288 let nodename = kv.nodename;
7adbc4a4
TL
289 delete kv.nodename;
290 delete kv.tmplstorage;
b1339314 291
4998ae6f
AN
292 if (!kv.pool.length) {
293 delete kv.pool;
294 }
7adbc4a4
TL
295 if (!kv.password.length && kv['ssh-public-keys']) {
296 delete kv.password;
297 }
fd776fca 298
7adbc4a4 299 Proxmox.Utils.API2Request({
4fd034b1 300 url: `/nodes/${nodename}/lxc`,
7adbc4a4
TL
301 waitMsgTarget: wizard,
302 method: 'POST',
303 params: kv,
8058410f 304 success: function(response, opts) {
4fd034b1
TL
305 Ext.create('Proxmox.window.TaskViewer', {
306 autoShow: true,
307 upid: response.result.data,
09358a73 308 });
7adbc4a4
TL
309 wizard.close();
310 },
4fd034b1 311 failure: (response, opts) => Ext.Msg.alert(gettext('Error'), response.htmlStatus),
7adbc4a4 312 });
f6710aac
TL
313 },
314 },
315 ],
09358a73 316});