]> git.proxmox.com Git - pve-storage.git/blobdiff - PVE/Storage.pm
plugins: allow limiting the number of protected backups per guest
[pve-storage.git] / PVE / Storage.pm
index 3b8695602ed3044f4a97ca1c1d1d9b505c327e86..72458cf8b97ceddb4a09c75ead29839a3effe071 100755 (executable)
@@ -211,6 +211,17 @@ sub storage_can_replicate {
     return $plugin->storage_can_replicate($scfg, $storeid, $format);
 }
 
+sub get_max_protected_backups {
+    my ($scfg, $storeid) = @_;
+
+    return $scfg->{'max-protected-backups'} if defined($scfg->{'max-protected-backups'});
+
+    my $rpcenv = PVE::RPCEnvironment::get();
+    my $authuser = $rpcenv->get_user();
+
+    return $rpcenv->check($authuser, "/storage/$storeid", ['Datastore.Allocate'], 1) ? -1 : 5;
+}
+
 sub storage_ids {
     my ($cfg) = @_;
 
@@ -240,6 +251,30 @@ sub update_volume_attribute {
     my $scfg = storage_config($cfg, $storeid);
     my $plugin = PVE::Storage::Plugin->lookup($scfg->{type});
 
+    my ($vtype, undef, $vmid) = $plugin->parse_volname($volname);
+    my $max_protected_backups = get_max_protected_backups($scfg, $storeid);
+
+    if (
+       $vtype eq 'backup'
+       && $vmid
+       && $attribute eq 'protected'
+       && $value
+       && !$plugin->get_volume_attribute($scfg, $storeid, $volname, 'protected')
+       && $max_protected_backups > -1 # -1 is unlimited
+    ) {
+       my $backups = $plugin->list_volumes($storeid, $scfg, $vmid, ['backup']);
+       my ($backup_type) = map { $_->{subtype} } grep { $_->{volid} eq $volid } $backups->@*;
+
+       my $protected_count = grep {
+           $_->{protected} && (!$backup_type || ($_->{subtype} && $_->{subtype} eq $backup_type))
+       } $backups->@*;
+
+       if ($max_protected_backups <= $protected_count) {
+           die "The number of protected backups per guest is limited to $max_protected_backups ".
+               "on storage '$storeid'\n";
+       }
+    }
+
     return $plugin->update_volume_attribute($scfg, $storeid, $volname, $attribute, $value);
 }