]> git.proxmox.com Git - pve-storage.git/blobdiff - PVE/API2/Storage/Content.pm
auto-detect format for files with vmdk extension
[pve-storage.git] / PVE / API2 / Storage / Content.pm
index 5544ea781767bf9dd6bd4377a08d95f7ff41957b..c8261d4886ec9b213cd32618cf63e28ede79fa7e 100644 (file)
@@ -21,6 +21,9 @@ __PACKAGE__->register_method ({
     path => '',
     method => 'GET',
     description => "List storage content.",
+    permissions => { 
+       check => ['perm', '/storage/{storage}', ['Datastore.Audit', 'Datastore.AllocateSpace'], any => 1],
+    },
     protected => 1,
     proxyto => 'node',
     parameters => {
@@ -55,13 +58,17 @@ __PACKAGE__->register_method ({
     code => sub {
        my ($param) = @_;
 
+       my $rpcenv = PVE::RPCEnvironment::get();
+
+       my $authuser = $rpcenv->get_user();
+
        my $cts = $param->{content} ? [ $param->{content} ] : [ @ctypes ];
 
        my $storeid = $param->{storage};
 
        my $cfg = cfs_read_file("storage.cfg");
 
-       my $scfg = PVE::Storage::storage_config ($cfg, $storeid);
+       my $scfg = PVE::Storage::storage_config($cfg, $storeid);
 
        my $res = [];
        foreach my $ct (@$cts) {
@@ -79,6 +86,8 @@ __PACKAGE__->register_method ({
            next if !$data || !$data->{$storeid};
 
            foreach my $item (@{$data->{$storeid}}) {
+               eval { $rpcenv->check_volume_access($authuser, $cfg, undef, $item->{volid}); };
+               next if $@;
                $item->{content} = $ct;
                push @$res, $item;
            }
@@ -92,6 +101,9 @@ __PACKAGE__->register_method ({
     path => '',
     method => 'POST',
     description => "Allocate disk images.",
+    permissions => { 
+       check => ['perm', '/storage/{storage}', ['Datastore.AllocateSpace']],
+    },
     protected => 1,
     proxyto => 'node',
     parameters => {
@@ -140,7 +152,7 @@ __PACKAGE__->register_method ({
        }
 
        # extract FORMAT from name
-       if ($name =~ m/\.(raw|qcow2)$/) {
+       if ($name =~ m/\.(raw|qcow2|vmdk)$/) {
            my $fmt = $1;
 
            raise_param_exc({ format => "different storage formats ($param->{format} != $fmt)" }) 
@@ -171,6 +183,7 @@ my $real_volume_id = sub {
            raise_param_exc({ storage => "storage ID missmatch" }) 
                if $storeid && $sid ne $storeid;
            $volid = $volume;
+           $storeid = $sid;
        };
        raise_param_exc({ volume => $@}) if $@; 
           
@@ -181,7 +194,7 @@ my $real_volume_id = sub {
        $volid = "$storeid:$volume";
     }
 
-    return $volid;
+    return wantarray ? ($volid, $storeid) : $volid;
 };
 
 __PACKAGE__->register_method ({
@@ -189,6 +202,10 @@ __PACKAGE__->register_method ({
     path => '{volume}',
     method => 'GET',
     description => "Get volume attributes",
+    permissions => { 
+       description => "You need read access for the volume.",
+       user => 'all',
+    },
     protected => 1,
     proxyto => 'node',
     parameters => {
@@ -206,18 +223,25 @@ __PACKAGE__->register_method ({
     code => sub {
        my ($param) = @_;
 
-       my $volid = &$real_volume_id($param->{storage}, $param->{volume});
+       my $rpcenv = PVE::RPCEnvironment::get();
+       my $authuser = $rpcenv->get_user();
+
+       my ($volid, $storeid) = &$real_volume_id($param->{storage}, $param->{volume});
 
        my $cfg = cfs_read_file('storage.cfg');
 
+       $rpcenv->check_volume_access($authuser, $cfg, undef, $volid);
+
        my $path = PVE::Storage::path($cfg, $volid);
-       my ($size, $format, $used) = PVE::Storage::file_size_info ($path);
+       my ($size, $format, $used, $parent) =  PVE::Storage::file_size_info($path);
+       die "file_size_info on '$volid' failed\n" if !($format && $size);
 
        # fixme: return more attributes?
        return {
            path => $path,
            size => $size,
             used => $used,
+           format => $format,
        };
     }});
 
@@ -226,6 +250,10 @@ __PACKAGE__->register_method ({
     path => '{volume}',
     method => 'DELETE',
     description => "Delete volume",
+    permissions => { 
+       description => "You need 'Datastore.Allocate' privilege on the storage (or 'Datastore.AllocateSpace' for backup volumes if you have VM.Backup privilege on the VM).",
+       user => 'all',
+    },
     protected => 1,
     proxyto => 'node',
     parameters => {
@@ -243,10 +271,21 @@ __PACKAGE__->register_method ({
     code => sub {
        my ($param) = @_;
 
-       my $volid = &$real_volume_id($param->{storage}, $param->{volume});
-       
+       my $rpcenv = PVE::RPCEnvironment::get();
+       my $authuser = $rpcenv->get_user();
+
        my $cfg = cfs_read_file('storage.cfg');
 
+       my ($volid, $storeid) = &$real_volume_id($param->{storage}, $param->{volume});
+
+       my ($path, $ownervm, $vtype) = PVE::Storage::path($cfg, $volid);
+       if ($vtype eq 'backup' && $ownervm) {
+           $rpcenv->check($authuser, "/storage/$storeid", ['Datastore.AllocateSpace']);
+           $rpcenv->check($authuser, "/vms/$ownervm", ['VM.Backup']);
+       } else {
+           $rpcenv->check($authuser, "/storage/$storeid", ['Datastore.Allocate']);
+       }
+
        PVE::Storage::vdisk_free ($cfg, $volid);
 
        return undef;
@@ -256,7 +295,7 @@ __PACKAGE__->register_method ({
     name => 'copy',
     path => '{volume}',
     method => 'POST',
-    description => "Copy a volume.",
+    description => "Copy a volume. This is experimental code - do not use.",
     protected => 1,
     proxyto => 'node',
     parameters => {