Skip to content

Commit 22f77f6

Browse files
authored
Merge pull request #42 from krigbaum/master
Cephfs
2 parents 020c7eb + 63861c2 commit 22f77f6

File tree

4 files changed

+194
-2
lines changed

4 files changed

+194
-2
lines changed

netshare/drivers/ceph.go

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
package drivers
2+
3+
import (
4+
"fmt"
5+
log "github.com/Sirupsen/logrus"
6+
"github.com/docker/go-plugins-helpers/volume"
7+
"os"
8+
"strings"
9+
)
10+
11+
const (
12+
CephOptions = "cephopts"
13+
)
14+
15+
type cephDriver struct {
16+
volumeDriver
17+
username string
18+
password string
19+
context string
20+
cephmount string
21+
cephport string
22+
localmount string
23+
cephopts map[string]string
24+
}
25+
26+
//var (
27+
// EmptyMap = map[string]string{}
28+
//)
29+
30+
func NewCephDriver(root string, username string, password string, context string, cephmount string, cephport string, localmount string, cephopts string) cephDriver {
31+
d := cephDriver{
32+
volumeDriver: newVolumeDriver(root),
33+
username: username,
34+
password: password,
35+
context: context,
36+
cephmount: cephmount,
37+
cephport: cephport,
38+
localmount: localmount,
39+
cephopts: map[string]string{},
40+
}
41+
if len(cephopts) > 0 {
42+
d.cephopts[CephOptions] = cephopts
43+
}
44+
45+
return d
46+
}
47+
48+
func (n cephDriver) Mount(r volume.Request) volume.Response {
49+
log.Debugf("Entering Mount: %v", r)
50+
n.m.Lock()
51+
defer n.m.Unlock()
52+
hostdir := mountpoint(n.root, r.Name)
53+
source := n.fixSource(r)
54+
if n.mountm.HasMount(r.Name) && n.mountm.Count(r.Name) > 0 {
55+
log.Infof("Using existing CEPH volume mount: %s", hostdir)
56+
n.mountm.Increment(r.Name)
57+
return volume.Response{Mountpoint: hostdir}
58+
}
59+
60+
log.Infof("Mounting CEPH volume %s on %s", source, hostdir)
61+
if err := createDest(hostdir); err != nil {
62+
return volume.Response{Err: err.Error()}
63+
}
64+
65+
if err := n.mountVolume(source, hostdir); err != nil {
66+
return volume.Response{Err: err.Error()}
67+
}
68+
n.mountm.Add(r.Name, hostdir)
69+
return volume.Response{Mountpoint: hostdir}
70+
}
71+
72+
func (n cephDriver) Unmount(r volume.Request) volume.Response {
73+
log.Debugf("Entering Unmount: %v", r)
74+
75+
n.m.Lock()
76+
defer n.m.Unlock()
77+
hostdir := mountpoint(n.root, r.Name)
78+
79+
if n.mountm.HasMount(r.Name) {
80+
if n.mountm.Count(r.Name) > 1 {
81+
log.Printf("Skipping unmount for %s - in use by other containers", r.Name)
82+
n.mountm.Decrement(r.Name)
83+
return volume.Response{}
84+
}
85+
n.mountm.Decrement(r.Name)
86+
}
87+
88+
log.Infof("Unmounting volume name %s from %s", r.Name, hostdir)
89+
90+
if err := run(fmt.Sprintf("umount %s", hostdir)); err != nil {
91+
return volume.Response{Err: err.Error()}
92+
}
93+
94+
n.mountm.DeleteIfNotManaged(r.Name)
95+
96+
if err := os.RemoveAll(hostdir); err != nil {
97+
return volume.Response{Err: err.Error()}
98+
}
99+
100+
return volume.Response{}
101+
}
102+
103+
func (n cephDriver) fixSource(r volume.Request) string {
104+
if n.mountm.HasOption(r.Name, ShareOpt) {
105+
return n.mountm.GetOption(r.Name, ShareOpt)
106+
}
107+
source := strings.Split(r.Name, "/")
108+
source[0] = source[0] + ":" + n.cephport + ":"
109+
return strings.Join(source, "/")
110+
}
111+
112+
func (n cephDriver) mountVolume(source, dest string) error {
113+
var cmd string
114+
115+
options := n.mountOptions(n.mountm.GetOptions(dest))
116+
opts := ""
117+
if val, ok := options[CephOptions]; ok {
118+
fmt.Println("opts = ", val)
119+
opts = "-o " + val
120+
}
121+
122+
mountCmd := "mount"
123+
124+
if log.GetLevel() == log.DebugLevel {
125+
mountCmd = mountCmd + " -t ceph"
126+
}
127+
128+
//cmd = fmt.Sprintf("%s -t ceph %s:%s:/ -o %s,%s,%s %s %s", mountCmd, n.cephmount, n.cephport, n.context, n.username, n.password, opts, dest)
129+
cmd = fmt.Sprintf("%s -t ceph %s -o %s,%s,%s %s %s", mountCmd, source, n.context, n.username, n.password, opts, dest)
130+
131+
log.Debugf("exec: %s\n", cmd)
132+
return run(cmd)
133+
}
134+
135+
func (n cephDriver) mountOptions(src map[string]string) map[string]string {
136+
if len(n.cephopts) == 0 && len(src) == 0 {
137+
return EmptyMap
138+
}
139+
140+
dst := map[string]string{}
141+
for k, v := range n.cephopts {
142+
dst[k] = v
143+
}
144+
for k, v := range src {
145+
dst[k] = v
146+
}
147+
return dst
148+
}

