From 3fdc8cc9b53be241cd636cafd4ecce4111f62b05 Mon Sep 17 00:00:00 2001 From: Richard Jones Date: Wed, 23 Sep 2009 16:54:03 +0100 Subject: [PATCH] virt-ifconfig working --- .gitignore | 2 + configure.ac | 15 ++-- linux/50-virt-tools.in | 22 +++++ linux/Makefile.am | 10 +++ tools/Makefile.am | 15 +++- tools/virt-ifconfig.pl | 237 ++++++++++++++++++++++++++++++++++++++++++++++++- 6 files changed, 291 insertions(+), 10 deletions(-) create mode 100644 linux/50-virt-tools.in diff --git a/.gitignore b/.gitignore index 0736ca2..a91ce02 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,8 @@ config.status configure install-sh missing +linux/50-virt-tools +localconfigure tools/virt-ifconfig tools/virt-tools-get-key tools/virt-tools-get-transport diff --git a/configure.ac b/configure.ac index adf06f3..e1c5702 100644 --- a/configure.ac +++ b/configure.ac @@ -15,7 +15,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -AC_INIT([libguestfs],0.1.0) +AC_INIT([virt-tools],0.1.0) AM_INIT_AUTOMAKE([foreign]) AC_CONFIG_MACRO_DIR([m4]) @@ -25,11 +25,12 @@ if test "x$PERL" = "xno"; then AC_MSG_FAILURE([Perl must be installed]) fi -dnl Check for Perl modules that must be present to compile and -dnl test the Perl bindings. +AM_PROG_MKDIR_P + +dnl Check for required and optional Perl modules. missing_perl_modules=no -required_perl_modules="Test::More Test::Pod Test::Pod::Coverage ExtUtils::MakeMaker Sys::Virt" -optional_perl_modules="Sys::Guestfs" +required_perl_modules="Test::More Test::Pod Test::Pod::Coverage ExtUtils::MakeMaker Sys::Virt Sys::Guestfs Locale::TextDomain" +optional_perl_modules="" for pm in $required_perl_modules; do AC_MSG_CHECKING([for $pm]) @@ -60,6 +61,9 @@ AC_CHECK_PROG([POD2TEXT],[pod2text],[pod2text],[no]) test "x$POD2TEXT" = "xno" && AC_MSG_ERROR([pod2text must be installed]) +AC_CONFIG_FILES([linux/50-virt-tools:linux/50-virt-tools.in], + [chmod +x linux/50-virt-tools]) + AC_CONFIG_FILES([tools/virt-tools-get-key:tools/virt-tools-get-key.pl], [chmod +x tools/virt-tools-get-key]) AC_CONFIG_FILES([tools/virt-tools-get-transport:tools/virt-tools-get-transport.pl], @@ -68,6 +72,7 @@ AC_CONFIG_FILES([tools/virt-uname:tools/virt-uname.pl], [chmod +x tools/virt-uname]) AC_CONFIG_FILES([tools/virt-ifconfig:tools/virt-ifconfig.pl], [chmod +x tools/virt-ifconfig]) + AC_CONFIG_FILES([Makefile daemon/Makefile docs/Makefile linux/Makefile tools/Makefile]) AC_OUTPUT diff --git a/linux/50-virt-tools.in b/linux/50-virt-tools.in new file mode 100644 index 0000000..5b7073f --- /dev/null +++ b/linux/50-virt-tools.in @@ -0,0 +1,22 @@ +#!/bin/sh - +# virt-tools NetworkManager configuration. +# Copyright (C) 2009 Red Hat Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +/sbin/ip addr show dev "$1" > @localstatedir@/run/virt-tools/ip-"$1" + +# Ensure the blocks get written to disk. +sync diff --git a/linux/Makefile.am b/linux/Makefile.am index 770700f..ac9bfb7 100644 --- a/linux/Makefile.am +++ b/linux/Makefile.am @@ -14,3 +14,13 @@ # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +# NetworkManager configuration for the guest side. +nmconfdir = $(sysconfdir)/NetworkManager/dispatcher.d +nmconf_DATA = 50-virt-tools + +# Directory for sharing data with the host. +sharingdir = $(localstatedir)/run/virt-tools + +install-data-hook: + $(MKDIR_P) $(DESTDIR)$(sharingdir) diff --git a/tools/Makefile.am b/tools/Makefile.am index c45258b..7391185 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -37,11 +37,20 @@ install-exec-hook: ln $(DESTDIR)$(bindir)/virt-uname $(DESTDIR)$(bindir)/$$prog; \ done -man_MANS = virt-uname.8 $(PROGS:%=%.8) +man_MANS = $(generated_mans) virt-ifconfig.8 -$(man_MANS): +generated_mans = virt-uname.8 $(PROGS:%=%.8) + +$(generated_mans): rm -f $@-t echo '.so man8/virt-tools.8' > $@-t mv $@-t $@ -CLEANFILES = virt-uname.8 $(PROGS:%=%.8) +virt-ifconfig.8: virt-ifconfig + $(POD2MAN) \ + --section 8 \ + -c "Virtualization Support" \ + --release "$(PACKAGE_NAME)-$(PACKAGE_VERSION)" \ + $< > $@-t && mv $@-t $@ + +CLEANFILES = $(generated_mans) diff --git a/tools/virt-ifconfig.pl b/tools/virt-ifconfig.pl index 0b478b8..74346a6 100755 --- a/tools/virt-ifconfig.pl +++ b/tools/virt-ifconfig.pl @@ -1,5 +1,5 @@ #!/usr/bin/perl -w -# virt-tools +# virt-ifconfig # Copyright (C) 2009 Red Hat Inc. # # This program is free software; you can redistribute it and/or modify @@ -16,5 +16,238 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -use Net::SNMP; +use strict; +use Sys::Guestfs; +use Sys::Guestfs::Lib qw(open_guest get_partitions resolve_windows_path + inspect_all_partitions inspect_partition + inspect_operating_systems mount_operating_system inspect_in_detail); +use Pod::Usage; +use Getopt::Long; +use Locale::TextDomain 'virt-tools'; + +=encoding utf8 + +=head1 NAME + +virt-ifconfig - Display IP address of a virtual machine + +=head1 SYNOPSIS + + virt-ifconfig [--options] domname + + virt-ifconfig [--options] + +=head1 DESCRIPTION + +C displays the IP address of a virtual machine +named C, where C is the libvirt name. If no +C is given, this lists out the IP addresses of all running +virtual machines known to libvirt. + +For Linux guests, this only works if the C package +is installed in the guest. + +=head1 OPTIONS + +=over 4 + +=cut + +my $help; + +=item B<--help> + +Display brief help. + +=cut + +my $version; + +=item B<--version> + +Display version number and exit. + +=cut + +my $uri; + +=item B<--connect URI> | B<-c URI> + +If using libvirt, connect to the given I. If omitted, then we +connect to the default libvirt hypervisor. + +=cut + +my $csv; + +=item B<--csv> + +Write out the results in CSV format (comma-separated values). +This format can be imported easily into databases and spreadsheets. + +=back + +=cut + +GetOptions ("help|?" => \$help, + "version" => \$version, + "connect|c=s" => \$uri, + "csv" => \$csv, + ) or pod2usage (2); +pod2usage (1) if $help; +if ($version) { + print "@PACKAGE_STRING@\n"; + exit +} + +# Open the guest handle. + +if (@ARGV == 0) { + my $conn; + + if ($uri) { + $conn = Sys::Virt->new (readonly => 1, address => $uri); + } else { + $conn = Sys::Virt->new (readonly => 1); + } + + # Ignore inactive domains - who cares about their IP address? + my @doms = $conn->list_domains (); + + my @domnames = map { $_->get_name () } @doms; + + if (@domnames) { + print_title (); + foreach (@domnames) { + do_ifconfig ($_); + } + } +} else { + print_title (); + do_ifconfig (@ARGV); +} + +sub print_title +{ + print_row (__"Guest", __"Iface", __"Family", __"IP address"); +} + +sub print_row +{ + my $domname = shift; + my $iface = shift; + my $family = shift; + my $ip = shift; + + if (!$csv) { + printf ("%-20s %-7s %-7s %s\n", $domname, $iface, $family, $ip); + } else { + printf ("%s,%s,%s,%s\n", $domname, $iface, $family, $ip); + } +} + +sub do_ifconfig +{ + my @args = @_; + my $g; + + if ($uri) { + $g = open_guest (\@args, address => $uri); + } else { + $g = open_guest (\@args); + } + + $g->launch (); + + # Don't care about mountpoints. Instead, just look for a + # directory with one of a selection of names on one of the + # partitions that we found. + my @partitions = get_partitions ($g); + + my %ips; + foreach my $partition (@partitions) { + eval { + $g->mount_ro ($partition, "/"); + my $dir; + my @dirs = ("/var/run/virt-tools", "/run/virt-tools"); + foreach $dir (@dirs) { + if ($g->is_dir ($dir)) { + my @names = $g->ls ($dir); + @names = grep { /^ip-/ } @names; + my $name; + foreach $name (@names) { + my $iface = $name; + $iface =~ s/^ip-//; + eval { + my @lines = $g->read_lines ("$dir/$name"); + foreach (@lines) { + if (m{^\s*inet (\S+)/\d+ }) { + $ips{$iface}{inet} = [] + unless exists $ips{$iface}{inet}; + push @{$ips{$iface}{inet}}, $1; + } elsif (m{^\s*inet6 (\S+)/\d+ }) { + $ips{$iface}{inet6} = [] + unless exists $ips{$iface}{inet6}; + push @{$ips{$iface}{inet6}}, $1; + } + } + } + } + } + } + }; + $g->umount_all (); + } + + my @ifaces = sort keys %ips; + if (@ifaces) { + my $iface; + foreach $iface (@ifaces) { + my @families = sort keys %{$ips{$iface}}; + my $family; + foreach $family (@families) { + foreach (@{$ips{$iface}{$family}}) { + print_row ($args[0], $iface, $family, $_); + } + } + } + } else { + print STDERR + __x("{n}: no IP address found (is guest running virt-tools?)\n", + n => $args[0]); + } +} + +exit 0; + +=head1 SEE ALSO + +L, +L, +L, +L, +L, +L. + +=head1 AUTHOR + +Richard W.M. Jones L + +=head1 COPYRIGHT + +Copyright (C) 2009 Red Hat Inc. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- 1.8.3.1