Skip to content

Commit

Permalink
Merge pull request #122 from dmaj/master
Browse files Browse the repository at this point in the history
Adding file_mode + dir_mode for cifs. Prevent the mounted data from being deleted (Removing the code)
  • Loading branch information
gondor authored May 29, 2017
2 parents ef4b683 + a760292 commit 4963f54
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 62 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ See example:
password somepass
domain optional
security optional
fileMode optional
dirMode optional
```

**2. Run the plugin**
Expand Down Expand Up @@ -146,7 +148,7 @@ options and other info can be eliminated when running a container.
This will create a new volume via the Docker daemon which will call `Create` in netshare passing in the corresponding user, pass and domain info.

```
$ docker volume create -d cifs --name cifshost/share --opt username=user --opt password=pass --opt domain=domain --opt security=security
$ docker volume create -d cifs --name cifshost/share --opt username=user --opt password=pass --opt domain=domain --opt security=security --opt fileMode=0777 --opt dirMode=0777
```

**3. Launch a container**
Expand Down
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package main

import (
"github.com/ContainX/docker-volume-netshare/netshare"
"github.com/dmaj/docker-volume-netshare/netshare"
)

var VERSION string = ""
Expand Down
84 changes: 59 additions & 25 deletions netshare/drivers/cifs.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,46 +3,55 @@ package drivers
import (
"bytes"
"fmt"
"path/filepath"
"strings"

log "github.com/Sirupsen/logrus"
"github.com/dickeyxxx/netrc"
"github.com/docker/go-plugins-helpers/volume"
"os"
"path/filepath"
"strings"
)

// Constants defining driver paremeters
const (
UsernameOpt = "username"
PasswordOpt = "password"
DomainOpt = "domain"
SecurityOpt = "security"
FileModeOpt = "fileMode"
DirModeOpt = "dirMode"
CifsOpts = "cifsopts"
)

type cifsDriver struct {
// CifsDriver driver structure
type CifsDriver struct {
volumeDriver
creds *CifsCreds
netrc *netrc.Netrc
cifsopts map[string]string
}

// CifsCreds contains Options for cifs-mount
type CifsCreds struct {
user string
pass string
domain string
security string
fileMode string
dirMode string
}

func (creds *CifsCreds) String() string {
return fmt.Sprintf("creds: { user=%s,pass=****,domain=%s,security=%s }", creds.user, creds.domain, creds.security)
return fmt.Sprintf("creds: { user=%s,pass=****,domain=%s,security=%s, fileMode=%s, dirMode=%s}", creds.user, creds.domain, creds.security, creds.fileMode, creds.dirMode)
}

func NewCifsCredentials(user, pass, domain, security string) *CifsCreds {
return &CifsCreds{user: user, pass: pass, domain: domain, security: security}
// NewCifsCredentials setting the credentials
func NewCifsCredentials(user, pass, domain, security, fileMode, dirMode string) *CifsCreds {
return &CifsCreds{user: user, pass: pass, domain: domain, security: security, fileMode: fileMode, dirMode: dirMode}
}

func NewCIFSDriver(root string, creds *CifsCreds, netrc, cifsopts string) cifsDriver {
d := cifsDriver{
// NewCIFSDriver creating the cifs driver
func NewCIFSDriver(root string, creds *CifsCreds, netrc, cifsopts string) CifsDriver {
d := CifsDriver{
volumeDriver: newVolumeDriver(root),
creds: creds,
netrc: parseNetRC(netrc),
Expand All @@ -63,7 +72,8 @@ func parseNetRC(path string) *netrc.Netrc {
return nil
}

func (c cifsDriver) Mount(r volume.MountRequest) volume.Response {
// Mount do the mounting
func (c CifsDriver) Mount(r volume.MountRequest) volume.Response {
c.m.Lock()
defer c.m.Unlock()
hostdir := mountpoint(c.root, r.Name)
Expand Down Expand Up @@ -114,7 +124,8 @@ func (c cifsDriver) Mount(r volume.MountRequest) volume.Response {
return volume.Response{Mountpoint: hostdir}
}

func (c cifsDriver) Unmount(r volume.UnmountRequest) volume.Response {
// Unmount do the unmounting
func (c CifsDriver) Unmount(r volume.UnmountRequest) volume.Response {
c.m.Lock()
defer c.m.Unlock()
hostdir := mountpoint(c.root, r.Name)
Expand All @@ -137,21 +148,26 @@ func (c cifsDriver) Unmount(r volume.UnmountRequest) volume.Response {

c.mountm.DeleteIfNotManaged(r.Name)

if err := os.RemoveAll(hostdir); err != nil {
return volume.Response{Err: err.Error()}
}
// ToDo:
// This is a bad idea.
// When there is a dangling mount you will lose all your data in the mounted folder
// I didn't understand why you delete all the data ...?

// if err := os.RemoveAll(hostdir); err != nil {
// return volume.Response{Err: err.Error()}
// }

return volume.Response{}
}

func (c cifsDriver) fixSource(name string) string {
func (c CifsDriver) fixSource(name string) string {
if c.mountm.HasOption(name, ShareOpt) {
return "//" + c.mountm.GetOption(name, ShareOpt)
}
return "//" + name
}

func (c cifsDriver) parseHost(name string) string {
func (c CifsDriver) parseHost(name string) string {
n := name
if c.mountm.HasOption(name, ShareOpt) {
n = c.mountm.GetOption(name, ShareOpt)
Expand All @@ -164,20 +180,22 @@ func (c cifsDriver) parseHost(name string) string {
return n
}

func (s cifsDriver) mountVolume(name, source, dest string, creds *CifsCreds) error {
func (c CifsDriver) mountVolume(name, source, dest string, creds *CifsCreds) error {
var opts bytes.Buffer
var user = creds.user
var pass = creds.pass
var domain = creds.domain
var security = creds.security
var fileMode = creds.fileMode
var dirMode = creds.dirMode

options := merge(s.mountm.GetOptions(name), s.cifsopts)
options := merge(c.mountm.GetOptions(name), c.cifsopts)
if val, ok := options[CifsOpts]; ok {
opts.WriteString(val + ",")
}

if s.mountm.HasOptions(name) {
mopts := s.mountm.GetOptions(name)
if c.mountm.HasOptions(name) {
mopts := c.mountm.GetOptions(name)
if v, found := mopts[UsernameOpt]; found {
user = v
}
Expand All @@ -190,6 +208,12 @@ func (s cifsDriver) mountVolume(name, source, dest string, creds *CifsCreds) err
if v, found := mopts[SecurityOpt]; found {
security = v
}
if v, found := mopts[FileModeOpt]; found {
fileMode = v
}
if v, found := mopts[DirModeOpt]; found {
dirMode = v
}
}

if user != "" {
Expand All @@ -209,6 +233,14 @@ func (s cifsDriver) mountVolume(name, source, dest string, creds *CifsCreds) err
opts.WriteString(fmt.Sprintf("sec=%s,", security))
}

if fileMode != "" {
opts.WriteString(fmt.Sprintf("file_mode=%s,", fileMode))
}

if dirMode != "" {
opts.WriteString(fmt.Sprintf("dir_mode=%s,", dirMode))
}

opts.WriteString("rw ")

opts.WriteString(fmt.Sprintf("%s %s", source, dest))
Expand All @@ -217,18 +249,20 @@ func (s cifsDriver) mountVolume(name, source, dest string, creds *CifsCreds) err
return run(cmd)
}

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)
func (c CifsDriver) getCreds(host string) *CifsCreds {
log.Debugf("GetCreds: host=%s, netrc=%v", host, c.netrc)
if c.netrc != nil {
m := c.netrc.Machine(host)
if m != nil {
return &CifsCreds{
user: m.Get("username"),
pass: m.Get("password"),
domain: m.Get("domain"),
security: m.Get("security"),
fileMode: m.Get("fileMode"),
dirMode: m.Get("dirMode"),
}
}
}
return s.creds
return c.creds
}
78 changes: 43 additions & 35 deletions netshare/netshare.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,51 @@ package netshare

import (
"fmt"
"github.com/ContainX/docker-volume-netshare/netshare/drivers"
log "github.com/Sirupsen/logrus"
"github.com/docker/go-plugins-helpers/volume"
"github.com/spf13/cobra"
"os"
"path/filepath"
"strconv"
"github.com/dmaj/docker-volume-netshare/netshare/drivers"
log "github.com/Sirupsen/logrus"
"github.com/docker/go-plugins-helpers/volume"
"github.com/spf13/cobra"
"syscall"
)

const (
UsernameFlag = "username"
PasswordFlag = "password"
DomainFlag = "domain"
SecurityFlag = "security"
VersionFlag = "version"
OptionsFlag = "options"
BasedirFlag = "basedir"
VerboseFlag = "verbose"
AvailZoneFlag = "az"
NoResolveFlag = "noresolve"
NetRCFlag = "netrc"
TCPFlag = "tcp"
PortFlag = "port"
NameServerFlag = "nameserver"
NameFlag = "name"
SecretFlag = "secret"
ContextFlag = "context"
CephMount = "sorcemount"
CephPort = "port"
CephOpts = "options"
ServerMount = "servermount"
EnvSambaUser = "NETSHARE_CIFS_USERNAME"
EnvSambaPass = "NETSHARE_CIFS_PASSWORD"
EnvSambaWG = "NETSHARE_CIFS_DOMAIN"
EnvSambaSec = "NETSHARE_CIFS_SECURITY"
EnvNfsVers = "NETSHARE_NFS_VERSION"
EnvTCP = "NETSHARE_TCP_ENABLED"
EnvTCPAddr = "NETSHARE_TCP_ADDR"
PluginAlias = "netshare"
NetshareHelp = `
UsernameFlag = "username"
PasswordFlag = "password"
DomainFlag = "domain"
SecurityFlag = "security"
FileModeFlag = "fileMode"
DirModeFlag = "dirMode"
VersionFlag = "version"
OptionsFlag = "options"
BasedirFlag = "basedir"
VerboseFlag = "verbose"
AvailZoneFlag = "az"
NoResolveFlag = "noresolve"
NetRCFlag = "netrc"
TCPFlag = "tcp"
PortFlag = "port"
NameServerFlag = "nameserver"
NameFlag = "name"
SecretFlag = "secret"
ContextFlag = "context"
CephMount = "sorcemount"
CephPort = "port"
CephOpts = "options"
ServerMount = "servermount"
EnvSambaUser = "NETSHARE_CIFS_USERNAME"
EnvSambaPass = "NETSHARE_CIFS_PASSWORD"
EnvSambaWG = "NETSHARE_CIFS_DOMAIN"
EnvSambaSec = "NETSHARE_CIFS_SECURITY"
EnvSambaFileMode = "NETSHARE_CIFS_FILEMODE"
EnvSambaDirMode = "NETSHARE_CIFS_DIRMODE"
EnvNfsVers = "NETSHARE_NFS_VERSION"
EnvTCP = "NETSHARE_TCP_ENABLED"
EnvTCPAddr = "NETSHARE_TCP_ADDR"
PluginAlias = "netshare"
NetshareHelp = `
docker-volume-netshare (NFS V3/4, AWS EFS and CIFS Volume Driver Plugin)
Provides docker volume support for NFS v3 and 4, EFS as well as CIFS. This plugin can be run multiple times to
Expand Down Expand Up @@ -113,6 +117,8 @@ func setupFlags() {
cifsCmd.Flags().StringP(PasswordFlag, "p", "", "Password to use for mounts. Can also set environment NETSHARE_CIFS_PASSWORD")
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(FileModeFlag, "f", "", "Setting access rights for files (mount.cifs's file_mode option). Can also set environment NETSHARE_CIFS_FILEMODE.")
cifsCmd.Flags().StringP(DirModeFlag, "z", "", "Setting access rights for folders (mount.cifs's dir_mode option). Can also set environment NETSHARE_CIFS_DIRMODE.")
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)")

Expand Down Expand Up @@ -191,10 +197,12 @@ func execCIFS(cmd *cobra.Command, args []string) {
pass := typeOrEnv(cmd, PasswordFlag, EnvSambaPass)
domain := typeOrEnv(cmd, DomainFlag, EnvSambaWG)
security := typeOrEnv(cmd, SecurityFlag, EnvSambaSec)
fileMode := typeOrEnv(cmd, FileModeFlag, EnvSambaFileMode)
dirMode := typeOrEnv(cmd, DirModeFlag, EnvSambaDirMode)
netrc, _ := cmd.Flags().GetString(NetRCFlag)
options, _ := cmd.Flags().GetString(OptionsFlag)

creds := drivers.NewCifsCredentials(user, pass, domain, security)
creds := drivers.NewCifsCredentials(user, pass, domain, security, fileMode, dirMode)

d := drivers.NewCIFSDriver(rootForType(drivers.CIFS), creds, netrc, options)
if len(user) > 0 {
Expand Down

0 comments on commit 4963f54

Please sign in to comment.