pve-manager/www/manager6/qemu/Monitor.js
Thomas Lamprecht 8b0bb902e6 ui: qemu monitor: rework comment about how (starting) trimming works
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-11-16 20:22:07 +01:00

158 lines
3.7 KiB
JavaScript

Ext.define('PVE.qemu.Monitor', {
extend: 'Ext.panel.Panel',
alias: 'widget.pveQemuMonitor',
// start to trim saved command output once there are *both*, more than `commandLimit` commands
// executed and the total of saved in+output is over `lineLimit` lines; repeat by dropping one
// full command output until either condition is false again
commandLimit: 10,
lineLimit: 5000,
initComponent: function() {
var me = this;
var nodename = me.pveSelNode.data.node;
if (!nodename) {
throw "no node name specified";
}
var vmid = me.pveSelNode.data.vmid;
if (!vmid) {
throw "no VM ID specified";
}
var history = [];
var histNum = -1;
let commands = [];
var textbox = Ext.createWidget('panel', {
region: 'center',
xtype: 'panel',
autoScroll: true,
border: true,
margins: '5 5 5 5',
bodyStyle: 'font-family: monospace;',
});
var scrollToEnd = function() {
var el = textbox.getTargetEl();
var dom = Ext.getDom(el);
var clientHeight = dom.clientHeight;
// BrowserBug: clientHeight reports 0 in IE9 StrictMode
// Instead we are using offsetHeight and hardcoding borders
if (Ext.isIE9 && Ext.isStrict) {
clientHeight = dom.offsetHeight + 2;
}
dom.scrollTop = dom.scrollHeight - clientHeight;
};
var refresh = function() {
textbox.update(`<pre>${commands.flat(2).join('\n')}</pre>`);
scrollToEnd();
};
let recordInput = line => {
commands.push([line]);
// drop oldest commands and their output until we're not over both limits anymore
while (commands.length > me.commandLimit && commands.flat(2).length > me.lineLimit) {
commands.shift();
}
};
let addResponse = lines => commands[commands.length - 1].push(lines);
var executeCmd = function(cmd) {
recordInput("# " + Ext.htmlEncode(cmd), true);
if (cmd) {
history.unshift(cmd);
if (history.length > 20) {
history.splice(20);
}
}
histNum = -1;
refresh();
Proxmox.Utils.API2Request({
params: { command: cmd },
url: '/nodes/' + nodename + '/qemu/' + vmid + "/monitor",
method: 'POST',
waitMsgTarget: me,
success: function(response, opts) {
var res = response.result.data;
addResponse(res.split('\n').map(line => Ext.htmlEncode(line)));
refresh();
},
failure: function(response, opts) {
Ext.Msg.alert('Error', response.htmlStatus);
},
});
};
Ext.apply(me, {
layout: { type: 'border' },
border: false,
items: [
textbox,
{
region: 'south',
margins: '0 5 5 5',
border: false,
xtype: 'textfield',
name: 'cmd',
value: '',
fieldStyle: 'font-family: monospace;',
allowBlank: true,
listeners: {
afterrender: function(f) {
f.focus(false);
recordInput("Type 'help' for help.");
refresh();
},
specialkey: function(f, e) {
var key = e.getKey();
switch (key) {
case e.ENTER:
var cmd = f.getValue();
f.setValue('');
executeCmd(cmd);
break;
case e.PAGE_UP:
textbox.scrollBy(0, -0.9*textbox.getHeight(), false);
break;
case e.PAGE_DOWN:
textbox.scrollBy(0, 0.9*textbox.getHeight(), false);
break;
case e.UP:
if (histNum + 1 < history.length) {
f.setValue(history[++histNum]);
}
e.preventDefault();
break;
case e.DOWN:
if (histNum > 0) {
f.setValue(history[--histNum]);
}
e.preventDefault();
break;
default:
break;
}
},
},
},
],
listeners: {
show: function() {
var field = me.query('textfield[name="cmd"]')[0];
field.focus(false, true);
},
},
});
me.callParent();
},
});