[pve-devel] [RFC manager 1/2] api: backup: Add endpoint for disk included status

Fabian Grünbichler f.gruenbichler at proxmox.com
Fri Dec 13 12:05:27 CET 2019


On December 12, 2019 11:27 am, Aaron Lauterer wrote:
> This endpoint provides information if disks and mountpoints of guests are
> included in a VZDump job.
> 
> The returned object is formatted to be used with the TreePanel of ExtJS.
> 
> Signed-off-by: Aaron Lauterer <a.lauterer at proxmox.com>
> ---
> 
> Unfortunately the logic of which disk / mp will be included is deeply
> engrained in the LXC and Qemu VZDump plugins and hard to use outside.
> Since AFAIU there are not that many cases I implemented the checks
> again.

haven't taken a closer look at the rest, but what about implementing 
this via AbstractConfig?

either something similar to get_replicatable_volumes (but not just 
returning the volumes that get backed up, but the complete picture), or 
a helper that you can call for each disk/mountpoint that returns whether 
it will be included in a backup or not (optionally, with reason (e.g., 
config, default, bindmount, ...)). IIRC we want to put a general disk 
iterator into AbstractConfig anyway, meaning you'd just have to use the 
correct AbstractConfig implementation and have a unified interface that 
"does the right thing" ;)

this is a bit more work as you need to adapt the other callers/backup 
code to use these new methods, but it would consolidate the logic and 
default in one place, and prevent them from diverting in the future.

