]> git.proxmox.com Git - pve-storage.git/blobdiff - PVE/Storage.pm
refactor disk/storage checks for Disk API
[pve-storage.git] / PVE / Storage.pm
index 995ebd397b1039462156c81f3253f5458758a239..81f9b67508538cd4de065cdda781bc0acda60aee 100755 (executable)
@@ -25,8 +25,10 @@ use PVE::Storage::DirPlugin;
 use PVE::Storage::LVMPlugin;
 use PVE::Storage::LvmThinPlugin;
 use PVE::Storage::NFSPlugin;
+use PVE::Storage::CIFSPlugin;
 use PVE::Storage::ISCSIPlugin;
 use PVE::Storage::RBDPlugin;
+use PVE::Storage::CephFSPlugin;
 use PVE::Storage::SheepdogPlugin;
 use PVE::Storage::ISCSIDirectPlugin;
 use PVE::Storage::GlusterfsPlugin;
@@ -42,8 +44,10 @@ PVE::Storage::DirPlugin->register();
 PVE::Storage::LVMPlugin->register();
 PVE::Storage::LvmThinPlugin->register();
 PVE::Storage::NFSPlugin->register();
+PVE::Storage::CIFSPlugin->register();
 PVE::Storage::ISCSIPlugin->register();
 PVE::Storage::RBDPlugin->register();
+PVE::Storage::CephFSPlugin->register();
 PVE::Storage::SheepdogPlugin->register();
 PVE::Storage::ISCSIDirectPlugin->register();
 PVE::Storage::GlusterfsPlugin->register();
@@ -1063,8 +1067,7 @@ sub storage_info {
            next;
        }
 
-       my ($total, $avail, $used, $active);
-       eval { ($total, $avail, $used, $active) = $plugin->status($storeid, $scfg, $cache); };
+       my ($total, $avail, $used, $active) = eval { $plugin->status($storeid, $scfg, $cache); };
        warn $@ if $@;
        next if !$active;
        $info->{$storeid}->{total} = int($total);
@@ -1114,6 +1117,41 @@ sub scan_nfs {
     return $res;
 }
 
+sub scan_cifs {
+    my ($server_in, $user, $password, $domain) = @_;
+
+    my $server;
+    if (!($server = resolv_server ($server_in))) {
+       die "unable to resolve address for server '${server_in}'\n";
+    }
+
+    # we support only Windows grater than 2012 cifsscan so use smb3
+    my $cmd = ['/usr/bin/smbclient', '-m', 'smb3', '-d', '0', '-L', $server];
+    if (defined($user)) {
+       die "password is required" if !defined($password);
+       push @$cmd, '-U', "$user\%$password";
+       push @$cmd, '-W', $domain if defined($domain);
+    } else {
+       push @$cmd, '-N';
+    }
+
+    my $res = {};
+    run_command($cmd,
+               outfunc => sub {
+                   my $line = shift;
+                   if ($line =~ m/(\S+)\s*Disk\s*(\S*)/) {
+                       $res->{$1} = $2;
+                   } elsif ($line =~ m/(NT_STATUS_(\S*))/) {
+                       $res->{$1} = '';
+                   }
+               },
+               errfunc => sub {},
+               noerr => 1
+    );
+
+    return $res;
+}
+
 sub scan_zfs {
 
     my $cmd = ['zfs',  'list', '-t', 'filesystem', '-H', '-o', 'name,avail,used'];
@@ -1562,8 +1600,11 @@ sub get_bandwidth_limit {
        $use_global_limits = 1;
     };
 
-    my $rpcenv = PVE::RPCEnvironment->get();
-    my $authuser = $rpcenv->get_user();
+    my ($rpcenv, $authuser);
+    if (defined($override)) {
+       $rpcenv = PVE::RPCEnvironment->get();
+       $authuser = $rpcenv->get_user();
+    }
 
     # Apply per-storage limits - if there are storages involved.
     if (@$storage_list) {
@@ -1573,7 +1614,7 @@ sub get_bandwidth_limit {
        # limits, therefore it also allows us to override them.
        # Since we have most likely multiple storages to check, do a quick check on
        # the general '/storage' path to see if we can skip the checks entirely:
-       return $override if $rpcenv->check($authuser, '/storage', ['Datastore.Allocate'], 1);
+       return $override if $rpcenv && $rpcenv->check($authuser, '/storage', ['Datastore.Allocate'], 1);
 
        my %done;
        foreach my $storage (@$storage_list) {
@@ -1582,7 +1623,7 @@ sub get_bandwidth_limit {
            $done{$storage} = 1;
 
            # Otherwise we may still have individual /storage/$ID permissions:
-           if (!$rpcenv->check($authuser, "/storage/$storage", ['Datastore.Allocate'], 1)) {
+           if (!$rpcenv || !$rpcenv->check($authuser, "/storage/$storage", ['Datastore.Allocate'], 1)) {
                # And if not: apply the limits.
                my $storecfg = storage_config($config, $storage);
                $apply_limit->($storecfg->{bwlimit});
@@ -1596,7 +1637,7 @@ sub get_bandwidth_limit {
 
     # Sys.Modify on '/' means we can change datacenter.cfg which contains the
     # global default limits.
-    if (!$rpcenv->check($authuser, '/', ['Sys.Modify'], 1)) {
+    if (!$rpcenv || !$rpcenv->check($authuser, '/', ['Sys.Modify'], 1)) {
        # So if we cannot modify global limits, apply them to our currently
        # requested override.
        my $dc = cfs_read_file('datacenter.cfg');
@@ -1606,4 +1647,16 @@ sub get_bandwidth_limit {
     return $override;
 }
 
+# checks if the storage id is available and dies if not
+sub check_available {
+    my ($id) = @_;
+
+    my $cfg = config();
+    if (my $scfg = storage_config($cfg, $id, 1)) {
+       die "storage ID '$id' already defined\n";
+    }
+
+    return undef;
+}
+
 1;