diff --git a/config-vm.md b/config-vm.md index ff551d317..c8cab3ed0 100644 --- a/config-vm.md +++ b/config-vm.md @@ -5,17 +5,87 @@ The virtual-machine container specification provides additional configuration fo ## Hypervisor Object -**`hypervisor`** (object, OPTIONAL) specifies details of the hypervisor that manages the container virtual machine. -* **`path`** (string, REQUIRED) path to the hypervisor binary that manages the container virtual machine. - This value MUST be an absolute path in the [runtime mount namespace](glossary.md#runtime-namespace). -* **`parameters`** (array of strings, OPTIONAL) specifies an array of parameters to pass to the hypervisor. +**`hypervisor`** (object, OPTIONAL) configures the hypervisor process. +The schema is a subset of the [`process`](config.md#process) schema with the terminal properties `terminal` and `consoleSize` removed. + +* **`cwd`** (string, REQUIRED) is the working directory that will be set for the executable. + This value MUST be an absolute path. +* **`env`** (array of strings, OPTIONAL) with the same semantics as [IEEE Std 1003.1-2008's `environ`][ieee-1003.1-2008-xbd-c8.1_2]. +* **`args`** (array of strings, REQUIRED) with similar semantics to [IEEE Std 1003.1-2008 `execvp`'s *argv*][ieee-1003.1-2008-functions-exec_2]. + This specification extends the IEEE standard in that at least one entry is REQUIRED, and that entry is used with the same semantics as `execvp`'s *file*. + +### POSIX process + +For systems that support POSIX rlimits (for example Linux and Solaris), the `hypervisor` object supports the following process-specific properties: + +* **`rlimits`** (array of objects, OPTIONAL) allows setting resource limits for the process. + Each entry has the following structure: + + * **`type`** (string, REQUIRED) the platform resource being limited. + * Linux: valid values are defined in the [`getrlimit(2)`][getrlimit.2_2] man page, such as `RLIMIT_MSGQUEUE`. + * Solaris: valid values are defined in the [`getrlimit(3)`][getrlimit.3_2] man page, such as `RLIMIT_CORE`. + + The runtime MUST [generate an error](runtime.md#errors) for any values which cannot be mapped to a relevant kernel interface. + For each entry in `rlimits`, a [`getrlimit(3)`][getrlimit.3_2] on `type` MUST succeed. + For the following properties, `rlim` refers to the status returned by the `getrlimit(3)` call. + + * **`soft`** (uint64, REQUIRED) the value of the limit enforced for the corresponding resource. + `rlim.rlim_cur` MUST match the configured value. + * **`hard`** (uint64, REQUIRED) the ceiling for the soft limit that could be set by an unprivileged process. + `rlim.rlim_max` MUST match the configured value. + Only a privileged process (e.g. one with the `CAP_SYS_RESOURCE` capability) can raise a hard limit. + + If `rlimits` contains duplicated entries with same `type`, the runtime MUST [generate an error](runtime.md#errors). + +### Linux Process + +For Linux-based systems, the `hypervisor` object supports the following process-specific properties. + +* **`apparmorProfile`** (string, OPTIONAL) specifies the name of the AppArmor profile for the process. + For more information about AppArmor, see [AppArmor documentation][apparmor_2]. +* **`capabilities`** (object, OPTIONAL) is an object containing arrays that specifies the sets of capabilities for the process. + Valid values are defined in the [capabilities(7)][capabilities.7_2] man page, such as `CAP_CHOWN`. + Any value which cannot be mapped to a relevant kernel interface MUST cause an error. + `capabilities` contains the following properties: + + * **`effective`** (array of strings, OPTIONAL) the `effective` field is an array of effective capabilities that are kept for the process. + * **`bounding`** (array of strings, OPTIONAL) the `bounding` field is an array of bounding capabilities that are kept for the process. + * **`inheritable`** (array of strings, OPTIONAL) the `inheritable` field is an array of inheritable capabilities that are kept for the process. + * **`permitted`** (array of strings, OPTIONAL) the `permitted` field is an array of permitted capabilities that are kept for the process. + * **`ambient`** (array of strings, OPTIONAL) the `ambient` field is an array of ambient capabilities that are kept for the process. +* **`noNewPrivileges`** (bool, OPTIONAL) setting `noNewPrivileges` to true prevents the process from gaining additional privileges. + As an example, the [`no_new_privs`][no-new-privs_2] article in the kernel documentation has information on how this is achieved using a `prctl` system call on Linux. +* **`oomScoreAdj`** *(int, OPTIONAL)* adjusts the oom-killer score in `[pid]/oom_score_adj` for the process's `[pid]` in a [proc pseudo-filesystem][proc_3]. + If `oomScoreAdj` is set, the runtime MUST set `oom_score_adj` to the given value. + If `oomScoreAdj` is not set, the runtime MUST NOT change the value of `oom_score_adj`. +* **`selinuxLabel`** (string, OPTIONAL) specifies the SELinux label for the process. + For more information about SELinux, see [SELinux documentation][selinux_2]. + +### User + +The user for the process is a platform-specific structure that allows specific control over which user the process runs as. + +#### POSIX-platform User + +For POSIX platforms the `user` structure has the following fields: + +* **`uid`** (int, REQUIRED) specifies the user ID in the [container namespace](glossary.md#container-namespace). +* **`gid`** (int, REQUIRED) specifies the group ID in the [container namespace](glossary.md#container-namespace). +* **`additionalGids`** (array of ints, OPTIONAL) specifies additional group IDs in the [container namespace](glossary.md#container-namespace) to be added to the process. + +_Note: symbolic name for uid and gid, such as uname and gname respectively, are left to upper levels to derive (i.e. `/etc/passwd` parsing, NSS, etc)_ + +#### Windows User + +For Windows based systems the user structure has the following fields: + +* **`username`** (string, OPTIONAL) specifies the user name for the process. ### Example ```json "hypervisor": { - "path": "/path/to/vmm", - "parameters": ["opts1=foo", "opts2=bar"] + "args": ["/path/to/vmm", "opts1=foo", "opts2=bar"] } ``` @@ -61,8 +131,18 @@ This image contains the root filesystem that the virtual machine **`kernel`** wi } ``` -[raw-image-format]: https://en.wikipedia.org/wiki/IMG_(file_format) +[apparmor_2]: https://wiki.ubuntu.com/AppArmor +[ieee-1003.1-2008-functions-exec_2]: http://pubs.opengroup.org/onlinepubs/9699919799/fu +[ieee-1003.1-2008-xbd-c8.1_2]: http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_01 +[no-new-privs_2]: https://www.kernel.org/doc/Documentation/prctl/no_new_privs.txt +[proc_3]: https://www.kernel.org/doc/Documentation/filesystems/proc.txt [qcow2-image-format]: https://git.qemu.org/?p=qemu.git;a=blob_plain;f=docs/interop/qcow2.txt;hb=HEAD +[raw-image-format]: https://en.wikipedia.org/wiki/IMG_(file_format) +[selinux_2]:http://selinuxproject.org/page/Main_Page [vdi-image-format]: https://forensicswiki.org/wiki/Virtual_Disk_Image_(VDI) -[vmdk-image-format]: http://www.vmware.com/app/vmdk/?src=vmdk [vhd-image-format]: https://github.com/libyal/libvhdi/blob/master/documentation/Virtual%20Hard%20Disk%20(VHD)%20image%20format.asciidoc +[vmdk-image-format]: http://www.vmware.com/app/vmdk/?src=vmdk + +[capabilities.7_2]: http://man7.org/linux/man-pages/man7/capabilities.7.html +[getrlimit.2_2]: http://man7.org/linux/man-pages/man2/getrlimit.2.html +[getrlimit.3_2]: http://pubs.opengroup.org/onlinepubs/9699919799/functions/getrlimit.html diff --git a/schema/config-schema.json b/schema/config-schema.json index f90bd4b7d..ec94e5627 100644 --- a/schema/config-schema.json +++ b/schema/config-schema.json @@ -48,112 +48,7 @@ } }, "process": { - "type": "object", - "required": [ - "cwd", - "args" - ], - "properties": { - "args": { - "$ref": "defs.json#/definitions/ArrayOfStrings" - }, - "consoleSize": { - "type": "object", - "required": [ - "height", - "width" - ], - "properties": { - "height": { - "$ref": "defs.json#/definitions/uint64" - }, - "width": { - "$ref": "defs.json#/definitions/uint64" - } - } - }, - "cwd": { - "type": "string" - }, - "env": { - "$ref": "defs.json#/definitions/Env" - }, - "terminal": { - "type": "boolean" - }, - "user": { - "type": "object", - "properties": { - "uid": { - "$ref": "defs.json#/definitions/UID" - }, - "gid": { - "$ref": "defs.json#/definitions/GID" - }, - "additionalGids": { - "$ref": "defs.json#/definitions/ArrayOfGIDs" - }, - "username": { - "type": "string" - } - } - }, - "capabilities": { - "type": "object", - "properties": { - "bounding": { - "$ref": "defs.json#/definitions/ArrayOfStrings" - }, - "permitted": { - "$ref": "defs.json#/definitions/ArrayOfStrings" - }, - "effective": { - "$ref": "defs.json#/definitions/ArrayOfStrings" - }, - "inheritable": { - "$ref": "defs.json#/definitions/ArrayOfStrings" - }, - "ambient": { - "$ref": "defs.json#/definitions/ArrayOfStrings" - } - } - }, - "apparmorProfile": { - "type": "string" - }, - "oomScoreAdj": { - "type": "integer" - }, - "selinuxLabel": { - "type": "string" - }, - "noNewPrivileges": { - "type": "boolean" - }, - "rlimits": { - "type": "array", - "items": { - "type": "object", - "required": [ - "type", - "soft", - "hard" - ], - "properties": { - "hard": { - "$ref": "defs.json#/definitions/uint64" - }, - "soft": { - "$ref": "defs.json#/definitions/uint64" - }, - "type": { - "type": "string", - "pattern": "^RLIMIT_[A-Z]+$" - } - } - } - } - } + "$ref": "defs.json#/definitions/Process" }, "linux": { "$ref": "config-linux.json#/linux" diff --git a/schema/config-vm.json b/schema/config-vm.json index 6b1fb4baf..9baf73f13 100644 --- a/schema/config-vm.json +++ b/schema/config-vm.json @@ -8,18 +8,7 @@ "properties": { "hypervisor": { "description": "hypervisor config used by VM-based containers", - "type": "object", - "required": [ - "path" - ], - "properties": { - "path": { - "$ref": "defs.json#/definitions/FilePath" - }, - "parameters": { - "$ref": "defs.json#/definitions/ArrayOfStrings" - } - } + "$ref": "defs.json#/definitions/Process" }, "kernel": { "description": "kernel config used by VM-based containers", diff --git a/schema/defs.json b/schema/defs.json index c1533aede..fe0a0287a 100644 --- a/schema/defs.json +++ b/schema/defs.json @@ -78,6 +78,114 @@ "Env": { "$ref": "#/definitions/ArrayOfStrings" }, + "Process": { + "type": "object", + "required": [ + "cwd", + "args" + ], + "properties": { + "args": { + "$ref": "defs.json#/definitions/ArrayOfStrings" + }, + "consoleSize": { + "type": "object", + "required": [ + "height", + "width" + ], + "properties": { + "height": { + "$ref": "defs.json#/definitions/uint64" + }, + "width": { + "$ref": "defs.json#/definitions/uint64" + } + } + }, + "cwd": { + "type": "string" + }, + "env": { + "$ref": "defs.json#/definitions/Env" + }, + "terminal": { + "type": "boolean" + }, + "user": { + "type": "object", + "properties": { + "uid": { + "$ref": "defs.json#/definitions/UID" + }, + "gid": { + "$ref": "defs.json#/definitions/GID" + }, + "additionalGids": { + "$ref": "defs.json#/definitions/ArrayOfGIDs" + }, + "username": { + "type": "string" + } + } + }, + "capabilities": { + "type": "object", + "properties": { + "bounding": { + "$ref": "defs.json#/definitions/ArrayOfStrings" + }, + "permitted": { + "$ref": "defs.json#/definitions/ArrayOfStrings" + }, + "effective": { + "$ref": "defs.json#/definitions/ArrayOfStrings" + }, + "inheritable": { + "$ref": "defs.json#/definitions/ArrayOfStrings" + }, + "ambient": { + "$ref": "defs.json#/definitions/ArrayOfStrings" + } + } + }, + "apparmorProfile": { + "type": "string" + }, + "oomScoreAdj": { + "type": "integer" + }, + "selinuxLabel": { + "type": "string" + }, + "noNewPrivileges": { + "type": "boolean" + }, + "rlimits": { + "type": "array", + "items": { + "type": "object", + "required": [ + "type", + "soft", + "hard" + ], + "properties": { + "hard": { + "$ref": "defs.json#/definitions/uint64" + }, + "soft": { + "$ref": "defs.json#/definitions/uint64" + }, + "type": { + "type": "string", + "pattern": "^RLIMIT_[A-Z]+$" + } + } + } + } + } + }, "Hook": { "type": "object", "properties": { diff --git a/specs-go/config.go b/specs-go/config.go index c9e848db6..99f4c6df8 100644 --- a/specs-go/config.go +++ b/specs-go/config.go @@ -58,6 +58,31 @@ type Process struct { SelinuxLabel string `json:"selinuxLabel,omitempty" platform:"linux"` } +// HypervisorProcess is like Process, except for launching the hypervisor instead of for launching a container process. +type Process struct { + // User specifies user information for the process. + User User `json:"user"` + // Args specifies the binary and arguments for the application to execute. + Args []string `json:"args"` + // Env populates the process environment for the process. + Env []string `json:"env,omitempty"` + // Cwd is the current working directory for the process and must be + // relative to the container's root. + Cwd string `json:"cwd"` + // Capabilities are Linux capabilities that are kept for the process. + Capabilities *LinuxCapabilities `json:"capabilities,omitempty" platform:"linux"` + // Rlimits specifies rlimit options to apply to the process. + Rlimits []POSIXRlimit `json:"rlimits,omitempty" platform:"linux,solaris"` + // NoNewPrivileges controls whether additional privileges could be gained by processes in the container. + NoNewPrivileges bool `json:"noNewPrivileges,omitempty" platform:"linux"` + // ApparmorProfile specifies the apparmor profile for the container. + ApparmorProfile string `json:"apparmorProfile,omitempty" platform:"linux"` + // Specify an oom_score_adj for the container. + OOMScoreAdj *int `json:"oomScoreAdj,omitempty" platform:"linux"` + // SelinuxLabel specifies the selinux context that the container process is run as. + SelinuxLabel string `json:"selinuxLabel,omitempty" platform:"linux"` +} + // LinuxCapabilities specifies the whitelist of capabilities that are kept for a process. // http://man7.org/linux/man-pages/man7/capabilities.7.html type LinuxCapabilities struct { @@ -504,21 +529,13 @@ type WindowsHyperV struct { // VM contains information for virtual-machine-based containers. type VM struct { // Hypervisor specifies hypervisor-related configuration for virtual-machine-based containers. - Hypervisor VMHypervisor `json:"hypervisor,omitempty"` + Hypervisor *HypervisorProcess `json:"hypervisor,omitempty"` // Kernel specifies kernel-related configuration for virtual-machine-based containers. Kernel VMKernel `json:"kernel"` // Image specifies guest image related configuration for virtual-machine-based containers. Image VMImage `json:"image,omitempty"` } -// VMHypervisor contains information about the hypervisor to use for a virtual machine. -type VMHypervisor struct { - // Path is the host path to the hypervisor used to manage the virtual machine. - Path string `json:"path"` - // Parameters specifies parameters to pass to the hypervisor. - Parameters string `json:"parameters,omitempty"` -} - // VMKernel contains information about the kernel to use for a virtual machine. type VMKernel struct { // Path is the host path to the kernel used to boot the virtual machine.