From a8fe84fd3fb17b27a33162e489c568526447e054 Mon Sep 17 00:00:00 2001 From: Jeremy Unruh Date: Fri, 27 May 2016 20:13:45 -0700 Subject: [PATCH] Issue #41 - support mount options in CIFS driver --- Makefile | 10 ++++----- netshare/drivers/cifs.go | 45 +++++++++++++++++++++++++++------------- netshare/drivers/nfs.go | 17 +-------------- netshare/drivers/util.go | 15 ++++++++++++++ netshare/netshare.go | 9 ++++++-- 5 files changed, 59 insertions(+), 37 deletions(-) diff --git a/Makefile b/Makefile index a789456..fd8b46e 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ -VERSION = 0.17 +VERSION = 0.18 GO_FMT = gofmt -s -w -l . -GO_XC = goxc -os="linux" -tasks-="rmbin" +GO_XC = goxc -os="linux" -tasks-="rmbin" GOXC_FILE = .goxc.local.json @@ -18,14 +18,14 @@ goxc: $(shell echo ' "body": "",' >> $(GOXC_FILE)) $(shell echo ' "include": "*.zip,*.tar.gz,*.deb,docker-volume-netshare_$(VERSION)_linux_amd64-bin"' >> $(GOXC_FILE)) $(shell echo ' }\n } \n}' >> $(GOXC_FILE)) - $(GO_XC) + $(GO_XC) cp build/$(VERSION)/linux_amd64/docker-volume-netshare build/$(VERSION)/docker-volume-netshare_$(VERSION)_linux_amd64-bin deps: go get -format: - $(GO_FMT) +format: + $(GO_FMT) bintray: $(GO_XC) bintray diff --git a/netshare/drivers/cifs.go b/netshare/drivers/cifs.go index 83e1bb6..c8014aa 100644 --- a/netshare/drivers/cifs.go +++ b/netshare/drivers/cifs.go @@ -16,26 +16,40 @@ const ( PasswordOpt = "password" DomainOpt = "domain" SecurityOpt = "security" + CifsOpts = "cifsopts" ) type cifsDriver struct { volumeDriver - creds *cifsCreds - netrc *netrc.Netrc + creds *CifsCreds + netrc *netrc.Netrc + cifsopts map[string]string } -type cifsCreds struct { +type CifsCreds struct { user string pass string domain string security string } -func NewCIFSDriver(root, user, pass, domain, security, netrc string) cifsDriver { +func (creds *CifsCreds) String() string { + return fmt.Sprintf("creds: { user=%s,pass=****,domain=%s,security=%s }", creds.user, creds.domain, creds.security) +} + +func NewCifsCredentials(user, pass, domain, security string) *CifsCreds { + return &CifsCreds{user: user, pass: pass, domain: domain, security: security} +} + +func NewCIFSDriver(root string, creds *CifsCreds, netrc, cifsopts string) cifsDriver { d := cifsDriver{ volumeDriver: newVolumeDriver(root), - creds: &cifsCreds{user: user, pass: pass, domain: domain, security: security}, + creds: creds, netrc: parseNetRC(netrc), + cifsopts: map[string]string{}, + } + if len(cifsopts) > 0 { + d.cifsopts[CifsOpts] = cifsopts } return d } @@ -70,7 +84,7 @@ func (c cifsDriver) Mount(r volume.Request) volume.Response { return volume.Response{Err: err.Error()} } - if err := c.mountVolume(r.Name, source, hostdir, c.getCreds(host)); err != nil { + if err := c.mountVolume(source, hostdir, c.getCreds(host)); err != nil { return volume.Response{Err: err.Error()} } c.mountm.Add(r.Name, hostdir) @@ -127,17 +141,20 @@ func (c cifsDriver) parseHost(r volume.Request) string { return name } -func (s cifsDriver) mountVolume(name, source, dest string, creds *cifsCreds) error { +func (s cifsDriver) mountVolume(source, dest string, creds *CifsCreds) error { var opts bytes.Buffer - - opts.WriteString("-o ") var user = creds.user var pass = creds.pass var domain = creds.domain var security = creds.security - if s.mountm.HasOptions(name) { - mopts := s.mountm.GetOptions(name) + options := merge(s.mountm.GetOptions(dest), s.cifsopts) + if val, ok := options[CifsOpts]; ok { + opts.WriteString(val + ",") + } + + if s.mountm.HasOptions(dest) { + mopts := s.mountm.GetOptions(dest) if v, found := mopts[UsernameOpt]; found { user = v } @@ -172,17 +189,17 @@ func (s cifsDriver) mountVolume(name, source, dest string, creds *cifsCreds) err opts.WriteString("rw ") opts.WriteString(fmt.Sprintf("%s %s", source, dest)) - cmd := fmt.Sprintf("mount -t cifs %s", opts.String()) + cmd := fmt.Sprintf("mount -t cifs -o %s", opts.String()) log.Debugf("Executing: %s\n", strings.Replace(cmd, "password="+pass, "password=****", 1)) return run(cmd) } -func (s cifsDriver) getCreds(host string) *cifsCreds { +func (s cifsDriver) getCreds(host string) *CifsCreds { log.Debugf("GetCreds: host=%s, netrc=%v", host, s.netrc) if s.netrc != nil { m := s.netrc.Machine(host) if m != nil { - return &cifsCreds{ + return &CifsCreds{ user: m.Get("username"), pass: m.Get("password"), domain: m.Get("domain"), diff --git a/netshare/drivers/nfs.go b/netshare/drivers/nfs.go index ce23c95..324a3a5 100644 --- a/netshare/drivers/nfs.go +++ b/netshare/drivers/nfs.go @@ -105,7 +105,7 @@ func (n nfsDriver) fixSource(r volume.Request) string { func (n nfsDriver) mountVolume(source, dest string, version int) error { var cmd string - options := n.mountOptions(n.mountm.GetOptions(dest)) + options := merge(n.mountm.GetOptions(dest), n.nfsopts) opts := "" if val, ok := options[NfsOptions]; ok { opts = val @@ -135,18 +135,3 @@ func (n nfsDriver) mountVolume(source, dest string, version int) error { log.Debugf("exec: %s\n", cmd) return run(cmd) } - -func (n nfsDriver) mountOptions(src map[string]string) map[string]string { - if len(n.nfsopts) == 0 && len(src) == 0 { - return EmptyMap - } - - dst := map[string]string{} - for k, v := range n.nfsopts { - dst[k] = v - } - for k, v := range src { - dst[k] = v - } - return dst -} diff --git a/netshare/drivers/util.go b/netshare/drivers/util.go index d8b27f6..5c2114c 100644 --- a/netshare/drivers/util.go +++ b/netshare/drivers/util.go @@ -36,3 +36,18 @@ func run(cmd string) error { } return nil } + +func merge(src, src2 map[string]string) map[string]string { + if len(src) == 0 && len(src2) == 0 { + return EmptyMap + } + + dst := map[string]string{} + for k, v := range src2 { + dst[k] = v + } + for k, v := range src { + dst[k] = v + } + return dst +} diff --git a/netshare/netshare.go b/netshare/netshare.go index adf3a02..694b9f2 100644 --- a/netshare/netshare.go +++ b/netshare/netshare.go @@ -100,6 +100,7 @@ func setupFlags() { cifsCmd.Flags().StringP(DomainFlag, "d", "", "Domain to use for mounts. Can also set environment NETSHARE_CIFS_DOMAIN") cifsCmd.Flags().StringP(SecurityFlag, "s", "", "Security mode to use for mounts (mount.cifs's sec option). Can also set environment NETSHARE_CIFS_SECURITY.") cifsCmd.Flags().StringP(NetRCFlag, "", os.Getenv("HOME"), "The default .netrc location. Default is the user.home directory") + cifsCmd.Flags().StringP(OptionsFlag, "o", "", "Options passed to Cifs mounts (ex: nounix,uid=433)") nfsCmd.Flags().IntP(VersionFlag, "v", 4, "NFS Version to use [3 | 4]. Can also be set with NETSHARE_NFS_VERSION") nfsCmd.Flags().StringP(OptionsFlag, "o", "", fmt.Sprintf("Options passed to nfs mounts (ex: %s)", drivers.DefaultNfsV3)) @@ -147,8 +148,12 @@ func execCIFS(cmd *cobra.Command, args []string) { domain := typeOrEnv(cmd, DomainFlag, EnvSambaWG) security := typeOrEnv(cmd, SecurityFlag, EnvSambaSec) netrc, _ := cmd.Flags().GetString(NetRCFlag) - d := drivers.NewCIFSDriver(rootForType(drivers.CIFS), user, pass, domain, security, netrc) - startOutput(fmt.Sprintf("CIFS :: user: %s, pass: ***, domain: %s, secutity: %s, netrc: %s", user, domain, security, netrc)) + options, _ := cmd.Flags().GetString(OptionsFlag) + + creds := drivers.NewCifsCredentials(user, pass, domain, security) + + d := drivers.NewCIFSDriver(rootForType(drivers.CIFS), creds, netrc, options) + startOutput(fmt.Sprintf("CIFS :: %s, netrc: %s, opts: %s", creds, netrc, options)) start(drivers.CIFS, d) }