build: Create an AUTHORS file.
[libguestfs.git] / tools / virt-cat
1 #!/usr/bin/perl -w
2 # virt-cat
3 # Copyright (C) 2009-2010 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 warnings;
20 use strict;
21
22 use Sys::Guestfs;
23 use Sys::Guestfs::Lib qw(open_guest);
24 use Pod::Usage;
25 use Getopt::Long;
26 use File::Basename;
27 use Locale::TextDomain 'libguestfs';
28
29 =encoding utf8
30
31 =head1 NAME
32
33 virt-cat - Display a file in a virtual machine
34
35 =head1 SYNOPSIS
36
37  virt-cat [--options] domname file
38
39  virt-cat [--options] disk.img [disk.img ...] file
40
41 =head1 DESCRIPTION
42
43 C<virt-cat> is a command line tool to display the contents of C<file>
44 where C<file> exists in the named virtual machine (or disk image).
45
46 C<virt-cat> can be used to quickly view a single file.  To edit a
47 file, use C<virt-edit>.  For more complex cases you should look at the
48 L<guestfish(1)> tool.
49
50 =head1 EXAMPLES
51
52 Display C</etc/fstab> file from inside the libvirt VM called
53 C<mydomain>:
54
55  virt-cat mydomain /etc/fstab
56
57 List syslog messages from a VM:
58
59  virt-cat mydomain /var/log/messages | tail
60
61 Find out what DHCP IP address a VM acquired:
62
63  virt-cat mydomain /var/log/messages | grep 'dhclient: bound to' | tail
64
65 Find out what packages were recently installed:
66
67  virt-cat mydomain /var/log/yum.log | tail
68
69 Find out who is logged on inside a virtual machine:
70
71  virt-cat mydomain /var/run/utmp > /tmp/utmp
72  who /tmp/utmp
73
74 or who was logged on:
75
76  virt-cat mydomain /var/log/wtmp > /tmp/wtmp
77  last -f /tmp/wtmp
78
79 =head1 OPTIONS
80
81 =over 4
82
83 =cut
84
85 my $help;
86
87 =item B<--help>
88
89 Display brief help.
90
91 =cut
92
93 my $version;
94
95 =item B<--version>
96
97 Display version number and exit.
98
99 =cut
100
101 my $uri;
102
103 =item B<--connect URI> | B<-c URI>
104
105 If using libvirt, connect to the given I<URI>.  If omitted, then we
106 connect to the default libvirt hypervisor.
107
108 If you specify guest block devices directly, then libvirt is not used
109 at all.
110
111 =cut
112
113 my $format;
114
115 =item B<--format> raw
116
117 Specify the format of disk images given on the command line.  If this
118 is omitted then the format is autodetected from the content of the
119 disk image.
120
121 If disk images are requested from libvirt, then this program asks
122 libvirt for this information.  In this case, the value of the format
123 parameter is ignored.
124
125 If working with untrusted raw-format guest disk images, you should
126 ensure the format is always specified.
127
128 =back
129
130 =cut
131
132 GetOptions ("help|?" => \$help,
133             "version" => \$version,
134             "connect|c=s" => \$uri,
135             "format=s" => \$format,
136     ) or pod2usage (2);
137 pod2usage (1) if $help;
138 if ($version) {
139     my $g = Sys::Guestfs->new ();
140     my %h = $g->version ();
141     print "$h{major}.$h{minor}.$h{release}$h{extra}\n";
142     exit
143 }
144
145 pod2usage (__"virt-cat: no image, VM names or filenames to cat given")
146     if @ARGV <= 1;
147
148 my $filename = pop @ARGV;
149
150 my $g;
151 if ($uri) {
152     $g = open_guest (\@ARGV, address => $uri, format => $format);
153 } else {
154     $g = open_guest (\@ARGV, format => $format);
155 }
156
157 $g->launch ();
158
159 my @roots = $g->inspect_os ();
160 if (@roots == 0) {
161     die __x("{prog}: No operating system could be detected inside this disk image.\n\nThis may be because the file is not a disk image, or is not a virtual machine\nimage, or because the OS type is not understood by libguestfs.\n\nIf you feel this is an error, please file a bug report including as much\ninformation about the disk image as possible.\n",
162             prog => basename ($0));
163 }
164 if (@roots > 1) {
165     die __x("{prog}: multiboot operating systems are not supported.\n",
166             prog => basename ($0))
167 }
168 my %fses = $g->inspect_get_mountpoints ($roots[0]);
169 my @fses = sort { length $a <=> length $b } keys %fses;
170 foreach (@fses) {
171     $g->mount_ro ($fses{$_}, $_);
172 }
173
174 # Allow this to fail in case eg. the file does not exist.
175 # NB: https://bugzilla.redhat.com/show_bug.cgi?id=501888
176 print $g->download($filename, "/dev/stdout");
177
178 =head1 SHELL QUOTING
179
180 Libvirt guest names can contain arbitrary characters, some of which
181 have meaning to the shell such as C<#> and space.  You may need to
182 quote or escape these characters on the command line.  See the shell
183 manual page L<sh(1)> for details.
184
185 =head1 SEE ALSO
186
187 L<guestfs(3)>,
188 L<guestfish(1)>,
189 L<virt-edit(1)>,
190 L<Sys::Guestfs(3)>,
191 L<Sys::Guestfs::Lib(3)>,
192 L<Sys::Virt(3)>,
193 L<http://libguestfs.org/>.
194
195 =head1 AUTHOR
196
197 Richard W.M. Jones L<http://people.redhat.com/~rjones/>
198
199 =head1 COPYRIGHT
200
201 Copyright (C) 2009 Red Hat Inc.
202
203 This program is free software; you can redistribute it and/or modify
204 it under the terms of the GNU General Public License as published by
205 the Free Software Foundation; either version 2 of the License, or
206 (at your option) any later version.
207
208 This program is distributed in the hope that it will be useful,
209 but WITHOUT ANY WARRANTY; without even the implied warranty of
210 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
211 GNU General Public License for more details.
212
213 You should have received a copy of the GNU General Public License
214 along with this program; if not, write to the Free Software
215 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.