[pve-devel] [PATCH storage 02/11] Add CIFS Storage Plugin.
Wolfgang Link
w.link at proxmox.com
Tue Mar 13 15:11:02 CET 2018
This Plugin use as template the NFSpluigin.
We do only support smbversion 2 and 3.
Version 3 is default and must override through the config.
---
PVE/Storage/CIFSPlugin.pm | 215 ++++++++++++++++++++++++++++++++++++++++++++++
PVE/Storage/Makefile | 2 +-
2 files changed, 216 insertions(+), 1 deletion(-)
create mode 100644 PVE/Storage/CIFSPlugin.pm
diff --git a/PVE/Storage/CIFSPlugin.pm b/PVE/Storage/CIFSPlugin.pm
new file mode 100644
index 0000000..5cf8509
--- /dev/null
+++ b/PVE/Storage/CIFSPlugin.pm
@@ -0,0 +1,215 @@
+package PVE::Storage::CIFSPlugin;
+
+use strict;
+use warnings;
+use Net::IP;
+use PVE::Tools qw(run_command);
+use PVE::ProcFSTools;
+use File::Path;
+use PVE::Storage::Plugin;
+use PVE::JSONSchema qw(get_standard_option);
+
+use base qw(PVE::Storage::Plugin);
+
+# CIFS helper functions
+
+sub cifs_is_mounted {
+ my ($server, $share, $mountpoint, $mountdata) = @_;
+
+ $server = "[$server]" if Net::IP::ip_is_ipv6($server);
+ my $source = "//${server}/$share";
+ $mountdata = PVE::ProcFSTools::parse_proc_mounts() if !$mountdata;
+
+ return $mountpoint if grep {
+ $_->[2] =~ /^cifs/ &&
+ $_->[0] =~ m|^\Q$source\E/?$| &&
+ $_->[1] eq $mountpoint
+ } @$mountdata;
+ return undef;
+}
+
+sub get_cred_file {
+ my ($storeid) = @_;
+
+ my $cred_file = '/etc/pve/priv/'.$storeid.'.cred';
+
+ if (-e $cred_file) {
+ return $cred_file;
+ }
+ return undef;
+}
+
+sub cifs_mount {
+ my ($server, $share, $mountpoint, $storeid, $smbver, $user, $domain) = @_;
+
+ $server = "[$server]" if Net::IP::ip_is_ipv6($server);
+ my $source = "//${server}/$share";
+
+ my $cmd = ['/bin/mount', '-t', 'cifs', $source, $mountpoint, '-o', 'soft', '-o'];
+
+ if (my $cred_file = get_cred_file($storeid)) {
+ push @$cmd, "username=$user", '-o', "credentials=$cred_file";
+ push @$cmd, '-o', "domain=$domain" if defined($domain);
+ } else {
+ push @$cmd, 'guest,username=guest';
+ }
+
+ push @$cmd, '-o', defined($smbver) ? "vers=$smbver" : "vers=3.0";
+
+ run_command($cmd, errmsg => "mount error");
+}
+
+# Configuration
+
+sub type {
+ return 'cifs';
+}
+
+sub plugindata {
+ return {
+ content => [ { images => 1, rootdir => 1, vztmpl => 1, iso => 1,
+ backup => 1}, { images => 1 }],
+ format => [ { raw => 1, qcow2 => 1, vmdk => 1 } , 'raw' ],
+ };
+}
+
+sub properties {
+ return {
+ share => {
+ description => "CIFS share.",
+ type => 'string',
+ },
+ password => {
+ description => "Password for CIFS share.",
+ type => 'string',
+ maxLength => 256,
+ },
+ domain => {
+ description => "CIFS domain.",
+ type => 'string',
+ optional => 1,
+ maxLength => 256,
+ },
+ smbversion => {
+ description => "",
+ type => 'string',
+ optional => 1,
+ },
+ };
+}
+
+sub options {
+ return {
+ path => { fixed => 1 },
+ server => { fixed => 1 },
+ share => { fixed => 1 },
+ nodes => { optional => 1 },
+ disable => { optional => 1 },
+ maxfiles => { optional => 1 },
+ content => { optional => 1 },
+ format => { optional => 1 },
+ username => { optional => 1 },
+ password => { optional => 1},
+ domain => { optional => 1},
+ smbversion => { optional => 1},
+ };
+}
+
+
+sub check_config {
+ my ($class, $sectionId, $config, $create, $skipSchemaCheck) = @_;
+
+ $config->{path} = "/mnt/pve/$sectionId" if $create && !$config->{path};
+
+ return $class->SUPER::check_config($sectionId, $config, $create, $skipSchemaCheck);
+}
+
+# Storage implementation
+
+sub status {
+ my ($class, $storeid, $scfg, $cache) = @_;
+
+ $cache->{mountdata} = PVE::ProcFSTools::parse_proc_mounts()
+ if !$cache->{mountdata};
+
+ my $path = $scfg->{path};
+ my $server = $scfg->{server};
+ my $share = $scfg->{share};
+
+ return undef
+ if !cifs_is_mounted($server, $share, $path, $cache->{mountdata});
+
+ return $class->SUPER::status($storeid, $scfg, $cache);
+}
+
+sub activate_storage {
+ my ($class, $storeid, $scfg, $cache) = @_;
+
+ $cache->{mountdata} = PVE::ProcFSTools::parse_proc_mounts()
+ if !$cache->{mountdata};
+
+ my $path = $scfg->{path};
+ my $server = $scfg->{server};
+ my $share = $scfg->{share};
+
+ if (!cifs_is_mounted($server, $share, $path, $cache->{mountdata})) {
+
+ mkpath $path;
+
+ die "unable to activate storage '$storeid' - " .
+ "directory '$path' does not exist\n" if ! -d $path;
+
+ cifs_mount($server, $share, $path, $storeid, $scfg->{smbversion},
+ $scfg->{username}, $scfg->{domain});
+ }
+
+ $class->SUPER::activate_storage($storeid, $scfg, $cache);
+}
+
+sub deactivate_storage {
+ my ($class, $storeid, $scfg, $cache) = @_;
+
+ $cache->{mountdata} = PVE::ProcFSTools::parse_proc_mounts()
+ if !$cache->{mountdata};
+
+ my $path = $scfg->{path};
+ my $server = $scfg->{server};
+ my $share = $scfg->{share};
+
+ if (cifs_is_mounted($server, $share, $path, $cache->{mountdata})) {
+ my $cmd = ['/bin/umount', $path];
+ run_command($cmd, errmsg => 'umount error');
+ }
+}
+
+sub check_connection {
+ my ($class, $storeid, $scfg) = @_;
+
+ my $server = $scfg->{server};
+
+ my $cmd = ['/usr/bin/smbclient', '-L', $server, '-d', '0', '-m'];
+
+ push @$cmd, $scfg->{smbversion} ? "smb".int($scfg->{smbversion}) : 'smb3';
+
+ if (my $cred_file = get_cred_file($storeid)) {
+ push @$cmd, '-U', $scfg->{username}, '-A', $cred_file;
+ push @$cmd, '-W', $scfg->{domain} if defined($scfg->{domain});
+ } else {
+ push @$cmd, '-U', 'Guest','-N';
+ }
+
+ my $out_str;
+ eval {
+ run_command($cmd, timeout => 2, outfunc => sub {$out_str .= shift;},
+ errfunc => sub {});
+ };
+
+ if (my $err = $@) {
+ die "$out_str\n" if ($out_str =~ m/NT_STATUS_ACCESS_DENIED/);
+ return 0;
+ }
+
+ return 1;
+}
+
+1;
diff --git a/PVE/Storage/Makefile b/PVE/Storage/Makefile
index b924f21..7b168fa 100644
--- a/PVE/Storage/Makefile
+++ b/PVE/Storage/Makefile
@@ -1,4 +1,4 @@
-SOURCES=Plugin.pm DirPlugin.pm LVMPlugin.pm NFSPlugin.pm ISCSIPlugin.pm RBDPlugin.pm SheepdogPlugin.pm ISCSIDirectPlugin.pm GlusterfsPlugin.pm ZFSPoolPlugin.pm ZFSPlugin.pm DRBDPlugin.pm LvmThinPlugin.pm
+SOURCES=Plugin.pm DirPlugin.pm LVMPlugin.pm NFSPlugin.pm CIFSPlugin.pm ISCSIPlugin.pm RBDPlugin.pm SheepdogPlugin.pm ISCSIDirectPlugin.pm GlusterfsPlugin.pm ZFSPoolPlugin.pm ZFSPlugin.pm DRBDPlugin.pm LvmThinPlugin.pm
.PHONY: install
install:
--
2.11.0
More information about the pve-devel
mailing list