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