package oci import ( "context" "path/filepath" "strings" specs "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" ) // MountOpts sets oci spec specific info for mount points type MountOpts func([]specs.Mount) ([]specs.Mount, error) //GetMounts returns default required for buildkit // https://github.com/moby/buildkit/issues/429 func GetMounts(ctx context.Context, mountOpts ...MountOpts) ([]specs.Mount, error) { mounts := []specs.Mount{ { Destination: "/proc", Type: "proc", Source: "proc", }, { Destination: "/dev", Type: "tmpfs", Source: "tmpfs", Options: []string{"nosuid", "strictatime", "mode=755", "size=65536k"}, }, { Destination: "/dev/pts", Type: "devpts", Source: "devpts", Options: []string{"nosuid", "noexec", "newinstance", "ptmxmode=0666", "mode=0620", "gid=5"}, }, { Destination: "/dev/shm", Type: "tmpfs", Source: "shm", Options: []string{"nosuid", "noexec", "nodev", "mode=1777", "size=65536k"}, }, { Destination: "/dev/mqueue", Type: "mqueue", Source: "mqueue", Options: []string{"nosuid", "noexec", "nodev"}, }, { Destination: "/sys", Type: "sysfs", Source: "sysfs", Options: []string{"nosuid", "noexec", "nodev", "ro"}, }, } var err error for _, o := range mountOpts { mounts, err = o(mounts) if err != nil { return nil, err } } return mounts, nil } func withROBind(src, dest string) func(m []specs.Mount) ([]specs.Mount, error) { return func(m []specs.Mount) ([]specs.Mount, error) { m = append(m, specs.Mount{ Destination: dest, Type: "bind", Source: src, Options: []string{"rbind", "ro"}, }) return m, nil } } func hasPrefix(p, prefixDir string) bool { prefixDir = filepath.Clean(prefixDir) if prefixDir == "/" { return true } p = filepath.Clean(p) return p == prefixDir || strings.HasPrefix(p, prefixDir+"/") } func removeMountsWithPrefix(mounts []specs.Mount, prefixDir string) []specs.Mount { var ret []specs.Mount for _, m := range mounts { if !hasPrefix(m.Destination, prefixDir) { ret = append(ret, m) } } return ret } func withProcessMode(processMode ProcessMode) func([]specs.Mount) ([]specs.Mount, error) { return func(m []specs.Mount) ([]specs.Mount, error) { switch processMode { case ProcessSandbox: // keep the default case NoProcessSandbox: m = removeMountsWithPrefix(m, "/proc") procMount := specs.Mount{ Destination: "/proc", Type: "bind", Source: "/proc", // NOTE: "rbind"+"ro" does not make /proc read-only recursively. // So we keep maskedPath and readonlyPaths (although not mandatory for rootless mode) Options: []string{"rbind"}, } m = append([]specs.Mount{procMount}, m...) default: return nil, errors.Errorf("unknown process mode: %v", processMode) } return m, nil } }