]>
Commit | Line | Data |
---|---|---|
7d44036a | 1 | Ext.define('PVE.qemu.Options', { |
bc0eaf58 | 2 | extend: 'Proxmox.grid.PendingObjectGrid', |
7d44036a DM |
3 | alias: ['widget.PVE.qemu.Options'], |
4 | ||
ba93a9c6 DC |
5 | onlineHelp: 'qm_options', |
6 | ||
7d44036a DM |
7 | initComponent : function() { |
8 | var me = this; | |
9 | var i; | |
10 | ||
11 | var nodename = me.pveSelNode.data.node; | |
12 | if (!nodename) { | |
13 | throw "no node name specified"; | |
14 | } | |
15 | ||
16 | var vmid = me.pveSelNode.data.vmid; | |
17 | if (!vmid) { | |
18 | throw "no VM ID specified"; | |
19 | } | |
20 | ||
21 | var caps = Ext.state.Manager.get('GuiCap'); | |
22 | ||
23 | var rows = { | |
24 | name: { | |
25 | required: true, | |
26 | defaultValue: me.pveSelNode.data.name, | |
27 | header: gettext('Name'), | |
28 | editor: caps.vms['VM.Config.Options'] ? { | |
9fccc702 | 29 | xtype: 'proxmoxWindowEdit', |
7d44036a DM |
30 | subject: gettext('Name'), |
31 | items: { | |
3335a948 DC |
32 | xtype: 'inputpanel', |
33 | items:{ | |
34 | xtype: 'textfield', | |
35 | name: 'name', | |
36 | vtype: 'DnsName', | |
37 | value: '', | |
38 | fieldLabel: gettext('Name'), | |
f6710aac | 39 | allowBlank: true, |
3335a948 DC |
40 | }, |
41 | onGetValues: function(values) { | |
42 | var params = values; | |
43 | if (values.name === undefined || | |
44 | values.name === null || | |
45 | values.name === '') { | |
46 | params = { 'delete':'name'}; | |
47 | } | |
48 | return params; | |
f6710aac TL |
49 | }, |
50 | }, | |
51 | } : undefined, | |
7d44036a DM |
52 | }, |
53 | onboot: { | |
54 | header: gettext('Start at boot'), | |
55 | defaultValue: '', | |
e7ade592 | 56 | renderer: Proxmox.Utils.format_boolean, |
7d44036a | 57 | editor: caps.vms['VM.Config.Options'] ? { |
9fccc702 | 58 | xtype: 'proxmoxWindowEdit', |
7d44036a DM |
59 | subject: gettext('Start at boot'), |
60 | items: { | |
896c0d50 | 61 | xtype: 'proxmoxcheckbox', |
7d44036a DM |
62 | name: 'onboot', |
63 | uncheckedValue: 0, | |
64 | defaultValue: 0, | |
65 | deleteDefaultValue: true, | |
f6710aac TL |
66 | fieldLabel: gettext('Start at boot'), |
67 | }, | |
68 | } : undefined, | |
7d44036a DM |
69 | }, |
70 | startup: { | |
71 | header: gettext('Start/Shutdown order'), | |
72 | defaultValue: '', | |
73 | renderer: PVE.Utils.render_kvm_startup, | |
998922c3 | 74 | editor: caps.vms['VM.Config.Options'] && caps.nodes['Sys.Modify'] ? |
a255dd7e EK |
75 | { |
76 | xtype: 'pveWindowStartupEdit', | |
f6710aac TL |
77 | onlineHelp: 'qm_startup_and_shutdown', |
78 | } : undefined, | |
7d44036a DM |
79 | }, |
80 | ostype: { | |
81 | header: gettext('OS Type'), | |
82 | editor: caps.vms['VM.Config.Options'] ? 'PVE.qemu.OSTypeEdit' : undefined, | |
83 | renderer: PVE.Utils.render_kvm_ostype, | |
f6710aac | 84 | defaultValue: 'other', |
7d44036a DM |
85 | }, |
86 | bootdisk: { | |
f6710aac | 87 | visible: false, |
7d44036a DM |
88 | }, |
89 | boot: { | |
ec99b1c3 | 90 | header: gettext('Boot Order'), |
7d44036a DM |
91 | defaultValue: 'cdn', |
92 | editor: caps.vms['VM.Config.Disk'] ? 'PVE.qemu.BootOrderEdit' : undefined, | |
16c162ec | 93 | multiKey: ['boot', 'bootdisk'], |
7d44036a | 94 | renderer: function(order, metaData, record, rowIndex, colIndex, store, pending) { |
1cc7c672 SR |
95 | if (/^\s*$/.test(order)) { |
96 | return gettext('(No boot device selected)'); | |
97 | } | |
98 | let boot = PVE.Parser.parsePropertyString(order, "legacy"); | |
99 | if (boot.order) { | |
100 | let list = boot.order.split(';'); | |
101 | let ret = ''; | |
102 | let i = 1; | |
103 | list.forEach(dev => { | |
104 | if (ret) { | |
105 | ret += ', '; | |
106 | } | |
107 | ret += dev; | |
108 | }); | |
109 | return ret; | |
110 | } | |
111 | ||
112 | // legacy style and fallback | |
7d44036a DM |
113 | var i; |
114 | var text = ''; | |
115 | var bootdisk = me.getObjectValue('bootdisk', undefined, pending); | |
1cc7c672 | 116 | order = boot.legacy || 'cdn'; |
7d44036a | 117 | for (i = 0; i < order.length; i++) { |
7d44036a DM |
118 | if (text) { |
119 | text += ', '; | |
120 | } | |
1cc7c672 | 121 | var sel = order.substring(i, i + 1); |
7d44036a DM |
122 | if (sel === 'c') { |
123 | if (bootdisk) { | |
1cc7c672 | 124 | text += bootdisk; |
7d44036a | 125 | } else { |
1cc7c672 | 126 | text += gettext('(no bootdisk)'); |
7d44036a DM |
127 | } |
128 | } else if (sel === 'n') { | |
1cc7c672 | 129 | text += gettext('any net'); |
7d44036a | 130 | } else if (sel === 'a') { |
1cc7c672 | 131 | text += gettext('Floppy'); |
7d44036a | 132 | } else if (sel === 'd') { |
1cc7c672 | 133 | text += gettext('any CD-ROM'); |
7d44036a DM |
134 | } else { |
135 | text += sel; | |
136 | } | |
137 | } | |
138 | return text; | |
f6710aac | 139 | }, |
7d44036a DM |
140 | }, |
141 | tablet: { | |
142 | header: gettext('Use tablet for pointer'), | |
143 | defaultValue: true, | |
e7ade592 | 144 | renderer: Proxmox.Utils.format_boolean, |
7d44036a | 145 | editor: caps.vms['VM.Config.HWType'] ? { |
9fccc702 | 146 | xtype: 'proxmoxWindowEdit', |
7d44036a DM |
147 | subject: gettext('Use tablet for pointer'), |
148 | items: { | |
896c0d50 | 149 | xtype: 'proxmoxcheckbox', |
7d44036a DM |
150 | name: 'tablet', |
151 | checked: true, | |
152 | uncheckedValue: 0, | |
153 | defaultValue: 1, | |
154 | deleteDefaultValue: true, | |
f6710aac TL |
155 | fieldLabel: gettext('Enabled'), |
156 | }, | |
157 | } : undefined, | |
7d44036a DM |
158 | }, |
159 | hotplug: { | |
160 | header: gettext('Hotplug'), | |
161 | defaultValue: 'disk,network,usb', | |
162 | renderer: PVE.Utils.render_hotplug_features, | |
163 | editor: caps.vms['VM.Config.HWType'] ? { | |
9fccc702 | 164 | xtype: 'proxmoxWindowEdit', |
7d44036a DM |
165 | subject: gettext('Hotplug'), |
166 | items: { | |
167 | xtype: 'pveHotplugFeatureSelector', | |
168 | name: 'hotplug', | |
169 | value: '', | |
170 | multiSelect: true, | |
171 | fieldLabel: gettext('Hotplug'), | |
f6710aac TL |
172 | allowBlank: true, |
173 | }, | |
174 | } : undefined, | |
7d44036a DM |
175 | }, |
176 | acpi: { | |
177 | header: gettext('ACPI support'), | |
178 | defaultValue: true, | |
e7ade592 | 179 | renderer: Proxmox.Utils.format_boolean, |
7d44036a | 180 | editor: caps.vms['VM.Config.HWType'] ? { |
9fccc702 | 181 | xtype: 'proxmoxWindowEdit', |
7d44036a DM |
182 | subject: gettext('ACPI support'), |
183 | items: { | |
896c0d50 | 184 | xtype: 'proxmoxcheckbox', |
7d44036a DM |
185 | name: 'acpi', |
186 | checked: true, | |
187 | uncheckedValue: 0, | |
188 | defaultValue: 1, | |
189 | deleteDefaultValue: true, | |
f6710aac TL |
190 | fieldLabel: gettext('Enabled'), |
191 | }, | |
192 | } : undefined, | |
7d44036a | 193 | }, |
7d44036a DM |
194 | kvm: { |
195 | header: gettext('KVM hardware virtualization'), | |
196 | defaultValue: true, | |
e7ade592 | 197 | renderer: Proxmox.Utils.format_boolean, |
7d44036a | 198 | editor: caps.vms['VM.Config.HWType'] ? { |
9fccc702 | 199 | xtype: 'proxmoxWindowEdit', |
7d44036a DM |
200 | subject: gettext('KVM hardware virtualization'), |
201 | items: { | |
896c0d50 | 202 | xtype: 'proxmoxcheckbox', |
7d44036a DM |
203 | name: 'kvm', |
204 | checked: true, | |
205 | uncheckedValue: 0, | |
206 | defaultValue: 1, | |
207 | deleteDefaultValue: true, | |
f6710aac TL |
208 | fieldLabel: gettext('Enabled'), |
209 | }, | |
210 | } : undefined, | |
7d44036a DM |
211 | }, |
212 | freeze: { | |
213 | header: gettext('Freeze CPU at startup'), | |
214 | defaultValue: false, | |
e7ade592 | 215 | renderer: Proxmox.Utils.format_boolean, |
7d44036a | 216 | editor: caps.vms['VM.PowerMgmt'] ? { |
9fccc702 | 217 | xtype: 'proxmoxWindowEdit', |
7d44036a DM |
218 | subject: gettext('Freeze CPU at startup'), |
219 | items: { | |
896c0d50 | 220 | xtype: 'proxmoxcheckbox', |
7d44036a DM |
221 | name: 'freeze', |
222 | uncheckedValue: 0, | |
223 | defaultValue: 0, | |
224 | deleteDefaultValue: true, | |
225 | labelWidth: 140, | |
f6710aac TL |
226 | fieldLabel: gettext('Freeze CPU at startup'), |
227 | }, | |
228 | } : undefined, | |
7d44036a DM |
229 | }, |
230 | localtime: { | |
231 | header: gettext('Use local time for RTC'), | |
0beff18b FE |
232 | defaultValue: '__default__', |
233 | renderer: PVE.Utils.render_localtime, | |
7d44036a | 234 | editor: caps.vms['VM.Config.Options'] ? { |
9fccc702 | 235 | xtype: 'proxmoxWindowEdit', |
7d44036a | 236 | subject: gettext('Use local time for RTC'), |
bc92b15f | 237 | width: 400, |
7d44036a | 238 | items: { |
0beff18b | 239 | xtype: 'proxmoxKVComboBox', |
7d44036a | 240 | name: 'localtime', |
0beff18b FE |
241 | value: '__default__', |
242 | comboItems: [ | |
243 | ['__default__', PVE.Utils.render_localtime('__default__')], | |
244 | [1, PVE.Utils.render_localtime(1)], | |
245 | [0, PVE.Utils.render_localtime(0)], | |
246 | ], | |
7d44036a | 247 | labelWidth: 140, |
f6710aac TL |
248 | fieldLabel: gettext('Use local time for RTC'), |
249 | }, | |
250 | } : undefined, | |
7d44036a DM |
251 | }, |
252 | startdate: { | |
253 | header: gettext('RTC start date'), | |
254 | defaultValue: 'now', | |
255 | editor: caps.vms['VM.Config.Options'] ? { | |
9fccc702 | 256 | xtype: 'proxmoxWindowEdit', |
7d44036a DM |
257 | subject: gettext('RTC start date'), |
258 | items: { | |
dbed4c1c | 259 | xtype: 'proxmoxtextfield', |
7d44036a DM |
260 | name: 'startdate', |
261 | deleteEmpty: true, | |
262 | value: 'now', | |
263 | fieldLabel: gettext('RTC start date'), | |
264 | vtype: 'QemuStartDate', | |
f6710aac TL |
265 | allowBlank: true, |
266 | }, | |
267 | } : undefined, | |
7d44036a DM |
268 | }, |
269 | smbios1: { | |
270 | header: gettext('SMBIOS settings (type1)'), | |
271 | defaultValue: '', | |
272 | renderer: Ext.String.htmlEncode, | |
f6710aac | 273 | editor: caps.vms['VM.Config.HWType'] ? 'PVE.qemu.Smbios1Edit' : undefined, |
7d44036a DM |
274 | }, |
275 | agent: { | |
ea6a4b52 | 276 | header: 'QEMU Guest Agent', |
7d44036a | 277 | defaultValue: false, |
1662ccdb | 278 | renderer: PVE.Utils.render_qga_features, |
7d44036a | 279 | editor: caps.vms['VM.Config.Options'] ? { |
9fccc702 | 280 | xtype: 'proxmoxWindowEdit', |
7d44036a | 281 | subject: gettext('Qemu Agent'), |
ea6a4b52 | 282 | width: 350, |
7d44036a | 283 | items: { |
1662ccdb | 284 | xtype: 'pveAgentFeatureSelector', |
f6710aac TL |
285 | name: 'agent', |
286 | }, | |
287 | } : undefined, | |
7d44036a DM |
288 | }, |
289 | protection: { | |
16152937 | 290 | header: gettext('Protection'), |
7d44036a | 291 | defaultValue: false, |
e7ade592 | 292 | renderer: Proxmox.Utils.format_boolean, |
7d44036a | 293 | editor: caps.vms['VM.Config.Options'] ? { |
9fccc702 | 294 | xtype: 'proxmoxWindowEdit', |
16152937 | 295 | subject: gettext('Protection'), |
7d44036a | 296 | items: { |
896c0d50 | 297 | xtype: 'proxmoxcheckbox', |
7d44036a DM |
298 | name: 'protection', |
299 | uncheckedValue: 0, | |
300 | defaultValue: 0, | |
301 | deleteDefaultValue: true, | |
f6710aac TL |
302 | fieldLabel: gettext('Enabled'), |
303 | }, | |
304 | } : undefined, | |
95f2a8a2 | 305 | }, |
9c22da32 AL |
306 | spice_enhancements: { |
307 | header: gettext('Spice Enhancements'), | |
308 | defaultValue: false, | |
309 | renderer: PVE.Utils.render_spice_enhancements, | |
310 | editor: caps.vms['VM.Config.Options'] ? { | |
311 | xtype: 'proxmoxWindowEdit', | |
312 | subject: gettext('Spice Enhancements'), | |
313 | onlineHelp: 'qm_spice_enhancements', | |
314 | items: { | |
315 | xtype: 'pveSpiceEnhancementSelector', | |
316 | name: 'spice_enhancements', | |
f6710aac TL |
317 | }, |
318 | } : undefined, | |
9c22da32 | 319 | }, |
ab84ee74 DC |
320 | vmstatestorage: { |
321 | header: gettext('VM State storage'), | |
322 | defaultValue: '', | |
323 | renderer: val => val || gettext('Automatic'), | |
324 | editor: caps.vms['VM.Config.Options'] ? { | |
325 | xtype: 'proxmoxWindowEdit', | |
326 | subject: gettext('VM State storage'), | |
4fe2c21c | 327 | onlineHelp: 'chapter_virtual_machines', // FIXME: use 'qm_vmstatestorage' once available |
56054937 | 328 | width: 350, |
ab84ee74 DC |
329 | items: { |
330 | xtype: 'pveStorageSelector', | |
331 | storageContent: 'images', | |
332 | allowBlank: true, | |
56054937 | 333 | emptyText: gettext("Automatic (Storage used by the VM, or 'local')"), |
ab84ee74 DC |
334 | autoSelect: false, |
335 | deleteEmpty: true, | |
336 | skipEmptyText: true, | |
337 | nodename: nodename, | |
338 | name: 'vmstatestorage', | |
f6710aac TL |
339 | }, |
340 | } : undefined, | |
ab84ee74 | 341 | }, |
95f2a8a2 | 342 | hookscript: { |
f6710aac TL |
343 | header: gettext('Hookscript'), |
344 | }, | |
7d44036a DM |
345 | }; |
346 | ||
347 | var baseurl = 'nodes/' + nodename + '/qemu/' + vmid + '/config'; | |
348 | ||
7d44036a DM |
349 | var edit_btn = new Ext.Button({ |
350 | text: gettext('Edit'), | |
351 | disabled: true, | |
f6710aac | 352 | handler: function() { me.run_editor(); }, |
7d44036a DM |
353 | }); |
354 | ||
417f904f | 355 | var revert_btn = new PVE.button.PendingRevert(); |
7d44036a DM |
356 | |
357 | var set_button_status = function() { | |
358 | var sm = me.getSelectionModel(); | |
359 | var rec = sm.getSelection()[0]; | |
360 | ||
361 | if (!rec) { | |
362 | edit_btn.disable(); | |
363 | return; | |
364 | } | |
365 | ||
366 | var key = rec.data.key; | |
367 | var pending = rec.data['delete'] || me.hasPendingChanges(key); | |
368 | var rowdef = rows[key]; | |
369 | ||
370 | edit_btn.setDisabled(!rowdef.editor); | |
371 | revert_btn.setDisabled(!pending); | |
372 | }; | |
373 | ||
a26cb711 | 374 | Ext.apply(me, { |
7d44036a DM |
375 | url: "/api2/json/nodes/" + nodename + "/qemu/" + vmid + "/pending", |
376 | interval: 5000, | |
3c813f74 | 377 | cwidth1: 250, |
7d44036a DM |
378 | tbar: [ edit_btn, revert_btn ], |
379 | rows: rows, | |
998922c3 | 380 | editorConfig: { |
f6710aac | 381 | url: "/api2/extjs/" + baseurl, |
998922c3 | 382 | }, |
7d44036a | 383 | listeners: { |
998922c3 | 384 | itemdblclick: me.run_editor, |
f6710aac TL |
385 | selectionchange: set_button_status, |
386 | }, | |
7d44036a DM |
387 | }); |
388 | ||
389 | me.callParent(); | |
390 | ||
43364516 TL |
391 | me.on('activate', () => me.rstore.startUpdate()); |
392 | me.on('destroy', () => me.rstore.stopUpdate()); | |
393 | me.on('deactivate', () => me.rstore.stopUpdate()); | |
7d44036a | 394 | |
141aba6b | 395 | me.mon(me.getStore(), 'datachanged', function() { |
7d44036a DM |
396 | set_button_status(); |
397 | }); | |
f6710aac | 398 | }, |
7d44036a DM |
399 | }); |
400 |