1 package PVE
::API2
::VZDump
;
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);
9 use PVE
::RPCEnvironment
;
10 use PVE
::AccessControl
;
11 use PVE
::JSONSchema
qw(get_standard_option);
14 use PVE
::VZDump
::Common
;
17 use Data
::Dumper
; # fixme: remove
20 use base
qw(PVE::RESTHandler);
22 __PACKAGE__-
>register_method ({
26 description
=> "Create backup.",
28 description
=> "The user needs 'VM.Backup' permissions on any VM, and 'Datastore.AllocateSpace' on the backup storage. The 'maxfiles', 'prune-backups', 'tmpdir', 'dumpdir', 'script', 'bwlimit' and 'ionice' parameters are restricted to the 'root\@pam' user.",
34 additionalProperties
=> 0,
35 properties
=> PVE
::VZDump
::Common
::json_config_properties
({
38 description
=> "Write tar to stdout, not to a file.",
43 returns
=> { type
=> 'string' },
47 my $rpcenv = PVE
::RPCEnvironment
::get
();
49 my $user = $rpcenv->get_user();
51 my $nodename = PVE
::INotify
::nodename
();
53 if ($rpcenv->{type
} ne 'cli') {
54 raise_param_exc
({ node
=> "option is only allowed on the command line interface."})
55 if $param->{node
} && $param->{node
} ne $nodename;
57 raise_param_exc
({ stdout
=> "option is only allowed on the command line interface."})
61 foreach my $key (qw(maxfiles prune-backups tmpdir dumpdir script bwlimit ionice)) {
62 raise_param_exc
({ $key => "Only root may set this option."})
63 if defined($param->{$key}) && ($user ne 'root@pam');
66 PVE
::VZDump
::verify_vzdump_parameters
($param, 1);
68 # silent exit if we run on wrong node
69 return 'OK' if $param->{node
} && $param->{node
} ne $nodename;
71 my $cmdline = PVE
::VZDump
::Common
::command_line
($param);
73 my $vmids_per_node = PVE
::VZDump
::get_included_guests
($param);
75 my $local_vmids = delete $vmids_per_node->{$nodename} // [];
77 # include IDs for deleted guests, and visibly fail later
78 my $orphaned_vmids = delete $vmids_per_node->{''} // [];
79 push @{$local_vmids}, @{$orphaned_vmids};
81 my $skiplist = [ map { @$_ } values $vmids_per_node->%* ];
84 PVE
::VZDump
::stop_running_backups
();
85 return 'OK' if !scalar(@{$local_vmids});
88 # silent exit if specified VMs run on other nodes
89 return "OK" if !scalar(@{$local_vmids}) && !$param->{all
};
91 PVE
::VZDump
::parse_mailto_exclude_path
($param);
93 die "you can only backup a single VM with option --stdout\n"
94 if $param->{stdout
} && scalar(@{$local_vmids}) != 1;
96 $rpcenv->check($user, "/storage/$param->{storage}", [ 'Datastore.AllocateSpace' ])
102 $SIG{INT
} = $SIG{TERM
} = $SIG{QUIT
} = $SIG{HUP
} = $SIG{PIPE
} = sub {
103 die "interrupted by signal\n";
106 $param->{vmids
} = $local_vmids;
107 my $vzdump = PVE
::VZDump-
>new($cmdline, $param, $skiplist);
110 $vzdump->getlock($upid); # only one process allowed
113 $vzdump->sendmail([], 0, $err);
117 if (defined($param->{ionice
})) {
118 if ($param->{ionice
} > 7) {
119 PVE
::VZDump
::run_command
(undef, "ionice -c3 -p $$");
121 PVE
::VZDump
::run_command
(undef, "ionice -c2 -n$param->{ionice} -p $$");
124 $vzdump->exec_backup($rpcenv, $user);
129 open STDOUT
, '>/dev/null' if $param->{quiet
} && !$param->{stdout
};
130 open STDERR
, '>/dev/null' if $param->{quiet
};
132 if ($rpcenv->{type
} eq 'cli') {
133 if ($param->{stdout
}) {
135 open my $saved_stdout, ">&STDOUT"
136 || die "can't dup STDOUT: $!\n";
138 open STDOUT
, '>&STDERR' ||
139 die "unable to redirect STDOUT: $!\n";
141 $param->{stdout
} = $saved_stdout;
146 $taskid = $local_vmids->[0] if scalar(@{$local_vmids}) == 1;
148 return $rpcenv->fork_worker('vzdump', $taskid, $user, $worker);
151 __PACKAGE__-
>register_method ({
152 name
=> 'extractconfig',
153 path
=> 'extractconfig',
155 description
=> "Extract configuration from vzdump backup archive.",
157 description
=> "The user needs 'VM.Backup' permissions on the backed up guest ID, and 'Datastore.AllocateSpace' on the backup storage.",
163 additionalProperties
=> 0,
165 node
=> get_standard_option
('pve-node'),
167 description
=> "Volume identifier",
169 completion
=> \
&PVE
::Storage
::complete_volume
,
173 returns
=> { type
=> 'string' },
177 my $volume = extract_param
($param, 'volume');
179 my $rpcenv = PVE
::RPCEnvironment
::get
();
180 my $authuser = $rpcenv->get_user();
182 my $storage_cfg = PVE
::Storage
::config
();
183 PVE
::Storage
::check_volume_access
($rpcenv, $authuser, $storage_cfg, undef, $volume);
185 return PVE
::Storage
::extract_vzdump_config
($storage_cfg, $volume);