mirror of
https://git.proxmox.com/git/pve-manager
synced 2025-07-04 21:59:15 +00:00
vzdump: move remaining guest include logic to single method
The `guest include` logic handling `all` and `exclude` parameters was in the `PVE::VZDump->exec_backup()` method. Moving this logic into the `get_included_guests` method allows us to simplify and generalize it. This helps to make the overall logic easier to test and develop other features around vzdump backup jobs. The method now returns a hash with node names as keys mapped to arrays of VMIDs on these nodes that are included in the vzdump job. The VZDump API call to create a new backup is adapted to use the new method to create the list of local VMIDs and the skiplist. Permission checks are kept where they are to be able to handle missing permissions according to the current context. The old behavior to die on a backup job when the user is missing the permission to a guest and the job is not an 'all' or 'exclude' job is kept. Signed-off-by: Aaron Lauterer <a.lauterer@proxmox.com>
This commit is contained in:
parent
4aa89cc0e8
commit
df5875b41e
@ -69,18 +69,20 @@ __PACKAGE__->register_method ({
|
||||
return 'OK' if $param->{node} && $param->{node} ne $nodename;
|
||||
|
||||
my $cmdline = PVE::VZDump::Common::command_line($param);
|
||||
my ($vmids, $skiplist) = PVE::VZDump::get_included_guests($param);
|
||||
|
||||
my $vmids_per_node = PVE::VZDump::get_included_guests($param);
|
||||
|
||||
my $local_vmids = delete $vmids_per_node->{$nodename} // [];
|
||||
|
||||
my $skiplist = [ map { @$_ } values $vmids_per_node->%* ];
|
||||
|
||||
if($param->{stop}){
|
||||
PVE::VZDump::stop_running_backups();
|
||||
return 'OK' if !scalar(@{$vmids});
|
||||
return 'OK' if !scalar(@{$local_vmids});
|
||||
}
|
||||
|
||||
# silent exit if specified VMs run on other nodes
|
||||
return "OK" if !scalar(@{$vmids}) && !$param->{all};
|
||||
|
||||
my @exclude = PVE::Tools::split_list(extract_param($param, 'exclude'));
|
||||
$param->{exclude} = PVE::VZDump::check_vmids(@exclude);
|
||||
return "OK" if !scalar(@{$local_vmids}) && !$param->{all};
|
||||
|
||||
# exclude-path list need to be 0 separated
|
||||
if (defined($param->{'exclude-path'})) {
|
||||
@ -94,7 +96,7 @@ __PACKAGE__->register_method ({
|
||||
}
|
||||
|
||||
die "you can only backup a single VM with option --stdout\n"
|
||||
if $param->{stdout} && scalar(@{$vmids}) != 1;
|
||||
if $param->{stdout} && scalar(@{$local_vmids}) != 1;
|
||||
|
||||
$rpcenv->check($user, "/storage/$param->{storage}", [ 'Datastore.AllocateSpace' ])
|
||||
if $param->{storage};
|
||||
@ -106,6 +108,7 @@ __PACKAGE__->register_method ({
|
||||
die "interrupted by signal\n";
|
||||
};
|
||||
|
||||
$param->{vmids} = $local_vmids;
|
||||
my $vzdump = PVE::VZDump->new($cmdline, $param, $skiplist);
|
||||
|
||||
eval {
|
||||
@ -143,7 +146,7 @@ __PACKAGE__->register_method ({
|
||||
}
|
||||
|
||||
my $taskid;
|
||||
$taskid = $vmids->[0] if scalar(@{$vmids}) == 1;
|
||||
$taskid = $local_vmids->[0] if scalar(@{$local_vmids}) == 1;
|
||||
|
||||
return $rpcenv->fork_worker('vzdump', $taskid, $user, $worker);
|
||||
}});
|
||||
|
@ -1044,29 +1044,23 @@ sub exec_backup {
|
||||
if scalar(@{$self->{skiplist}});
|
||||
|
||||
my $tasklist = [];
|
||||
my $vzdump_plugins = {};
|
||||
foreach my $plugin (@{$self->{plugins}}) {
|
||||
my $type = $plugin->type();
|
||||
next if exists $vzdump_plugins->{$type};
|
||||
$vzdump_plugins->{$type} = $plugin;
|
||||
}
|
||||
|
||||
if ($opts->{all}) {
|
||||
foreach my $plugin (@{$self->{plugins}}) {
|
||||
my $vmlist = $plugin->vmlist();
|
||||
foreach my $vmid (sort @$vmlist) {
|
||||
next if grep { $_ eq $vmid } @{$opts->{exclude}};
|
||||
next if !$rpcenv->check($authuser, "/vms/$vmid", [ 'VM.Backup' ], 1);
|
||||
push @$tasklist, { vmid => $vmid, state => 'todo', plugin => $plugin, mode => $opts->{mode} };
|
||||
}
|
||||
}
|
||||
} else {
|
||||
foreach my $vmid (sort @{$opts->{vmids}}) {
|
||||
my $plugin;
|
||||
foreach my $pg (@{$self->{plugins}}) {
|
||||
my $vmlist = $pg->vmlist();
|
||||
if (grep { $_ eq $vmid } @$vmlist) {
|
||||
$plugin = $pg;
|
||||
last;
|
||||
}
|
||||
}
|
||||
$rpcenv->check($authuser, "/vms/$vmid", [ 'VM.Backup' ]);
|
||||
push @$tasklist, { vmid => $vmid, state => 'todo', plugin => $plugin, mode => $opts->{mode} };
|
||||
}
|
||||
my $vmlist = PVE::Cluster::get_vmlist();
|
||||
foreach my $vmid (sort @{$opts->{vmids}}) {
|
||||
my $guest_type = $vmlist->{ids}->{$vmid}->{type};
|
||||
my $plugin = $vzdump_plugins->{$guest_type};
|
||||
next if !$rpcenv->check($authuser, "/vms/$vmid", [ 'VM.Backup' ], $opts->{all});
|
||||
push @$tasklist, {
|
||||
vmid => $vmid,
|
||||
state => 'todo',
|
||||
plugin => $plugin,
|
||||
mode => $opts->{mode} };
|
||||
}
|
||||
|
||||
# Use in-memory files for the outer hook logs to pass them to sendmail.
|
||||
@ -1174,34 +1168,38 @@ sub get_included_guests {
|
||||
|
||||
my $nodename = PVE::INotify::nodename();
|
||||
my $vmids = [];
|
||||
my $vmids_per_node = {};
|
||||
|
||||
my $vmlist = PVE::Cluster::get_vmlist();
|
||||
|
||||
# convert string lists to arrays
|
||||
if ($job->{pool}) {
|
||||
$vmids = PVE::API2Tools::get_resource_pool_guest_members($job->{pool});
|
||||
} elsif ($job->{vmid}) {
|
||||
$vmids = [ PVE::Tools::split_list($job->{vmid}) ];
|
||||
} else {
|
||||
$vmids = [ PVE::Tools::split_list(extract_param($job, 'vmid')) ];
|
||||
}
|
||||
# all or exclude
|
||||
my @exclude = PVE::Tools::split_list($job->{exclude});
|
||||
@exclude = @{PVE::VZDump::check_vmids(@exclude)};
|
||||
my $excludehash = { map { $_ => 1 } @exclude };
|
||||
|
||||
my $skiplist = [];
|
||||
if (!$job->{all}) {
|
||||
if (!$job->{node} || $job->{node} eq $nodename) {
|
||||
my $vmlist = PVE::Cluster::get_vmlist();
|
||||
my $localvmids = [];
|
||||
foreach my $vmid (@{$vmids}) {
|
||||
my $d = $vmlist->{ids}->{$vmid};
|
||||
if ($d && ($d->{node} ne $nodename)) {
|
||||
push @{$skiplist}, $vmid;
|
||||
} else {
|
||||
push @{$localvmids}, $vmid;
|
||||
}
|
||||
}
|
||||
$vmids = $localvmids;
|
||||
for my $id (keys %{ $vmlist->{ids} }) {
|
||||
next if $excludehash->{$id};
|
||||
push @$vmids, $id;
|
||||
}
|
||||
}
|
||||
$vmids = [ sort {$a <=> $b} @$vmids];
|
||||
|
||||
$job->{vmids} = PVE::VZDump::check_vmids(@{$vmids})
|
||||
$vmids = PVE::VZDump::check_vmids(@$vmids);
|
||||
|
||||
foreach my $vmid (@$vmids) {
|
||||
my $vmid_data = $vmlist->{ids}->{$vmid};
|
||||
my $node = $vmid_data->{node};
|
||||
|
||||
next if (defined $job->{node} && $job->{node} ne $node);
|
||||
push @{$vmids_per_node->{$node}}, $vmid;
|
||||
}
|
||||
|
||||
return ($vmids, $skiplist);
|
||||
return $vmids_per_node;
|
||||
}
|
||||
|
||||
1;
|
||||
|
Loading…
Reference in New Issue
Block a user