]>
Commit | Line | Data |
---|---|---|
342225bf DC |
1 | Ext.define('PVE.lxc.MountPointInputPanel', { |
2 | extend: 'PVE.panel.InputPanel', | |
3 | alias: 'widget.pveLxcMountPointInputPanel', | |
4 | ||
5 | insideWizard: false, | |
6 | ||
7 | onlineHelp: 'pct_container_storage', | |
8 | ||
9 | unused: false, // add unused disk imaged | |
10 | ||
11 | unprivileged: false, | |
12 | ||
13 | vmconfig: {}, // used to select unused disks | |
14 | ||
15 | onGetValues: function(values) { | |
16 | var me = this; | |
17 | ||
18 | var confid = me.confid || values.mpsel; | |
19 | ||
20 | if (me.unused) { | |
21 | me.mpdata.file = me.vmconfig[values.unusedId]; | |
22 | confid = values.mpsel; | |
23 | } else if (me.isCreate) { | |
234d2e37 | 24 | me.mpdata.file = values.hdstorage + ':' + values.disksize; |
342225bf DC |
25 | } |
26 | ||
27 | if (confid !== 'rootfs') { | |
28 | me.mpdata.mp = values.mp; | |
29 | } | |
30 | ||
31 | if (values.ro) { | |
32 | me.mpdata.ro = 1; | |
33 | } else { | |
34 | delete me.mpdata.ro; | |
35 | } | |
36 | ||
37 | if (values.quota) { | |
38 | me.mpdata.quota = 1; | |
39 | } else { | |
40 | delete me.mpdata.quota; | |
41 | } | |
42 | ||
43 | if (values.acl === 'Default') { | |
44 | delete me.mpdata.acl; | |
45 | } else { | |
46 | me.mpdata.acl = values.acl; | |
47 | } | |
48 | ||
49 | if (values.backup) { | |
50 | me.mpdata.backup = 1; | |
51 | } else { | |
52 | delete me.mpdata.backup; | |
53 | } | |
54 | ||
55 | if (values.noreplicate) { | |
56 | me.mpdata.replicate = '0'; | |
57 | } | |
58 | delete me.mpdata.noreplicate; | |
59 | ||
60 | var res = {}; | |
61 | res[confid] = PVE.Parser.printLxcMountPoint(me.mpdata); | |
62 | return res; | |
63 | }, | |
64 | ||
65 | setMountPoint: function(mp) { | |
66 | var me = this; | |
67 | ||
234d2e37 DC |
68 | // the fields name is 'hdstorage', |
69 | // but the api expects/has 'storage' | |
70 | mp.hdstorage = mp.storage; | |
71 | delete mp.hdstorage; | |
72 | ||
342225bf DC |
73 | me.mpdata = mp; |
74 | if (!Ext.isDefined(me.mpdata.acl)) { | |
75 | me.mpdata.acl = 'Default'; | |
76 | } | |
77 | ||
78 | if (mp.type === 'bind') { | |
79 | me.quota.setDisabled(true); | |
80 | me.quota.setValue(false); | |
81 | me.acl.setDisabled(true); | |
82 | me.acl.setValue('Default'); | |
234d2e37 | 83 | me.down('#hdstorage').setDisabled(true); |
342225bf DC |
84 | if (me.confid !== 'rootfs') { |
85 | me.backup.setDisabled(true); | |
86 | } | |
87 | } | |
88 | ||
89 | if (mp.replicate) { // check box reverses the config option | |
90 | mp.noreplicate = !PVE.Parser.parseBoolean(mp.replicate, 1); | |
91 | delete mp.replicate; | |
92 | } | |
93 | ||
94 | me.setValues(mp); | |
95 | }, | |
96 | ||
97 | setVMConfig: function(vmconfig) { | |
98 | var me = this; | |
99 | ||
100 | me.vmconfig = vmconfig; | |
101 | ||
102 | if (me.mpsel) { | |
103 | var i; | |
104 | for (i = 0; i != 8; ++i) { | |
105 | var name = "mp" + i.toString(); | |
106 | if (!Ext.isDefined(vmconfig[name])) { | |
107 | me.mpsel.setValue(name); | |
108 | break; | |
109 | } | |
110 | } | |
111 | } | |
112 | ||
113 | if (me.unusedDisks) { | |
114 | var disklist = []; | |
115 | Ext.Object.each(vmconfig, function(key, value) { | |
116 | if (key.match(/^unused\d+$/)) { | |
117 | disklist.push([key, value]); | |
118 | } | |
119 | }); | |
120 | me.unusedDisks.store.loadData(disklist); | |
121 | me.unusedDisks.setValue(me.confid); | |
122 | } | |
123 | }, | |
124 | ||
125 | setNodename: function(nodename) { | |
126 | var me = this; | |
234d2e37 DC |
127 | me.down('#hdstorage').setNodename(nodename); |
128 | me.down('#hdimage').setStorage(undefined, nodename); | |
342225bf DC |
129 | }, |
130 | ||
131 | initComponent : function() { | |
132 | var me = this; | |
133 | ||
134 | var isroot = me.confid === 'rootfs'; | |
135 | ||
136 | me.mpdata = {}; | |
137 | ||
138 | me.column1 = []; | |
139 | ||
140 | if (!me.confid || me.unused) { | |
141 | var names = []; | |
142 | var i; | |
143 | for (i = 0; i != 8; ++i) { | |
144 | var name = 'mp' + i.toString(); | |
145 | names.push([name, name]); | |
146 | } | |
09cacce7 | 147 | me.mpsel = Ext.create('Proxmox.form.KVComboBox', { |
342225bf DC |
148 | name: 'mpsel', |
149 | fieldLabel: gettext('Mount Point'), | |
150 | matchFieldWidth: false, | |
151 | allowBlank: false, | |
152 | comboItems: names, | |
153 | validator: function(value) { | |
154 | if (!me.rendered) { | |
155 | return; | |
156 | } | |
157 | if (Ext.isDefined(me.vmconfig[value])) { | |
158 | return "Mount point is already in use."; | |
159 | } | |
160 | /*jslint confusion: true*/ | |
161 | /* returns a string above */ | |
162 | return true; | |
163 | }, | |
164 | listeners: { | |
165 | change: function(field, value) { | |
166 | field.validate(); | |
167 | } | |
168 | } | |
169 | }); | |
170 | me.column1.push(me.mpsel); | |
171 | } | |
172 | ||
234d2e37 DC |
173 | me.column1.push({ |
174 | xtype: 'pveDiskStorageSelector', | |
342225bf | 175 | nodename: me.nodename, |
342225bf | 176 | storageContent: 'rootdir', |
342225bf | 177 | autoSelect: true, |
c6c8e2fc | 178 | defaultSize: 8, |
234d2e37 | 179 | hidden: me.unused || !me.isCreate |
342225bf | 180 | }); |
342225bf DC |
181 | |
182 | if (me.unused) { | |
09cacce7 | 183 | me.unusedDisks = Ext.create('Proxmox.form.KVComboBox', { |
342225bf DC |
184 | name: 'unusedId', |
185 | fieldLabel: gettext('Disk image'), | |
186 | matchFieldWidth: false, | |
187 | listConfig: { | |
188 | width: 350 | |
189 | }, | |
190 | data: [], | |
191 | allowBlank: false, | |
192 | listeners: { | |
193 | change: function(f, value) { | |
194 | // make sure our buttons are enabled/disabled when switching | |
195 | // between images on different storages: | |
196 | var disk = me.vmconfig[value]; | |
197 | var storage = disk.split(':')[0]; | |
234d2e37 | 198 | me.down('#hdstorage').setValue(storage); |
342225bf DC |
199 | } |
200 | } | |
201 | }); | |
202 | me.column1.push(me.unusedDisks); | |
234d2e37 | 203 | } else if (!me.isCreate) { |
342225bf DC |
204 | me.column1.push({ |
205 | xtype: 'textfield', | |
206 | disabled: true, | |
207 | submitValue: false, | |
208 | fieldLabel: gettext('Disk image'), | |
209 | name: 'file' | |
210 | }); | |
211 | } | |
212 | ||
09cacce7 | 213 | me.acl = Ext.createWidget('proxmoxKVComboBox', { |
342225bf | 214 | name: 'acl', |
1ca8a8f2 | 215 | fieldLabel: 'ACLs', |
342225bf DC |
216 | comboItems: [['Default', 'Default'], ['1', 'On'], ['0', 'Off']], |
217 | value: 'Default', | |
218 | allowBlank: true | |
219 | }); | |
220 | ||
896c0d50 | 221 | me.quota = Ext.createWidget('proxmoxcheckbox', { |
342225bf DC |
222 | name: 'quota', |
223 | defaultValue: 0, | |
224 | disabled: me.unprivileged, | |
225 | fieldLabel: gettext('Enable quota') | |
226 | }); | |
227 | ||
228 | me.column2 = [ | |
229 | me.acl, | |
230 | me.quota | |
231 | ]; | |
232 | ||
233 | if (!isroot) { | |
234 | me.column2.splice(1, 0, { | |
896c0d50 | 235 | xtype: 'proxmoxcheckbox', |
342225bf DC |
236 | name: 'ro', |
237 | defaultValue: 0, | |
238 | fieldLabel: gettext('Read-only'), | |
239 | hidden: me.insideWizard | |
240 | }); | |
241 | ||
896c0d50 TL |
242 | me.backup = Ext.createWidget('proxmoxcheckbox',{ |
243 | xtype: 'proxmoxcheckbox', | |
342225bf DC |
244 | name: 'backup', |
245 | fieldLabel: gettext('Backup') | |
246 | }); | |
247 | if (me.mpdata.type !== 'bind') { | |
248 | me.column2.push(me.backup); | |
249 | } | |
250 | me.column2.push({ | |
896c0d50 | 251 | xtype: 'proxmoxcheckbox', |
342225bf DC |
252 | name: 'noreplicate', |
253 | fieldLabel: gettext('Skip replication') | |
254 | }); | |
255 | me.column2.push({ | |
256 | xtype: 'textfield', | |
257 | name: 'mp', | |
258 | value: '', | |
259 | emptyText: gettext('/some/path'), | |
260 | allowBlank: false, | |
261 | hidden: isroot, | |
262 | fieldLabel: gettext('Path') | |
263 | }); | |
264 | } | |
265 | ||
266 | me.callParent(); | |
234d2e37 DC |
267 | |
268 | if (me.unused || me.isCreate) { | |
269 | me.mon(me.down('#hdstorage'), 'change', function(field, newValue) { | |
270 | if (!newValue) { | |
271 | return; | |
272 | } | |
273 | var rec = field.store.getById(newValue); | |
274 | if (!rec) { | |
275 | return; | |
276 | } | |
277 | if (rec.data.type === 'zfs' || rec.data.type === 'zfspool') { | |
278 | me.quota.setDisabled(true); | |
279 | me.quota.setValue(false); | |
280 | } else { | |
281 | me.quota.setDisabled(me.unprivileged); | |
282 | } | |
283 | }); | |
284 | } | |
342225bf DC |
285 | } |
286 | }); | |
287 | ||
288 | Ext.define('PVE.lxc.MountPointEdit', { | |
289 | extend: 'PVE.window.Edit', | |
290 | ||
291 | unprivileged: false, | |
292 | ||
293 | initComponent : function() { | |
294 | var me = this; | |
295 | ||
296 | var nodename = me.pveSelNode.data.node; | |
297 | if (!nodename) { | |
298 | throw "no node name specified"; | |
299 | } | |
300 | ||
301 | var unused = me.confid && me.confid.match(/^unused\d+$/); | |
302 | ||
303 | me.isCreate = me.confid ? unused : true; | |
304 | ||
305 | var ipanel = Ext.create('PVE.lxc.MountPointInputPanel', { | |
306 | confid: me.confid, | |
307 | nodename: nodename, | |
308 | unused: unused, | |
309 | unprivileged: me.unprivileged, | |
310 | isCreate: me.isCreate | |
311 | }); | |
312 | ||
313 | var subject; | |
314 | if (unused) { | |
315 | subject = gettext('Unused Disk'); | |
316 | } else if (me.isCreate) { | |
317 | subject = gettext('Mount Point'); | |
318 | } else { | |
319 | subject = gettext('Mount Point') + ' (' + me.confid + ')'; | |
320 | } | |
321 | ||
322 | Ext.apply(me, { | |
323 | subject: subject, | |
324 | items: ipanel | |
325 | }); | |
326 | ||
327 | me.callParent(); | |
328 | ||
329 | me.load({ | |
330 | success: function(response, options) { | |
331 | ipanel.setVMConfig(response.result.data); | |
332 | if (me.confid) { | |
333 | /*jslint confusion: true*/ | |
334 | /*data is defined as array above*/ | |
335 | var value = response.result.data[me.confid]; | |
336 | /*jslint confusion: false*/ | |
337 | var mp = PVE.Parser.parseLxcMountPoint(value); | |
338 | ||
339 | if (!mp) { | |
340 | Ext.Msg.alert(gettext('Error'), 'Unable to parse mount point options'); | |
341 | me.close(); | |
342 | return; | |
343 | } | |
344 | ||
345 | ipanel.setMountPoint(mp); | |
346 | me.isValid(); // trigger validation | |
347 | } | |
348 | } | |
349 | }); | |
350 | } | |
351 | }); |