2018-07-21 11:35:31 +00:00
|
|
|
package s3
|
|
|
|
|
2018-07-22 20:08:48 +00:00
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"os/exec"
|
2019-03-07 19:27:02 +00:00
|
|
|
"time"
|
2018-07-22 20:08:48 +00:00
|
|
|
|
|
|
|
"github.com/golang/glog"
|
|
|
|
"k8s.io/kubernetes/pkg/util/mount"
|
|
|
|
)
|
2018-07-21 11:35:31 +00:00
|
|
|
|
|
|
|
// Mounter interface which can be implemented
|
|
|
|
// by the different mounter types
|
|
|
|
type Mounter interface {
|
2018-07-26 20:43:51 +00:00
|
|
|
Stage(stagePath string) error
|
|
|
|
Unstage(stagePath string) error
|
|
|
|
Mount(source string, target string) error
|
2018-07-21 11:35:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const (
|
2018-07-22 20:08:48 +00:00
|
|
|
s3fsMounterType = "s3fs"
|
|
|
|
goofysMounterType = "goofys"
|
|
|
|
s3backerMounterType = "s3backer"
|
2019-03-07 19:27:02 +00:00
|
|
|
rcloneMounterType = "rclone"
|
2018-07-29 08:00:53 +00:00
|
|
|
mounterTypeKey = "mounter"
|
2021-01-20 07:45:54 +00:00
|
|
|
bucketKey = "bucket"
|
2018-07-21 11:35:31 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// newMounter returns a new mounter depending on the mounterType parameter
|
2018-07-27 10:56:28 +00:00
|
|
|
func newMounter(bucket *bucket, cfg *Config) (Mounter, error) {
|
2018-07-29 08:00:53 +00:00
|
|
|
mounter := bucket.Mounter
|
|
|
|
// Fall back to mounterType in cfg
|
|
|
|
if len(bucket.Mounter) == 0 {
|
|
|
|
mounter = cfg.Mounter
|
|
|
|
}
|
|
|
|
switch mounter {
|
2018-07-21 11:35:31 +00:00
|
|
|
case s3fsMounterType:
|
|
|
|
return newS3fsMounter(bucket, cfg)
|
|
|
|
|
|
|
|
case goofysMounterType:
|
|
|
|
return newGoofysMounter(bucket, cfg)
|
|
|
|
|
2018-07-22 20:08:48 +00:00
|
|
|
case s3backerMounterType:
|
|
|
|
return newS3backerMounter(bucket, cfg)
|
|
|
|
|
2019-03-07 19:27:02 +00:00
|
|
|
case rcloneMounterType:
|
|
|
|
return newRcloneMounter(bucket, cfg)
|
|
|
|
|
2018-07-29 08:00:53 +00:00
|
|
|
default:
|
|
|
|
// default to s3backer
|
|
|
|
return newS3backerMounter(bucket, cfg)
|
2018-07-21 11:35:31 +00:00
|
|
|
}
|
|
|
|
}
|
2018-07-22 20:08:48 +00:00
|
|
|
|
|
|
|
func fuseMount(path string, command string, args []string) error {
|
|
|
|
cmd := exec.Command(command, args...)
|
2019-05-15 17:58:39 +00:00
|
|
|
glog.V(3).Infof("Mounting fuse with command: %s and args: %s", command, args)
|
2018-07-22 20:08:48 +00:00
|
|
|
|
|
|
|
out, err := cmd.CombinedOutput()
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("Error fuseMount command: %s\nargs: %s\noutput: %s", command, args, out)
|
|
|
|
}
|
|
|
|
|
2019-03-07 19:27:02 +00:00
|
|
|
return waitForMount(path, 10*time.Second)
|
2018-07-22 20:08:48 +00:00
|
|
|
}
|
|
|
|
|
2019-03-10 11:19:02 +00:00
|
|
|
func fuseUnmount(path string) error {
|
2018-07-22 20:08:48 +00:00
|
|
|
if err := mount.New("").Unmount(path); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
// as fuse quits immediately, we will try to wait until the process is done
|
2019-03-10 11:19:02 +00:00
|
|
|
process, err := findFuseMountProcess(path)
|
2018-07-22 20:08:48 +00:00
|
|
|
if err != nil {
|
|
|
|
glog.Errorf("Error getting PID of fuse mount: %s", err)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
if process == nil {
|
|
|
|
glog.Warningf("Unable to find PID of fuse mount %s, it must have finished already", path)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
glog.Infof("Found fuse pid %v of mount %s, checking if it still runs", process.Pid, path)
|
|
|
|
return waitForProcess(process, 1)
|
|
|
|
}
|