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