]> git.proxmox.com Git - pve-manager.git/blame - www/manager6/qemu/HDEdit.js
disable discard for non-scsi disks
[pve-manager.git] / www / manager6 / qemu / HDEdit.js
CommitLineData
df15b3da 1/*jslint confusion: true */
d5e771ce 2/* 'change' property is assigned a string and then a function */
df15b3da
DM
3Ext.define('PVE.qemu.HDInputPanel', {
4 extend: 'PVE.panel.InputPanel',
85806e47 5 alias: 'widget.pveQemuHDInputPanel',
c8802a60 6 onlineHelp: 'qm_hard_disk',
df15b3da
DM
7
8 insideWizard: false,
9
10 unused: false, // ADD usused disk imaged
11
12 vmconfig: {}, // used to select usused disks
13
180d7ef5
DM
14 controller: {
15
16 xclass: 'Ext.app.ViewController',
17
18 onControllerChange: function(field) {
19 var value = field.getValue();
ed1ac8f4
TL
20
21 var allowIOthread = value.match(/^(virtio|scsi)/);
22 this.lookup('iothread').setDisabled(!allowIOthread);
23 if (!allowIOthread) {
24 this.lookup('iothread').setValue(false);
25 }
36958639
TL
26
27 var allowDiscard = value.match(/^scsi/);
28 this.lookup('discard').setDisabled(!allowDiscard);
29 if (!allowDiscard) {
30 this.lookup('discard').setValue(false);
31 }
180d7ef5
DM
32 },
33
34 control: {
9cac6b75 35 'field[name=controller]': {
180d7ef5
DM
36 change: 'onControllerChange',
37 afterrender: 'onControllerChange'
9cac6b75
DM
38 },
39 'field[name=hdstorage]': {
40 change: function(f, value) {
41 if (!value) { // initial store loading fires an unwanted 'change'
42 return;
43 }
44 var me = this.getView();
45 var rec = f.store.getById(value);
46 if (rec.data.type === 'iscsi') {
47 me.hdfilesel.setStorage(value);
48 me.hdfilesel.setDisabled(false);
49 me.formatsel.setValue('raw');
50 me.formatsel.setDisabled(true);
51 me.hdfilesel.setVisible(true);
52 me.hdsizesel.setDisabled(true);
53 me.hdsizesel.setVisible(false);
54 } else if (rec.data.type === 'lvm' ||
55 rec.data.type === 'lvmthin' ||
56 rec.data.type === 'drbd' ||
57 rec.data.type === 'rbd' ||
58 rec.data.type === 'sheepdog' ||
59 rec.data.type === 'zfs' ||
60 rec.data.type === 'zfspool') {
61 me.hdfilesel.setDisabled(true);
62 me.hdfilesel.setVisible(false);
63 me.formatsel.setValue('raw');
64 me.formatsel.setDisabled(true);
65 me.hdsizesel.setDisabled(false);
66 me.hdsizesel.setVisible(true);
67 } else {
68 me.hdfilesel.setDisabled(true);
69 me.hdfilesel.setVisible(false);
70 me.formatsel.setValue('qcow2');
71 me.formatsel.setDisabled(false);
72 me.hdsizesel.setDisabled(false);
73 me.hdsizesel.setVisible(true);
74 }
75 }
180d7ef5
DM
76 }
77 }
78 },
79
df15b3da
DM
80 onGetValues: function(values) {
81 var me = this;
82
9a8a5735 83 var params = {};
df15b3da 84 var confid = me.confid || (values.controller + values.deviceid);
7a6e0635 85
df15b3da
DM
86 if (me.unused) {
87 me.drive.file = me.vmconfig[values.unusedId];
88 confid = values.controller + values.deviceid;
d5e771ce 89 } else if (me.isCreate) {
df15b3da
DM
90 if (values.hdimage) {
91 me.drive.file = values.hdimage;
92 } else {
93 me.drive.file = values.hdstorage + ":" + values.disksize;
94 }
95 me.drive.format = values.diskformat;
96 }
7a6e0635 97
df15b3da
DM
98 if (values.nobackup) {
99 me.drive.backup = 'no';
100 } else {
101 delete me.drive.backup;
102 }
103
1b6f87ab
EK
104 if (values.noreplicate) {
105 me.drive.replicate = 'no';
106 } else {
107 delete me.drive.replicate;
108 }
109
df15b3da
DM
110 if (values.discard) {
111 me.drive.discard = 'on';
112 } else {
113 delete me.drive.discard;
114 }
115
ed1ac8f4 116 if (values.iothread) {
df15b3da 117 me.drive.iothread = 'on';
2a2dce70
EK
118 // do not silently change a VM-wide option after creating it
119 if (me.insideWizard) {
120 params.scsihw = 'virtio-scsi-single';
121 }
df15b3da
DM
122 } else {
123 delete me.drive.iothread;
124 }
125
126 if (values.cache) {
127 me.drive.cache = values.cache;
128 } else {
129 delete me.drive.cache;
130 }
131
df15b3da 132 params[confid] = PVE.Parser.printQemuDrive(me.drive);
7a6e0635
TL
133
134 return params;
df15b3da
DM
135 },
136
137 setVMConfig: function(vmconfig) {
138 var me = this;
139
140 me.vmconfig = vmconfig;
141
142 if (me.bussel) {
143 me.bussel.setVMConfig(vmconfig, true);
144 }
145 if (me.unusedDisks) {
7a6e0635 146 var disklist = [];
df15b3da
DM
147 Ext.Object.each(vmconfig, function(key, value) {
148 if (key.match(/^unused\d+$/)) {
149 disklist.push([key, value]);
150 }
151 });
152 me.unusedDisks.store.loadData(disklist);
153 me.unusedDisks.setValue(me.confid);
154 }
155 },
156
157 setDrive: function(drive) {
158 var me = this;
159
160 me.drive = drive;
161
162 var values = {};
163 var match = drive.file.match(/^([^:]+):/);
164 if (match) {
165 values.hdstorage = match[1];
166 }
167
168 values.hdimage = drive.file;
169 values.nobackup = !PVE.Parser.parseBoolean(drive.backup, 1);
1b6f87ab 170 values.noreplicate = !PVE.Parser.parseBoolean(drive.replicate, 1);
df15b3da 171 values.diskformat = drive.format || 'raw';
ac7db8f7 172 values.cache = drive.cache || '__default__';
df15b3da
DM
173 values.discard = (drive.discard === 'on');
174 values.iothread = PVE.Parser.parseBoolean(drive.iothread);
175
176 me.setValues(values);
177 },
178
179 setNodename: function(nodename) {
180 var me = this;
181 me.hdstoragesel.setNodename(nodename);
182 me.hdfilesel.setStorage(undefined, nodename);
183 },
184
185 initComponent : function() {
186 var me = this;
187
188 me.drive = {};
189
190 me.column1 = [];
191 me.column2 = [];
192
193 if (!me.confid || me.unused) {
42902182 194 me.bussel = Ext.create('PVE.form.ControllerSelector', {
df15b3da
DM
195 vmconfig: me.insideWizard ? {ide2: 'cdrom'} : {}
196 });
197 me.column1.push(me.bussel);
198 }
199
200 if (me.unused) {
201 me.unusedDisks = Ext.create('PVE.form.KVComboBox', {
7a6e0635 202 name: 'unusedId',
df15b3da
DM
203 fieldLabel: gettext('Disk image'),
204 matchFieldWidth: false,
205 listConfig: {
206 width: 350
207 },
208 data: [],
209 allowBlank: false
210 });
211 me.column1.push(me.unusedDisks);
d5e771ce 212 } else if (me.isCreate) {
df15b3da
DM
213 me.formatsel = Ext.create('PVE.form.DiskFormatSelector', {
214 name: 'diskformat',
215 fieldLabel: gettext('Format'),
216 value: 'qcow2',
217 allowBlank: false
218 });
219
220 me.hdfilesel = Ext.create('PVE.form.FileSelector', {
221 name: 'hdimage',
222 nodename: me.nodename,
223 storageContent: 'images',
224 fieldLabel: gettext('Disk image'),
225 disabled: true,
226 hidden: true,
227 allowBlank: false
228 });
229
230 me.hdsizesel = Ext.createWidget('numberfield', {
231 name: 'disksize',
232 minValue: 0.001,
233 maxValue: 128*1024,
234 decimalPrecision: 3,
235 value: '32',
236 fieldLabel: gettext('Disk size') + ' (GB)',
237 allowBlank: false
238 });
239
240 me.hdstoragesel = Ext.create('PVE.form.StorageSelector', {
241 name: 'hdstorage',
242 nodename: me.nodename,
243 fieldLabel: gettext('Storage'),
244 storageContent: 'images',
245 autoSelect: me.insideWizard,
9cac6b75 246 allowBlank: false
df15b3da
DM
247 });
248 me.column1.push(me.hdstoragesel);
249 me.column1.push(me.hdfilesel);
250 me.column1.push(me.hdsizesel);
251 me.column1.push(me.formatsel);
252
253 } else {
254 me.column1.push({
255 xtype: 'textfield',
256 disabled: true,
257 submitValue: false,
258 fieldLabel: gettext('Disk image'),
259 name: 'hdimage'
260 });
261 }
262
263 me.column2.push({
264 xtype: 'CacheTypeSelector',
265 name: 'cache',
ca6372bd 266 value: '__default__',
df15b3da 267 fieldLabel: gettext('Cache')
2d06e723
TL
268 },
269 {
df15b3da
DM
270 xtype: 'pvecheckbox',
271 fieldLabel: gettext('No backup'),
272 name: 'nobackup'
2d06e723
TL
273 },
274 {
1b6f87ab
EK
275 xtype: 'pvecheckbox',
276 hidden: me.insideWizard,
277 fieldLabel: gettext('Skip replication'),
278 name: 'noreplicate'
2d06e723
TL
279 },
280 {
df15b3da
DM
281 xtype: 'pvecheckbox',
282 fieldLabel: gettext('Discard'),
36958639
TL
283 disabled: me.confid && !me.confid.match(/^scsi/),
284 reference: 'discard',
df15b3da 285 name: 'discard'
2d06e723
TL
286 },
287 {
df15b3da 288 xtype: 'pvecheckbox',
ed1ac8f4 289 disabled: me.confid && !me.confid.match(/^(virtio|scsi)/),
185a77e5 290 fieldLabel: gettext('IO thread'),
180d7ef5 291 reference: 'iothread',
df15b3da
DM
292 name: 'iothread'
293 });
294
295 me.callParent();
296 }
297});
d5e771ce 298/*jslint confusion: false */
df15b3da
DM
299
300Ext.define('PVE.qemu.HDEdit', {
301 extend: 'PVE.window.Edit',
302
303 isAdd: true,
304
305 initComponent : function() {
306 var me = this;
307
308 var nodename = me.pveSelNode.data.node;
7a6e0635
TL
309 if (!nodename) {
310 throw "no node name specified";
df15b3da
DM
311 }
312
313 var unused = me.confid && me.confid.match(/^unused\d+$/);
314
d5e771ce 315 me.isCreate = me.confid ? unused : true;
df15b3da
DM
316
317 var ipanel = Ext.create('PVE.qemu.HDInputPanel', {
318 confid: me.confid,
319 nodename: nodename,
320 unused: unused,
d5e771ce 321 isCreate: me.isCreate
df15b3da
DM
322 });
323
324 var subject;
325 if (unused) {
326 me.subject = gettext('Unused Disk');
d5e771ce 327 } else if (me.isCreate) {
df15b3da
DM
328 me.subject = gettext('Hard Disk');
329 } else {
330 me.subject = gettext('Hard Disk') + ' (' + me.confid + ')';
331 }
332
333 me.items = [ ipanel ];
334
335 me.callParent();
d5e771ce
EK
336 /*jslint confusion: true*/
337 /* 'data' is assigned an empty array in same file, and here we
338 * use it like an object
339 */
df15b3da
DM
340 me.load({
341 success: function(response, options) {
342 ipanel.setVMConfig(response.result.data);
343 if (me.confid) {
344 var value = response.result.data[me.confid];
345 var drive = PVE.Parser.parseQemuDrive(me.confid, value);
346 if (!drive) {
185a77e5 347 Ext.Msg.alert(gettext('Error'), 'Unable to parse drive options');
df15b3da
DM
348 me.close();
349 return;
350 }
351 ipanel.setDrive(drive);
352 me.isValid(); // trigger validation
353 }
354 }
355 });
d5e771ce 356 /*jslint confusion: false*/
df15b3da
DM
357 }
358});