netshare/drivers/driver_types.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@ const (
66
CIFS DriverType = iota
77
NFS
88
EFS
9+
CEPH
910
)
1011

1112
var driverTypes = []string{
1213
"cifs",
1314
"nfs",
1415
"efs",
16+
"ceph",
1517
}
1618

1719
func (dt DriverType) String() string {

netshare/drivers/nfs.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,6 @@ func (n nfsDriver) mountVolume(source, dest string, version int) error {
123123
if len(opts) < 1 {
124124
opts = DefaultNfsV3
125125
}
126-
cmd = fmt.Sprintf("%s -o %s %s %s", mountCmd, opts, source, dest)
127126
default:
128127
log.Debugf("Mounting with NFSv4 - src: %s, dest: %s", source, dest)
129128
if len(opts) > 0 {

netshare/netshare.go

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@ const (
2626
TCPFlag = "tcp"
2727
PortFlag = "port"
2828
NameServerFlag = "nameserver"
29+
NameFlag = "name"
30+
SecretFlag = "secret"
31+
ContextFlag = "context"
32+
CephMount = "sorcemount"
33+
CephPort = "port"
34+
CephOpts = "options"
35+
ServerMount = "servermount"
2936
EnvSambaUser = "NETSHARE_CIFS_USERNAME"
3037
EnvSambaPass = "NETSHARE_CIFS_PASSWORD"
3138
EnvSambaWG = "NETSHARE_CIFS_DOMAIN"
@@ -70,6 +77,12 @@ var (
7077
Run: execEFS,
7178
}
7279

80+
cephCmd = &cobra.Command{
81+
Use: "ceph",
82+
Short: "run plugin in Ceph mode",
83+
Run: execCEPH,
84+
}
85+
7386
versionCmd = &cobra.Command{
7487
Use: "version",
7588
Short: "Display current version and build date",
@@ -85,7 +98,7 @@ var (
8598
func Execute() {
8699
setupFlags()
87100
rootCmd.Long = fmt.Sprintf(NetshareHelp, Version, BuildDate)
88-
rootCmd.AddCommand(versionCmd, cifsCmd, nfsCmd, efsCmd)
101+
rootCmd.AddCommand(versionCmd, cifsCmd, nfsCmd, efsCmd, cephCmd)
89102
rootCmd.Execute()
90103
}
91104

@@ -108,6 +121,14 @@ func setupFlags() {
108121
efsCmd.Flags().String(AvailZoneFlag, "", "AWS Availability zone [default: \"\", looks up via metadata]")
109122
efsCmd.Flags().String(NameServerFlag, "", "Custom DNS nameserver. [default \"\", uses /etc/resolv.conf]")
110123
efsCmd.Flags().Bool(NoResolveFlag, false, "Indicates EFS mount sources are IP Addresses vs File System ID")
124+
125+
cephCmd.Flags().StringP(NameFlag, "n", "admin", "Username to use for ceph mount.")
126+
cephCmd.Flags().StringP(SecretFlag, "s", "NoneProvided", "Password to use for Ceph Mount.")
127+
cephCmd.Flags().StringP(ContextFlag, "c", "system_u:object_r:tmp_t:s0", "SELinux Context of Ceph Mount.")
128+
cephCmd.Flags().StringP(CephMount, "m", "10.0.0.1", "Address of Ceph source mount.")
129+
cephCmd.Flags().StringP(CephPort, "p", "6789", "Port to use for ceph mount.")
130+
cephCmd.Flags().StringP(ServerMount, "S", "/mnt/ceph", "Directory to use as ceph local mount.")
131+
cephCmd.Flags().StringP(OptionsFlag, "o", "", "Options passed to Ceph mounts ")
111132
}
112133

113134
func setupLogger(cmd *cobra.Command, args []string) {
@@ -118,6 +139,28 @@ func setupLogger(cmd *cobra.Command, args []string) {
118139
}
119140
}
120141

142+
func execCEPH(cmd *cobra.Command, args []string) {
143+
username, _ := cmd.Flags().GetString(NameFlag)
144+
password, _ := cmd.Flags().GetString(SecretFlag)
145+
context, _ := cmd.Flags().GetString(ContextFlag)
146+
cephmount, _ := cmd.Flags().GetString(CephMount)
147+
cephport, _ := cmd.Flags().GetString(CephPort)
148+
servermount, _ := cmd.Flags().GetString(ServerMount)
149+
cephopts, _ := cmd.Flags().GetString(CephOpts)
150+
151+
if len(username) > 0 {
152+
username = "name=" + username
153+
}
154+
if len(password) > 0 {
155+
password = "secret=" + password
156+
}
157+
if len(context) > 0 {
158+
context = "context=" + "\"" + context + "\""
159+
}
160+
d := drivers.NewCephDriver(rootForType(drivers.CEPH), username, password, context, cephmount, cephport, servermount, cephopts)
161+
start(drivers.CEPH, d)
162+
}
163+
121164
func execNFS(cmd *cobra.Command, args []string) {
122165
version, _ := cmd.Flags().GetInt(VersionFlag)
123166
if os.Getenv(EnvNfsVers) != "" {

0 commit comments

Comments
 (0)