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