Commit 0010066f authored by Cyrill Troxler's avatar Cyrill Troxler
Browse files

Implement stage/unstage

This helps the reliability of s3backer as the fuse mount
is done on NodeStageVolume and only once per volume per
node.
parent 1fe218a5
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -11,9 +11,10 @@ import (
// Mounter interface which can be implemented
// by the different mounter types
type Mounter interface {
	Format() error
	Mount(targetPath string) error
	Unmount(targetPath string) error
	Stage(stagePath string) error
	Unstage(stagePath string) error
	Mount(source string, target string) error
	Unmount(target string) error
}

const (
+7 −3
Original line number Diff line number Diff line
@@ -38,13 +38,17 @@ func newGoofysMounter(bucket string, cfg *Config) (Mounter, error) {
	}, nil
}

func (goofys *goofysMounter) Format() error {
func (goofys *goofysMounter) Stage(stageTarget string) error {
	return nil
}

func (goofys *goofysMounter) Mount(targetPath string) error {
func (goofys *goofysMounter) Unstage(stageTarget string) error {
	return nil
}

func (goofys *goofysMounter) Mount(source string, target string) error {
	goofysCfg := &goofysApi.Config{
		MountPoint: targetPath,
		MountPoint: target,
		Endpoint:   goofys.endpoint,
		Region:     goofys.region,
		DirMode:    0755,
+21 −38
Original line number Diff line number Diff line
@@ -2,7 +2,6 @@ package s3

import (
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
@@ -19,13 +18,11 @@ type s3backerMounter struct {
	accessKeyID     string
	secretAccessKey string
	size            int64
	initMountPath   string
}

const (
	s3backerCmd    = "s3backer"
	s3backerFsType = "xfs"
	s3backerMountBase = "/mnt"
	s3backerDevice = "file"
	// blockSize to use in k
	s3backerBlockSize = "128k"
@@ -38,7 +35,6 @@ func newS3backerMounter(bucket string, cfg *Config) (Mounter, error) {
		region:          cfg.Region,
		accessKeyID:     cfg.AccessKeyID,
		secretAccessKey: cfg.SecretAccessKey,
		initMountPath:   path.Join(s3backerMountBase, bucket),
		size:            1024 * 1024 * 1024 * 10,
	}

@@ -49,37 +45,32 @@ func (s3backer *s3backerMounter) String() string {
	return s3backer.bucket
}

func (s3backer *s3backerMounter) Format() error {
	tmpDir, err := ioutil.TempDir("", "s3backer")
	if err != nil {
func (s3backer *s3backerMounter) Stage(stageTarget string) error {
	// s3backer requires two mounts
	// first mount will fuse mount the bucket to a single 'file'
	if err := s3backer.mountInit(stageTarget); err != nil {
		return err
	}
	defer os.RemoveAll(tmpDir)

	if err := s3backer.mountInit(tmpDir); err != nil {
	// ensure 'file' device is formatted
	err := formatFs(s3backerFsType, path.Join(stageTarget, s3backerDevice))
	if err != nil {
		fuseUnmount(stageTarget, s3backerCmd)
	}
	return err
}
	defer fuseUnmount(tmpDir, s3backerCmd)

	return formatFs(s3backerFsType, path.Join(tmpDir, s3backerDevice))
func (s3backer *s3backerMounter) Unstage(stageTarget string) error {
	// Unmount the s3backer fuse mount
	return fuseUnmount(stageTarget, s3backerCmd)
}

func (s3backer *s3backerMounter) Mount(targetPath string) error {
	if err := os.MkdirAll(s3backer.initMountPath, 0700); err != nil {
		return err
	}
	// s3backer requires two mounts
	// first mount will fuse mount the bucket to a single 'file'
	err := s3backer.mountInit(s3backer.initMountPath)
	if err != nil {
		return err
	}
	device := path.Join(s3backer.initMountPath, s3backerDevice)
func (s3backer *s3backerMounter) Mount(source string, target string) error {
	device := path.Join(source, s3backerDevice)
	// second mount will mount the 'file' as a filesystem
	err = mount.New("").Mount(device, targetPath, s3backerFsType, []string{})
	err := mount.New("").Mount(device, target, s3backerFsType, []string{})
	if err != nil {
		// cleanup fuse mount
		fuseUnmount(targetPath, s3backerCmd)
		fuseUnmount(target, s3backerCmd)
		return err
	}
	return nil
@@ -87,15 +78,7 @@ func (s3backer *s3backerMounter) Mount(targetPath string) error {

func (s3backer *s3backerMounter) Unmount(targetPath string) error {
	// Unmount the filesystem first
	if err := mount.New("").Unmount(targetPath); err != nil {
		return err
	}
	// Unmount the s3backer fuse mount
	err := fuseUnmount(s3backer.initMountPath, s3backerCmd)
	if err != nil {
		return err
	}
	return nil
	return mount.New("").Unmount(targetPath)
}

func (s3backer *s3backerMounter) mountInit(path string) error {
+10 −6
Original line number Diff line number Diff line
@@ -26,17 +26,21 @@ func newS3fsMounter(bucket string, cfg *Config) (Mounter, error) {
	}, nil
}

func (s3fs *s3fsMounter) Format() error {
func (s3fs *s3fsMounter) Stage(stageTarget string) error {
	return nil
}

func (s3fs *s3fsMounter) Mount(targetPath string) error {
func (s3fs *s3fsMounter) Unstage(stageTarget string) error {
	return nil
}

func (s3fs *s3fsMounter) Mount(source string, target string) error {
	if err := writes3fsPass(s3fs.pwFileContent); err != nil {
		return err
	}
	args := []string{
		fmt.Sprintf("%s", s3fs.bucket),
		fmt.Sprintf("%s", targetPath),
		fmt.Sprintf("%s", target),
		"-o", "sigv2",
		"-o", "use_path_request_style",
		"-o", fmt.Sprintf("url=%s", s3fs.url),
@@ -44,11 +48,11 @@ func (s3fs *s3fsMounter) Mount(targetPath string) error {
		"-o", "allow_other",
		"-o", "mp_umask=000",
	}
	return fuseMount(targetPath, s3fsCmd, args)
	return fuseMount(target, s3fsCmd, args)
}

func (s3fs *s3fsMounter) Unmount(targetPath string) error {
	return fuseUnmount(targetPath, s3fsCmd)
func (s3fs *s3fsMounter) Unmount(target string) error {
	return fuseUnmount(target, s3fsCmd)
}

func writes3fsPass(pwFileContent string) error {
+10 −6
Original line number Diff line number Diff line
@@ -59,7 +59,7 @@ func newS3qlMounter(bucket string, cfg *Config) (Mounter, error) {
	return s3ql, s3ql.writeConfig()
}

func (s3ql *s3qlMounter) Format() error {
func (s3ql *s3qlMounter) Stage(stagePath string) error {
	// force creation to ignore existing data
	args := []string{
		s3ql.bucketURL,
@@ -78,17 +78,21 @@ func (s3ql *s3qlMounter) Format() error {
	return nil
}

func (s3ql *s3qlMounter) Mount(targetPath string) error {
func (s3ql *s3qlMounter) Unstage(stagePath string) error {
	return nil
}

func (s3ql *s3qlMounter) Mount(source string, target string) error {
	args := []string{
		s3ql.bucketURL,
		targetPath,
		target,
		"--allow-other",
	}
	return fuseMount(targetPath, s3qlCmdMount, append(args, s3ql.options...))
	return fuseMount(target, s3qlCmdMount, append(args, s3ql.options...))
}

func (s3ql *s3qlMounter) Unmount(targetPath string) error {
	return fuseUnmount(targetPath, s3qlCmdMount)
func (s3ql *s3qlMounter) Unmount(target string) error {
	return fuseUnmount(target, s3qlCmdMount)
}

func (s3ql *s3qlMounter) writeConfig() error {
Loading