]>
Commit | Line | Data |
---|---|---|
7d44036a DM |
1 | /*jslint confusion: true */ |
2 | Ext.define('PVE.qemu.Options', { | |
3 | extend: 'PVE.grid.PendingObjectGrid', | |
4 | alias: ['widget.PVE.qemu.Options'], | |
5 | ||
6 | initComponent : function() { | |
7 | var me = this; | |
8 | var i; | |
9 | ||
10 | var nodename = me.pveSelNode.data.node; | |
11 | if (!nodename) { | |
12 | throw "no node name specified"; | |
13 | } | |
14 | ||
15 | var vmid = me.pveSelNode.data.vmid; | |
16 | if (!vmid) { | |
17 | throw "no VM ID specified"; | |
18 | } | |
19 | ||
20 | var caps = Ext.state.Manager.get('GuiCap'); | |
21 | ||
22 | var rows = { | |
23 | name: { | |
24 | required: true, | |
25 | defaultValue: me.pveSelNode.data.name, | |
26 | header: gettext('Name'), | |
27 | editor: caps.vms['VM.Config.Options'] ? { | |
28 | xtype: 'pveWindowEdit', | |
29 | subject: gettext('Name'), | |
30 | items: { | |
3335a948 DC |
31 | xtype: 'inputpanel', |
32 | items:{ | |
33 | xtype: 'textfield', | |
34 | name: 'name', | |
35 | vtype: 'DnsName', | |
36 | value: '', | |
37 | fieldLabel: gettext('Name'), | |
38 | allowBlank: true | |
39 | }, | |
40 | onGetValues: function(values) { | |
41 | var params = values; | |
42 | if (values.name === undefined || | |
43 | values.name === null || | |
44 | values.name === '') { | |
45 | params = { 'delete':'name'}; | |
46 | } | |
47 | return params; | |
48 | } | |
7d44036a DM |
49 | } |
50 | } : undefined | |
51 | }, | |
52 | onboot: { | |
53 | header: gettext('Start at boot'), | |
54 | defaultValue: '', | |
55 | renderer: PVE.Utils.format_boolean, | |
56 | editor: caps.vms['VM.Config.Options'] ? { | |
57 | xtype: 'pveWindowEdit', | |
58 | subject: gettext('Start at boot'), | |
59 | items: { | |
60 | xtype: 'pvecheckbox', | |
61 | name: 'onboot', | |
62 | uncheckedValue: 0, | |
63 | defaultValue: 0, | |
64 | deleteDefaultValue: true, | |
65 | fieldLabel: gettext('Start at boot') | |
66 | } | |
67 | } : undefined | |
68 | }, | |
69 | startup: { | |
70 | header: gettext('Start/Shutdown order'), | |
71 | defaultValue: '', | |
72 | renderer: PVE.Utils.render_kvm_startup, | |
73 | editor: caps.vms['VM.Config.Options'] && caps.nodes['Sys.Modify'] ? | |
74 | 'PVE.qemu.StartupEdit' : undefined | |
75 | }, | |
76 | ostype: { | |
77 | header: gettext('OS Type'), | |
78 | editor: caps.vms['VM.Config.Options'] ? 'PVE.qemu.OSTypeEdit' : undefined, | |
79 | renderer: PVE.Utils.render_kvm_ostype, | |
80 | defaultValue: 'other' | |
81 | }, | |
82 | bootdisk: { | |
83 | visible: false | |
84 | }, | |
85 | boot: { | |
86 | header: gettext('Boot order'), | |
87 | defaultValue: 'cdn', | |
88 | editor: caps.vms['VM.Config.Disk'] ? 'PVE.qemu.BootOrderEdit' : undefined, | |
16c162ec | 89 | multiKey: ['boot', 'bootdisk'], |
7d44036a DM |
90 | renderer: function(order, metaData, record, rowIndex, colIndex, store, pending) { |
91 | var i; | |
92 | var text = ''; | |
93 | var bootdisk = me.getObjectValue('bootdisk', undefined, pending); | |
94 | order = order || 'cdn'; | |
95 | for (i = 0; i < order.length; i++) { | |
96 | var sel = order.substring(i, i + 1); | |
97 | if (text) { | |
98 | text += ', '; | |
99 | } | |
100 | if (sel === 'c') { | |
101 | if (bootdisk) { | |
102 | text += "Disk '" + bootdisk + "'"; | |
103 | } else { | |
104 | text += "Disk"; | |
105 | } | |
106 | } else if (sel === 'n') { | |
107 | text += 'Network'; | |
108 | } else if (sel === 'a') { | |
109 | text += 'Floppy'; | |
110 | } else if (sel === 'd') { | |
111 | text += 'CD-ROM'; | |
112 | } else { | |
113 | text += sel; | |
114 | } | |
115 | } | |
116 | return text; | |
117 | } | |
118 | }, | |
119 | tablet: { | |
120 | header: gettext('Use tablet for pointer'), | |
121 | defaultValue: true, | |
122 | renderer: PVE.Utils.format_boolean, | |
123 | editor: caps.vms['VM.Config.HWType'] ? { | |
124 | xtype: 'pveWindowEdit', | |
125 | subject: gettext('Use tablet for pointer'), | |
126 | items: { | |
127 | xtype: 'pvecheckbox', | |
128 | name: 'tablet', | |
129 | checked: true, | |
130 | uncheckedValue: 0, | |
131 | defaultValue: 1, | |
132 | deleteDefaultValue: true, | |
133 | fieldLabel: gettext('Enabled') | |
134 | } | |
135 | } : undefined | |
136 | }, | |
137 | hotplug: { | |
138 | header: gettext('Hotplug'), | |
139 | defaultValue: 'disk,network,usb', | |
140 | renderer: PVE.Utils.render_hotplug_features, | |
141 | editor: caps.vms['VM.Config.HWType'] ? { | |
142 | xtype: 'pveWindowEdit', | |
143 | subject: gettext('Hotplug'), | |
144 | items: { | |
145 | xtype: 'pveHotplugFeatureSelector', | |
146 | name: 'hotplug', | |
147 | value: '', | |
148 | multiSelect: true, | |
149 | fieldLabel: gettext('Hotplug'), | |
150 | allowBlank: true | |
151 | } | |
152 | } : undefined | |
153 | }, | |
154 | acpi: { | |
155 | header: gettext('ACPI support'), | |
156 | defaultValue: true, | |
157 | renderer: PVE.Utils.format_boolean, | |
158 | editor: caps.vms['VM.Config.HWType'] ? { | |
159 | xtype: 'pveWindowEdit', | |
160 | subject: gettext('ACPI support'), | |
161 | items: { | |
162 | xtype: 'pvecheckbox', | |
163 | name: 'acpi', | |
164 | checked: true, | |
165 | uncheckedValue: 0, | |
166 | defaultValue: 1, | |
167 | deleteDefaultValue: true, | |
168 | fieldLabel: gettext('Enabled') | |
169 | } | |
170 | } : undefined | |
171 | }, | |
172 | scsihw: { | |
173 | header: gettext('SCSI Controller Type'), | |
174 | editor: caps.vms['VM.Config.Options'] ? 'PVE.qemu.ScsiHwEdit' : undefined, | |
175 | renderer: PVE.Utils.render_scsihw, | |
176 | defaultValue: '' | |
177 | }, | |
178 | bios: { | |
179 | header: 'BIOS', | |
180 | editor: caps.vms['VM.Config.Options'] ? 'PVE.qemu.BiosEdit' : undefined, | |
181 | renderer: PVE.Utils.render_qemu_bios, | |
182 | defaultValue: '' | |
183 | }, | |
184 | kvm: { | |
185 | header: gettext('KVM hardware virtualization'), | |
186 | defaultValue: true, | |
187 | renderer: PVE.Utils.format_boolean, | |
188 | editor: caps.vms['VM.Config.HWType'] ? { | |
189 | xtype: 'pveWindowEdit', | |
190 | subject: gettext('KVM hardware virtualization'), | |
191 | items: { | |
192 | xtype: 'pvecheckbox', | |
193 | name: 'kvm', | |
194 | checked: true, | |
195 | uncheckedValue: 0, | |
196 | defaultValue: 1, | |
197 | deleteDefaultValue: true, | |
198 | fieldLabel: gettext('Enabled') | |
199 | } | |
200 | } : undefined | |
201 | }, | |
202 | freeze: { | |
203 | header: gettext('Freeze CPU at startup'), | |
204 | defaultValue: false, | |
205 | renderer: PVE.Utils.format_boolean, | |
206 | editor: caps.vms['VM.PowerMgmt'] ? { | |
207 | xtype: 'pveWindowEdit', | |
208 | subject: gettext('Freeze CPU at startup'), | |
209 | items: { | |
210 | xtype: 'pvecheckbox', | |
211 | name: 'freeze', | |
212 | uncheckedValue: 0, | |
213 | defaultValue: 0, | |
214 | deleteDefaultValue: true, | |
215 | labelWidth: 140, | |
216 | fieldLabel: gettext('Freeze CPU at startup') | |
217 | } | |
218 | } : undefined | |
219 | }, | |
220 | localtime: { | |
221 | header: gettext('Use local time for RTC'), | |
222 | defaultValue: false, | |
223 | renderer: PVE.Utils.format_boolean, | |
224 | editor: caps.vms['VM.Config.Options'] ? { | |
225 | xtype: 'pveWindowEdit', | |
226 | subject: gettext('Use local time for RTC'), | |
227 | items: { | |
228 | xtype: 'pvecheckbox', | |
229 | name: 'localtime', | |
230 | uncheckedValue: 0, | |
231 | defaultValue: 0, | |
232 | deleteDefaultValue: true, | |
233 | labelWidth: 140, | |
234 | fieldLabel: gettext('Use local time for RTC') | |
235 | } | |
236 | } : undefined | |
237 | }, | |
238 | startdate: { | |
239 | header: gettext('RTC start date'), | |
240 | defaultValue: 'now', | |
241 | editor: caps.vms['VM.Config.Options'] ? { | |
242 | xtype: 'pveWindowEdit', | |
243 | subject: gettext('RTC start date'), | |
244 | items: { | |
245 | xtype: 'pvetextfield', | |
246 | name: 'startdate', | |
247 | deleteEmpty: true, | |
248 | value: 'now', | |
249 | fieldLabel: gettext('RTC start date'), | |
250 | vtype: 'QemuStartDate', | |
251 | allowBlank: true | |
252 | } | |
253 | } : undefined | |
254 | }, | |
255 | smbios1: { | |
256 | header: gettext('SMBIOS settings (type1)'), | |
257 | defaultValue: '', | |
258 | renderer: Ext.String.htmlEncode, | |
259 | editor: caps.vms['VM.Config.HWType'] ? 'PVE.qemu.Smbios1Edit' : undefined | |
260 | }, | |
261 | agent: { | |
262 | header: gettext('Qemu Agent'), | |
263 | defaultValue: false, | |
264 | renderer: PVE.Utils.format_boolean, | |
265 | editor: caps.vms['VM.Config.Options'] ? { | |
266 | xtype: 'pveWindowEdit', | |
267 | subject: gettext('Qemu Agent'), | |
268 | items: { | |
269 | xtype: 'pvecheckbox', | |
270 | name: 'agent', | |
271 | uncheckedValue: 0, | |
272 | defaultValue: 0, | |
273 | deleteDefaultValue: true, | |
274 | fieldLabel: gettext('Enabled') | |
275 | } | |
276 | } : undefined | |
277 | }, | |
278 | protection: { | |
16152937 | 279 | header: gettext('Protection'), |
7d44036a DM |
280 | defaultValue: false, |
281 | renderer: PVE.Utils.format_boolean, | |
282 | editor: caps.vms['VM.Config.Options'] ? { | |
283 | xtype: 'pveWindowEdit', | |
16152937 | 284 | subject: gettext('Protection'), |
7d44036a DM |
285 | items: { |
286 | xtype: 'pvecheckbox', | |
287 | name: 'protection', | |
288 | uncheckedValue: 0, | |
289 | defaultValue: 0, | |
290 | deleteDefaultValue: true, | |
291 | fieldLabel: gettext('Enabled') | |
292 | } | |
293 | } : undefined | |
294 | } | |
295 | }; | |
296 | ||
297 | var baseurl = 'nodes/' + nodename + '/qemu/' + vmid + '/config'; | |
298 | ||
299 | var reload = function() { | |
300 | me.rstore.load(); | |
301 | }; | |
302 | ||
303 | var run_editor = function() { | |
304 | var sm = me.getSelectionModel(); | |
305 | var rec = sm.getSelection()[0]; | |
306 | if (!rec) { | |
307 | return; | |
308 | } | |
309 | ||
310 | var rowdef = rows[rec.data.key]; | |
311 | if (!rowdef.editor) { | |
312 | return; | |
313 | } | |
314 | ||
315 | var win; | |
316 | if (Ext.isString(rowdef.editor)) { | |
317 | win = Ext.create(rowdef.editor, { | |
318 | pveSelNode: me.pveSelNode, | |
319 | confid: rec.data.key, | |
320 | url: '/api2/extjs/' + baseurl | |
321 | }); | |
322 | } else { | |
323 | var config = Ext.apply({ | |
324 | pveSelNode: me.pveSelNode, | |
325 | confid: rec.data.key, | |
326 | url: '/api2/extjs/' + baseurl | |
327 | }, rowdef.editor); | |
328 | win = Ext.createWidget(rowdef.editor.xtype, config); | |
329 | win.load(); | |
330 | } | |
331 | ||
332 | win.show(); | |
333 | win.on('destroy', reload); | |
334 | }; | |
335 | ||
336 | var edit_btn = new Ext.Button({ | |
337 | text: gettext('Edit'), | |
338 | disabled: true, | |
339 | handler: run_editor | |
340 | }); | |
341 | ||
342 | var revert_btn = new PVE.button.Button({ | |
343 | text: gettext('Revert'), | |
344 | disabled: true, | |
345 | handler: function() { | |
346 | var sm = me.getSelectionModel(); | |
347 | var rec = sm.getSelection()[0]; | |
348 | if (!rec) { | |
349 | return; | |
350 | } | |
351 | ||
16c162ec DC |
352 | var rowdef = me.rows[rec.data.key] || {}; |
353 | var keys = rowdef.multiKey || [ rec.data.key ]; | |
354 | var revert = keys.join(','); | |
355 | ||
7d44036a DM |
356 | PVE.Utils.API2Request({ |
357 | url: '/api2/extjs/' + baseurl, | |
358 | waitMsgTarget: me, | |
359 | method: 'PUT', | |
360 | params: { | |
16c162ec | 361 | 'revert': revert |
7d44036a DM |
362 | }, |
363 | callback: function() { | |
364 | reload(); | |
365 | }, | |
366 | failure: function (response, opts) { | |
367 | Ext.Msg.alert('Error',response.htmlStatus); | |
368 | } | |
369 | }); | |
370 | } | |
371 | }); | |
372 | ||
373 | var set_button_status = function() { | |
374 | var sm = me.getSelectionModel(); | |
375 | var rec = sm.getSelection()[0]; | |
376 | ||
377 | if (!rec) { | |
378 | edit_btn.disable(); | |
379 | return; | |
380 | } | |
381 | ||
382 | var key = rec.data.key; | |
383 | var pending = rec.data['delete'] || me.hasPendingChanges(key); | |
384 | var rowdef = rows[key]; | |
385 | ||
386 | edit_btn.setDisabled(!rowdef.editor); | |
387 | revert_btn.setDisabled(!pending); | |
388 | }; | |
389 | ||
a26cb711 | 390 | Ext.apply(me, { |
7d44036a DM |
391 | url: "/api2/json/nodes/" + nodename + "/qemu/" + vmid + "/pending", |
392 | interval: 5000, | |
3c813f74 | 393 | cwidth1: 250, |
7d44036a DM |
394 | tbar: [ edit_btn, revert_btn ], |
395 | rows: rows, | |
396 | listeners: { | |
397 | itemdblclick: run_editor, | |
398 | selectionchange: set_button_status | |
399 | } | |
400 | }); | |
401 | ||
402 | me.callParent(); | |
403 | ||
a26cb711 | 404 | me.on('activate', me.rstore.startUpdate); |
7d44036a DM |
405 | me.on('destroy', me.rstore.stopUpdate); |
406 | ||
407 | me.rstore.on('datachanged', function() { | |
408 | set_button_status(); | |
409 | }); | |
410 | } | |
411 | }); | |
412 |