>  PVE/API2/Backup.pm | 168 +++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 168 insertions(+)
> 
> diff --git a/PVE/API2/Backup.pm b/PVE/API2/Backup.pm
> index 86377c0a..e7baaa3b 100644
> --- a/PVE/API2/Backup.pm
> +++ b/PVE/API2/Backup.pm
> @@ -324,4 +324,172 @@ __PACKAGE__->register_method({
>  	die "$@" if ($@);
>      }});
>  
> +__PACKAGE__->register_method({
> +    name => 'get_disk_status',
> +    path => '{id}/included_disks',
> +    method => 'GET',
> +    protected => 1,
> +    description => "Shows included guests and the backup status of their disks.",
> +    permissions => {
> +	check => ['perm', '/', ['Sys.Audit']],
> +    },
> +    parameters => {
> +	additionalProperties => 0,
> +	properties => {
> +	    id => $vzdump_job_id_prop
> +	},
> +    },
> +    returns => {
> +	type => 'object',
> +	properties => {
> +	    children => {
> +		type => 'array',
> +		items => {
> +		    type => 'object',
> +		    properties => {
> +			id => {
> +			    type => 'string',
> +			    description => 'ID of the guest.',
> +			},
> +			type => {
> +			    type => 'string',
> +			    description => 'Type of the guest, VM or CT.',
> +			},
> +			children => {
> +			    type => 'array',
> +			    description => 'The disks or mount points of the guest with the information if they will be included in backups.',
> +			    items => {
> +				type => 'object',
> +				properties => {
> +				    id => {
> +					type => 'string',
> +					description => 'Name of the disk or mount point.',
> +				    },
> +				    status => {
> +					type => 'string',
> +					description => 'The included status of the disk or mount point.',
> +				    },
> +				},
> +			    },
> +			},
> +		    },
> +		},
> +	    },
> +	},
> +    },
> +    code => sub {
> +	my ($param) = @_;
> +
> +	my $vzconf = cfs_read_file('vzdump.cron');
> +	my $jobs = $vzconf->{jobs} || [];
> +	my $job;
> +
> +	foreach my $j (@$jobs) {
> +	    $job = $j if $j->{id} eq $param->{id};
> +	}
> +	raise_param_exc({ id => "No such job '$param->{id}'" }) if !$job;
> +
> +	my @vmids;
> +	my $vmlist = PVE::Cluster::get_vmlist();
> +
> +	# get VMIDs from pool or selected individual guests
> +	if ($job->{pool}) {
> +	    @vmids = @{PVE::API2Tools::get_resource_pool_guest_members($job->{pool})};
> +	} elsif ($job->{vmid}) {
> +	    @vmids = PVE::Tools::split_list(extract_param($job, 'vmid'));
> +	}
> +
> +	# get excluded guests
> +	my @exclude = PVE::Tools::split_list(extract_param($job, 'exclude'));
> +	@exclude = @{PVE::VZDump::check_vmids(@exclude)};
> +	@vmids = @{PVE::VZDump::check_vmids(@vmids)};
> +
> +	my $excludehash = { map { $_ => 1 } @exclude };
> +
> +	# no list of guests? (from pool or manually)
> +	# get all except excluded
> +	if (!@vmids) {
> +	    if ($job->{all} && $job->{node}) {
> +		foreach my $id (keys %{ $vmlist->{ids} }) {
> +		    push @vmids, $id
> +			if $vmlist->{ids}->{$id}->{node} eq $job->{node} && !$excludehash->{$id};
> +		}
> +	    } elsif ($job->{all}) {
> +		foreach my $id (keys %{ $vmlist->{ids} }) {
> +		    push @vmids, $id if !$excludehash->{$id};
> +		}
> +	    }
> +	}
> +
> +	@vmids = sort {$a <=> $b} @vmids;
> +
> +	# prepare API response
> +	my $result = {
> +	    children => [],
> +	    leaf => 0,
> +	};
> +
> +	foreach (@vmids) {
> +	    my $id = $_;
> +	    my $type = $vmlist->{ids}->{$id}->{type};
> +	    my $node = $vmlist->{ids}->{$id}->{node};
> +
> +	    my $guest = {
> +		id => $id,
> +		children => [],
> +		leaf => 0,
> +	    };
> +
> +	    if ($type eq 'qemu') {
> +		my $conf = PVE::QemuConfig->load_config($id, $node);
> +
> +		$guest->{id} = $guest->{id} . " " . $conf->{name};
> +		$guest->{type} = 'VM';
> +
> +		PVE::QemuServer::foreach_drive($conf, sub {
> +			my ($key, $attr) = @_;
> +
> +			return if PVE::QemuServer::drive_is_cdrom($attr);
> +
> +			my $status = 'true';
> +
> +			$status = 'false' if (exists($attr->{backup}) && !$attr->{backup});
> +
> +			my $disk = {
> +			    id => $key . ' - '. $attr->{file},
> +			    status => $status,
> +			    leaf => 1,
> +			};
> +			push @{$guest->{children}}, $disk;
> +		});
> +	    } elsif ($type eq 'lxc') {
> +		my $conf = PVE::LXC::Config->load_config($id, $node);
> +
> +		$guest->{id} = $guest->{id} . " " . $conf->{hostname};
> +		$guest->{type} = 'CT';
> +
> +		PVE::LXC::Config->foreach_mountpoint($conf, sub {
> +			my ($key, $attr) = @_;
> +
> +			my $status = 'false';
> +
> +			$status = 'true' if ($key eq 'rootfs' || (exists($attr->{backup}) && $attr->{backup}));
> +			$status = 'not possible' if ($attr->{type} ne 'volume');
> +
> +			my $disk = {
> +			    id => $key . ' - '. $attr->{volume},
> +			    status => $status,
> +			    leaf => 1,
> +			};
> +			push @{$guest->{children}}, $disk;
> +		});
> +	    } else {
> +		die "VMID $id is not Qemu nor LXC guest\n";
> +	    }
> +
> +	    push @{$result->{children}}, $guest;
> +	}
> +
> +	return $result;
> +    }});
>  1;
> -- 
> 2.20.1
> 
> 
> _______________________________________________
> pve-devel mailing list
> pve-devel at pve.proxmox.com
> https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
> 
> 



More information about the pve-devel mailing list