github.com/adrianjagielak/goofys@v0.24.1-0.20230810095418-94919a5d2254/api/api.go (about) 1 package goofys 2 3 import ( 4 . "github.com/kahing/goofys/api/common" 5 "github.com/kahing/goofys/internal" 6 7 "context" 8 "fmt" 9 "os" 10 "os/exec" 11 "time" 12 13 "github.com/jacobsa/fuse" 14 "github.com/jacobsa/fuse/fuseutil" 15 "github.com/sirupsen/logrus" 16 ) 17 18 var log = GetLogger("main") 19 20 func Mount( 21 ctx context.Context, 22 bucketName string, 23 flags *FlagStorage) (fs *Goofys, mfs *fuse.MountedFileSystem, err error) { 24 25 if flags.DebugS3 { 26 SetCloudLogLevel(logrus.DebugLevel) 27 } 28 29 // Mount the file system. 30 mountCfg := &fuse.MountConfig{ 31 FSName: bucketName, 32 Subtype: "goofys", 33 Options: flags.MountOptions, 34 ErrorLogger: GetStdLogger(NewLogger("fuse"), logrus.ErrorLevel), 35 DisableWritebackCaching: true, 36 } 37 38 if flags.DebugFuse { 39 fuseLog := GetLogger("fuse") 40 fuseLog.Level = logrus.DebugLevel 41 log.Level = logrus.DebugLevel 42 mountCfg.DebugLogger = GetStdLogger(fuseLog, logrus.DebugLevel) 43 } 44 45 if flags.Backend == nil { 46 if spec, err := internal.ParseBucketSpec(bucketName); err == nil { 47 switch spec.Scheme { 48 case "adl": 49 auth, err := AzureAuthorizerConfig{ 50 Log: GetLogger("adlv1"), 51 }.Authorizer() 52 if err != nil { 53 err = fmt.Errorf("couldn't load azure credentials: %v", 54 err) 55 return nil, nil, err 56 } 57 flags.Backend = &ADLv1Config{ 58 Endpoint: spec.Bucket, 59 Authorizer: auth, 60 } 61 // adlv1 doesn't really have bucket 62 // names, but we will rebuild the 63 // prefix 64 bucketName = "" 65 if spec.Prefix != "" { 66 bucketName = ":" + spec.Prefix 67 } 68 case "wasb": 69 config, err := AzureBlobConfig(flags.Endpoint, spec.Bucket, "blob") 70 if err != nil { 71 return nil, nil, err 72 } 73 flags.Backend = &config 74 if config.Container != "" { 75 bucketName = config.Container 76 } else { 77 bucketName = spec.Bucket 78 } 79 if config.Prefix != "" { 80 spec.Prefix = config.Prefix 81 } 82 if spec.Prefix != "" { 83 bucketName += ":" + spec.Prefix 84 } 85 case "abfs": 86 config, err := AzureBlobConfig(flags.Endpoint, spec.Bucket, "dfs") 87 if err != nil { 88 return nil, nil, err 89 } 90 flags.Backend = &config 91 if config.Container != "" { 92 bucketName = config.Container 93 } else { 94 bucketName = spec.Bucket 95 } 96 if config.Prefix != "" { 97 spec.Prefix = config.Prefix 98 } 99 if spec.Prefix != "" { 100 bucketName += ":" + spec.Prefix 101 } 102 103 flags.Backend = &ADLv2Config{ 104 Endpoint: config.Endpoint, 105 Authorizer: &config, 106 } 107 bucketName = spec.Bucket 108 if spec.Prefix != "" { 109 bucketName += ":" + spec.Prefix 110 } 111 case "gs": 112 config := NewGCSConfig() 113 bucketName = spec.Bucket 114 flags.Backend = config 115 } 116 } 117 } 118 119 fs = NewGoofys(ctx, bucketName, flags) 120 if fs == nil { 121 err = fmt.Errorf("Mount: initialization failed") 122 return 123 } 124 server := fuseutil.NewFileSystemServer(FusePanicLogger{fs}) 125 126 mfs, err = fuse.Mount(flags.MountPoint, server, mountCfg) 127 if err != nil { 128 err = fmt.Errorf("Mount: %v", err) 129 return 130 } 131 132 if len(flags.Cache) != 0 { 133 log.Infof("Starting catfs %v", flags.Cache) 134 catfs := exec.Command("catfs", flags.Cache...) 135 lvl := logrus.InfoLevel 136 if flags.DebugFuse { 137 lvl = logrus.DebugLevel 138 catfs.Env = append(catfs.Env, "RUST_LOG=debug") 139 } else { 140 catfs.Env = append(catfs.Env, "RUST_LOG=info") 141 } 142 catfsLog := GetLogger("catfs") 143 catfsLog.Formatter.(*LogHandle).Lvl = &lvl 144 catfs.Stderr = catfsLog.Writer() 145 err = catfs.Start() 146 if err != nil { 147 err = fmt.Errorf("Failed to start catfs: %v", err) 148 149 // sleep a bit otherwise can't unmount right away 150 time.Sleep(time.Second) 151 err2 := TryUnmount(flags.MountPoint) 152 if err2 != nil { 153 err = fmt.Errorf("%v. Failed to unmount: %v", err, err2) 154 } 155 } 156 157 go func() { 158 err := catfs.Wait() 159 log.Errorf("catfs exited: %v", err) 160 161 if err != nil { 162 // if catfs terminated cleanly, it 163 // should have unmounted this, 164 // otherwise we will do it ourselves 165 err2 := TryUnmount(flags.MountPointArg) 166 if err2 != nil { 167 log.Errorf("Failed to unmount: %v", err2) 168 } 169 } 170 171 if flags.MountPointArg != flags.MountPoint { 172 err2 := TryUnmount(flags.MountPoint) 173 if err2 != nil { 174 log.Errorf("Failed to unmount: %v", err2) 175 } 176 } 177 178 if err != nil { 179 os.Exit(1) 180 } 181 }() 182 } 183 184 return 185 } 186 187 // expose Goofys related functions and types for extending and mounting elsewhere 188 var ( 189 MassageMountFlags = internal.MassageMountFlags 190 NewGoofys = internal.NewGoofys 191 TryUnmount = internal.TryUnmount 192 MyUserAndGroup = internal.MyUserAndGroup 193 ) 194 195 type ( 196 Goofys = internal.Goofys 197 )