github.com/pachyderm/pachyderm@v1.13.4/src/server/pfs/fuse/fuse.go (about) 1 package fuse 2 3 import ( 4 "io/ioutil" 5 "os" 6 "os/signal" 7 pathpkg "path" 8 "path/filepath" 9 "strings" 10 11 "github.com/hanwen/go-fuse/v2/fs" 12 13 "github.com/pachyderm/pachyderm/src/client" 14 "github.com/pachyderm/pachyderm/src/client/pkg/errors" 15 "github.com/pachyderm/pachyderm/src/server/pkg/progress" 16 "github.com/pachyderm/pachyderm/src/server/pkg/uuid" 17 ) 18 19 // Mount pfs to target, opts may be left nil. 20 func Mount(c *client.APIClient, target string, opts *Options) (retErr error) { 21 if err := opts.validate(c); err != nil { 22 return err 23 } 24 commits := make(map[string]string) 25 for repo, branch := range opts.getBranches() { 26 if uuid.IsUUIDWithoutDashes(branch) { 27 commits[repo] = branch 28 } 29 } 30 rootDir, err := ioutil.TempDir("", "pfs") 31 if err != nil { 32 return errors.WithStack(err) 33 } 34 defer func() { 35 if err := os.RemoveAll(rootDir); err != nil && retErr == nil { 36 retErr = errors.WithStack(err) 37 } 38 }() 39 root, err := newLoopbackRoot(rootDir, target, c, opts) 40 if err != nil { 41 return err 42 } 43 server, err := fs.Mount(target, root, opts.getFuse()) 44 if err != nil { 45 return errors.WithStack(err) 46 } 47 sigChan := make(chan os.Signal, 1) 48 signal.Notify(sigChan, os.Interrupt) 49 go func() { 50 select { 51 case <-sigChan: 52 case <-opts.getUnmount(): 53 } 54 server.Unmount() 55 }() 56 server.Serve() 57 pfcs := make(map[string]client.PutFileClient) 58 pfc := func(repo string) (client.PutFileClient, error) { 59 if pfc, ok := pfcs[repo]; ok { 60 return pfc, nil 61 } 62 pfc, err := c.NewPutFileClient() 63 if err != nil { 64 return nil, err 65 } 66 pfcs[repo] = pfc 67 return pfc, nil 68 } 69 defer func() { 70 for _, pfc := range pfcs { 71 if err := pfc.Close(); err != nil && retErr == nil { 72 retErr = err 73 } 74 } 75 }() 76 for path, state := range root.files { 77 if state != dirty { 78 continue 79 } 80 parts := strings.Split(path, "/") 81 pfc, err := pfc(parts[0]) 82 if err != nil { 83 return err 84 } 85 if err := func() (retErr error) { 86 f, err := progress.Open(filepath.Join(root.rootPath, path)) 87 if err != nil { 88 if errors.Is(err, os.ErrNotExist) { 89 return pfc.DeleteFile(parts[0], root.branch(parts[0]), pathpkg.Join(parts[1:]...)) 90 } 91 return errors.WithStack(err) 92 } 93 defer func() { 94 if err := f.Close(); err != nil && retErr == nil { 95 retErr = errors.WithStack(err) 96 } 97 }() 98 if _, err := pfc.PutFileOverwrite(parts[0], root.branch(parts[0]), 99 pathpkg.Join(parts[1:]...), f, 0); err != nil { 100 return err 101 } 102 return nil 103 }(); err != nil { 104 return err 105 } 106 } 107 return nil 108 }