[pve-devel] [PATCH manager] show guest-agent provided ip address in qemu summary

Dominik Csapak d.csapak at proxmox.com
Tue Feb 20 13:38:17 CET 2018


this adds a new component 'AgentIPView' which
uses the qemu-agent api call to tries to get the ip information for
the guests

only for vms at the moment, since for containers you already
set it on their network tab

Signed-off-by: Dominik Csapak <d.csapak at proxmox.com>
---
 www/manager6/Makefile                 |   1 +
 www/manager6/panel/GuestStatusView.js |  15 +++
 www/manager6/qemu/AgentIPView.js      | 214 ++++++++++++++++++++++++++++++++++
 www/manager6/qemu/Summary.js          |   2 +-
 4 files changed, 231 insertions(+), 1 deletion(-)
 create mode 100644 www/manager6/qemu/AgentIPView.js

diff --git a/www/manager6/Makefile b/www/manager6/Makefile
index 77449aa0..2688fd0e 100644
--- a/www/manager6/Makefile
+++ b/www/manager6/Makefile
@@ -128,6 +128,7 @@ JSSRC= 				                 	\
 	qemu/Config.js					\
 	qemu/CreateWizard.js				\
 	qemu/USBEdit.js					\
+	qemu/AgentIPView.js				\
 	lxc/Summary.js					\
 	lxc/Network.js					\
 	lxc/Resources.js				\
diff --git a/www/manager6/panel/GuestStatusView.js b/www/manager6/panel/GuestStatusView.js
index 250a93a7..340be21b 100644
--- a/www/manager6/panel/GuestStatusView.js
+++ b/www/manager6/panel/GuestStatusView.js
@@ -1,6 +1,7 @@
 Ext.define('PVE.panel.GuestStatusView', {
     extend: 'PVE.panel.StatusView',
     alias: 'widget.pveGuestStatusView',
+    mixins: ['Proxmox.Mixin.CBind'],
 
     height: 300,
 
@@ -75,6 +76,18 @@ Ext.define('PVE.panel.GuestStatusView', {
 		    return PVE.Utils.render_size_usage(used,max);
 		}
 	    }
+	},
+	{
+	    xtype: 'box',
+	    height: 15
+	},
+	{
+	    itemId: 'ips',
+	    xtype: 'pveAgentIPView',
+	    cbind: {
+		rstore: '{rstore}',
+		pveSelNode: '{pveSelNode}'
+	    }
 	}
     ],
 
