]>
git.proxmox.com Git - pve-manager.git/blob - www/manager6/qemu/Config.js
1 Ext
.define('PVE.qemu.Config', {
2 extend
: 'PVE.panel.Config',
3 alias
: 'widget.PVE.qemu.Config',
5 onlineHelp
: 'chapter_virtual_machines',
7 initComponent: function() {
9 var vm
= me
.pveSelNode
.data
;
11 var nodename
= vm
.node
;
13 throw "no node name specified";
18 throw "no VM ID specified";
21 var template
= !!vm
.template
;
23 var running
= !!vm
.uptime
;
25 var caps
= Ext
.state
.Manager
.get('GuiCap');
27 var base_url
= '/nodes/' + nodename
+ "/qemu/" + vmid
;
29 me
.statusStore
= Ext
.create('Proxmox.data.ObjectStore', {
30 url
: '/api2/json' + base_url
+ '/status/current',
34 var vm_command = function(cmd
, params
) {
35 Proxmox
.Utils
.API2Request({
37 url
: base_url
+ '/status/' + cmd
,
40 failure: function(response
, opts
) {
41 Ext
.Msg
.alert('Error', response
.htmlStatus
);
46 var resumeBtn
= Ext
.create('Ext.Button', {
47 text
: gettext('Resume'),
48 disabled
: !caps
.vms
['VM.PowerMgmt'],
53 iconCls
: 'fa fa-play',
56 var startBtn
= Ext
.create('Ext.Button', {
57 text
: gettext('Start'),
58 disabled
: !caps
.vms
['VM.PowerMgmt'] || running
,
63 iconCls
: 'fa fa-play',
66 var migrateBtn
= Ext
.create('Ext.Button', {
67 text
: gettext('Migrate'),
68 disabled
: !caps
.vms
['VM.Migrate'],
69 hidden
: PVE
.data
.ResourceStore
.getNodes().length
< 2,
71 var win
= Ext
.create('PVE.window.Migrate', {
78 iconCls
: 'fa fa-send-o',
81 var moreBtn
= Ext
.create('Proxmox.button.Button', {
82 text
: gettext('More'),
86 text
: gettext('Clone'),
87 iconCls
: 'fa fa-fw fa-clone',
88 hidden
: !caps
.vms
['VM.Clone'],
90 PVE
.window
.Clone
.wrap(nodename
, vmid
, template
, 'qemu');
94 text
: gettext('Convert to template'),
97 iconCls
: 'fa fa-fw fa-file-o',
98 hidden
: !caps
.vms
['VM.Allocate'],
99 confirmMsg
: Proxmox
.Utils
.format_task_description('qmtemplate', vmid
),
100 handler: function() {
101 Proxmox
.Utils
.API2Request({
102 url
: base_url
+ '/template',
105 failure: function(response
, opts
) {
106 Ext
.Msg
.alert('Error', response
.htmlStatus
);
112 iconCls
: 'fa fa-heartbeat ',
113 hidden
: !caps
.nodes
['Sys.Console'],
114 text
: gettext('Manage HA'),
115 handler: function() {
117 Ext
.create('PVE.ha.VMResourceEdit', {
119 isCreate
: !ha
|| ha
=== 'unmanaged',
124 text
: gettext('Remove'),
126 disabled
: !caps
.vms
['VM.Allocate'],
127 handler: function() {
128 Ext
.create('PVE.window.SafeDestroyGuest', {
130 item
: { type
: 'VM', id
: vmid
},
131 taskName
: 'qmdestroy',
134 iconCls
: 'fa fa-trash-o',
140 var shutdownBtn
= Ext
.create('PVE.button.Split', {
141 text
: gettext('Shutdown'),
142 disabled
: !caps
.vms
['VM.PowerMgmt'] || !running
,
144 confirmMsg
: Proxmox
.Utils
.format_task_description('qmshutdown', vmid
),
145 handler: function() {
146 vm_command('shutdown');
150 text
: gettext('Reboot'),
151 disabled
: !caps
.vms
['VM.PowerMgmt'],
152 tooltip
: Ext
.String
.format(gettext('Shutdown, apply pending changes and reboot {0}'), 'VM'),
153 confirmMsg
: Proxmox
.Utils
.format_task_description('qmreboot', vmid
),
154 handler: function() {
155 vm_command("reboot");
157 iconCls
: 'fa fa-refresh',
159 text
: gettext('Pause'),
160 disabled
: !caps
.vms
['VM.PowerMgmt'],
161 confirmMsg
: Proxmox
.Utils
.format_task_description('qmpause', vmid
),
162 handler: function() {
163 vm_command("suspend");
165 iconCls
: 'fa fa-pause',
167 text
: gettext('Hibernate'),
168 disabled
: !caps
.vms
['VM.PowerMgmt'],
169 confirmMsg
: Proxmox
.Utils
.format_task_description('qmsuspend', vmid
),
170 tooltip
: gettext('Suspend to disk'),
171 handler: function() {
172 vm_command("suspend", { todisk
: 1 });
174 iconCls
: 'fa fa-download',
176 text
: gettext('Stop'),
177 disabled
: !caps
.vms
['VM.PowerMgmt'],
179 tooltip
: Ext
.String
.format(gettext('Stop {0} immediately'), 'VM'),
180 confirmMsg
: Proxmox
.Utils
.format_task_description('qmstop', vmid
),
181 handler: function() {
182 vm_command("stop", { timeout
: 30 });
184 iconCls
: 'fa fa-stop',
186 text
: gettext('Reset'),
187 disabled
: !caps
.vms
['VM.PowerMgmt'],
188 tooltip
: Ext
.String
.format(gettext('Reset {0} immediately'), 'VM'),
189 confirmMsg
: Proxmox
.Utils
.format_task_description('qmreset', vmid
),
190 handler: function() {
193 iconCls
: 'fa fa-bolt',
196 iconCls
: 'fa fa-power-off',
199 var consoleBtn
= Ext
.create('PVE.button.ConsoleButton', {
200 disabled
: !caps
.vms
['VM.Console'],
203 // disable spice/xterm for default action until status api call succeeded
205 enableXtermjs
: false,
206 consoleName
: vm
.name
,
211 var statusTxt
= Ext
.create('Ext.toolbar.TextItem', {
217 '<i class="fa fa-lg fa-lock"></i> ({lock})',
223 title
: Ext
.String
.format(gettext("Virtual Machine {0} on node '{1}'"), vm
.text
, nodename
),
226 tbar
: [statusTxt
, '->', resumeBtn
, startBtn
, shutdownBtn
, migrateBtn
, consoleBtn
, moreBtn
],
227 defaults
: { statusStore
: me
.statusStore
},
230 title
: gettext('Summary'),
231 xtype
: 'pveGuestSummary',
232 iconCls
: 'fa fa-book',
238 if (caps
.vms
['VM.Console'] && !template
) {
240 title
: gettext('Console'),
242 iconCls
: 'fa fa-terminal',
243 xtype
: 'pveNoVncConsole',
252 title
: gettext('Hardware'),
254 iconCls
: 'fa fa-desktop',
255 xtype
: 'PVE.qemu.HardwareView',
260 iconCls
: 'fa fa-cloud',
264 title
: gettext('Options'),
265 iconCls
: 'fa fa-gear',
267 xtype
: 'PVE.qemu.Options',
270 title
: gettext('Task History'),
272 xtype
: 'proxmoxNodeTasks',
273 iconCls
: 'fa fa-list-alt',
281 if (caps
.vms
['VM.Monitor'] && !template
) {
283 title
: gettext('Monitor'),
284 iconCls
: 'fa fa-eye',
286 xtype
: 'pveQemuMonitor',
290 if (caps
.vms
['VM.Backup']) {
292 title
: gettext('Backup'),
293 iconCls
: 'fa fa-floppy-o',
294 xtype
: 'pveBackupView',
298 title
: gettext('Replication'),
299 iconCls
: 'fa fa-retweet',
300 xtype
: 'pveReplicaView',
301 itemId
: 'replication',
305 if ((caps
.vms
['VM.Snapshot'] || caps
.vms
['VM.Snapshot.Rollback'] ||
306 caps
.vms
['VM.Audit']) && !template
) {
308 title
: gettext('Snapshots'),
309 iconCls
: 'fa fa-history',
311 xtype
: 'pveGuestSnapshotTree',
316 if (caps
.vms
['VM.Console']) {
319 xtype
: 'pveFirewallRules',
320 title
: gettext('Firewall'),
321 iconCls
: 'fa fa-shield',
323 base_url
: base_url
+ '/firewall/rules',
324 list_refs_url
: base_url
+ '/firewall/refs',
328 xtype
: 'pveFirewallOptions',
329 groups
: ['firewall'],
330 iconCls
: 'fa fa-gear',
331 onlineHelp
: 'pve_firewall_vm_container_configuration',
332 title
: gettext('Options'),
333 base_url
: base_url
+ '/firewall/options',
335 itemId
: 'firewall-options',
338 xtype
: 'pveFirewallAliases',
339 title
: gettext('Alias'),
340 groups
: ['firewall'],
341 iconCls
: 'fa fa-external-link',
342 base_url
: base_url
+ '/firewall/aliases',
343 itemId
: 'firewall-aliases',
347 title
: gettext('IPSet'),
348 groups
: ['firewall'],
349 iconCls
: 'fa fa-list-ol',
350 base_url
: base_url
+ '/firewall/ipset',
351 list_refs_url
: base_url
+ '/firewall/refs',
352 itemId
: 'firewall-ipset',
355 title
: gettext('Log'),
356 groups
: ['firewall'],
357 iconCls
: 'fa fa-list',
358 onlineHelp
: 'chapter_pve_firewall',
359 itemId
: 'firewall-fwlog',
360 xtype
: 'proxmoxLogView',
361 url
: '/api2/extjs' + base_url
+ '/firewall/log',
366 if (caps
.vms
['Permissions.Modify']) {
369 title
: gettext('Permissions'),
370 iconCls
: 'fa fa-unlock',
371 itemId
: 'permissions',
372 path
: '/vms/' + vmid
,
378 var prevQMPStatus
= 'unknown';
379 me
.mon(me
.statusStore
, 'load', function(s
, records
, success
) {
387 status
= qmpstatus
= 'unknown';
389 var rec
= s
.data
.get('status');
390 status
= rec
? rec
.data
.value
: 'unknown';
391 rec
= s
.data
.get('qmpstatus');
392 qmpstatus
= rec
? rec
.data
.value
: 'unknown';
393 rec
= s
.data
.get('template');
394 template
= rec
? rec
.data
.value
: false;
395 rec
= s
.data
.get('lock');
396 lock
= rec
? rec
.data
.value
: undefined;
398 spice
= !!s
.data
.get('spice');
399 xtermjs
= !!s
.data
.get('serial');
406 var resume
= ['prelaunch', 'paused', 'suspended'].indexOf(qmpstatus
) !== -1;
408 if (resume
|| lock
=== 'suspended') {
409 startBtn
.setVisible(false);
410 resumeBtn
.setVisible(true);
412 startBtn
.setVisible(true);
413 resumeBtn
.setVisible(false);
416 consoleBtn
.setEnableSpice(spice
);
417 consoleBtn
.setEnableXtermJS(xtermjs
);
419 statusTxt
.update({ lock
: lock
});
421 let guest_running
= status
=== 'running' &&
422 !(qmpstatus
=== "shutdown" || qmpstatus
=== "prelaunch");
423 startBtn
.setDisabled(!caps
.vms
['VM.PowerMgmt'] || template
|| guest_running
);
425 shutdownBtn
.setDisabled(!caps
.vms
['VM.PowerMgmt'] || status
!== 'running');
426 me
.down('#removeBtn').setDisabled(!caps
.vms
['VM.Allocate'] || status
!== 'stopped');
427 consoleBtn
.setDisabled(template
);
429 let wasStopped
= ['prelaunch', 'stopped', 'suspended'].indexOf(prevQMPStatus
) !== -1;
430 if (wasStopped
&& qmpstatus
=== 'running') {
431 let con
= me
.down('#console');
437 prevQMPStatus
= qmpstatus
;
440 me
.on('afterrender', function() {
441 me
.statusStore
.startUpdate();
444 me
.on('destroy', function() {
445 me
.statusStore
.stopUpdate();