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