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