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