]> git.proxmox.com Git - pve-manager.git/blobdiff - PVE/API2/Backup.pm
bump version to 8.2.6
[pve-manager.git] / PVE / API2 / Backup.pm
index 1d3d68963ebd3a92f137d8a6747b922564cc9934..f37e2393107c022a04c2ad51eeb5f148eb424036 100644 (file)
@@ -10,7 +10,7 @@ use PVE::Tools qw(extract_param);
 use PVE::Cluster qw(cfs_lock_file cfs_read_file cfs_write_file);
 use PVE::RESTHandler;
 use PVE::RPCEnvironment;
-use PVE::JSONSchema;
+use PVE::JSONSchema qw(get_standard_option);
 use PVE::Storage;
 use PVE::Exception qw(raise_param_exc);
 use PVE::VZDump;
@@ -34,24 +34,59 @@ sub verify_day_of_week {
     die "invalid day '$value'\n";
 }
 
-my $vzdump_job_id_prop = {
-    type => 'string',
-    description => "The job ID.",
-    maxLength => 50
-};
-
 # NOTE: also used by the vzdump API call.
 sub assert_param_permission_common {
-    my ($rpcenv, $user, $param) = @_;
+    my ($rpcenv, $user, $param, $is_delete) = @_;
     return if $user eq 'root@pam'; # always OK
 
-    for my $key (qw(tmpdir dumpdir script)) {
+    for my $key (qw(tmpdir dumpdir script job-id)) {
        raise_param_exc({ $key => "Only root may set this option."}) if exists $param->{$key};
     }
 
-    if (defined($param->{bwlimit}) || defined($param->{ionice}) || defined($param->{performance})) {
+    if (grep { defined($param->{$_}) } qw(bwlimit ionice performance)) {
        $rpcenv->check($user, "/", [ 'Sys.Modify' ]);
     }
+
+    if ($param->{fleecing} && !$is_delete) {
+       my $fleecing = PVE::VZDump::parse_fleecing($param) // {};
+       $rpcenv->check($user, "/storage/$fleecing->{storage}", [ 'Datastore.AllocateSpace' ])
+           if $fleecing->{storage};
+    }
+}
+
+my sub assert_param_permission_create {
+    my ($rpcenv, $user, $param) = @_;
+    return if $user eq 'root@pam'; # always OK
+
+    assert_param_permission_common($rpcenv, $user, $param);
+
+    if (my $storeid = PVE::VZDump::get_storage_param($param)) {
+       $rpcenv->check($user, "/storage/$storeid", [ 'Datastore.Allocate' ]);
+    }
+}
+
+my sub assert_param_permission_update {
+    my ($rpcenv, $user, $update, $delete, $current) = @_;
+    return if $user eq 'root@pam'; # always OK
+
+    assert_param_permission_common($rpcenv, $user, $update);
+    assert_param_permission_common($rpcenv, $user, $delete, 1);
+
+    if ($update->{storage}) {
+       $rpcenv->check($user, "/storage/$update->{storage}", [ 'Datastore.Allocate' ])
+    } elsif ($delete->{storage}) {
+       $rpcenv->check($user, "/storage/local", [ 'Datastore.Allocate' ]);
+    }
+
+    return if !$current; # early check done
+
+    if ($current->{dumpdir}) {
+       die "only root\@pam may edit jobs with a 'dumpdir' option.";
+    } else {
+       if (my $storeid = PVE::VZDump::get_storage_param($current)) {
+           $rpcenv->check($user, "/storage/$storeid", [ 'Datastore.Allocate' ]);
+       }
+    }
 }
 
 my $convert_to_schedule = sub {
@@ -101,7 +136,7 @@ __PACKAGE__->register_method({
        items => {
            type => "object",
            properties => {
-               id => $vzdump_job_id_prop
+               id => get_standard_option('pve-backup-jobid'),
            },
        },
        links => [ { rel => 'child', href => "{id}" } ],
@@ -212,7 +247,7 @@ __PACKAGE__->register_method({
        my $rpcenv = PVE::RPCEnvironment::get();
        my $user = $rpcenv->get_user();
 
-       assert_param_permission_common($rpcenv, $user, $param);
+       assert_param_permission_create($rpcenv, $user, $param);
 
        if (my $pool = $param->{pool}) {
            $rpcenv->check_pool_exist($pool);
@@ -257,7 +292,7 @@ __PACKAGE__->register_method({
     parameters => {
        additionalProperties => 0,
        properties => {
-           id => $vzdump_job_id_prop
+           id => get_standard_option('pve-backup-jobid'),
        },
     },
     returns => {
@@ -305,7 +340,7 @@ __PACKAGE__->register_method({
     parameters => {
        additionalProperties => 0,
        properties => {
-           id => $vzdump_job_id_prop
+           id => get_standard_option('pve-backup-jobid'),
        },
     },
     returns => { type => 'null' },
@@ -371,7 +406,7 @@ __PACKAGE__->register_method({
     parameters => {
        additionalProperties => 0,
        properties => PVE::VZDump::Common::json_config_properties({
-           id => $vzdump_job_id_prop,
+           id => get_standard_option('pve-backup-jobid'),
            schedule => {
                description => "Backup schedule. The format is a subset of `systemd` calendar events.",
                type => 'string', format => 'pve-calendar-event',
@@ -424,7 +459,11 @@ __PACKAGE__->register_method({
        my $rpcenv = PVE::RPCEnvironment::get();
        my $user = $rpcenv->get_user();
 
-       assert_param_permission_common($rpcenv, $user, $param);
+       my $id = extract_param($param, 'id');
+       my $delete = extract_param($param, 'delete');
+       $delete = { map { $_ => 1 } PVE::Tools::split_list($delete) } if $delete;
+
+       assert_param_permission_update($rpcenv, $user, $param, $delete);
 
        if (my $pool = $param->{pool}) {
            $rpcenv->check_pool_exist($pool);
@@ -433,17 +472,13 @@ __PACKAGE__->register_method({
 
        $schedule_param_check->($param);
 
-       my $id = extract_param($param, 'id');
-       my $delete = extract_param($param, 'delete');
-       $delete = { map { $_ => 1 } PVE::Tools::split_list($delete) } if $delete;
-
        my $update_job = sub {
            my $data = cfs_read_file('vzdump.cron');
            my $jobs_data = cfs_read_file('jobs.cfg');
 
            my $jobs = $data->{jobs} || [];
 
-           die "no options specified\n" if !scalar(keys %$param);
+           die "no options specified\n" if !scalar(keys $param->%*) && !scalar(keys $delete->%*);
 
            PVE::VZDump::verify_vzdump_parameters($param);
            my $opts = PVE::VZDump::JobBase->check_config($id, $param, 0, 1);
@@ -465,6 +500,8 @@ __PACKAGE__->register_method({
                die "no such vzdump job\n" if !$job || $job->{type} ne 'vzdump';
            }
 
+           assert_param_permission_update($rpcenv, $user, $param, $delete, $job);
+
            my $deletable = {
                comment => 1,
                'repeat-missed' => 1,
@@ -527,7 +564,7 @@ __PACKAGE__->register_method({
     parameters => {
        additionalProperties => 0,
        properties => {
-           id => $vzdump_job_id_prop
+           id => get_standard_option('pve-backup-jobid'),
        },
     },
     returns => {