localmounter_unix.go 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. //go:build !windows
  2. // +build !windows
  3. package snapshot
  4. import (
  5. "io/ioutil"
  6. "os"
  7. "syscall"
  8. "github.com/containerd/containerd/mount"
  9. "github.com/pkg/errors"
  10. )
  11. func (lm *localMounter) Mount() (string, error) {
  12. lm.mu.Lock()
  13. defer lm.mu.Unlock()
  14. if lm.mounts == nil && lm.mountable != nil {
  15. mounts, release, err := lm.mountable.Mount()
  16. if err != nil {
  17. return "", err
  18. }
  19. lm.mounts = mounts
  20. lm.release = release
  21. }
  22. if len(lm.mounts) == 1 && (lm.mounts[0].Type == "bind" || lm.mounts[0].Type == "rbind") {
  23. ro := false
  24. for _, opt := range lm.mounts[0].Options {
  25. if opt == "ro" {
  26. ro = true
  27. break
  28. }
  29. }
  30. if !ro {
  31. return lm.mounts[0].Source, nil
  32. }
  33. }
  34. dir, err := ioutil.TempDir("", "buildkit-mount")
  35. if err != nil {
  36. return "", errors.Wrap(err, "failed to create temp dir")
  37. }
  38. if err := mount.All(lm.mounts, dir); err != nil {
  39. os.RemoveAll(dir)
  40. return "", errors.Wrapf(err, "failed to mount %s: %+v", dir, lm.mounts)
  41. }
  42. lm.target = dir
  43. return dir, nil
  44. }
  45. func (lm *localMounter) Unmount() error {
  46. lm.mu.Lock()
  47. defer lm.mu.Unlock()
  48. if lm.target != "" {
  49. if err := mount.Unmount(lm.target, syscall.MNT_DETACH); err != nil {
  50. return err
  51. }
  52. os.RemoveAll(lm.target)
  53. lm.target = ""
  54. }
  55. if lm.release != nil {
  56. return lm.release()
  57. }
  58. return nil
  59. }