3 # Copyright (C) 2009 Red Hat Inc.
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.
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.
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.
21 use Sys::Guestfs::Lib qw(open_guest get_partitions);
24 use Locale::TextDomain 'virt-tools';
31 virt-tools-get-transport - virt-tools helper to get the guest's transport
35 virt-tools-get-transport [--options] domname
39 This helper program is used by L<virt-tools(8)> to get the transport
40 that should be used to connect to the SNMP daemon inside the guest.
41 If you don't know anything about this, you probably want to start by
42 reading L<virt-tools(8)>. Otherwise read on.
44 The single command line argument should be a libvirt domain name (see
49 Transports look somewhat like a URL, with a transport schema followed
50 by some specific details. Currently we have defined these transports:
54 =item udp:ip-address[:port]
56 Connect via UDP to C<ip-address>, optionally on the non-default port
57 C<port> (the usual SNMP port 161 is used otherwise).
59 =item tcp:ip-address[:port]
61 Connect via TCP to C<ip-address>, optionally on the non-default port
62 C<port> (the usual SNMP port 161 is used otherwise).
66 Connect via Unix domain socket C<path>. This would be used in future
67 for vmchannel implementations, but it is not used at the moment.
71 =head2 TRANSPORT CACHE
73 The cache is described in detail in L<virt-tools(8)>. In brief, if
74 C<@localstatedir@/lib/virt-tools/transports/E<lt>UUIDE<gt>> exists
75 (where E<lt>UUIDE<gt> is the guest's UUID), then the contents of that
76 file are returned directly. Otherwise we will try to create this file
77 after reading the transport so that we don't have to determine the
78 guest's transport each time.
98 Display version number and exit.
104 =item B<--connect URI> | B<-c URI>
106 If using libvirt, connect to the given I<URI>. If omitted, then we
107 connect to the default libvirt hypervisor.
113 =item B<--verbose> | B<-v>
115 Enable verbose messages, useful for debugging.
121 =item B<--no-ping> | B<-n>
123 Do not try to check that the transport is working by pinging the
126 If this option is I<not> given, then this program will expire the
127 cache entry for the guest if the transport from the cache doesn't
128 work, then it will try to determine the new transport, test that, and
129 fail if it still doesn't work.
135 GetOptions ("help|?" => \$help,
136 "version" => \$version,
137 "connect|c=s" => \$uri,
138 "verbose|v" => \$verbose,
139 "no-ping|n" => \$no_ping,
141 pod2usage (1) if $help;
143 print "@PACKAGE_STRING@\n";
147 die __"no domain name listed on the command line\n" unless @ARGV == 1;
149 my ($g, $conn, $dom);
152 ($g, $conn, $dom) = open_guest (\@ARGV, address => $uri);
154 ($g, $conn, $dom) = open_guest (\@ARGV);
157 my $uuid = $dom->get_uuid_string ();
158 my $domname = $dom->get_name ();
160 # See if the UUID exists in the cache already.
161 print STDERR "checking for UUID $uuid in the cache directory\n" if $verbose;
163 my $cachedir = "@localstatedir@/lib/virt-tools/transports";
164 if (-r "$cachedir/$uuid") {
165 print STDERR "$cachedir/$uuid exists\n" if $verbose;
166 open FILE, "$cachedir/$uuid" or die "$cachedir/$uuid: $!";
167 my $transport = <FILE>;
173 if (!test_transport ($transport)) {
174 unlink "$cachedir/$uuid"; # allow this to fail
179 print $transport, "\n";
184 print STDERR "$cachedir/$uuid not found, looking inside guest\n" if $verbose;
189 # Do not care about mountpoints. Instead, just look for a
190 # directory with one of a selection of names on one of the
191 # partitions that we found.
192 my @partitions = get_partitions ($g);
194 my ($transport, $key, $ip);
196 foreach my $partition (@partitions) {
198 $g->mount_ro ($partition, "/");
200 my @dirs = ("/var/lib/virt-tools", "/lib/virt-tools");
201 foreach $dir (@dirs) {
202 if ($g->is_dir ($dir)) {
203 if ($g->is_file ("$dir/transport")) {
204 $transport = $g->cat ("$dir/transport");
206 if ($g->is_file ("$dir/key")) {
207 $key = $g->cat ("$dir/key");
209 if ($g->is_file ("$dir/ip-eth0")) {
210 $ip = $g->cat ("$dir/ip-eth0");
216 last if $transport || $key;
221 die __x("{n}: no transport or key found in guest.\nDoes it have the virt-tool-guest package installed?\n",
223 unless $transport && $key;
226 if ($ip =~ m{inet (\S+)/}) {
228 } elsif ($ip =~ m{inet6 (\S+)/}) {
231 die __"could not parse the content of ip-eth0 file from the guest";
235 if ($transport =~ /^udp:(\d+)/) {
236 die __"UDP transport, but no IP address in guest" unless $ip;
237 $transport = "udp:$ip:$1";
239 elsif ($transport =~ /^udp/) {
240 die __"UDP transport, but no IP address in guest" unless $ip;
241 $transport = "udp:$ip:161";
243 elsif ($transport =~ /^tcp:(\d+)/) {
244 die __"TCP transport, but no IP address in guest" unless $ip;
245 $transport = "tcp:$ip:$1";
247 elsif ($transport =~ /^tcp/) {
248 die __"TCP transport, but no IP address in guest" unless $ip;
249 $transport = "tcp:$ip:161";
252 die __x("unknown transport type: {t}", t => $transport);
255 # Test the transport works.
256 die __x("transport {t} does not work", t => $transport)
257 unless test_transport ($transport, $key);
259 print STDERR "try to write $transport to $cachedir/$uuid\n" if $verbose;
261 if (open FILE, ">$cachedir/$uuid") {
262 print FILE $transport;
272 my $transport = shift;
276 my $cmd = "virt-tools-get-key";
277 $cmd .= " -v" if $verbose;
279 $cmd .= " -c '$uri'" if $uri;
280 $cmd .= " '$domname'";
282 print STDERR "$cmd\n" if $verbose;
284 open PIPE, "$cmd |" or die "$cmd: $!";
286 die __"no response from virt-tools-get-key\n" unless $key;
291 print "XXX PING XXX\n";
302 L<Sys::Guestfs::Lib(3)>,
304 L<http://libguestfs.org/>.
312 Richard W.M. Jones (C<rjones at redhat dot com>)
316 Matthew Booth (C<mbooth at redhat dot com>)
322 Copyright (C) 2009 Red Hat Inc.
324 This program is free software; you can redistribute it and/or modify
325 it under the terms of the GNU General Public License as published by
326 the Free Software Foundation; either version 2 of the License, or
327 (at your option) any later version.
329 This program is distributed in the hope that it will be useful,
330 but WITHOUT ANY WARRANTY; without even the implied warranty of
331 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
332 GNU General Public License for more details.
334 You should have received a copy of the GNU General Public License
335 along with this program; if not, write to the Free Software
336 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.