]> git.proxmox.com Git - pve-manager.git/blame - bin/vzdump
use new get_options
[pve-manager.git] / bin / vzdump
CommitLineData
aaeeeebe 1#!/usr/bin/perl -w
aaeeeebe
DM
2
3use strict;
4a4051d8
DM
4
5use PVE::Exception qw(raise_param_exc);;
6use PVE::Tools qw(extract_param);
7use PVE::Cluster qw(cfs_register_file cfs_read_file);
8use PVE::SafeSyslog;
9use PVE::INotify;
10use PVE::RPCEnvironment;
11use PVE::CLIHandler;
12use PVE::JSONSchema qw(get_standard_option);
13use PVE::Storage;
aaeeeebe
DM
14use PVE::VZDump;
15
4a4051d8
DM
16use Data::Dumper; # fixme: remove
17
18use base qw(PVE::CLIHandler);
19
20$ENV{'PATH'} = '/sbin:/bin:/usr/sbin:/usr/bin';
21
22initlog('vzdump');
23
24die "please run as root\n" if $> != 0;
25
26PVE::INotify::inotify_init();
27my $nodename = PVE::INotify::nodename();
28
29my $rpcenv = PVE::RPCEnvironment->init('cli');
30
31$rpcenv->init_request();
32$rpcenv->set_language($ENV{LANG});
33$rpcenv->set_user('root@pam');
34
35__PACKAGE__->register_method ({
36 name => 'vzdump',
37 path => 'vzdump',
38 method => 'PUT',
39 description => "Create backup.",
40 parameters => {
41 additionalProperties => 0,
42 properties => {
43 vmid => {
44 type => 'string', format => 'pve-vmid-list',
45 description => "The ID of the VM you want to backup.",
46 optional => 1,
47 },
48 node => get_standard_option('pve-node', {
49 description => "Only run if executed on this node.",
50 optional => 1,
51 }),
52 all => {
53 type => 'boolean',
54 description => "Backup all known VMs on this host.",
55 optional => 1,
56 default => 0,
57 },
58 stdexcludes => {
59 type => 'boolean',
60 description => "Exclude temorary files and logs.",
61 optional => 1,
62 default => 1,
63 },
64 compress => {
65 type => 'boolean',
66 description => "Compress dump file (gzip).",
67 optional => 1,
68 default => 0,
69 },
70 quiet => {
71 type => 'boolean',
72 description => "Be quiet.",
73 optional => 1,
74 default => 0,
75 },
76 stop => {
77 type => 'boolean',
78 description => "Stop/Restart VM when running.",
79 optional => 1,
80 },
81 snapshot => {
82 type => 'boolean',
83 description => "Try to use (LVM) snapshots when running.",
84 optional => 1,
85 },
86 suspend => {
87 type => 'boolean',
88 description => "Suspend/resume VM when running",
89 optional => 1,
90 },
91 stdout => {
92 type => 'boolean',
93 description => "Write tar to stdout, not to a file.",
94 optional => 1,
95 },
96 exclude => {
97 type => 'string', format => 'pve-vmid-list',
98 description => "exclude specified VMs (assumes --all)",
99 optional => 1,
100 },
101 'exclude-path' => {
102 type => 'string', format => 'string-list',
103 description => "exclude certain files/directories (regex).",
104 optional => 1,
105 },
106 mailto => {
107 type => 'string', format => 'string-list',
108 description => "",
109 optional => 1,
110 },
111 tmpdir => {
112 type => 'string',
113 description => "Store temporary files to specified directory.",
114 optional => 1,
115 },
116 dumpdir => {
117 type => 'string',
118 description => "Store resulting files to specified directory.",
119 optional => 1,
120 },
121 script => {
122 type => 'string',
123 description => "Use specified hook script.",
124 optional => 1,
125 },
126 storage => get_standard_option('pve-storage-id', {
127 description => "Store resulting file to this storage.",
128 optional => 1,
129 }),
130 size => {
131 type => 'integer',
132 description => "LVM snapshot size im MB.",
133 optional => 1,
134 minimum => 500,
135 },
136 bwlimit => {
137 type => 'integer',
138 description => "Limit I/O bandwidth (KBytes per second).",
139 optional => 1,
140 minimum => 0,
141 },
142 ionice => {
143 type => 'integer',
144 description => "Set CFQ ionice priority.",
145 optional => 1,
146 minimum => 0,
147 maximum => 8,
148 },
149 lockwait => {
150 type => 'integer',
151 description => "Maximal time to wait for the global lock (minutes).",
152 optional => 1,
153 minimum => 0,
154 },
155 stopwait => {
156 type => 'integer',
157 description => "Maximal time to wait until a VM is stopped (minutes).",
158 optional => 1,
159 minimum => 0,
160 },
161 maxfiles => {
162 type => 'integer',
163 description => "Maximal number of backup files per VM.",
164 optional => 1,
165 minimum => 1,
166 },
167 },
168 },
169 returns => { type => 'string' },
170 code => sub {
171 my ($param) = @_;
172
4a4051d8 173 my $rpcenv = PVE::RPCEnvironment::get();
aaeeeebe 174
4a4051d8 175 my $user = $rpcenv->get_user();
aaeeeebe 176
4a4051d8
DM
177 if ($rpcenv->{type} ne 'cli') {
178 raise_param_exc({ node => "option is only allowed on the command line interface."})
179 if $param->{node};
aaeeeebe 180
4a4051d8
DM
181 raise_param_exc({ stdout => "option is only allowed on the command line interface."})
182 if $param->{stdout};
183 }
aaeeeebe 184
4a4051d8
DM
185 # by default we set --rsyncable for gzip
186 local $ENV{GZIP} = "--rsyncable" if !$ENV{GZIP};
aaeeeebe 187
4a4051d8 188 $param->{all} = 1 if defined($param->{exclude});
aaeeeebe 189
4a4051d8 190 raise_param_exc({ all => "option conflicts with option 'vmid'"})
b2ae28cc 191 if $param->{all} && $param->{vmid};
aaeeeebe 192
4a4051d8 193 raise_param_exc({ vmid => "property is missing"})
b2ae28cc 194 if !$param->{all} && !$param->{vmid};
aaeeeebe 195
4a4051d8
DM
196 # silent exit if we run on wrong node
197 my $nodename = PVE::INotify::nodename();
198 exit(0) if $param->{node} && $param->{node} ne $nodename;
aaeeeebe 199
4a4051d8
DM
200 # convert string lists to arrays
201 my @vmids = PVE::Tools::split_list(extract_param($param, 'vmid'));
b2ae28cc
DM
202
203 my $cmdline = 'vzdump';
204 $cmdline .= ' ' . join(' ', @vmids) if scalar(@vmids);
205 foreach my $p (keys %$param) {
206 $cmdline .= " --$p $param->{$p}";
207 }
208
4a4051d8
DM
209 $param->{vmids} = PVE::VZDump::check_vmids(@vmids) if !$param->{all};
210 my @exclude = PVE::Tools::split_list(extract_param($param, 'exclude'));
211 $param->{exclude} = PVE::VZDump::check_vmids(@exclude);
212
213 # exclude-path list need to be 0 separated
214 my @expaths = split(/\0/, $param->{'exclude-path'} || '');
215 $param->{'exclude-path'} = @expaths;
aaeeeebe 216
4a4051d8
DM
217 my @mailto = PVE::Tools::split_list(extract_param($param, 'mailto'));
218 $param->{mailto} = [ @mailto ];
aaeeeebe 219
4a4051d8
DM
220 die "you can only backup a single VM with option --stdout\n"
221 if $param->{stdout} && scalar(@vmids) != 1;
aaeeeebe 222
4a4051d8 223 my $vzdump = PVE::VZDump->new($cmdline, $param);
aaeeeebe 224
4a4051d8
DM
225 my $worker = sub {
226 $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = $SIG{PIPE} = sub {
227 die "interrupted by signal\n";
228 };
aaeeeebe 229
4a4051d8 230 $vzdump->getlock (); # only one process allowed
aaeeeebe 231
4a4051d8
DM
232 if (defined($param->{ionice})) {
233 if ($param->{ionice} > 7) {
234 PVE::VZDump::run_command(undef, "ionice -c3 -p $$");
235 } else {
236 PVE::VZDump::run_command(undef, "ionice -c2 -n$param->{ionice} -p $$");
237 }
238 }
239 $vzdump->exec_backup();
240 };
aaeeeebe 241
4a4051d8
DM
242 open STDOUT, '>/dev/null' if $param->{quiet} && !$param->{stdout};
243 open STDERR, '>/dev/null' if $param->{quiet};
aaeeeebe 244
4a4051d8
DM
245 if ($rpcenv->{type} eq 'cli') {
246 if ($param->{stdout}) {
aaeeeebe 247
4a4051d8
DM
248 open my $saved_stdout, ">&STDOUT"
249 || die "can't dup STDOUT: $!\n";
aaeeeebe 250
4a4051d8
DM
251 open STDOUT, '>&STDERR' ||
252 die "unable to redirect STDOUT: $!\n";
aaeeeebe 253
4a4051d8
DM
254 $param->{stdout} = $saved_stdout;
255 }
256 }
aaeeeebe 257
4a4051d8
DM
258 return $rpcenv->fork_worker('vzdump', undef, $user, $worker);
259 }});
aaeeeebe 260
b2ae28cc 261my $cmddef = [ __PACKAGE__, 'vzdump', 'vmid', undef,
4a4051d8
DM
262 sub {
263 my $upid = shift;
264 my $status = PVE::Tools::upid_read_status($upid);
265 exit($status eq 'OK' ? 0 : -1);
266 }];
aaeeeebe 267
4a4051d8
DM
268push @ARGV, 'help' if !scalar(@ARGV);
269
270PVE::CLIHandler::handle_simple_cmd($cmddef, \@ARGV, undef, $0);
271
272exit 0;
273
274__END__
275
276=head1 NAME
277
278vzdump - backup utility for virtual machine
279
280=head1 SYNOPSIS
281
282=include synopsis
aaeeeebe
DM
283
284=head1 DESCRIPTION
285
286vzdump is an utility to make consistent snapshots of running virtual
287machines (VMs). It basically creates a tar archive of the VM private area,
288which also includes the VM configuration files. vzdump currently
289supports OpenVZ and QemuServer VMs.
290
291There are several ways to provide consistency:
292
293=over 2
294
295=item C<stop> mode
296
297Stop the VM during backup. This results in a very long downtime.
298
299=item C<suspend> mode
300
301For OpenVZ, this mode uses rsync to copy the VM to a temporary
302location (see option --tmpdir). Then the VM is suspended and a second
303rsync copies changed files. After that, the VM is started (resume)
304again. This results in a minimal downtime, but needs additional space
305to hold the VM copy.
306
307For QemuServer, this mode work like C<stop> mode, but uses
308suspend/resume instead of stop/start.
309
310=item C<snapshot> mode
311
312This mode uses LVM2 snapshots. There is no downtime, but snapshot mode
313needs LVM2 and some free space on the corresponding volume group to
314create the LVM snapshot.
315
316=back
317
318=head1 BACKUP FILE NAMES
319
320Newer version of vzdump encodes the virtual machine type and the
321backup time into the filename, for example
322
323 vzdump-openvz-105-2009_10_09-11_04_43.tar
324
325That way it is possible to store several backup into the same
326directory. The parameter C<maxfiles> can be used to specify the maximal
327number of backups to keep.
328
329=head1 RESTORE
330
331The resulting tar files can be restored with the following programs.
332
333=over 1
334
335=item vzrestore: OpenVZ restore utility
336
337=item qmrestore: QemuServer restore utility
338
339=back
340
341For details see the corresponding manual pages.
342
343=head1 CONFIGURATION
344
345Global configuration is stored in /etc/vzdump.conf.
346
347 tmpdir: DIR
348 dumpdir: DIR
349 storage: STORAGE_ID
350 mode: snapshot|suspend|stop
351 bwlimit: KBPS
352 ionize: PRI
353 lockwait: MINUTES
354 stopwait: MINUTES
355 size: MB
356 maxfiles: N
357 script: FILENAME
358
359=head1 HOOK SCRIPT
360
361You can specify a hook script with option C<--script>. This script is called at various phases of the backup process, with parameters accordingly set. You can find an example in the documentation directory (C<hook-script.pl>).
362
363=head1 EXCLUSIONS (OpenVZ only)
364
365vzdump skips the following files wit option --stdexcludes
366
367 /var/log/.+
368 /tmp/.+
369 /var/tmp/.+
370 /var/run/.+pid
371
372You can manually specify exclude paths, for example:
373
b2ae28cc 374 # vzdump 777 --exclude-path C</tmp/.+> --exclude-path C</var/tmp/.+>
aaeeeebe
DM
375
376(only excludes tmp directories)
377
378Configuration files are also stored inside the backup archive (/etc/vzdump), and will be correctly restored.
379
380=head1 LIMITATIONS
381
382VZDump does not save ACLs.
383
384=head1 EXAMPLES
385
386Simply dump VM 777 - no snapshot, just archive the VM private area and configuration files to the default dump directory (usually /vz/dump/).
387
b2ae28cc 388 # vzdump 777
aaeeeebe
DM
389
390Use rsync and suspend/resume to create an snapshot (minimal downtime).
391
b2ae28cc 392 # vzdump 777 --suspend
aaeeeebe 393
4a4051d8 394Backup all VMs and send notification mails to root and admin.
aaeeeebe 395
b2ae28cc 396 # vzdump --all --suspend --mailto root --mailto admin
aaeeeebe
DM
397
398Use LVM2 to create snapshots (no downtime).
399
b2ae28cc
DM
400 # vzdump 777 --dumpdir /mnt/backup --snapshot
401
402Backup more than one VM (selectively)
403
404 # vzdump 101 102 103 --mailto root
aaeeeebe
DM
405
406Backup all VMs excluding VM 101 and 102
407
b2ae28cc 408 # vzdump --suspend --exclude 101,102
aaeeeebe
DM
409
410Restore an OpenVZ machine to VM 600
411
4a4051d8 412 # vzrestore /mnt/backup/vzdump-openvz-777.tar 600
aaeeeebe
DM
413
414Restore an Qemu/KVM machine to VM 601
415
4a4051d8 416 # qmrestore /mnt/backup/vzdump-qemu-888.tar 601
aaeeeebe
DM
417
418=head1 SEE ALSO
419
4a4051d8 420vzrestore(1) qmrestore(1)
aaeeeebe 421
4a4051d8 422=include pve_copyright