po: Include strings from Perl programs in the PO files (RHBZ#559963).
[libguestfs.git] / tools / virt-tar
1 #!/usr/bin/perl -w
2 # virt-tar
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 warnings;
20 use strict;
21
22 use Sys::Guestfs;
23 use Sys::Guestfs::Lib qw(open_guest get_partitions resolve_windows_path
24   inspect_all_partitions inspect_partition
25   inspect_operating_systems mount_operating_system);
26 use Pod::Usage;
27 use Getopt::Long;
28 use File::Temp qw/tempfile/;
29 use Locale::TextDomain 'libguestfs';
30
31 =encoding utf8
32
33 =head1 NAME
34
35 virt-tar - Extract or upload files to a virtual machine
36
37 =head1 SYNOPSIS
38
39  virt-tar [--options] -x domname directory tarball
40
41  virt-tar [--options] -u domname tarball directory
42
43  virt-tar [--options] disk.img [disk.img ...] -x directory tarball
44
45  virt-tar [--options] disk.img [disk.img ...] -u tarball directory
46
47 =head1 EXAMPLES
48
49 Download C</home> from the VM into a local tarball:
50
51  virt-tar -x domname /home home.tar
52
53  virt-tar -zx domname /home home.tar.gz
54
55 Upload a local tarball and unpack it inside C</tmp> in the VM:
56
57  virt-tar -u domname uploadstuff.tar /tmp
58
59  virt-tar -zu domname uploadstuff.tar.gz /tmp
60
61 =head1 WARNING
62
63 You must I<not> use C<virt-tar> with the C<-u> option (upload) on live
64 virtual machines.  If you do this, you risk disk corruption in the VM.
65 C<virt-tar> tries to stop you from doing this, but doesn't catch all
66 cases.
67
68 You can use C<-x> (extract) on live virtual machines, but you might
69 get inconsistent results or errors if there is filesystem activity
70 inside the VM.  If the live VM is synched and quiescent, then
71 C<virt-tar> will usually work, but the only way to guarantee
72 consistent results is if the virtual machine is shut down.
73
74 =head1 DESCRIPTION
75
76 C<virt-tar> is a general purpose archive tool for downloading and
77 uploading parts of a guest filesystem.  There are many possibilities:
78 making backups, uploading data files, snooping on guest activity,
79 fixing or customizing guests, etc.
80
81 If you want to just view a single file, use L<virt-cat(1)>.  If you
82 just want to edit a single file, use L<virt-edit(1)>.  For more
83 complex cases you should look at the L<guestfish(1)> tool.
84
85 There are two modes of operation: C<-x> (eXtract) downloads a
86 directory and its contents (recursively) from the virtual machine into
87 a local tarball.  C<-u> uploads from a local tarball, unpacking it
88 into a directory inside the virtual machine.  You cannot use these two
89 options together.
90
91 In addition, you may need to use the C<-z> (gZip) option to enable
92 compression.  When uploading, you have to specify C<-z> if the upload
93 file is compressed because virt-tar won't detect this on its own.
94
95 C<virt-tar> can only handle tar (optionally gzipped) format tarballs.
96 For example it cannot do PKZip files or bzip2 compression.  If you
97 want that then you'll have to rebuild the tarballs yourself.  (This is
98 a limitation of the L<libguestfs(3)> API).
99
100 =head1 OPTIONS
101
102 =over 4
103
104 =cut
105
106 my $help;
107
108 =item B<--help>
109
110 Display brief help.
111
112 =cut
113
114 my $version;
115
116 =item B<--version>
117
118 Display version number and exit.
119
120 =cut
121
122 my $uri;
123
124 =item B<--connect URI> | B<-c URI>
125
126 If using libvirt, connect to the given I<URI>.  If omitted, then we
127 connect to the default libvirt hypervisor.
128
129 If you specify guest block devices directly, then libvirt is not used
130 at all.
131
132 =cut
133
134 my $mode;
135
136 =item B<-x> | B<--extract> | B<--download>
137
138 =item B<-u> | B<--upload>
139
140 Use C<-x> to extract (download) a directory from a virtual machine
141 to a local tarball.
142
143 Use C<-u> to upload and unpack from a local tarball into a virtual
144 machine.  Please read the L</WARNING> section above before using this
145 option.
146
147 You must specify exactly one of these options.
148
149 =cut
150
151 my $gzip;
152
153 =item B<-z> | B<--gzip>
154
155 Specify that the input or output tarball is gzip-compressed.
156
157 =back
158
159 =cut
160
161 sub set_mode_x
162 {
163     die __"virt-tar: extract/upload mode specified twice on the command line\n"
164         if $mode;
165     $mode = "x";
166 }
167
168 sub set_mode_u
169 {
170     die __"virt-tar: extract/upload mode specified twice on the command line\n"
171         if $mode;
172     $mode = "u";
173 }
174
175 Getopt::Long::Configure ("bundling");
176 GetOptions ("help|?" => \$help,
177             "version" => \$version,
178             "connect|c=s" => \$uri,
179             "extract|download|x" => \&set_mode_x,
180             "upload|u" => \&set_mode_u,
181             "gzip|z" => \$gzip,
182     ) or pod2usage (2);
183 pod2usage (1) if $help;
184 if ($version) {
185     my $g = Sys::Guestfs->new ();
186     my %h = $g->version ();
187     print "$h{major}.$h{minor}.$h{release}$h{extra}\n";
188     exit
189 }
190
191 pod2usage (__"virt-tar: no image, VM names, directory or filename given")
192     if @ARGV <= 2;
193
194 die __"virt-tar: either -x or -u must be specified on the command line\n"
195     unless $mode;
196
197 # Note: 'pop' reads arguments right to left.
198 my ($tarball, $directory);
199 if ($mode eq "x") {
200     $tarball = pop @ARGV;
201     $directory = pop @ARGV;
202 } else { # $mode eq "u"
203     $directory = pop @ARGV;
204     $tarball = pop @ARGV;
205     die __x("virt-tar: {tarball}: file not found\n",
206             tarball => $tarball) unless -f $tarball;
207 }
208 die __x("virt-tar: {dir}: directory name must start with '/' character\n",
209         dir => $directory)
210     unless substr ($directory, 0, 1) eq "/";
211
212 my @args = (\@ARGV);
213 push @args, address => $uri if $uri;
214 push @args, rw => 1 if $mode eq "u";
215
216 my $g = open_guest (@args);
217 $g->launch ();
218
219 # List of possible filesystems.
220 my @partitions = get_partitions ($g);
221
222 # Now query each one to build up a picture of what's in it.
223 my %fses =
224     inspect_all_partitions ($g, \@partitions,
225       use_windows_registry => 0);
226
227 my $oses = inspect_operating_systems ($g, \%fses);
228
229 my @roots = keys %$oses;
230 die __"no root device found in this operating system image\n" if @roots == 0;
231 die __"multiboot operating systems are not supported by virt-tar\n" if @roots > 1;
232 my $root_dev = $roots[0];
233
234 my $os = $oses->{$root_dev};
235 mount_operating_system ($g, $os, $mode eq "u" ? 0 : 1);
236
237 # Do the tar command.
238 if ($mode eq "x") {
239     if ($gzip) {
240         $g->tgz_out ($directory, $tarball);
241     } else {
242         $g->tar_out ($directory, $tarball);
243     }
244 } else { # mode eq "u"
245     if ($gzip) {
246         $g->tgz_in ($tarball, $directory);
247     } else {
248         $g->tar_in ($tarball, $directory);
249     }
250 }
251
252 $g->sync ();
253 $g->umount_all ();
254
255 undef $g;
256
257 exit 0;
258
259 =head1 SEE ALSO
260
261 L<guestfs(3)>,
262 L<guestfish(1)>,
263 L<virt-cat(1)>,
264 L<virt-edit(1)>,
265 L<Sys::Guestfs(3)>,
266 L<Sys::Guestfs::Lib(3)>,
267 L<Sys::Virt(3)>,
268 L<http://libguestfs.org/>.
269
270 =head1 AUTHOR
271
272 Richard W.M. Jones L<http://people.redhat.com/~rjones/>
273
274 =head1 COPYRIGHT
275
276 Copyright (C) 2009 Red Hat Inc.
277
278 This program is free software; you can redistribute it and/or modify
279 it under the terms of the GNU General Public License as published by
280 the Free Software Foundation; either version 2 of the License, or
281 (at your option) any later version.
282
283 This program is distributed in the hope that it will be useful,
284 but WITHOUT ANY WARRANTY; without even the implied warranty of
285 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
286 GNU General Public License for more details.
287
288 You should have received a copy of the GNU General Public License
289 along with this program; if not, write to the Free Software
290 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.