]> git.proxmox.com Git - pve-manager.git/blob - PVE/API2/VZDump.pm
allow exclude-path in /etc/vzdump.conf
[pve-manager.git] / PVE / API2 / VZDump.pm
1 package PVE::API2::VZDump;
2
3 use strict;
4 use warnings;
5 use PVE::Exception qw(raise_param_exc);
6 use PVE::Tools qw(extract_param);
7 use PVE::Cluster qw(cfs_register_file cfs_read_file);
8 use PVE::INotify;
9 use PVE::RPCEnvironment;
10 use PVE::AccessControl;
11 use PVE::JSONSchema qw(get_standard_option);
12 use PVE::Storage;
13 use PVE::VZDump;
14
15 use Data::Dumper; # fixme: remove
16
17
18 use base qw(PVE::RESTHandler);
19
20 __PACKAGE__->register_method ({
21 name => 'vzdump',
22 path => '',
23 method => 'POST',
24 description => "Create backup.",
25 protected => 1,
26 proxyto => 'node',
27 parameters => {
28 additionalProperties => 0,
29 properties => PVE::VZDump::json_config_properties({
30 stdout => {
31 type => 'boolean',
32 description => "Write tar to stdout, not to a file.",
33 optional => 1,
34 },
35 }),
36 },
37 returns => { type => 'string' },
38 code => sub {
39 my ($param) = @_;
40
41 my $rpcenv = PVE::RPCEnvironment::get();
42
43 my $user = $rpcenv->get_user();
44
45 my $nodename = PVE::INotify::nodename();
46
47 if ($rpcenv->{type} ne 'cli') {
48 raise_param_exc({ node => "option is only allowed on the command line interface."})
49 if $param->{node} && $param->{node} ne $nodename;
50
51 raise_param_exc({ stdout => "option is only allowed on the command line interface."})
52 if $param->{stdout};
53 }
54
55 # by default we set --rsyncable for gzip
56 local $ENV{GZIP} = "--rsyncable" if !$ENV{GZIP};
57
58 PVE::VZDump::verify_vzdump_parameters($param, 1);
59
60 # silent exit if we run on wrong node
61 exit(0) if $param->{node} && $param->{node} ne $nodename;
62
63 my $cmdline = PVE::VZDump::command_line($param);
64
65 # convert string lists to arrays
66 my @vmids = PVE::Tools::split_list(extract_param($param, 'vmid'));
67
68 $param->{vmids} = PVE::VZDump::check_vmids(@vmids) if !$param->{all};
69 my @exclude = PVE::Tools::split_list(extract_param($param, 'exclude'));
70 $param->{exclude} = PVE::VZDump::check_vmids(@exclude);
71
72 # exclude-path list need to be 0 separated
73 my @expaths = split(/\0/, $param->{'exclude-path'} || '');
74 $param->{'exclude-path'} = [ @expaths ];
75
76 my @mailto = PVE::Tools::split_list(extract_param($param, 'mailto'));
77 $param->{mailto} = [ @mailto ];
78
79 die "you can only backup a single VM with option --stdout\n"
80 if $param->{stdout} && scalar(@vmids) != 1;
81
82 my $vzdump = PVE::VZDump->new($cmdline, $param);
83
84 my $worker = sub {
85 $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = $SIG{PIPE} = sub {
86 die "interrupted by signal\n";
87 };
88
89 $vzdump->getlock (); # only one process allowed
90
91 if (defined($param->{ionice})) {
92 if ($param->{ionice} > 7) {
93 PVE::VZDump::run_command(undef, "ionice -c3 -p $$");
94 } else {
95 PVE::VZDump::run_command(undef, "ionice -c2 -n$param->{ionice} -p $$");
96 }
97 }
98 $vzdump->exec_backup();
99 };
100
101 open STDOUT, '>/dev/null' if $param->{quiet} && !$param->{stdout};
102 open STDERR, '>/dev/null' if $param->{quiet};
103
104 if ($rpcenv->{type} eq 'cli') {
105 if ($param->{stdout}) {
106
107 open my $saved_stdout, ">&STDOUT"
108 || die "can't dup STDOUT: $!\n";
109
110 open STDOUT, '>&STDERR' ||
111 die "unable to redirect STDOUT: $!\n";
112
113 $param->{stdout} = $saved_stdout;
114 }
115 }
116
117 return $rpcenv->fork_worker('vzdump', undef, $user, $worker);
118 }});