@@ -97,6 +110,8 @@ Ext.define('PVE.panel.GuestStatusView', {
 	me.callParent();
 	if (me.pveSelNode.data.type !== 'lxc') {
 	    me.remove(me.getComponent('swap'));
+	} else {
+	    me.remove(me.getComponent('ips'));
 	}
 	me.getComponent('node').updateValue(me.pveSelNode.data.node);
     }
diff --git a/www/manager6/qemu/AgentIPView.js b/www/manager6/qemu/AgentIPView.js
new file mode 100644
index 00000000..1910dfc2
--- /dev/null
+++ b/www/manager6/qemu/AgentIPView.js
@@ -0,0 +1,214 @@
+Ext.define('PVE.window.IPInfo', {
+    extend: 'Ext.window.Window',
+    width: 600,
+    title: gettext('Network'),
+    height: 300,
+    layout: {
+	type: 'fit'
+    },
+    modal: true,
+    items: [
+	{
+	    xtype: 'grid',
+	    emptyText: gettext('No network information'),
+	    columns: [
+		{
+		    dataIndex: 'name',
+		    text: gettext('Name'),
+		    flex: 3
+		},
+		{
+		    dataIndex: 'hardware-address',
+		    text: gettext('MAC address'),
+		    width: 140
+		},
+		{
+		    dataIndex: 'ip-addresses',
+		    text: gettext('IP address'),
+		    align: 'right',
+		    flex: 4,
+		    renderer: function(val) {
+			if (!Ext.isArray(val)) {
+			    return '';
+			}
+			var ips = [];
+			val.forEach(function(ip) {
+			    var addr = ip['ip-address'];
+			    var pref = ip.prefix;
+			    if  (addr && pref) {
+				ips.push(addr + '/' + pref);
+			    }
+			});
+			return ips.join('<br>');
+		    }
+		}
+	    ]
+	}
+    ]
+});
+
+Ext.define('PVE.qemu.AgentIPView', {
+    extend: 'Ext.container.Container',
+    xtype: 'pveAgentIPView',
+
+    layout: {
+	type: 'hbox',
+	align: 'top'
+    },
+
+    nics: [],
+
+    items: [
+	{
+	    xtype: 'box',
+	    html: '<i class="fa fa-exchange"></i> IPs'
+	},
+	{
+	    xtype: 'container',
+	    flex: 1,
+	    layout: {
+		type: 'vbox',
+		align: 'right',
+		pack: 'end'
+	    },
+	    items: [
+		{
+		    xtype: 'label',
+		    flex: 1,
+		    itemId: 'ipBox',
+		    style: {
+			'text-align': 'right'
+		    }
+		},
+		{
+		    xtype: 'button',
+		    itemId: 'moreBtn',
+		    hidden: true,
+		    ui: 'default-toolbar',
+		    handler: function(btn) {
+			var me = this.up('pveAgentIPView');
+
+			var win = Ext.create('PVE.window.IPInfo');
+			win.down('grid').getStore().setData(me.nics);
+			win.show();
+		    },
+		    text: gettext('More')
+		}
+	    ]
+	}
+    ],
+
+    getDefaultIps: function(nics) {
+	var me = this;
+	var ips = [];
+	nics.forEach(function(nic) {
+	    if (nic['hardware-address'] &&
+		nic['hardware-address'] != '00:00:00:00:00:00') {
+
+		var nic_ips = nic['ip-addresses'] || [];
+		nic_ips.forEach(function(ip) {
+		    var p = ip['ip-address'];
+		    // show 2 ips at maximum
+		    if (ips.length < 2) {
+			ips.push(p);
+		    }
+		});
+	    }
+	});
+
+	return ips;
+    },
+
+    startIPStore: function(store, records, success) {
+	var me = this;
+	var agentRec = store.getById('agent');
+	/*jslint confusion: true*/
+	/* value is number and string */
+	me.agent = (agentRec && agentRec.data.value === 1);
+	me.running = (store.getById('status').data.value === 'running');
+	/*jslint confusion: false*/
+
+	if (me.agent && me.running && me.ipStore.isStopped) {
+	    me.ipStore.startUpdate();
+	}
+	me.updateStatus();
+    },
+
+    updateStatus: function(unsuccessful) {
+	var me = this;
+	var text = gettext('No network information');
+	var more = false;
+	if (unsuccessful) {
+	    text = gettext('Guest Agent not running');
+	} else if (me.agent && me.running) {
+	    if (Ext.isArray(me.nics)) {
+		more = true;
+		var ips = me.getDefaultIps(me.nics);
+		if (ips.length !== 0) {
+		    text = ips.join('<br>');
+		}
+	    } else if (me.nics && me.nics.error) {
+		var msg = gettext('Cannot get info from Guest Agent<br>Error: {0}');
+		text = Ext.String.format(text, me.nics.error.desc);
+	    }
+	} else if (me.agent) {
+	    text = gettext('Guest Agent not running');
+	} else {
+	    text = gettext('No Guest Agent configured');
+	}
+
+	var ipBox = me.down('#ipBox');
+	ipBox.update(text);
+
+	var moreBtn = me.down('#moreBtn');
+	moreBtn.setVisible(more);
+    },
+
+    initComponent: function() {
+	var me = this;
+
+	if (!me.rstore) {
+	    throw 'rstore not given';
+	}
+
+	if (!me.pveSelNode) {
+	    throw 'pveSelNode not given';
+	}
+
+	var nodename = me.pveSelNode.data.node;
+	var vmid = me.pveSelNode.data.vmid;
+
+	me.ipStore = Ext.create('Proxmox.data.UpdateStore', {
+	    interval: 10000,
+	    storeid: 'pve-qemu-agent-' + vmid,
+	    method: 'POST',
+	    proxy: {
+		type: 'proxmox',
+		url: '/api2/json/nodes/' + nodename + '/qemu/' + vmid + '/agent/network-get-interfaces'
+	    }
+	});
+
+	me.callParent();
+
+	me.mon(me.ipStore, 'load', function(store, records, success) {
+	    if (records && records.length) {
+		me.nics = records[0].data.result;
+	    } else {
+		me.nics = undefined;
+	    }
+	    me.updateStatus(!success);
+	});
+
+	me.on('destroy', me.ipStore.stopUpdate);
+
+	// start ipstore immediatly if we already have data in the
+	// statusstore
+	if (me.rstore.getCount()) {
+	    me.startIPStore(me.rstore, me.rstore.getData(), false);
+	}
+
+	// with every load of the statusstore,
+	// we check if the guest agent is there
+	me.mon(me.rstore, 'load', me.startIPStore, me);
+    }
+});
diff --git a/www/manager6/qemu/Summary.js b/www/manager6/qemu/Summary.js
index 73d273ac..18977bf4 100644
--- a/www/manager6/qemu/Summary.js
+++ b/www/manager6/qemu/Summary.js
@@ -96,7 +96,7 @@ Ext.define('PVE.qemu.Summary', {
 			    items: [
 				{
 				    width: 770,
-				    height: 300,
+				    height: 330,
 				    layout: {
 					type: 'hbox',
 					align: 'stretch'
-- 
2.11.0





More information about the pve-devel mailing list