X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=PVE%2FStorage%2FCIFSPlugin.pm;h=3a7e638c25407f84655a025957dc6791c05d29b1;hb=bc7fecb0821db8c4171e89f5d8073eb842b5213c;hp=cb7c8447a6d715ecd512aa14c7bf9e1eea362869;hpb=ff6fa67fb6a688ea8c206f7a2b0e5f3f5bd5e3e9;p=pve-storage.git diff --git a/PVE/Storage/CIFSPlugin.pm b/PVE/Storage/CIFSPlugin.pm index cb7c844..3a7e638 100644 --- a/PVE/Storage/CIFSPlugin.pm +++ b/PVE/Storage/CIFSPlugin.pm @@ -30,14 +30,22 @@ sub cifs_is_mounted { sub cifs_cred_file_name { my ($storeid) = @_; + return "/etc/pve/priv/storage/${storeid}.pw"; +} + +sub cifs_delete_credentials { + my ($storeid) = @_; - return "/etc/pve/priv/${storeid}.cred"; + if (my $cred_file = get_cred_file($storeid)) { + unlink($cred_file) or warn "removing cifs credientials '$cred_file' failed: $!\n"; + } } sub cifs_set_credentials { my ($password, $storeid) = @_; my $cred_file = cifs_cred_file_name($storeid); + mkdir "/etc/pve/priv/storage"; PVE::Tools::file_set_contents($cred_file, "password=$password\n"); @@ -49,7 +57,10 @@ sub get_cred_file { my $cred_file = cifs_cred_file_name($storeid); - return -e $cred_file ? $cred_file : undef; + if (-e $cred_file) { + return $cred_file; + } + return undef; } sub cifs_mount { @@ -67,7 +78,7 @@ sub cifs_mount { push @$cmd, 'guest,username=guest'; } - push @$cmd, '-o', defined($smbver) ? "vers=$smbver" : "vers=3.0"; + push @$cmd, '-o', defined($smbver) ? "vers=$smbver" : "vers=default"; run_command($cmd, errmsg => "mount error"); } @@ -81,7 +92,7 @@ sub type { sub plugindata { return { content => [ { images => 1, rootdir => 1, vztmpl => 1, iso => 1, - backup => 1}, { images => 1 }], + backup => 1, snippets => 1}, { images => 1 }], format => [ { raw => 1, qcow2 => 1, vmdk => 1 } , 'raw' ], }; } @@ -93,7 +104,7 @@ sub properties { type => 'string', }, password => { - description => "Password for CIFS share.", + description => "Password for accessing the share/datastore.", type => 'string', maxLength => 256, }, @@ -104,8 +115,11 @@ sub properties { maxLength => 256, }, smbversion => { - description => "", + description => "SMB protocol version. 'default' if not set, negotiates the highest SMB2+" + ." version supported by both the client and server.", type => 'string', + default => 'default', + enum => ['default', '2.0', '2.1', '3', '3.0', '3.11'], optional => 1, }, }; @@ -119,12 +133,16 @@ sub options { nodes => { optional => 1 }, disable => { optional => 1 }, maxfiles => { optional => 1 }, + 'prune-backups' => { optional => 1 }, content => { optional => 1 }, format => { optional => 1 }, username => { optional => 1 }, password => { optional => 1}, domain => { optional => 1}, smbversion => { optional => 1}, + mkdir => { optional => 1 }, + bwlimit => { optional => 1 }, + preallocation => { optional => 1 }, }; } @@ -139,6 +157,46 @@ sub check_config { # Storage implementation +sub on_add_hook { + my ($class, $storeid, $scfg, %sensitive) = @_; + + if (defined($sensitive{password})) { + cifs_set_credentials($sensitive{password}, $storeid); + if (!exists($scfg->{username})) { + warn "storage $storeid: ignoring password parameter, no user set\n"; + } + } else { + cifs_delete_credentials($storeid); + } + + return; +} + +sub on_update_hook { + my ($class, $storeid, $scfg, %sensitive) = @_; + + return if !exists($sensitive{password}); + + if (defined($sensitive{password})) { + cifs_set_credentials($sensitive{password}, $storeid); + if (!exists($scfg->{username})) { + warn "storage $storeid: ignoring password parameter, no user set\n"; + } + } else { + cifs_delete_credentials($storeid); + } + + return; +} + +sub on_delete_hook { + my ($class, $storeid, $scfg) = @_; + + cifs_delete_credentials($storeid); + + return; +} + sub status { my ($class, $storeid, $scfg, $cache) = @_; @@ -167,7 +225,7 @@ sub activate_storage { if (!cifs_is_mounted($server, $share, $path, $cache->{mountdata})) { - mkpath $path; + mkpath $path if !(defined($scfg->{mkdir}) && !$scfg->{mkdir}); die "unable to activate storage '$storeid' - " . "directory '$path' does not exist\n" if ! -d $path; @@ -200,9 +258,12 @@ sub check_connection { my $servicename = '//'.$scfg->{server}.'/'.$scfg->{share}; - my $cmd = ['/usr/bin/smbclient', $servicename, '-d', '0', '-m']; + my $cmd = ['/usr/bin/smbclient', $servicename, '-d', '0']; - push @$cmd, $scfg->{smbversion} ? "smb".int($scfg->{smbversion}) : 'smb3'; + if (defined($scfg->{smbversion}) && $scfg->{smbversion} ne 'default') { + # max-protocol version, so basically only relevant for smb2 vs smb3 + push @$cmd, '-m', "smb" . int($scfg->{smbversion}); + } if (my $cred_file = get_cred_file($storeid)) { push @$cmd, '-U', $scfg->{username}, '-A', $cred_file; @@ -210,14 +271,12 @@ sub check_connection { } else { push @$cmd, '-U', 'Guest','-N'; } - push @$cmd, '-c', 'echo 1 0'; my $out_str; - eval { - run_command($cmd, timeout => 2, outfunc => sub {$out_str .= shift;}, - errfunc => sub {}); - }; + my $out = sub { $out_str .= shift }; + + eval { run_command($cmd, timeout => 10, outfunc => $out, errfunc => sub {}) }; if (my $err = $@) { die "$out_str\n" if defined($out_str) && @@ -228,4 +287,13 @@ sub check_connection { return 1; } +sub get_volume_notes { + my $class = shift; + PVE::Storage::DirPlugin::get_volume_notes($class, @_); +} +sub update_volume_notes { + my $class = shift; + PVE::Storage::DirPlugin::update_volume_notes($class, @_); +} + 1;