github.com/sagansystems/goofys-app@v0.19.1-0.20180410053237-b2302fdf5af9/api/api.go (about) 1 package goofys 2 3 import ( 4 . "github.com/kahing/goofys/internal" 5 6 "context" 7 "fmt" 8 "net" 9 "net/http" 10 "os" 11 "os/exec" 12 "time" 13 14 "github.com/aws/aws-sdk-go/aws" 15 "github.com/aws/aws-sdk-go/aws/credentials" 16 17 "github.com/jacobsa/fuse" 18 "github.com/jacobsa/fuse/fuseutil" 19 "github.com/jinzhu/copier" 20 "github.com/sirupsen/logrus" 21 ) 22 23 var log = GetLogger("main") 24 25 type Config struct { 26 // File system 27 MountOptions map[string]string 28 MountPoint string 29 30 Cache []string 31 DirMode os.FileMode 32 FileMode os.FileMode 33 Uid uint32 34 Gid uint32 35 36 // S3 37 Endpoint string 38 Region string 39 RegionSet bool 40 StorageClass string 41 Profile string 42 UseContentType bool 43 UseSSE bool 44 UseKMS bool 45 KMSKeyID string 46 ACL string 47 48 // Tuning 49 Cheap bool 50 ExplicitDir bool 51 StatCacheTTL time.Duration 52 TypeCacheTTL time.Duration 53 54 // Debugging 55 DebugFuse bool 56 DebugS3 bool 57 Foreground bool 58 } 59 60 func Mount( 61 ctx context.Context, 62 bucketName string, 63 config *Config) (fs *Goofys, mfs *fuse.MountedFileSystem, err error) { 64 65 var flags FlagStorage 66 copier.Copy(&flags, config) 67 68 awsConfig := (&aws.Config{ 69 Region: &flags.Region, 70 Logger: GetLogger("s3"), 71 //LogLevel: aws.LogLevel(aws.LogDebug), 72 }).WithHTTPClient(&http.Client{ 73 Transport: &http.Transport{ 74 Proxy: http.ProxyFromEnvironment, 75 DialContext: (&net.Dialer{ 76 Timeout: 30 * time.Second, 77 KeepAlive: 30 * time.Second, 78 DualStack: true, 79 }).DialContext, 80 MaxIdleConns: 1000, 81 MaxIdleConnsPerHost: 1000, 82 IdleConnTimeout: 90 * time.Second, 83 TLSHandshakeTimeout: 10 * time.Second, 84 ExpectContinueTimeout: 10 * time.Second, 85 }, 86 }) 87 88 if len(flags.Profile) > 0 { 89 awsConfig.Credentials = credentials.NewSharedCredentials("", flags.Profile) 90 } 91 92 if len(flags.Endpoint) > 0 { 93 awsConfig.Endpoint = &flags.Endpoint 94 } 95 96 awsConfig.S3ForcePathStyle = aws.Bool(true) 97 98 fs = NewGoofys(ctx, bucketName, awsConfig, &flags) 99 if fs == nil { 100 err = fmt.Errorf("Mount: initialization failed") 101 return 102 } 103 server := fuseutil.NewFileSystemServer(fs) 104 105 fuseLog := GetLogger("fuse") 106 107 // Mount the file system. 108 mountCfg := &fuse.MountConfig{ 109 FSName: bucketName, 110 Options: flags.MountOptions, 111 ErrorLogger: GetStdLogger(NewLogger("fuse"), logrus.ErrorLevel), 112 DisableWritebackCaching: true, 113 } 114 115 if flags.DebugFuse { 116 fuseLog.Level = logrus.DebugLevel 117 log.Level = logrus.DebugLevel 118 mountCfg.DebugLogger = GetStdLogger(fuseLog, logrus.DebugLevel) 119 } 120 121 mfs, err = fuse.Mount(flags.MountPoint, server, mountCfg) 122 if err != nil { 123 err = fmt.Errorf("Mount: %v", err) 124 return 125 } 126 127 if len(flags.Cache) != 0 { 128 log.Infof("Starting catfs %v", flags.Cache) 129 catfs := exec.Command("catfs", flags.Cache...) 130 lvl := logrus.InfoLevel 131 if flags.DebugFuse { 132 lvl = logrus.DebugLevel 133 catfs.Env = append(catfs.Env, "RUST_LOG=debug") 134 } else { 135 catfs.Env = append(catfs.Env, "RUST_LOG=info") 136 } 137 catfsLog := GetLogger("catfs") 138 catfsLog.Formatter.(*LogHandle).Lvl = &lvl 139 catfs.Stderr = catfsLog.Writer() 140 err = catfs.Start() 141 if err != nil { 142 err = fmt.Errorf("Failed to start catfs: %v", err) 143 144 // sleep a bit otherwise can't unmount right away 145 time.Sleep(time.Second) 146 err2 := TryUnmount(flags.MountPoint) 147 if err2 != nil { 148 err = fmt.Errorf("%v. Failed to unmount: %v", err, err2) 149 } 150 } 151 152 go func() { 153 err := catfs.Wait() 154 log.Errorf("catfs exited: %v", err) 155 156 if err != nil { 157 // if catfs terminated cleanly, it 158 // should have unmounted this, 159 // otherwise we will do it ourselves 160 err2 := TryUnmount(flags.MountPointArg) 161 if err2 != nil { 162 log.Errorf("Failed to unmount: %v", err2) 163 } 164 } 165 166 if flags.MountPointArg != flags.MountPoint { 167 err2 := TryUnmount(flags.MountPoint) 168 if err2 != nil { 169 log.Errorf("Failed to unmount: %v", err2) 170 } 171 } 172 173 if err != nil { 174 os.Exit(1) 175 } 176 }() 177 } 178 179 return 180 }