74346a61dd3056fc3e06f2f148405e2b3e62f9c9
[virt-tools.git] / tools / virt-ifconfig.pl
1 #!/usr/bin/perl -w
2 # virt-ifconfig
3 # Copyright (C) 2009 Red Hat Inc.
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19 use strict;
20
21 use Sys::Guestfs;
22 use Sys::Guestfs::Lib qw(open_guest get_partitions resolve_windows_path
23   inspect_all_partitions inspect_partition
24   inspect_operating_systems mount_operating_system inspect_in_detail);
25 use Pod::Usage;
26 use Getopt::Long;
27 use Locale::TextDomain 'virt-tools';
28
29 =encoding utf8
30
31 =head1 NAME
32
33 virt-ifconfig - Display IP address of a virtual machine
34
35 =head1 SYNOPSIS
36
37  virt-ifconfig [--options] domname
38
39  virt-ifconfig [--options]
40
41 =head1 DESCRIPTION
42
43 C<virt-ifconfig domname> displays the IP address of a virtual machine
44 named C<domname>, where C<domname> is the libvirt name.  If no
45 C<domname> is given, this lists out the IP addresses of all running
46 virtual machines known to libvirt.
47
48 For Linux guests, this only works if the C<virt-tools-guest> package
49 is installed in the guest.
50
51 =head1 OPTIONS
52
53 =over 4
54
55 =cut
56
57 my $help;
58
59 =item B<--help>
60
61 Display brief help.
62
63 =cut
64
65 my $version;
66
67 =item B<--version>
68
69 Display version number and exit.
70
71 =cut
72
73 my $uri;
74
75 =item B<--connect URI> | B<-c URI>
76
77 If using libvirt, connect to the given I<URI>.  If omitted, then we
78 connect to the default libvirt hypervisor.
79
80 =cut
81
82 my $csv;
83
84 =item B<--csv>
85
86 Write out the results in CSV format (comma-separated values).
87 This format can be imported easily into databases and spreadsheets.
88
89 =back
90
91 =cut
92
93 GetOptions ("help|?" => \$help,
94             "version" => \$version,
95             "connect|c=s" => \$uri,
96             "csv" => \$csv,
97     ) or pod2usage (2);
98 pod2usage (1) if $help;
99 if ($version) {
100     print "@PACKAGE_STRING@\n";
101     exit
102 }
103
104 # Open the guest handle.
105
106 if (@ARGV == 0) {
107     my $conn;
108
109     if ($uri) {
110         $conn = Sys::Virt->new (readonly => 1, address => $uri);
111     } else {
112         $conn = Sys::Virt->new (readonly => 1);
113     }
114
115     # Ignore inactive domains - who cares about their IP address?
116     my @doms = $conn->list_domains ();
117
118     my @domnames = map { $_->get_name () } @doms;
119
120     if (@domnames) {
121         print_title ();
122         foreach (@domnames) {
123             do_ifconfig ($_);
124         }
125     }
126 } else {
127     print_title ();
128     do_ifconfig (@ARGV);
129 }
130
131 sub print_title
132 {
133     print_row (__"Guest", __"Iface", __"Family", __"IP address");
134 }
135
136 sub print_row
137 {
138     my $domname = shift;
139     my $iface = shift;
140     my $family = shift;
141     my $ip = shift;
142
143     if (!$csv) {
144         printf ("%-20s %-7s %-7s %s\n", $domname, $iface, $family, $ip);
145     } else {
146         printf ("%s,%s,%s,%s\n", $domname, $iface, $family, $ip);
147     }
148 }
149
150 sub do_ifconfig
151 {
152     my @args = @_;
153     my $g;
154
155     if ($uri) {
156         $g = open_guest (\@args, address => $uri);
157     } else {
158         $g = open_guest (\@args);
159     }
160
161     $g->launch ();
162
163     # Don't care about mountpoints.  Instead, just look for a
164     # directory with one of a selection of names on one of the
165     # partitions that we found.
166     my @partitions = get_partitions ($g);
167
168     my %ips;
169     foreach my $partition (@partitions) {
170         eval {
171             $g->mount_ro ($partition, "/");
172             my $dir;
173             my @dirs = ("/var/run/virt-tools", "/run/virt-tools");
174             foreach $dir (@dirs) {
175                 if ($g->is_dir ($dir)) {
176                     my @names = $g->ls ($dir);
177                     @names = grep { /^ip-/ } @names;
178                     my $name;
179                     foreach $name (@names) {
180                         my $iface = $name;
181                         $iface =~ s/^ip-//;
182                         eval {
183                             my @lines = $g->read_lines ("$dir/$name");
184                             foreach (@lines) {
185                                 if (m{^\s*inet (\S+)/\d+ }) {
186                                     $ips{$iface}{inet} = []
187                                         unless exists $ips{$iface}{inet};
188                                     push @{$ips{$iface}{inet}}, $1;
189                                 } elsif (m{^\s*inet6 (\S+)/\d+ }) {
190                                     $ips{$iface}{inet6} = []
191                                         unless exists $ips{$iface}{inet6};
192                                     push @{$ips{$iface}{inet6}}, $1;
193                                 }
194                             }
195                         }
196                     }
197                 }
198             }
199         };
200         $g->umount_all ();
201     }
202
203     my @ifaces = sort keys %ips;
204     if (@ifaces) {
205         my $iface;
206         foreach $iface (@ifaces) {
207             my @families = sort keys %{$ips{$iface}};
208             my $family;
209             foreach $family (@families) {
210                 foreach (@{$ips{$iface}{$family}}) {
211                     print_row ($args[0], $iface, $family, $_);
212                 }
213             }
214         }
215     } else {
216         print STDERR
217             __x("{n}: no IP address found (is guest running virt-tools?)\n",
218                 n => $args[0]);
219     }
220 }
221
222 exit 0;
223
224 =head1 SEE ALSO
225
226 L<guestfs(3)>,
227 L<guestfish(1)>,
228 L<Sys::Guestfs(3)>,
229 L<Sys::Guestfs::Lib(3)>,
230 L<Sys::Virt(3)>,
231 L<http://libguestfs.org/>.
232
233 =head1 AUTHOR
234
235 Richard W.M. Jones L<http://et.redhat.com/~rjones/>
236
237 =head1 COPYRIGHT
238
239 Copyright (C) 2009 Red Hat Inc.
240
241 This program is free software; you can redistribute it and/or modify
242 it under the terms of the GNU General Public License as published by
243 the Free Software Foundation; either version 2 of the License, or
244 (at your option) any later version.
245
246 This program is distributed in the hope that it will be useful,
247 but WITHOUT ANY WARRANTY; without even the implied warranty of
248 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
249 GNU General Public License for more details.
250
251 You should have received a copy of the GNU General Public License
252 along with this program; if not, write to the Free Software
253 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.