tar: Remove redundant use statement.
[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 __"virt-tar: $tarball: file not found\n" unless -f $tarball;
205 }
206 die __"virt-tar: $directory: directory name must start with '/' character\n"
207     unless substr ($directory, 0, 1) eq "/";
208
209 my @args = (\@ARGV);
210 push @args, address => $uri if $uri;
211 push @args, rw => 1 if $mode eq "u";
212
213 my $g = open_guest (@args);
214 $g->launch ();
215
216 # List of possible filesystems.
217 my @partitions = get_partitions ($g);
218
219 # Now query each one to build up a picture of what's in it.
220 my %fses =
221     inspect_all_partitions ($g, \@partitions,
222       use_windows_registry => 0);
223
224 my $oses = inspect_operating_systems ($g, \%fses);
225
226 my @roots = keys %$oses;
227 die __"multiboot operating systems are not supported by virt-tar\n" if @roots > 1;
228 my $root_dev = $roots[0];
229
230 my $os = $oses->{$root_dev};
231 mount_operating_system ($g, $os, $mode eq "u" ? 0 : 1);
232
233 # Do the tar command.
234 if ($mode eq "x") {
235     if ($gzip) {
236         $g->tgz_out ($directory, $tarball);
237     } else {
238         $g->tar_out ($directory, $tarball);
239     }
240 } else { # mode eq "u"
241     if ($gzip) {
242         $g->tgz_in ($tarball, $directory);
243     } else {
244         $g->tar_in ($tarball, $directory);
245     }
246 }
247
248 $g->sync ();
249 $g->umount_all ();
250
251 undef $g;
252
253 exit 0;
254
255 =head1 SEE ALSO
256
257 L<guestfs(3)>,
258 L<guestfish(1)>,
259 L<virt-cat(1)>,
260 L<virt-edit(1)>,
261 L<Sys::Guestfs(3)>,
262 L<Sys::Guestfs::Lib(3)>,
263 L<Sys::Virt(3)>,
264 L<http://libguestfs.org/>.
265
266 =head1 AUTHOR
267
268 Richard W.M. Jones L<http://people.redhat.com/~rjones/>
269
270 =head1 COPYRIGHT
271
272 Copyright (C) 2009 Red Hat Inc.
273
274 This program is free software; you can redistribute it and/or modify
275 it under the terms of the GNU General Public License as published by
276 the Free Software Foundation; either version 2 of the License, or
277 (at your option) any later version.
278
279 This program is distributed in the hope that it will be useful,
280 but WITHOUT ANY WARRANTY; without even the implied warranty of
281 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
282 GNU General Public License for more details.
283
284 You should have received a copy of the GNU General Public License
285 along with this program; if not, write to the Free Software
286 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.