[pve-devel] [PATCH v2 container] vmstatus: include detected IP address of running containers

Oguz Bektas o.bektas at proxmox.com
Thu Jul 29 14:26:29 CEST 2021


add a helper 'find_lxc_ip_address' to fetch IP address of container from
its network namespace using lxc-info.

for the moment it can be queried with the pct tool:
$ pct status 1000 --verbose
cpu: 0
cpus: 1
disk: 6422528
diskread: 368640
diskwrite: 0
ipaddress: 192.168.31.83        <----
maxdisk: 4294967296
maxmem: 536870912
maxswap: 536870912
mem: 864256
name: CT1000
netin: 3281265
netout: 15794
pid: 34897
status: running
swap: 94208
type: lxc
uptime: 11088
vmid: 1000

Signed-off-by: Oguz Bektas <o.bektas at proxmox.com>
---
v1->v2:
* add to vmstatus_return_properties
* add a global variable for caching results
* handle multiple addresses
* pct also needs to handle array when printing verbose status



 src/PVE/CLI/pct.pm |  7 ++++++-
 src/PVE/LXC.pm     | 35 +++++++++++++++++++++++++++++++++++
 2 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/src/PVE/CLI/pct.pm b/src/PVE/CLI/pct.pm
index 254b3b3..827a68c 100755
--- a/src/PVE/CLI/pct.pm
+++ b/src/PVE/CLI/pct.pm
@@ -66,7 +66,12 @@ __PACKAGE__->register_method ({
 	    foreach my $k (sort (keys %$stat)) {
 		my $v = $stat->{$k};
 		next if !defined($v);
-		print "$k: $v\n";
+		if (ref($v) eq 'ARRAY') {
+		    my $str = join(",", @$v);
+		    print "$k: $str\n";
+		} else {
+		    print "$k: $v\n";
+		}
 	    }
 	} else {
 	    my $status = $stat->{status} || 'unknown';
diff --git a/src/PVE/LXC.pm b/src/PVE/LXC.pm
index 139f901..3354290 100644
--- a/src/PVE/LXC.pm
+++ b/src/PVE/LXC.pm
@@ -118,6 +118,9 @@ sub get_container_disk_usage {
 
 my $last_proc_vmid_stat;
 
+
+my $container_ip_cache = {};
+
 our $vmstatus_return_properties = {
     vmid => get_standard_option('pve-vmid'),
     status => {
@@ -148,6 +151,11 @@ our $vmstatus_return_properties = {
 	type => 'string',
 	optional => 1,
     },
+    ipaddress => {
+	description => "IP addresses.",
+	type => 'array', items => { type => 'string' },
+	optional => 1,
+    },
     uptime => {
 	description => "Uptime.",
 	type => 'integer',
@@ -245,6 +253,11 @@ sub vmstatus {
 	my $d = $list->{$vmid};
 	my $pid = $d->{pid};
 
+	$container_ip_cache->{$vmid} = {
+	    ipaddress => [],
+	    timestamp => $cdtime,
+	};
+
 	next if !$pid; # skip stopped CTs
 
 	my $proc_pid_stat = PVE::ProcFSTools::read_proc_pid_stat($pid);
@@ -254,6 +267,13 @@ sub vmstatus {
 
 	my $cgroups = PVE::LXC::CGroup->new($vmid);
 
+	my $cache_period = 60; # seconds
+	if ($cdtime - $container_ip_cache->{$vmid}->{timestamp} < $cache_period) {
+	    $container_ip_cache->{$vmid}->{timestamp} = gettimeofday;
+	    $container_ip_cache->{$vmid}->{ipaddress} = find_lxc_ip_address($vmid);
+	    $d->{ipaddress} = $container_ip_cache->{$vmid}->{ipaddress};
+	}
+
 	if (defined(my $mem = $cgroups->get_memory_stat())) {
 	    $d->{mem} = int($mem->{mem});
 	    $d->{swap} = int($mem->{swap});
@@ -397,6 +417,21 @@ sub open_ppid {
     return ($ppid, $fd);
 }
 
+sub find_lxc_ip_address {
+    my ($vmid) = @_;
+
+    my $ip_list = [];
+
+    my $parser = sub {
+	my $line = shift;
+	my $ip = $1 if $line =~ m/^IP:\s+(.*)$/;
+	push @$ip_list, $ip;
+    };
+
+    PVE::Tools::run_command(['lxc-info', '-n', $vmid, '--ips'], outfunc => $parser, errfunc => sub {});
+    return $ip_list;
+}
+
 # Note: we cannot use Net:IP, because that only allows strict
 # CIDR networks
 sub parse_ipv4_cidr {
-- 
2.30.2






More information about the pve-devel mailing list