| 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{"nosuid", "noexec", "nodev", "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 |
| } |
| } |