]>
Commit | Line | Data |
---|---|---|
bf58f8dd DM |
1 | package PVE::API2::VZDump; |
2 | ||
3 | use strict; | |
4 | use warnings; | |
31aef761 | 5 | use PVE::Exception qw(raise_param_exc); |
bf58f8dd DM |
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.", | |
98e84b16 | 25 | permissions => { |
4412265f | 26 | description => "The user needs 'VM.Backup' permissions on any VM, and 'Datastore.AllocateSpace' on the backup storage.", |
98e84b16 DM |
27 | user => 'all', |
28 | }, | |
30edfad9 | 29 | protected => 1, |
49046e53 | 30 | proxyto => 'node', |
bf58f8dd DM |
31 | parameters => { |
32 | additionalProperties => 0, | |
ac27b58d | 33 | properties => PVE::VZDump::json_config_properties({ |
bf58f8dd DM |
34 | stdout => { |
35 | type => 'boolean', | |
36 | description => "Write tar to stdout, not to a file.", | |
37 | optional => 1, | |
38 | }, | |
ac27b58d | 39 | }), |
bf58f8dd DM |
40 | }, |
41 | returns => { type => 'string' }, | |
42 | code => sub { | |
43 | my ($param) = @_; | |
44 | ||
45 | my $rpcenv = PVE::RPCEnvironment::get(); | |
46 | ||
47 | my $user = $rpcenv->get_user(); | |
48 | ||
49 | my $nodename = PVE::INotify::nodename(); | |
50 | ||
51 | if ($rpcenv->{type} ne 'cli') { | |
52 | raise_param_exc({ node => "option is only allowed on the command line interface."}) | |
53 | if $param->{node} && $param->{node} ne $nodename; | |
54 | ||
55 | raise_param_exc({ stdout => "option is only allowed on the command line interface."}) | |
56 | if $param->{stdout}; | |
57 | } | |
58 | ||
59 | # by default we set --rsyncable for gzip | |
60 | local $ENV{GZIP} = "--rsyncable" if !$ENV{GZIP}; | |
61 | ||
31aef761 | 62 | PVE::VZDump::verify_vzdump_parameters($param, 1); |
bf58f8dd DM |
63 | |
64 | # silent exit if we run on wrong node | |
eab837c4 | 65 | return 'OK' if $param->{node} && $param->{node} ne $nodename; |
8682f6fc | 66 | |
31aef761 DM |
67 | my $cmdline = PVE::VZDump::command_line($param); |
68 | ||
bf58f8dd DM |
69 | # convert string lists to arrays |
70 | my @vmids = PVE::Tools::split_list(extract_param($param, 'vmid')); | |
71 | ||
eab837c4 DM |
72 | if($param->{stop}){ |
73 | PVE::VZDump::stop_running_backups(); | |
74 | return 'OK' if !scalar(@vmids); | |
75 | } | |
76 | ||
a7e42354 DM |
77 | my $skiplist = []; |
78 | if (!$param->{all}) { | |
79 | if (!$param->{node}) { | |
80 | my $vmlist = PVE::Cluster::get_vmlist(); | |
81 | my @localvmids = (); | |
82 | foreach my $vmid (@vmids) { | |
83 | my $d = $vmlist->{ids}->{$vmid}; | |
84 | if ($d && ($d->{node} ne $nodename)) { | |
85 | push @$skiplist, $vmid; | |
86 | } else { | |
87 | push @localvmids, $vmid; | |
88 | } | |
89 | } | |
90 | @vmids = @localvmids; | |
91 | # silent exit if specified VMs run on other nodes | |
eab837c4 | 92 | return "OK" if !scalar(@vmids); |
a7e42354 DM |
93 | } |
94 | ||
95 | $param->{vmids} = PVE::VZDump::check_vmids(@vmids) | |
96 | } | |
97 | ||
bf58f8dd DM |
98 | my @exclude = PVE::Tools::split_list(extract_param($param, 'exclude')); |
99 | $param->{exclude} = PVE::VZDump::check_vmids(@exclude); | |
336ec53a | 100 | |
bf58f8dd | 101 | # exclude-path list need to be 0 separated |
336ec53a DM |
102 | if (defined($param->{'exclude-path'})) { |
103 | my @expaths = split(/\0/, $param->{'exclude-path'} || ''); | |
104 | $param->{'exclude-path'} = [ @expaths ]; | |
105 | } | |
bf58f8dd | 106 | |
336ec53a DM |
107 | if (defined($param->{mailto})) { |
108 | my @mailto = PVE::Tools::split_list(extract_param($param, 'mailto')); | |
109 | $param->{mailto} = [ @mailto ]; | |
110 | } | |
bf58f8dd DM |
111 | |
112 | die "you can only backup a single VM with option --stdout\n" | |
113 | if $param->{stdout} && scalar(@vmids) != 1; | |
114 | ||
e2a2525e | 115 | foreach my $key (qw(maxfiles tmpdir dumpdir script bwlimit ionice)) { |
98e84b16 DM |
116 | raise_param_exc({ $key => "Only root may set this option."}) |
117 | if defined($param->{$key}) && ($user ne 'root@pam'); | |
118 | } | |
119 | ||
4412265f DM |
120 | $rpcenv->check($user, "/storage/$param->{storage}", [ 'Datastore.AllocateSpace' ]) |
121 | if $param->{storage}; | |
122 | ||
a7e42354 | 123 | my $vzdump = PVE::VZDump->new($cmdline, $param, $skiplist); |
bf58f8dd DM |
124 | |
125 | my $worker = sub { | |
eab837c4 DM |
126 | my $upid = shift; |
127 | ||
bf58f8dd DM |
128 | $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = $SIG{PIPE} = sub { |
129 | die "interrupted by signal\n"; | |
130 | }; | |
131 | ||
6ec9de44 | 132 | eval { |
eab837c4 | 133 | $vzdump->getlock($upid); # only one process allowed |
6ec9de44 | 134 | }; |
eab837c4 DM |
135 | if (my $err = $@) { |
136 | $vzdump->sendmail([], 0, $err); | |
6ec9de44 SP |
137 | exit(-1); |
138 | } | |
bf58f8dd DM |
139 | |
140 | if (defined($param->{ionice})) { | |
141 | if ($param->{ionice} > 7) { | |
142 | PVE::VZDump::run_command(undef, "ionice -c3 -p $$"); | |
143 | } else { | |
144 | PVE::VZDump::run_command(undef, "ionice -c2 -n$param->{ionice} -p $$"); | |
145 | } | |
146 | } | |
98e84b16 | 147 | $vzdump->exec_backup($rpcenv, $user); |
bf58f8dd DM |
148 | }; |
149 | ||
150 | open STDOUT, '>/dev/null' if $param->{quiet} && !$param->{stdout}; | |
151 | open STDERR, '>/dev/null' if $param->{quiet}; | |
152 | ||
153 | if ($rpcenv->{type} eq 'cli') { | |
154 | if ($param->{stdout}) { | |
155 | ||
156 | open my $saved_stdout, ">&STDOUT" | |
157 | || die "can't dup STDOUT: $!\n"; | |
158 | ||
159 | open STDOUT, '>&STDERR' || | |
160 | die "unable to redirect STDOUT: $!\n"; | |
161 | ||
162 | $param->{stdout} = $saved_stdout; | |
163 | } | |
164 | } | |
165 | ||
166 | return $rpcenv->fork_worker('vzdump', undef, $user, $worker); | |
167 | }}); |