]> git.proxmox.com Git - pve-manager.git/blame - www/manager6/lxc/MPEdit.js
ui: eslint: enforce "no-extra-parens" rule
[pve-manager.git] / www / manager6 / lxc / MPEdit.js
CommitLineData
34c235be
DC
1/* hidden: boolean and string
2 * bind: function and object
3 * disabled: boolean and string
4 */
342225bf 5Ext.define('PVE.lxc.MountPointInputPanel', {
ef4ef788 6 extend: 'Proxmox.panel.InputPanel',
34c235be 7 xtype: 'pveLxcMountPointInputPanel',
342225bf
DC
8
9 insideWizard: false,
10
11 onlineHelp: 'pct_container_storage',
12
13 unused: false, // add unused disk imaged
14
15 unprivileged: false,
16
17 vmconfig: {}, // used to select unused disks
18
658bf725 19 setUnprivileged: function(unprivileged) {
34c235be
DC
20 var me = this;
21 var vm = me.getViewModel();
22 me.unprivileged = unprivileged;
23 vm.set('unpriv', unprivileged);
658bf725
TL
24 },
25
342225bf
DC
26 onGetValues: function(values) {
27 var me = this;
28
85e6b368 29 var confid = me.confid || "mp"+values.mpid;
f9b63366 30 me.mp.file = me.down('field[name=file]').getValue();
342225bf
DC
31
32 if (me.unused) {
85e6b368 33 confid = "mp"+values.mpid;
342225bf 34 } else if (me.isCreate) {
f9b63366 35 me.mp.file = values.hdstorage + ':' + values.disksize;
342225bf
DC
36 }
37
34c235be 38 // delete unnecessary fields
85e6b368 39 delete values.mpid;
34c235be
DC
40 delete values.hdstorage;
41 delete values.disksize;
42 delete values.diskformat;
342225bf 43
f9b63366
DC
44 let mountopts = (values.mountoptions || []).join(';');
45 PVE.Utils.propertyStringSet(me.mp, values.mp, 'mp');
46 PVE.Utils.propertyStringSet(me.mp, values.mountoptions, 'mountoptions', mountopts);
47 PVE.Utils.propertyStringSet(me.mp, values.backup, 'backup');
48 PVE.Utils.propertyStringSet(me.mp, values.quota, 'quota');
49 PVE.Utils.propertyStringSet(me.mp, values.ro, 'ro');
50 PVE.Utils.propertyStringSet(me.mp, values.acl, 'acl');
51 PVE.Utils.propertyStringSet(me.mp, values.replicate, 'replicate');
52
342225bf 53 var res = {};
f9b63366 54 res[confid] = PVE.Parser.printLxcMountPoint(me.mp);
342225bf
DC
55 return res;
56 },
57
34c235be 58
342225bf
DC
59 setMountPoint: function(mp) {
60 var me = this;
34c235be
DC
61 var vm = this.getViewModel();
62 vm.set('mptype', mp.type);
c115473d
OB
63 if (mp.mountoptions) {
64 mp.mountoptions = mp.mountoptions.split(';');
65 }
f9b63366 66 me.mp = mp;
1780a644
OB
67
68 if (this.confid === 'rootfs') {
69 var field = me.down('field[name=mountoptions]');
70 var forbidden = ['nodev', 'noexec'];
71 var filtered = field.comboItems.filter(e => !forbidden.includes(e[0]));
72 field.setComboItems(filtered);
73 }
74
342225bf
DC
75 me.setValues(mp);
76 },
77
78 setVMConfig: function(vmconfig) {
79 var me = this;
34c235be 80 var vm = me.getViewModel();
342225bf 81 me.vmconfig = vmconfig;
34c235be 82 vm.set('unpriv', vmconfig.unprivileged);
34c235be
DC
83
84 PVE.Utils.forEachMP(function(bus, i) {
85 var name = "mp" + i.toString();
86 if (!Ext.isDefined(vmconfig[name])) {
85e6b368 87 me.down('field[name=mpid]').setValue(i);
34c235be 88 return false;
342225bf 89 }
34c235be 90 });
342225bf
DC
91 },
92
93 setNodename: function(nodename) {
94 var me = this;
34c235be
DC
95 var vm = me.getViewModel();
96 vm.set('node', nodename);
34c235be 97 me.down('#diskstorage').setNodename(nodename);
342225bf
DC
98 },
99
8058410f 100 controller: {
34c235be 101 xclass: 'Ext.app.ViewController',
342225bf 102
34c235be 103 control: {
85e6b368 104 'field[name=mpid]': {
34c235be
DC
105 change: function(field, value) {
106 field.validate();
f6710aac 107 },
34c235be
DC
108 },
109 '#hdstorage': {
110 change: function(field, newValue) {
111 var me = this;
112 if (!newValue) {
342225bf
DC
113 return;
114 }
34c235be
DC
115
116 var rec = field.store.getById(newValue);
117 if (!rec) {
118 return;
342225bf 119 }
34c235be
DC
120
121 var vm = me.getViewModel();
122 vm.set('type', rec.data.type);
f6710aac
TL
123 },
124 },
34c235be
DC
125 },
126
127 init: function(view) {
128 var me = this;
129 var vm = this.getViewModel();
f9b63366 130 view.mp = {};
34c235be
DC
131 vm.set('confid', view.confid);
132 vm.set('unused', view.unused);
133 vm.set('node', view.nodename);
134 vm.set('unpriv', view.unprivileged);
135 vm.set('hideStorSelector', view.unused || !view.isCreate);
2b4c02c0
AL
136
137 // can be array if created from unused disk
138 if (view.isCreate) {
139 vm.set('isIncludedInBackup', true);
140 }
f6710aac 141 },
34c235be
DC
142 },
143
144 viewModel: {
145 data: {
146 unpriv: false,
147 unused: false,
148 showStorageSelector: false,
149 mptype: '',
150 type: '',
151 confid: '',
f6710aac 152 node: '',
34c235be
DC
153 },
154
155 formulas: {
156 quota: function(get) {
157 return !(get('type') === 'zfs' ||
158 get('type') === 'zfspool' ||
159 get('unpriv') ||
160 get('isBind'));
161 },
162 hasMP: function(get) {
163 return !!get('confid') && !get('unused');
164 },
165 isRoot: function(get) {
166 return get('confid') === 'rootfs';
167 },
168 isBind: function(get) {
169 return get('mptype') === 'bind';
170 },
171 isBindOrRoot: function(get) {
172 return get('isBind') || get('isRoot');
f6710aac
TL
173 },
174 },
34c235be 175 },
342225bf 176
34c235be
DC
177 column1: [
178 {
85e6b368
FG
179 xtype: 'proxmoxintegerfield',
180 name: 'mpid',
181 fieldLabel: gettext('Mount Point ID'),
182 minValue: 0,
183 maxValue: PVE.Utils.mp_counts.mps - 1,
34c235be
DC
184 hidden: true,
185 allowBlank: false,
6c442961 186 disabled: true,
34c235be
DC
187 bind: {
188 hidden: '{hasMP}',
f6710aac 189 disabled: '{hasMP}',
34c235be 190 },
34c235be
DC
191 validator: function(value) {
192 var me = this.up('inputpanel');
193 if (!me.rendered) {
194 return;
195 }
85e6b368 196 if (Ext.isDefined(me.vmconfig["mp"+value])) {
34c235be
DC
197 return "Mount point is already in use.";
198 }
34c235be
DC
199 /* returns a string above */
200 return true;
f6710aac 201 },
34c235be
DC
202 },
203 {
234d2e37 204 xtype: 'pveDiskStorageSelector',
34c235be 205 itemId: 'diskstorage',
342225bf 206 storageContent: 'rootdir',
34c235be 207 hidden: true,
342225bf 208 autoSelect: true,
34c235be 209 selectformat: false,
c6c8e2fc 210 defaultSize: 8,
34c235be
DC
211 bind: {
212 hidden: '{hideStorSelector}',
213 disabled: '{hideStorSelector}',
f6710aac
TL
214 nodename: '{node}',
215 },
34c235be
DC
216 },
217 {
218 xtype: 'textfield',
219 disabled: true,
220 submitValue: false,
221 fieldLabel: gettext('Disk image'),
222 name: 'file',
223 bind: {
f6710aac
TL
224 hidden: '{!hideStorSelector}',
225 },
226 },
34c235be
DC
227 ],
228
229 column2: [
230 {
231 xtype: 'textfield',
232 name: 'mp',
233 value: '',
8058410f 234 emptyText: gettext('/some/path'),
34c235be 235 allowBlank: false,
6c442961 236 disabled: true,
34c235be
DC
237 fieldLabel: gettext('Path'),
238 bind: {
239 hidden: '{isRoot}',
f6710aac
TL
240 disabled: '{isRoot}',
241 },
34c235be
DC
242 },
243 {
244 xtype: 'proxmoxcheckbox',
245 name: 'backup',
0bead056
TL
246 fieldLabel: gettext('Backup'),
247 autoEl: {
248 tag: 'div',
249 'data-qtip': gettext('Include volume in backup job'),
250 },
34c235be
DC
251 bind: {
252 hidden: '{isRoot}',
2b4c02c0 253 disabled: '{isBindOrRoot}',
f6710aac
TL
254 value: '{isIncludedInBackup}',
255 },
256 },
34c235be 257 ],
342225bf 258
34c235be
DC
259 advancedColumn1: [
260 {
261 xtype: 'proxmoxcheckbox',
342225bf
DC
262 name: 'quota',
263 defaultValue: 0,
34c235be 264 bind: {
f6710aac 265 disabled: '{!quota}',
34c235be 266 },
658bf725
TL
267 fieldLabel: gettext('Enable quota'),
268 listeners: {
269 disable: function() {
270 this.reset();
f6710aac
TL
271 },
272 },
34c235be
DC
273 },
274 {
275 xtype: 'proxmoxcheckbox',
276 name: 'ro',
277 defaultValue: 0,
278 bind: {
279 hidden: '{isRoot}',
f6710aac 280 disabled: '{isRoot}',
34c235be 281 },
f6710aac 282 fieldLabel: gettext('Read-only'),
7b6c7881
TL
283 },
284 {
285 xtype: 'proxmoxKVComboBox',
286 name: 'mountoptions',
287 fieldLabel: gettext('Mount options'),
288 deleteEmpty: false,
289 comboItems: [
290 ['noatime', 'noatime'],
291 ['nodev', 'nodev'],
292 ['noexec', 'noexec'],
f6710aac 293 ['nosuid', 'nosuid'],
7b6c7881
TL
294 ],
295 multiSelect: true,
296 value: [],
f6710aac 297 allowBlank: true,
7b6c7881 298 },
34c235be 299 ],
342225bf 300
34c235be
DC
301 advancedColumn2: [
302 {
303 xtype: 'proxmoxKVComboBox',
304 name: 'acl',
305 fieldLabel: 'ACLs',
306 deleteEmpty: false,
307 comboItems: [
308 ['__default__', Proxmox.Utils.defaultText],
309 ['1', Proxmox.Utils.enabledText],
f6710aac 310 ['0', Proxmox.Utils.disabledText],
34c235be
DC
311 ],
312 value: '__default__',
313 bind: {
f6710aac 314 disabled: '{isBind}',
34c235be 315 },
f6710aac 316 allowBlank: true,
34c235be
DC
317 },
318 {
319 xtype: 'proxmoxcheckbox',
320 inputValue: '0', // reverses the logic
321 name: 'replicate',
f6710aac
TL
322 fieldLabel: gettext('Skip replication'),
323 },
324 ],
342225bf
DC
325});
326
327Ext.define('PVE.lxc.MountPointEdit', {
9fccc702 328 extend: 'Proxmox.window.Edit',
342225bf
DC
329
330 unprivileged: false,
331
8058410f 332 initComponent: function() {
342225bf
DC
333 var me = this;
334
335 var nodename = me.pveSelNode.data.node;
336 if (!nodename) {
337 throw "no node name specified";
338 }
339
340 var unused = me.confid && me.confid.match(/^unused\d+$/);
341
342 me.isCreate = me.confid ? unused : true;
343
344 var ipanel = Ext.create('PVE.lxc.MountPointInputPanel', {
345 confid: me.confid,
346 nodename: nodename,
347 unused: unused,
348 unprivileged: me.unprivileged,
f6710aac 349 isCreate: me.isCreate,
342225bf
DC
350 });
351
352 var subject;
353 if (unused) {
354 subject = gettext('Unused Disk');
355 } else if (me.isCreate) {
356 subject = gettext('Mount Point');
357 } else {
358 subject = gettext('Mount Point') + ' (' + me.confid + ')';
359 }
360
361 Ext.apply(me, {
362 subject: subject,
dc683ca0 363 defaultFocus: me.confid !== 'rootfs' ? 'textfield[name=mp]' : 'tool',
f6710aac 364 items: ipanel,
342225bf
DC
365 });
366
367 me.callParent();
368
369 me.load({
370 success: function(response, options) {
371 ipanel.setVMConfig(response.result.data);
372 if (me.confid) {
342225bf
DC
373 /*data is defined as array above*/
374 var value = response.result.data[me.confid];
342225bf
DC
375 var mp = PVE.Parser.parseLxcMountPoint(value);
376
377 if (!mp) {
378 Ext.Msg.alert(gettext('Error'), 'Unable to parse mount point options');
379 me.close();
380 return;
381 }
382
383 ipanel.setMountPoint(mp);
384 me.isValid(); // trigger validation
385 }
f6710aac 386 },
342225bf 387 });
f6710aac 388 },
342225bf 389});