package env import ( "fmt" "io/ioutil" "path" "github.com/criyle/go-sandbox/pkg/mount" "gopkg.in/yaml.v2" ) // Mount defines single mount point configuration. // type could be bind / tmpfs type Mount struct { Type string `yaml:"type"` Source string `yaml:"source"` Target string `yaml:"target"` Readonly bool `yaml:"readonly"` Data string `yaml:"data"` } // Mounts defines mount points for the container. type Mounts struct { Mount []Mount `yaml:"mount"` Proc bool `yaml:"proc"` } func parseMountConfig(p string) (*mount.Builder, error) { var m Mounts d, err := ioutil.ReadFile(p) if err != nil { return nil, err } if err := yaml.Unmarshal(d, &m); err != nil { return nil, err } b := mount.NewBuilder() for _, mt := range m.Mount { target := mt.Target if path.IsAbs(target) { target = path.Clean(target[1:]) } switch mt.Type { case "bind": b.WithBind(mt.Source, target, mt.Readonly) case "tmpfs": b.WithTmpfs(target, mt.Data) default: return nil, fmt.Errorf("Invalid mount type") } } if m.Proc { b.WithProc() } return b, nil } func getDefaultMount(tmpFsConf string) *mount.Builder { return mount.NewBuilder(). // basic exec and lib WithBind("/bin", "bin", true). WithBind("/lib", "lib", true). WithBind("/lib64", "lib64", true). WithBind("/usr", "usr", true). // java wants /proc/self/exe as it need relative path for lib // however, /proc gives interface like /proc/1/fd/3 .. // it is fine since open that file will be a EPERM // changing the fs uid and gid would be a good idea WithProc(). // some compiler have multiple version WithBind("/etc/alternatives", "etc/alternatives", true). // fpc wants /etc/fpc.cfg WithBind("/etc/fpc.cfg", "etc/fpc.cfg", true). // go wants /dev/null WithBind("/dev/null", "dev/null", false). // ghc wants /var/lib/ghc WithBind("/var/lib/ghc", "var/lib/ghc", true). // javaScript wants /dev/urandom WithBind("/dev/urandom", "dev/urandom", true). // work dir WithTmpfs("w", tmpFsConf). // tmp dir WithTmpfs("tmp", tmpFsConf) }