]> git.proxmox.com Git - pve-manager.git/blob - www/manager6/qemu/Monitor.js
7f1626e3c4c89324beac8e2d7e42b111e393c8ed
[pve-manager.git] / www / manager6 / qemu / Monitor.js
1 Ext.define('PVE.qemu.Monitor', {
2 extend: 'Ext.panel.Panel',
3
4 alias: 'widget.pveQemuMonitor',
5
6 // ouput is trimmed when it's over both commandLimit and lineLimit
7 // by removing the first commands and their output
8 commandLimit: 10,
9 lineLimit: 5000,
10
11 initComponent: function() {
12 var me = this;
13
14 var nodename = me.pveSelNode.data.node;
15 if (!nodename) {
16 throw "no node name specified";
17 }
18
19 var vmid = me.pveSelNode.data.vmid;
20 if (!vmid) {
21 throw "no VM ID specified";
22 }
23
24 var history = [];
25 var histNum = -1;
26 let commands = [];
27
28 var textbox = Ext.createWidget('panel', {
29 region: 'center',
30 xtype: 'panel',
31 autoScroll: true,
32 border: true,
33 margins: '5 5 5 5',
34 bodyStyle: 'font-family: monospace;',
35 });
36
37 var scrollToEnd = function() {
38 var el = textbox.getTargetEl();
39 var dom = Ext.getDom(el);
40
41 var clientHeight = dom.clientHeight;
42 // BrowserBug: clientHeight reports 0 in IE9 StrictMode
43 // Instead we are using offsetHeight and hardcoding borders
44 if (Ext.isIE9 && Ext.isStrict) {
45 clientHeight = dom.offsetHeight + 2;
46 }
47 dom.scrollTop = dom.scrollHeight - clientHeight;
48 };
49
50 var refresh = function() {
51 textbox.update(`<pre>${commands.flat(2).join('\n')}</pre>`);
52 scrollToEnd();
53 };
54
55 let recordInput = line => {
56 commands.push([line]);
57
58 // drop oldest commands and their output until we're not over both limits anymore
59 while (commands.length > me.commandLimit && commands.flat(2).length > me.lineLimit) {
60 commands.shift();
61 }
62 };
63
64 let addResponse = lines => commands[commands.length - 1].push(lines);
65
66 var executeCmd = function(cmd) {
67 recordInput("# " + Ext.htmlEncode(cmd), true);
68 if (cmd) {
69 history.unshift(cmd);
70 if (history.length > 20) {
71 history.splice(20);
72 }
73 }
74 histNum = -1;
75
76 refresh();
77 Proxmox.Utils.API2Request({
78 params: { command: cmd },
79 url: '/nodes/' + nodename + '/qemu/' + vmid + "/monitor",
80 method: 'POST',
81 waitMsgTarget: me,
82 success: function(response, opts) {
83 var res = response.result.data;
84 addResponse(res.split('\n').map(line => Ext.htmlEncode(line)));
85 refresh();
86 },
87 failure: function(response, opts) {
88 Ext.Msg.alert('Error', response.htmlStatus);
89 },
90 });
91 };
92
93 Ext.apply(me, {
94 layout: { type: 'border' },
95 border: false,
96 items: [
97 textbox,
98 {
99 region: 'south',
100 margins: '0 5 5 5',
101 border: false,
102 xtype: 'textfield',
103 name: 'cmd',
104 value: '',
105 fieldStyle: 'font-family: monospace;',
106 allowBlank: true,
107 listeners: {
108 afterrender: function(f) {
109 f.focus(false);
110 recordInput("Type 'help' for help.");
111 refresh();
112 },
113 specialkey: function(f, e) {
114 var key = e.getKey();
115 switch (key) {
116 case e.ENTER:
117 var cmd = f.getValue();
118 f.setValue('');
119 executeCmd(cmd);
120 break;
121 case e.PAGE_UP:
122 textbox.scrollBy(0, -0.9*textbox.getHeight(), false);
123 break;
124 case e.PAGE_DOWN:
125 textbox.scrollBy(0, 0.9*textbox.getHeight(), false);
126 break;
127 case e.UP:
128 if (histNum + 1 < history.length) {
129 f.setValue(history[++histNum]);
130 }
131 e.preventDefault();
132 break;
133 case e.DOWN:
134 if (histNum > 0) {
135 f.setValue(history[--histNum]);
136 }
137 e.preventDefault();
138 break;
139 default:
140 break;
141 }
142 },
143 },
144 },
145 ],
146 listeners: {
147 show: function() {
148 var field = me.query('textfield[name="cmd"]')[0];
149 field.focus(false, true);
150 },
151 },
152 });
153
154 me.callParent();
155 },
156 });