diff --git a/README.md b/README.md index b36999a42..fa4f23795 100644 --- a/README.md +++ b/README.md @@ -63,39 +63,7 @@ user named `daemon` defined within that file-system. "path": "rootfs", "readonly": true }, - "cpus": 1.1, - "memory": 1024, "hostname": "shell", - "namespaces": [ - { - "type": "process" - }, - { - "type": "network" - }, - { - "type": "mount" - }, - { - "type": "ipc" - }, - { - "type": "uts" - } - ], - "capabilities": [ - "AUDIT_WRITE", - "KILL", - "NET_BIND_SERVICE" - ], - "devices": [ - "null", - "random", - "full", - "tty", - "zero", - "urandom" - ], "mounts": [ { "type": "proc", diff --git a/restore.go b/restore.go index e604895f8..ff3acd0ad 100644 --- a/restore.go +++ b/restore.go @@ -44,7 +44,7 @@ var restoreCommand = cli.Command{ }, } -func restoreContainer(context *cli.Context, spec *LinuxSpec, config *configs.Config, imagePath string) (code int, err error) { +func restoreContainer(context *cli.Context, spec *Spec, config *configs.Config, imagePath string) (code int, err error) { rootuid := 0 factory, err := loadFactory(context) if err != nil { diff --git a/run.go b/run.go index 9fbb01eda..14ffc606c 100644 --- a/run.go +++ b/run.go @@ -9,7 +9,7 @@ import ( "github.com/opencontainers/runc/libcontainer" ) -func execContainer(context *cli.Context, spec *LinuxSpec) (int, error) { +func execContainer(context *cli.Context, spec *Spec) (int, error) { if len(spec.Processes) != 1 { return -1, fmt.Errorf("runc only supports one(1) process for the container") } diff --git a/spec.go b/spec.go index 5fc241158..78cc44b36 100644 --- a/spec.go +++ b/spec.go @@ -36,18 +36,13 @@ type Namespace struct { } type PortableSpec struct { - Version string `json:"version"` - OS string `json:"os"` - Arch string `json:"arch"` - Processes []*Process `json:"processes"` - Root Root `json:"root"` - Cpus float64 `json:"cpus"` // in 1.1 for 110% cpus - Memory int64 `json:"memory"` // in mb; 1024m - Hostname string `json:"hostname"` - Namespaces []Namespace `json:"namespaces"` - Capabilities []string `json:"capabilities"` - Devices []string `json:"devices"` - Mounts []Mount `json:"mounts"` + Version string `json:"version"` + OS string `json:"os"` + Arch string `json:"arch"` + Processes []*Process `json:"processes"` + Root Root `json:"root"` + Hostname string `json:"hostname"` + Mounts []Mount `json:"mounts"` } var specCommand = cli.Command{ @@ -75,29 +70,7 @@ var specCommand = cli.Command{ }, }, }, - Cpus: 1.1, - Memory: 1024, Hostname: "shell", - Capabilities: []string{ - "AUDIT_WRITE", - "KILL", - "NET_BIND_SERVICE", - }, - Devices: []string{ - "null", - "random", - "full", - "tty", - "zero", - "urandom", - }, - Namespaces: []Namespace{ - {Type: "process"}, - {Type: "network"}, - {Type: "mount"}, - {Type: "ipc"}, - {Type: "uts"}, - }, Mounts: []Mount{ { Type: "proc", diff --git a/spec_linux.go b/spec_linux.go index 34d157038..917d68094 100644 --- a/spec_linux.go +++ b/spec_linux.go @@ -15,6 +15,21 @@ import ( "github.com/opencontainers/runc/libcontainer/devices" ) +type Spec struct { + PortableSpec + Linux Linux `json:"linux"` +} + +type Linux struct { + UserMapping map[string]UserMapping `json:"userMapping"` + Rlimits []Rlimit `json:"rlimits"` + SystemProperties map[string]string `json:"systemProperties"` + Resources *Resources `json:"resources"` + Namespaces []Namespace `json:"namespaces"` + Capabilities []string `json:"capabilities"` + Devices []string `json:"devices"` +} + type UserMapping struct { From int `json:"from"` To int `json:"to"` @@ -38,6 +53,8 @@ type IfPrioMap struct { } type Resources struct { + // Memory limit (in bytes) + MemoryLimit int64 `json:"memoryLimit"` // Memory reservation or soft_limit (in bytes) MemoryReservation int64 `json:"memoryReservation"` // Total memory usage (memory + swap); set `-1' to disable swap @@ -80,14 +97,6 @@ type Resources struct { NetClsClassid string `json:"netClsClassid"` } -type LinuxSpec struct { - PortableSpec - UserMapping map[string]UserMapping `json:"userMapping"` - Rlimits []Rlimit `json:"rlimits"` - SystemProperties map[string]string `json:"systemProperties"` - Resources *Resources `json:"resources"` -} - var namespaceMapping = map[string]configs.NamespaceType{ "process": configs.NEWPID, "network": configs.NEWNET, @@ -99,7 +108,7 @@ var namespaceMapping = map[string]configs.NamespaceType{ // loadSpec loads the specification from the provided path. // If the path is empty then the default path will be "container.json" -func loadSpec(path string) (*LinuxSpec, error) { +func loadSpec(path string) (*Spec, error) { if path == "" { path = "container.json" } @@ -111,14 +120,14 @@ func loadSpec(path string) (*LinuxSpec, error) { return nil, err } defer f.Close() - var s *LinuxSpec + var s *Spec if err := json.NewDecoder(f).Decode(&s); err != nil { return nil, err } return s, nil } -func createLibcontainerConfig(spec *LinuxSpec) (*configs.Config, error) { +func createLibcontainerConfig(spec *Spec) (*configs.Config, error) { cwd, err := os.Getwd() if err != nil { return nil, err @@ -128,13 +137,13 @@ func createLibcontainerConfig(spec *LinuxSpec) (*configs.Config, error) { rootfsPath = filepath.Join(cwd, rootfsPath) } config := &configs.Config{ - Capabilities: spec.Capabilities, Rootfs: rootfsPath, + Capabilities: spec.Linux.Capabilities, Readonlyfs: spec.Root.Readonly, Hostname: spec.Hostname, Privatefs: true, } - for _, ns := range spec.Namespaces { + for _, ns := range spec.Linux.Namespaces { t, exists := namespaceMapping[ns.Type] if !exists { return nil, fmt.Errorf("namespace %q does not exist", ns) @@ -184,7 +193,7 @@ func createLibcontainerMount(cwd string, m Mount) *configs.Mount { } } -func createCgroupConfig(spec *LinuxSpec, devices []*configs.Device) (*configs.Cgroup, error) { +func createCgroupConfig(spec *Spec, devices []*configs.Device) (*configs.Cgroup, error) { myCgroupPath, err := cgroups.GetThisCgroupDir("devices") if err != nil { return nil, err @@ -193,12 +202,10 @@ func createCgroupConfig(spec *LinuxSpec, devices []*configs.Device) (*configs.Cg Name: getDefaultID(), Parent: myCgroupPath, AllowedDevices: append(devices, allowedDevices...), - CpuQuota: getCPUQuota(spec.Cpus), - Memory: spec.Memory * 1024 * 1024, MemorySwap: -1, MemorySwappiness: -1, } - if r := spec.Resources; r != nil { + if r := spec.Linux.Resources; r != nil { c.MemoryReservation = r.MemoryReservation c.MemorySwap = r.MemorySwap c.KernelMemory = r.KernelMemory @@ -233,8 +240,8 @@ func createCgroupConfig(spec *LinuxSpec, devices []*configs.Device) (*configs.Cg return c, nil } -func createDevices(spec *LinuxSpec, config *configs.Config) error { - for _, name := range spec.Devices { +func createDevices(spec *Spec, config *configs.Config) error { + for _, name := range spec.Linux.Devices { d, err := devices.DeviceFromPath(filepath.Join("/dev", name), "rwm") if err != nil { return err @@ -256,13 +263,13 @@ func getCPUQuota(cpus float64) int64 { return int64(cpus * cpuQuotaMultiplyer) } -func setupUserNamespace(spec *LinuxSpec, config *configs.Config) error { - if len(spec.UserMapping) == 0 { +func setupUserNamespace(spec *Spec, config *configs.Config) error { + if len(spec.Linux.UserMapping) == 0 { return nil } config.Namespaces.Add(configs.NEWUSER, "") mappings := make(map[string][]configs.IDMap) - for k, v := range spec.UserMapping { + for k, v := range spec.Linux.UserMapping { mappings[k] = append(mappings[k], configs.IDMap{ ContainerID: v.From, HostID: v.To,