1
0
Fork 0
mirror of https://github.com/containers/youki synced 2024-05-09 17:16:16 +02:00

Merge pull request #202 from utam0k/improvement/change-to-use-oci-spec-rs

Reflected that oci_spec has been moved to a separate repository
This commit is contained in:
utam0k 2021-08-17 21:53:14 +09:00 committed by GitHub
commit befc5c0ded
Signed by: GitHub
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 8 additions and 2289 deletions

1
Cargo.lock generated
View File

@ -580,6 +580,7 @@ dependencies = [
[[package]]
name = "oci_spec"
version = "0.1.0"
source = "git+https://github.com/containers/oci-spec-rs?rev=e0de21b89dc1e65f69a5f45a08bbe426787c7fa1#e0de21b89dc1e65f69a5f45a08bbe426787c7fa1"
dependencies = [
"anyhow",
"caps",

View File

@ -29,7 +29,7 @@ mio = { version = "0.7.13", features = ["os-ext", "os-poll"] }
chrono = { version="0.4", features = ["serde"] }
once_cell = "1.6.0"
futures = { version = "0.3", features = ["thread-pool"] }
oci_spec = { version = "0.1.0", path = "./oci_spec" }
oci_spec = { git = "https://github.com/containers/oci-spec-rs", rev = "e0de21b89dc1e65f69a5f45a08bbe426787c7fa1"}
cgroups = { version = "0.1.0", path = "./cgroups" }
systemd = { version = "0.8", default-features = false, optional = true }
dbus = "0.9.2"
@ -38,7 +38,7 @@ fastrand = "1.4.1"
crossbeam-channel = "0.5"
[dev-dependencies]
oci_spec = { version = "0.1.0", path = "./oci_spec", features = ["proptests"] }
oci_spec = { git = "https://github.com/containers/oci-spec-rs", rev = "e0de21b89dc1e65f69a5f45a08bbe426787c7fa1", features = ["proptests"]}
quickcheck = "1"
serial_test = "0.5.1"

3
cgroups/Cargo.lock generated
View File

@ -1,5 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "adler"
version = "1.0.2"
@ -332,6 +334,7 @@ dependencies = [
[[package]]
name = "oci_spec"
version = "0.1.0"
source = "git+https://github.com/containers/oci-spec-rs?rev=e0de21b89dc1e65f69a5f45a08bbe426787c7fa1#e0de21b89dc1e65f69a5f45a08bbe426787c7fa1"
dependencies = [
"anyhow",
"caps",

View File

@ -12,11 +12,11 @@ nix = "0.22.0"
procfs = "0.9.1"
log = "0.4"
anyhow = "1.0"
oci_spec = { version = "0.1.0", path = "../oci_spec" }
oci_spec = { git = "https://github.com/containers/oci-spec-rs", rev = "e0de21b89dc1e65f69a5f45a08bbe426787c7fa1"}
systemd = { version = "0.8", default-features = false, optional = true }
dbus = "0.9.2"
serde = { version = "1.0", features = ["derive"] }
[dev-dependencies]
oci_spec = { version = "0.1.0", path = "../oci_spec", features = ["proptests"] }
oci_spec = { git = "https://github.com/containers/oci-spec-rs", rev = "e0de21b89dc1e65f69a5f45a08bbe426787c7fa1", features = ["proptests"]}
quickcheck = "1"

1
oci_spec/.gitignore vendored
View File

@ -1 +0,0 @@
/target

389
oci_spec/Cargo.lock generated
View File

@ -1,389 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "aho-corasick"
version = "0.7.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
dependencies = [
"memchr",
]
[[package]]
name = "anyhow"
version = "1.0.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "595d3cfa7a60d4555cb5067b99f07142a08ea778de5cf993f7b75c7d8fabc486"
[[package]]
name = "autocfg"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "bitflags"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "caps"
version = "0.5.3-alpha.0"
source = "git+https://github.com/lucab/caps-rs?rev=cb54844#cb54844125d9dd6de51d6c8c8a951aefbd0d3904"
dependencies = [
"errno",
"libc",
"serde",
"thiserror",
]
[[package]]
name = "cc"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "env_logger"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3"
dependencies = [
"log",
"regex",
]
[[package]]
name = "errno"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa68f2fb9cae9d37c9b2b3584aba698a2e97f72d7aef7b9f7aa71d8b54ce46fe"
dependencies = [
"errno-dragonfly",
"libc",
"winapi",
]
[[package]]
name = "errno-dragonfly"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14ca354e36190500e1e1fb267c647932382b54053c50b14970856c0b00a35067"
dependencies = [
"gcc",
"libc",
]
[[package]]
name = "gcc"
version = "0.3.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
[[package]]
name = "getrandom"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "itoa"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
[[package]]
name = "libc"
version = "0.2.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
[[package]]
name = "log"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
dependencies = [
"cfg-if",
]
[[package]]
name = "memchr"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
[[package]]
name = "memoffset"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9"
dependencies = [
"autocfg",
]
[[package]]
name = "nix"
version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1e25ee6b412c2a1e3fcb6a4499a5c1bfe7f43e014bdce9a6b6666e5aa2d187"
dependencies = [
"bitflags",
"cc",
"cfg-if",
"libc",
"memoffset",
]
[[package]]
name = "oci_spec"
version = "0.1.0"
dependencies = [
"anyhow",
"caps",
"nix",
"quickcheck",
"serde",
"serde_json",
"tempfile",
]
[[package]]
name = "ppv-lite86"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
[[package]]
name = "proc-macro2"
version = "1.0.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quickcheck"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "588f6378e4dd99458b60ec275b4477add41ce4fa9f64dcba6f15adccb19b50d6"
dependencies = [
"env_logger",
"log",
"rand",
]
[[package]]
name = "quote"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
"rand_hc",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
dependencies = [
"getrandom",
]
[[package]]
name = "rand_hc"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
dependencies = [
"rand_core",
]
[[package]]
name = "redox_syscall"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ab49abadf3f9e1c4bc499e8845e152ad87d2ad2d30371841171169e9d75feee"
dependencies = [
"bitflags",
]
[[package]]
name = "regex"
version = "1.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.6.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
[[package]]
name = "remove_dir_all"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
dependencies = [
"winapi",
]
[[package]]
name = "ryu"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
[[package]]
name = "serde"
version = "1.0.127"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.127"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a024926d3432516606328597e0f224a51355a493b49fdd67e9209187cbe55ecc"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127"
dependencies = [
"itoa",
"ryu",
"serde",
]
[[package]]
name = "syn"
version = "1.0.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "tempfile"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22"
dependencies = [
"cfg-if",
"libc",
"rand",
"redox_syscall",
"remove_dir_all",
"winapi",
]
[[package]]
name = "thiserror"
version = "1.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "unicode-xid"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

View File

@ -1,18 +0,0 @@
[package]
name = "oci_spec"
version = "0.1.0"
edition = "2018"
[features]
default = []
proptests = ["quickcheck"]
[dependencies]
serde = { version = "1.0", features = ["derive"] }
nix = "0.22.0"
anyhow = "1.0"
serde_json = "1.0"
# Waiting for new caps release, replace git with version on release
caps = { git = "https://github.com/lucab/caps-rs", rev = "cb54844", features = ["serde_support"] }
quickcheck = { version = "1", optional = true }
tempfile = "3"

View File

@ -1,75 +0,0 @@
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
/// Hooks specifies a command that is run in the container at a particular event in the lifecycle
/// (setup and teardown) of a container.
pub struct Hooks {
#[deprecated(
note = "Prestart hooks were deprecated in favor of `createRuntime`, `createContainer` and `startContainer` hooks"
)]
#[serde(default, skip_serializing_if = "Option::is_none")]
/// The `prestart` hooks MUST be called after the `start` operation is called but before the
/// user-specified program command is executed.
///
/// On Linux, for example, they are called after the container namespaces are created, so they
/// provide an opportunity to customize the container (e.g. the network namespace could be
/// specified in this hook).
///
/// The `prestart` hooks' path MUST resolve in the runtime namespace.
/// The `prestart` hooks MUST be executed in the runtime namespace.
pub prestart: Option<Vec<Hook>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// CreateRuntime is a list of hooks to be run after the container has been created but before
/// `pivot_root` or any equivalent operation has been called. It is called in the Runtime
/// Namespace.
pub create_runtime: Option<Vec<Hook>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// CreateContainer is a list of hooks to be run after the container has been created but
/// before `pivot_root` or any equivalent operation has been called. It is called in the
/// Container Namespace.
pub create_container: Option<Vec<Hook>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// StartContainer is a list of hooks to be run after the start operation is called but before
/// the container process is started. It is called in the Container Namespace.
pub start_container: Option<Vec<Hook>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Poststart is a list of hooks to be run after the container process is started. It is called
/// in the Runtime Namespace.
pub poststart: Option<Vec<Hook>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Poststop is a list of hooks to be run after the container process exits. It is called in
/// the Runtime Namespace.
pub poststop: Option<Vec<Hook>>,
}
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
/// Hook specifies a command that is run at a particular event in the lifecycle of a container.
pub struct Hook {
/// Path to the binary to be executed. Following similar semantics to [IEEE Std 1003.1-2008
/// `execv`'s path](https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html). This
/// specification extends the IEEE standard in that path MUST be absolute.
pub path: PathBuf,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Arguments used for the binary, including the binary name itself. Following the same
/// semantics as [IEEE Std 1003.1-2008 `execv`'s
/// argv](https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html).
pub args: Option<Vec<String>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Additional `key=value` environment variables. Following the same semantics as [IEEE Std
/// 1003.1-2008's `environ`](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_01).
pub env: Option<Vec<String>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Timeout is the number of seconds before aborting the hook. If set, timeout MUST be greater
/// than zero.
pub timeout: Option<i64>,
}

View File

@ -1,255 +0,0 @@
use anyhow::{Context, Result};
use serde::{Deserialize, Serialize};
use std::{
collections::HashMap,
fs,
path::{Path, PathBuf},
};
mod hooks;
mod linux;
mod miscellaneous;
mod process;
mod solaris;
mod test;
mod vm;
mod windows;
// re-export for ease of use
pub use hooks::*;
pub use linux::*;
pub use miscellaneous::*;
pub use process::*;
pub use solaris::*;
pub use vm::*;
pub use windows::*;
/// Base configuration for the container.
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct Spec {
#[serde(default, rename = "ociVersion")]
/// MUST be in SemVer v2.0.0 format and specifies the version of the Open Container Initiative
/// Runtime Specification with which the bundle complies. The Open Container Initiative
/// Runtime Specification follows semantic versioning and retains forward and backward
/// compatibility within major versions. For example, if a configuration is compliant with
/// version 1.1 of this specification, it is compatible with all runtimes that support any 1.1
/// or later release of this specification, but is not compatible with a runtime that supports
/// 1.0 and not 1.1.
pub version: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Specifies the container's root filesystem. On Windows, for Windows Server Containers, this
/// field is REQUIRED. For Hyper-V Containers, this field MUST NOT be set.
///
/// On all other platforms, this field is REQUIRED.
pub root: Option<Root>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Specifies additional mounts beyond `root`. The runtime MUST mount entries in the listed
/// order.
///
/// For Linux, the parameters are as documented in
/// [`mount(2)`](http://man7.org/linux/man-pages/man2/mount.2.html) system call man page. For
/// Solaris, the mount entry corresponds to the 'fs' resource in the
/// [`zonecfg(1M)`](http://docs.oracle.com/cd/E86824_01/html/E54764/zonecfg-1m.html) man page.
pub mounts: Option<Vec<Mount>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Specifies the container process. This property is REQUIRED when
/// [`start`](https://github.com/opencontainers/runtime-spec/blob/master/runtime.md#start) is
/// called.
pub process: Option<Process>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Specifies the container's hostname as seen by processes running inside the container. On
/// Linux, for example, this will change the hostname in the container [UTS
/// namespace](http://man7.org/linux/man-pages/man7/namespaces.7.html). Depending on your
/// [namespace
/// configuration](https://github.com/opencontainers/runtime-spec/blob/master/config-linux.md#namespaces),
/// the container UTS namespace may be the runtime UTS namespace.
pub hostname: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Hooks allow users to specify programs to run before or after various lifecycle events.
/// Hooks MUST be called in the listed order. The state of the container MUST be passed to
/// hooks over stdin so that they may do work appropriate to the current state of the
/// container.
pub hooks: Option<Hooks>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Annotations contains arbitrary metadata for the container. This information MAY be
/// structured or unstructured. Annotations MUST be a key-value map. If there are no
/// annotations then this property MAY either be absent or an empty map.
///
/// Keys MUST be strings. Keys MUST NOT be an empty string. Keys SHOULD be named using a
/// reverse domain notation - e.g. com.example.myKey. Keys using the org.opencontainers
/// namespace are reserved and MUST NOT be used by subsequent specifications. Runtimes MUST
/// handle unknown annotation keys like any other unknown property.
///
/// Values MUST be strings. Values MAY be an empty string.
pub annotations: Option<HashMap<String, String>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Linux is platform-specific configuration for Linux based containers.
pub linux: Option<Linux>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Solaris is platform-specific configuration for Solaris based containers.
pub solaris: Option<Solaris>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Windows is platform-specific configuration for Windows based containers.
pub windows: Option<Windows>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// VM specifies configuration for Virtual Machine based containers.
pub vm: Option<VM>,
}
// This gives a basic boilerplate for Spec that can be used calling Default::default().
// The values given are similar to the defaults seen in docker and runc, it creates a containerized shell!
// (see respective types default impl for more info)
impl Default for Spec {
fn default() -> Self {
Spec {
// Defaults to most current oci version
version: String::from("1.0.2-dev"),
process: Some(Default::default()),
root: Some(Default::default()),
// Defaults hostname as youki
hostname: "youki".to_string().into(),
mounts: get_default_mounts().into(),
// Defaults to empty metadata
annotations: Some(Default::default()),
linux: Some(Default::default()),
hooks: None,
solaris: None,
windows: None,
vm: None,
}
}
}
impl Spec {
pub fn load<P: AsRef<Path>>(path: P) -> Result<Self> {
let path = path.as_ref();
let file = fs::File::open(path)
.with_context(|| format!("load spec: failed to open {:?}", path))?;
let spec: Spec = serde_json::from_reader(&file)?;
Ok(spec)
}
pub fn save<P: AsRef<Path>>(&self, path: P) -> Result<()> {
let path = path.as_ref();
let file = fs::File::create(path)
.with_context(|| format!("save spec: failed to create/open {:?}", path))?;
serde_json::to_writer(&file, self)
.with_context(|| format!("failed to save spec to {:?}", path))?;
Ok(())
}
pub fn canonicalize_rootfs<P: AsRef<Path>>(&mut self, bundle: P) -> Result<()> {
let root = self.root.as_mut().context("no root path provided")?;
root.path = Self::canonicalize_path(bundle, &root.path)?;
Ok(())
}
fn canonicalize_path<B, P>(bundle: B, path: P) -> Result<PathBuf>
where
B: AsRef<Path>,
P: AsRef<Path>,
{
Ok(if path.as_ref().is_absolute() {
fs::canonicalize(path.as_ref())
.with_context(|| format!("failed to canonicalize {}", path.as_ref().display()))?
} else {
let canonical_bundle_path = fs::canonicalize(&bundle).context(format!(
"failed to canonicalize bundle: {}",
bundle.as_ref().display()
))?;
fs::canonicalize(canonical_bundle_path.join(path.as_ref())).context(format!(
"failed to canonicalize rootfs: {}",
path.as_ref().display()
))?
})
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_canonicalize_rootfs() -> Result<()> {
let rootfs_name = "rootfs";
let bundle = tempfile::tempdir().with_context(|| "Failed to create tmp test bundle dir")?;
let rootfs_absolute_path = bundle.path().join(rootfs_name);
assert!(
rootfs_absolute_path.is_absolute(),
"rootfs path is not absolute path"
);
fs::create_dir_all(&rootfs_absolute_path)
.with_context(|| "Failed to create the testing rootfs")?;
{
// Test the case with absolute path
let mut spec = Spec {
root: Root {
path: rootfs_absolute_path.clone(),
..Default::default()
}
.into(),
..Default::default()
};
spec.canonicalize_rootfs(bundle.path())
.with_context(|| "Failed to canonicalize rootfs")?;
assert_eq!(
rootfs_absolute_path,
spec.root.context("no root in spec")?.path
);
}
{
// Test the case with relative path
let mut spec = Spec {
root: Root {
path: PathBuf::from(rootfs_name),
..Default::default()
}
.into(),
..Default::default()
};
spec.canonicalize_rootfs(bundle.path())
.with_context(|| "Failed to canonicalize rootfs")?;
assert_eq!(
rootfs_absolute_path,
spec.root.context("no root in spec")?.path
);
}
Ok(())
}
#[test]
fn test_load_save() -> Result<()> {
let spec = Spec {
..Default::default()
};
let test_dir = tempfile::tempdir().with_context(|| "Failed to create tmp test dir")?;
let spec_path = test_dir.into_path().join("config.json");
// Test first save the default config, and then load the saved config.
// The before and after should be the same.
spec.save(&spec_path)
.with_context(|| "Failed to save spec")?;
let loaded_spec =
Spec::load(&spec_path).with_context(|| "Failed to load the saved spec.")?;
assert_eq!(
spec, loaded_spec,
"The saved spec is not the same as the loaded spec"
);
Ok(())
}
}

View File

@ -1,852 +0,0 @@
use anyhow::{bail, Result};
use nix::sys::stat::SFlag;
use serde::{Deserialize, Serialize};
use std::{collections::HashMap, convert::TryFrom, path::PathBuf};
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
/// Linux contains platform-specific configuration for Linux based containers.
pub struct Linux {
#[serde(default, skip_serializing_if = "Option::is_none")]
/// UIDMappings specifies user mappings for supporting user namespaces.
pub uid_mappings: Option<Vec<LinuxIdMapping>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// GIDMappings specifies group mappings for supporting user namespaces.
pub gid_mappings: Option<Vec<LinuxIdMapping>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Sysctl are a set of key value pairs that are set for the container on start.
pub sysctl: Option<HashMap<String, String>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Resources contain cgroup information for handling resource constraints for the container.
pub resources: Option<LinuxResources>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// CgroupsPath specifies the path to cgroups that are created and/or joined by the container.
/// The path is expected to be relative to the cgroups mountpoint. If resources are specified,
/// the cgroups at CgroupsPath will be updated based on resources.
pub cgroups_path: Option<PathBuf>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Namespaces contains the namespaces that are created and/or joined by the container.
pub namespaces: Option<Vec<LinuxNamespace>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Devices are a list of device nodes that are created for the container.
pub devices: Option<Vec<LinuxDevice>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Seccomp specifies the seccomp security settings for the container.
pub seccomp: Option<LinuxSeccomp>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// RootfsPropagation is the rootfs mount propagation mode for the container.
pub rootfs_propagation: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// MaskedPaths masks over the provided paths inside the container.
pub masked_paths: Option<Vec<String>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// ReadonlyPaths sets the provided paths as RO inside the container.
pub readonly_paths: Option<Vec<String>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// MountLabel specifies the selinux context for the mounts in the container.
pub mount_label: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// IntelRdt contains Intel Resource Director Technology (RDT) information for handling
/// resource constraints (e.g., L3 cache, memory bandwidth) for the container.
pub intel_rdt: Option<LinuxIntelRdt>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Personality contains configuration for the Linux personality syscall.
pub personality: Option<LinuxPersonality>,
}
// Default impl for Linux (see funtions for more info)
impl Default for Linux {
fn default() -> Self {
Linux {
// Creates empty Vec
uid_mappings: Default::default(),
// Creates empty Vec
gid_mappings: Default::default(),
// Empty sysctl Hashmap
sysctl: Default::default(),
resources: Some(LinuxResources {
devices: vec![LinuxDeviceCgroup {
access: "rwm".to_string().into(),
allow: false,
typ: Default::default(),
major: Default::default(),
minor: Default::default(),
}]
.into(),
disable_oom_killer: Default::default(),
oom_score_adj: Default::default(),
memory: Default::default(),
cpu: Default::default(),
pids: Default::default(),
block_io: Default::default(),
hugepage_limits: Default::default(),
network: Default::default(),
freezer: Default::default(),
rdma: Default::default(),
unified: Default::default(),
}),
// Defaults to None
cgroups_path: Default::default(),
namespaces: get_default_namespaces().into(),
// Empty Vec
devices: Default::default(),
// Empty String
rootfs_propagation: Default::default(),
masked_paths: get_default_maskedpaths().into(),
readonly_paths: get_default_readonly_paths().into(),
// Empty String
mount_label: Default::default(),
seccomp: None,
intel_rdt: None,
personality: None,
}
}
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
/// LinuxIDMapping specifies UID/GID mappings.
pub struct LinuxIdMapping {
#[serde(default, rename = "hostID")]
/// HostID is the starting UID/GID on the host to be mapped to `container_id`.
pub host_id: u32,
#[serde(default, rename = "containerID")]
/// ContainerID is the starting UID/GID in the container.
pub container_id: u32,
#[serde(default)]
/// Size is the number of IDs to be mapped.
pub size: u32,
}
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "lowercase")]
/// Device types
pub enum LinuxDeviceType {
/// block (buffered)
B,
/// character (unbuffered)
C,
/// character (unbufferd)
U,
/// FIFO
P,
/// ??
A,
}
impl Default for LinuxDeviceType {
fn default() -> LinuxDeviceType {
LinuxDeviceType::A
}
}
impl LinuxDeviceType {
pub fn to_sflag(&self) -> Result<SFlag> {
Ok(match self {
Self::B => SFlag::S_IFBLK,
Self::C | LinuxDeviceType::U => SFlag::S_IFCHR,
Self::P => SFlag::S_IFIFO,
Self::A => bail!("type a is not allowed for linux device"),
})
}
pub fn as_str(&self) -> &str {
match self {
Self::B => "b",
Self::C => "c",
Self::U => "u",
Self::P => "p",
Self::A => "a",
}
}
}
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
/// Represents a device rule for the devices specified to the device controller
pub struct LinuxDeviceCgroup {
#[serde(default)]
/// Allow or deny
pub allow: bool,
/// Device type, block, char, etc.
#[serde(default, rename = "type")]
pub typ: Option<LinuxDeviceType>,
/// Device's major number
pub major: Option<i64>,
/// Device's minor number
pub minor: Option<i64>,
/// Cgroup access premissions format, rwm.
#[serde(default)]
pub access: Option<String>,
}
impl ToString for LinuxDeviceCgroup {
fn to_string(&self) -> String {
let major = self
.major
.map(|mj| mj.to_string())
.unwrap_or_else(|| "*".to_string());
let minor = self
.minor
.map(|mi| mi.to_string())
.unwrap_or_else(|| "*".to_string());
let access = self.access.as_deref().unwrap_or("");
format!(
"{} {}:{} {}",
&self.typ.unwrap_or_default().as_str(),
&major,
&minor,
&access
)
}
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
/// LinuxMemory for Linux cgroup 'memory' resource management.
pub struct LinuxMemory {
#[serde(skip_serializing_if = "Option::is_none")]
/// Memory limit (in bytes).
pub limit: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
/// Memory reservation or soft_limit (in bytes).
pub reservation: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
/// Total memory limit (memory + swap).
pub swap: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
/// Kernel memory limit (in bytes).
pub kernel: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none", rename = "kernelTCP")]
/// Kernel memory limit for tcp (in bytes).
pub kernel_tcp: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
/// How aggressive the kernel will swap memory pages.
pub swappiness: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none", rename = "disableOOMKiller")]
/// DisableOOMKiller disables the OOM killer for out of memory conditions.
pub disable_oom_killer: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
/// Enables hierarchical memory accounting
pub use_hierarchy: Option<bool>,
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
/// LinuxCPU for Linux cgroup 'cpu' resource management.
pub struct LinuxCpu {
#[serde(skip_serializing_if = "Option::is_none")]
/// CPU shares (relative weight (ratio) vs. other cgroups with cpu shares).
pub shares: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
/// CPU hardcap limit (in usecs). Allowed cpu time in a given period.
pub quota: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
/// CPU period to be used for hardcapping (in usecs).
pub period: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
/// How much time realtime scheduling may use (in usecs).
pub realtime_runtime: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
/// CPU period to be used for realtime scheduling (in usecs).
pub realtime_period: Option<u64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// CPUs to use within the cpuset. Default is to use any CPU available.
pub cpus: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// List of memory nodes in the cpuset. Default is to use any available memory node.
pub mems: Option<String>,
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
/// LinuxPids for Linux cgroup 'pids' resource management (Linux 4.3).
pub struct LinuxPids {
#[serde(default)]
/// Maximum number of PIDs. Default is "no limit".
pub limit: i64,
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
/// LinuxWeightDevice struct holds a `major:minor weight` pair for weightDevice.
pub struct LinuxWeightDevice {
#[serde(default)]
/// Major is the device's major number.
pub major: i64,
#[serde(default)]
/// Minor is the device's minor number.
pub minor: i64,
#[serde(skip_serializing_if = "Option::is_none")]
/// Weight is the bandwidth rate for the device.
pub weight: Option<u16>,
#[serde(skip_serializing_if = "Option::is_none")]
/// LeafWeight is the bandwidth rate for the device while competing with the cgroup's child
/// cgroups, CFQ scheduler only.
pub leaf_weight: Option<u16>,
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
/// LinuxThrottleDevice struct holds a `major:minor rate_per_second` pair.
pub struct LinuxThrottleDevice {
#[serde(default)]
/// Major is the device's major number.
pub major: i64,
#[serde(default)]
/// Minor is the device's minor number.
pub minor: i64,
#[serde(default)]
/// Rate is the IO rate limit per cgroup per device.
pub rate: u64,
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
/// LinuxBlockIO for Linux cgroup 'blkio' resource management.
pub struct LinuxBlockIo {
#[serde(skip_serializing_if = "Option::is_none")]
/// Specifies per cgroup weight.
pub weight: Option<u16>,
#[serde(skip_serializing_if = "Option::is_none")]
/// Specifies tasks' weight in the given cgroup while competing with the cgroup's child
/// cgroups, CFQ scheduler only.
pub leaf_weight: Option<u16>,
#[serde(skip_serializing_if = "Option::is_none")]
/// Weight per cgroup per device, can override BlkioWeight.
pub weight_device: Option<Vec<LinuxWeightDevice>>,
#[serde(skip_serializing_if = "Option::is_none")]
/// IO read rate limit per cgroup per device, bytes per second.
pub throttle_read_bps_device: Option<Vec<LinuxThrottleDevice>>,
#[serde(skip_serializing_if = "Option::is_none")]
/// IO write rate limit per cgroup per device, bytes per second.
pub throttle_write_bps_device: Option<Vec<LinuxThrottleDevice>>,
#[serde(skip_serializing_if = "Option::is_none")]
/// IO read rate limit per cgroup per device, IO per second.
pub throttle_read_iops_device: Option<Vec<LinuxThrottleDevice>>,
#[serde(skip_serializing_if = "Option::is_none")]
/// IO write rate limit per cgroup per device, IO per second.
pub throttle_write_iops_device: Option<Vec<LinuxThrottleDevice>>,
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
/// LinuxHugepageLimit structure corresponds to limiting kernel hugepages.
pub struct LinuxHugepageLimit {
#[serde(default)]
/// Pagesize is the hugepage size.
/// Format: "<size><unit-prefix>B' (e.g. 64KB, 2MB, 1GB, etc.)
pub page_size: String,
#[serde(default)]
/// Limit is the limit of "hugepagesize" hugetlb usage.
pub limit: i64,
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
/// LinuxInterfacePriority for network interfaces.
pub struct LinuxInterfacePriority {
#[serde(default)]
/// Name is the name of the network interface.
pub name: String,
#[serde(default)]
/// Priority for the interface.
pub priority: u32,
}
impl ToString for LinuxInterfacePriority {
fn to_string(&self) -> String {
format!("{} {}\n", self.name, self.priority)
}
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
/// LinuxNetwork identification and priority configuration.
pub struct LinuxNetwork {
#[serde(skip_serializing_if = "Option::is_none", rename = "classID")]
/// Set class identifier for container's network packets
pub class_id: Option<u32>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Set priority of network traffic for container.
pub priorities: Option<Vec<LinuxInterfacePriority>>,
}
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
/// Resource constraints for container
pub struct LinuxResources {
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Devices configures the device allowlist.
pub devices: Option<Vec<LinuxDeviceCgroup>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Memory restriction configuration.
pub memory: Option<LinuxMemory>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// CPU resource restriction configuration.
pub cpu: Option<LinuxCpu>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Task resource restrictions
pub pids: Option<LinuxPids>,
#[serde(default, skip_serializing_if = "Option::is_none", rename = "blockIO")]
/// BlockIO restriction configuration.
pub block_io: Option<LinuxBlockIo>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Hugetlb limit (in bytes).
pub hugepage_limits: Option<Vec<LinuxHugepageLimit>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Network restriction configuration.
pub network: Option<LinuxNetwork>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Rdma resource restriction configuration. Limits are a set of key value pairs that define
/// RDMA resource limits, where the key is device name and value is resource limits.
pub rdma: Option<HashMap<String, LinuxRdma>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Unified resources.
pub unified: Option<HashMap<String, String>>,
// TODO: I am not part of the official spec
#[serde(default)]
// Disables the OOM killer for out of memory conditions
pub disable_oom_killer: bool,
// TODO: I am not part of the official spec
// Specify an oom_score_adj for container
pub oom_score_adj: Option<i32>,
// TODO: I am not part of the official spec
pub freezer: Option<FreezerState>,
}
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
/// LinuxRdma for Linux cgroup 'rdma' resource management (Linux 4.11).
pub struct LinuxRdma {
#[serde(skip_serializing_if = "Option::is_none")]
/// Maximum number of HCA handles that can be opened. Default is "no limit".
hca_handles: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
/// Maximum number of HCA objects that can be created. Default is "no limit".
hca_objects: Option<u32>,
}
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum LinuxNamespaceType {
/// Mount Namespace for isolating mount points
Mount = 0x00020000,
/// Cgroup Namespace for isolating cgroup hierarchies
Cgroup = 0x02000000,
/// Uts Namespace for isolating hostname and NIS domain name
Uts = 0x04000000,
/// Ipc Namespace for isolating System V, IPC, POSIX message queues
Ipc = 0x08000000,
/// User Namespace for isolating user and group ids
User = 0x10000000,
/// PID Namespace for isolating process ids
Pid = 0x20000000,
/// Network Namespace for isolating network devices, ports, stacks etc.
Network = 0x40000000,
}
impl TryFrom<&str> for LinuxNamespaceType {
type Error = anyhow::Error;
fn try_from(namespace: &str) -> Result<Self, Self::Error> {
match namespace {
"mnt" => Ok(LinuxNamespaceType::Mount),
"cgroup" => Ok(LinuxNamespaceType::Cgroup),
"uts" => Ok(LinuxNamespaceType::Uts),
"ipc" => Ok(LinuxNamespaceType::Ipc),
"user" => Ok(LinuxNamespaceType::User),
"pid" => Ok(LinuxNamespaceType::Pid),
"net" => Ok(LinuxNamespaceType::Network),
_ => bail!("unknown namespace {}, could not convert", namespace),
}
}
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
/// LinuxNamespace is the configuration for a Linux namespace.
pub struct LinuxNamespace {
#[serde(rename = "type")]
/// Type is the type of namespace.
pub typ: LinuxNamespaceType,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Path is a path to an existing namespace persisted on disk that can be joined and is of the
/// same type
pub path: Option<PathBuf>,
}
// Utility function to get default namespaces
pub fn get_default_namespaces() -> Vec<LinuxNamespace> {
vec![
LinuxNamespace {
typ: LinuxNamespaceType::Pid,
path: Default::default(),
},
LinuxNamespace {
typ: LinuxNamespaceType::Network,
path: Default::default(),
},
LinuxNamespace {
typ: LinuxNamespaceType::Ipc,
path: Default::default(),
},
LinuxNamespace {
typ: LinuxNamespaceType::Uts,
path: Default::default(),
},
LinuxNamespace {
typ: LinuxNamespaceType::Mount,
path: Default::default(),
},
]
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
/// LinuxDevice represents the mknod information for a Linux special device file.
pub struct LinuxDevice {
#[serde(default)]
/// Path to the device.
pub path: PathBuf,
#[serde(rename = "type")]
/// Device type, block, char, etc..
pub typ: LinuxDeviceType,
#[serde(default)]
/// Major is the device's major number.
pub major: i64,
#[serde(default)]
/// Minor is the device's minor number.
pub minor: i64,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// FileMode permission bits for the device.
pub file_mode: Option<u32>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// UID of the device.
pub uid: Option<u32>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Gid of the device.
pub gid: Option<u32>,
}
impl From<&LinuxDevice> for LinuxDeviceCgroup {
fn from(linux_device: &LinuxDevice) -> LinuxDeviceCgroup {
LinuxDeviceCgroup {
allow: true,
typ: linux_device.typ.into(),
major: Some(linux_device.major as i64),
minor: Some(linux_device.minor as i64),
access: "rwm".to_string().into(),
}
}
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
/// LinuxSeccomp represents syscall restrictions.
pub struct LinuxSeccomp {
pub default_action: LinuxSeccompAction,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub architectures: Option<Vec<Arch>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub flags: Option<Vec<String>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub syscalls: Option<Vec<LinuxSyscall>>,
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
#[repr(u32)]
pub enum LinuxSeccompAction {
ScmpActKill = 0x00000000,
ScmpActTrap = 0x00030000,
ScmpActErrno = 0x00050001,
ScmpActTrace = 0x7ff00001,
ScmpActAllow = 0x7fff0000,
}
#[allow(clippy::enum_clike_unportable_variant)]
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum Arch {
ScmpArchNative = 0x00000000,
ScmpArchX86 = 0x40000003,
ScmpArchX86_64 = 0xc000003e,
ScmpArchX32 = 0x4000003e,
ScmpArchArm = 0x40000028,
ScmpArchAarch64 = 0xc00000b7,
ScmpArchMips = 0x00000008,
ScmpArchMips64 = 0x80000008,
ScmpArchMips64n32 = 0xa0000008,
ScmpArchMipsel = 0x40000008,
ScmpArchMipsel64 = 0xc0000008,
ScmpArchMipsel64n32 = 0xe0000008,
ScmpArchPpc = 0x00000014,
ScmpArchPpc64 = 0x80000015,
ScmpArchPpc64le = 0xc0000015,
ScmpArchS390 = 0x00000016,
ScmpArchS390x = 0x80000016,
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
#[repr(u32)]
pub enum LinuxSeccompOperator {
ScmpCmpNe = 1,
ScmpCmpLt = 2,
ScmpCmpLe = 3,
ScmpCmpEq = 4,
ScmpCmpGe = 5,
ScmpCmpGt = 6,
ScmpCmpMaskedEq = 7,
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
/// LinuxSyscall is used to match a syscall in seccomp.
pub struct LinuxSyscall {
pub names: Vec<String>,
pub action: LinuxSeccompAction,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub errno_ret: Option<u32>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub args: Option<Vec<LinuxSeccompArg>>,
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
/// LinuxSeccompArg used for matching specific syscall arguments in seccomp.
pub struct LinuxSeccompArg {
pub index: usize,
pub value: u64,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub value_two: Option<u64>,
pub op: LinuxSeccompOperator,
}
// Default masks paths, cannot read these host files
pub fn get_default_maskedpaths() -> Vec<String> {
vec![
// For example now host interfaces such as
// bluetooth cannot be accessed due to /proc/acpi
"/proc/acpi".to_string(),
"/proc/asound".to_string(),
"/proc/kcore".to_string(),
"/proc/keys".to_string(),
"/proc/latency_stats".to_string(),
"/proc/timer_list".to_string(),
"/proc/timer_stats".to_string(),
"/proc/sched_debug".to_string(),
"/sys/firmware".to_string(),
"/proc/scsi".to_string(),
]
}
// Default readonly paths,
// For example most containers shouldn't have permission to write to /proc/sys
pub fn get_default_readonly_paths() -> Vec<String> {
vec![
"/proc/bus".to_string(),
"/proc/fs".to_string(),
"/proc/irq".to_string(),
"/proc/sys".to_string(),
"/proc/sysrq-trigger".to_string(),
]
}
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub enum FreezerState {
Undefined,
Frozen,
Thawed,
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
/// LinuxIntelRdt has container runtime resource constraints for Intel RDT CAT and MBA features
/// which introduced in Linux 4.10 and 4.12 kernel.
pub struct LinuxIntelRdt {
#[serde(default, skip_serializing_if = "Option::is_none")]
/// The identity for RDT Class of Service.
pub clos_id: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// The schema for L3 cache id and capacity bitmask (CBM).
/// Format: "L3:<cache_id0>=<cbm0>;<cache_id1>=<cbm1>;..."
pub l3_cache_schema: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// The schema of memory bandwidth per L3 cache id.
/// Format: "MB:<cache_id0>=bandwidth0;<cache_id1>=bandwidth1;..."
/// The unit of memory bandwidth is specified in "percentages" by default, and in "MBps" if MBA
/// Software Controller is enabled.
pub mem_bw_schema: Option<String>,
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
/// LinuxPersonality represents the Linux personality syscall input.
pub struct LinuxPersonality {
/// Domain for the personality.
domain: LinuxPersonalityDomain,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Additional flags
flags: Option<Vec<String>>,
}
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
/// Define domain and flags for LinuxPersonality.
pub enum LinuxPersonalityDomain {
#[serde(rename = "LINUX")]
/// PerLinux is the standard Linux personality.
PerLinux,
#[serde(rename = "LINUX32")]
/// PerLinux32 sets personality to 32 bit.
PerLinux32,
}
#[cfg(feature = "proptests")]
use quickcheck::{Arbitrary, Gen};
#[cfg(feature = "proptests")]
fn some_none_generator_util<T: Arbitrary>(g: &mut Gen) -> Option<T> {
let choice = g.choose(&[true, false]).unwrap();
match choice {
false => None,
true => Some(T::arbitrary(g)),
}
}
#[cfg(feature = "proptests")]
impl Arbitrary for LinuxDeviceCgroup {
fn arbitrary(g: &mut Gen) -> LinuxDeviceCgroup {
let typ_choices = ["b", "c", "u", "p", "a"];
let typ_chosen = g.choose(&typ_choices).unwrap();
let typ = match typ_chosen.to_string().as_str() {
"b" => LinuxDeviceType::B,
"c" => LinuxDeviceType::C,
"u" => LinuxDeviceType::U,
"p" => LinuxDeviceType::P,
"a" => LinuxDeviceType::A,
_ => LinuxDeviceType::A,
};
let access_choices = ["rwm", "m"];
LinuxDeviceCgroup {
allow: bool::arbitrary(g),
typ: typ.into(),
major: some_none_generator_util::<i64>(g),
minor: some_none_generator_util::<i64>(g),
access: g.choose(&access_choices).unwrap().to_string().into(),
}
}
}
#[cfg(feature = "proptests")]
impl Arbitrary for LinuxMemory {
fn arbitrary(g: &mut Gen) -> LinuxMemory {
LinuxMemory {
kernel: some_none_generator_util::<i64>(g),
kernel_tcp: some_none_generator_util::<i64>(g),
limit: some_none_generator_util::<i64>(g),
reservation: some_none_generator_util::<i64>(g),
swap: some_none_generator_util::<i64>(g),
swappiness: some_none_generator_util::<u64>(g),
disable_oom_killer: some_none_generator_util::<bool>(g),
use_hierarchy: some_none_generator_util::<bool>(g),
}
}
}
#[cfg(feature = "proptests")]
impl Arbitrary for LinuxHugepageLimit {
fn arbitrary(g: &mut Gen) -> LinuxHugepageLimit {
let unit_choice = ["KB", "MB", "GB"];
let unit = g.choose(&unit_choice).unwrap();
let page_size = u64::arbitrary(g).to_string() + unit;
LinuxHugepageLimit {
page_size,
limit: i64::arbitrary(g),
}
}
}

View File

@ -1,126 +0,0 @@
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
/// Root contains information about the container's root filesystem on the host.
pub struct Root {
/// Path is the absolute path to the container's root filesystem.
#[serde(default)]
pub path: PathBuf,
/// Readonly makes the root filesystem for the container readonly before the process is
/// executed.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub readonly: Option<bool>,
}
/// Default path for container root is "./rootfs" from config.json, with readonly true
impl Default for Root {
fn default() -> Self {
Root {
path: PathBuf::from("rootfs"),
readonly: true.into(),
}
}
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
/// Mount specifies a mount for a container.
pub struct Mount {
/// Destination is the absolute path where the mount will be placed in the container.
pub destination: PathBuf,
#[serde(default, skip_serializing_if = "Option::is_none", rename = "type")]
/// Type specifies the mount kind.
pub typ: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Source specifies the source path of the mount.
pub source: Option<PathBuf>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Options are fstab style mount options.
pub options: Option<Vec<String>>,
}
// utility function to generate default config for mounts
pub fn get_default_mounts() -> Vec<Mount> {
vec![
Mount {
destination: PathBuf::from("/proc"),
typ: "proc".to_string().into(),
source: PathBuf::from("proc").into(),
options: None,
},
Mount {
destination: PathBuf::from("/dev"),
typ: "tmpfs".to_string().into(),
source: PathBuf::from("tmpfs").into(),
options: vec![
"nosuid".into(),
"strictatime".into(),
"mode=755".into(),
"size=65536k".into(),
]
.into(),
},
Mount {
destination: PathBuf::from("/dev/pts"),
typ: "devpts".to_string().into(),
source: PathBuf::from("devpts").into(),
options: vec![
"nosuid".into(),
"noexec".into(),
"newinstance".into(),
"ptmxmode=0666".into(),
"mode=0620".into(),
"gid=5".into(),
]
.into(),
},
Mount {
destination: PathBuf::from("/dev/shm"),
typ: "tmpfs".to_string().into(),
source: PathBuf::from("shm").into(),
options: vec![
"nosuid".into(),
"noexec".into(),
"nodev".into(),
"mode=1777".into(),
"size=65536k".into(),
]
.into(),
},
Mount {
destination: PathBuf::from("/dev/mqueue"),
typ: "mqueue".to_string().into(),
source: PathBuf::from("mqueue").into(),
options: vec!["nosuid".into(), "noexec".into(), "nodev".into()].into(),
},
Mount {
destination: PathBuf::from("/sys"),
typ: "sysfs".to_string().into(),
source: PathBuf::from("sysfs").into(),
options: vec![
"nosuid".into(),
"noexec".into(),
"nodev".into(),
"ro".into(),
]
.into(),
},
Mount {
destination: PathBuf::from("/sys/fs/cgroup"),
typ: "cgroup".to_string().into(),
source: PathBuf::from("cgroup").into(),
options: vec![
"nosuid".into(),
"noexec".into(),
"nodev".into(),
"relatime".into(),
"ro".into(),
]
.into(),
},
]
}

View File

@ -1,249 +0,0 @@
use caps::Capability;
use serde::{Deserialize, Serialize};
/// Process contains information to start a specific application inside the container.
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Process {
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Terminal creates an interactive terminal for the container.
pub terminal: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// ConsoleSize specifies the size of the console.
pub console_size: Option<Box>,
/// User specifies user information for the process.
pub user: User,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Args specifies the binary and arguments for the application to execute.
pub args: Option<Vec<String>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// CommandLine specifies the full command line for the application to execute on Windows.
pub command_line: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Env populates the process environment for the process.
pub env: Option<Vec<String>>,
/// Cwd is the current working directory for the process and must be relative to the
/// container's root.
pub cwd: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Capabilities are Linux capabilities that are kept for the process.
pub capabilities: Option<LinuxCapabilities>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Rlimits specifies rlimit options to apply to the process.
pub rlimits: Option<Vec<LinuxRlimit>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// NoNewPrivileges controls whether additional privileges could be gained by processes in the
/// container.
pub no_new_privileges: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// ApparmorProfile specifies the apparmor profile for the container.
pub apparmor_profile: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
/// Specify an oom_score_adj for the container.
pub oom_score_adj: Option<i32>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// SelinuxLabel specifies the selinux context that the container process is run as.
pub selinux_label: Option<String>,
}
// Default impl for processes in the container
impl Default for Process {
fn default() -> Self {
Process {
// Creates an interactive terminal for container by default
terminal: true.into(),
// Gives default console size of 0, 0
console_size: Default::default(),
// Gives process a uid and gid of 0 (root)
user: Default::default(),
// By default executes sh command, giving user shell
args: vec!["sh".to_string()].into(),
// Sets linux default enviroment for binaries and default xterm emulator
env: vec![
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin".into(),
"TERM=xterm".into(),
]
.into(),
// Sets cwd of process to the container root by default
cwd: "/".into(),
// By default does not allow process to gain additional privileges
no_new_privileges: true.into(),
// Empty String, no default apparmor
apparmor_profile: Default::default(),
// Empty String, no default selinux
selinux_label: Default::default(),
// See impl Default for LinuxCapabilities
capabilities: Some(Default::default()),
// Sets the default maximum of 1024 files the process can open
// This is the same as the linux kernel default
rlimits: vec![LinuxRlimit {
typ: LinuxRlimitType::RlimitNofile,
hard: 1024,
soft: 1024,
}]
.into(),
oom_score_adj: None,
command_line: None,
}
}
}
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
/// Box specifies dimensions of a rectangle. Used for specifying the size of a console.
pub struct Box {
#[serde(default)]
/// Height is the vertical dimension of a box.
pub height: u64,
#[serde(default)]
/// Width is the horizontal dimension of a box.
pub width: u64,
}
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
/// Available rlimti types (see https://man7.org/linux/man-pages/man2/getrlimit.2.html)
pub enum LinuxRlimitType {
/// Limit in seconds of the amount of CPU time that the process can consume.
RlimitCpu,
/// Maximum size in bytes of the files that the process creates.
RlimitFsize,
/// Maximum size of the process's data segment (init data, uninit data and heap) in bytes.
RlimitData,
/// Maximum size of the proces stack in bytes.
RlimitStack,
/// Maximum size of a core dump file in bytes.
RlimitCore,
/// Limit on the process's resident set (the number of virtual pages resident in RAM).
RlimitRss,
/// Limit on number of threads for the real uid calling processes.
RlimitNproc,
/// One greator than the maximum number of file descritors that one process may open.
RlimitNofile,
/// Maximum number of bytes of memory that may be locked into RAM.
RlimitMemlock,
/// Maximum size of the process's virtual memory(address space) in bytes.
RlimitAs,
/// Limit on the number of locks and leases for the process.
RlimitLocks,
/// Limit on number of signals that may be queued for the process.
RlimitSigpending,
/// Limit on the number of bytes that can be allocated for POSIX message queue.
RlimitMsgqueue,
/// Specifies a ceiling to which the process's nice value can be raised.
RlimitNice,
/// Specifies a ceiling on the real-time priority.
RlimitRtprio,
/// This is a limit (in microseconds) on the amount of CPU time that a process scheduled under
/// a real-time scheduling policy may consume without making a blocking system call.
RlimitRttime,
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
/// RLimit types and restrictions.
pub struct LinuxRlimit {
#[serde(rename = "type")]
/// Type of Rlimit to set
pub typ: LinuxRlimitType,
#[serde(default)]
/// Hard limit for specified type
pub hard: u64,
#[serde(default)]
/// Soft limit for specified type
pub soft: u64,
}
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
/// User id (uid) and group id (gid) tracks file permssions.
pub struct User {
#[serde(default)]
/// UID is the user id.
pub uid: u32,
#[serde(default)]
/// GID is the group id.
pub gid: u32,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// AdditionalGids are additional group ids set for the container's process.
pub additional_gids: Option<Vec<u32>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Username is the user name.
pub username: Option<String>,
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
/// LinuxCapabilities specifies the list of allowed capabilities that are kept for a process.
/// http://man7.org/linux/man-pages/man7/capabilities.7.html
pub struct LinuxCapabilities {
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Bounding is the set of capabilities checked by the kernel.
pub bounding: Option<Vec<Capability>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Effective is the set of capabilities checked by the kernel.
pub effective: Option<Vec<Capability>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Inheritable is the capabilities preserved across execve.
pub inheritable: Option<Vec<Capability>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Permitted is the limiting superset for effective capabilities.
pub permitted: Option<Vec<Capability>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
//// Ambient is the ambient set of capabilities that are kept.
pub ambient: Option<Vec<Capability>>,
}
// Default container's linux capabilities:
// CAP_AUDIT_WRITE gives container ability to write to linux audit logs,
// CAP_KILL gives container ability to kill non root processes
// CAP_NET_BIND_SERVICE allows container to bind to ports below 1024
impl Default for LinuxCapabilities {
fn default() -> Self {
let audit_write = Capability::CAP_AUDIT_WRITE;
let cap_kill = Capability::CAP_KILL;
let net_bind = Capability::CAP_NET_BIND_SERVICE;
let default_vec = vec![audit_write, cap_kill, net_bind];
LinuxCapabilities {
bounding: default_vec.clone().into(),
effective: default_vec.clone().into(),
inheritable: default_vec.clone().into(),
permitted: default_vec.clone().into(),
ambient: default_vec.into(),
}
}
}

View File

@ -1,85 +0,0 @@
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
/// Solaris contains platform-specific configuration for Solaris application containers.
pub struct Solaris {
#[serde(default, skip_serializing_if = "Option::is_none")]
/// SMF FMRI which should go "online" before we start the container process.
pub milestone: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Maximum set of privileges any process in this container can obtain.
pub limitpriv: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// The maximum amount of shared memory allowed for this container.
pub max_shm_memory: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Specification for automatic creation of network resources for this container.
pub anet: Option<Vec<SolarisAnet>>,
#[serde(default, skip_serializing_if = "Option::is_none", rename = "cappedCPU")]
/// Set limit on the amount of CPU time that can be used by container.
pub capped_cpu: Option<SolarisCappedCPU>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// The physical and swap caps on the memory that can be used by this container.
pub capped_memory: Option<SolarisCappedMemory>,
}
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
/// SolarisAnet provides the specification for automatic creation of network resources for this
/// container.
pub struct SolarisAnet {
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Specify a name for the automatically created VNIC datalink.
pub linkname: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Specify the link over which the VNIC will be created.
pub lower_link: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// The set of IP addresses that the container can use.
pub allowed_address: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Specifies whether allowedAddress limitation is to be applied to the VNIC.
pub configure_allowed_address: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// The value of the optional default router.
pub defrouter: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Enable one or more types of link protection.
pub link_protection: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Set the VNIC's macAddress.
pub mac_address: Option<String>,
}
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
/// SolarisCappedCPU allows users to set limit on the amount of CPU time that can be used by
/// container.
pub struct SolarisCappedCPU {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub ncpus: Option<String>,
}
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
/// SolarisCappedMemory allows users to set the physical and swap caps on the memory that can be
/// used by this container.
pub struct SolarisCappedMemory {
#[serde(default, skip_serializing_if = "Option::is_none")]
/// The physical caps on the memory.
pub physical: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// The swap caps on the memory.
pub swap: Option<String>,
}

View File

@ -1,30 +0,0 @@
#[cfg(test)]
use super::*;
#[test]
fn serialize_and_deserialize_spec() {
let spec: Spec = Default::default();
let json_string = serde_json::to_string(&spec).unwrap();
let new_spec = serde_json::from_str(&json_string).unwrap();
assert_eq!(spec, new_spec);
}
#[test]
fn test_linux_device_cgroup_to_string() {
let ldc = LinuxDeviceCgroup {
allow: true,
typ: Some(LinuxDeviceType::A),
major: None,
minor: None,
access: Some("rwm".into()),
};
assert_eq!(ldc.to_string(), "a *:* rwm");
let ldc = LinuxDeviceCgroup {
allow: true,
typ: Some(LinuxDeviceType::A),
major: Some(1),
minor: Some(9),
access: Some("rwm".into()),
};
assert_eq!(ldc.to_string(), "a 1:9 rwm");
}

View File

@ -1,53 +0,0 @@
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
/// VM contains information for virtual-machine-based containers.
pub struct VM {
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Hypervisor specifies hypervisor-related configuration for virtual-machine-based containers.
pub hypervisor: Option<VMHypervisor>,
/// Kernel specifies kernel-related configuration for virtual-machine-based containers.
pub kernel: VMKernel,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Image specifies guest image related configuration for virtual-machine-based containers.
pub image: Option<VMImage>,
}
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
/// VMHypervisor contains information about the hypervisor to use for a virtual machine.
pub struct VMHypervisor {
/// Path is the host path to the hypervisor used to manage the virtual machine.
pub path: PathBuf,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Parameters specifies parameters to pass to the hypervisor.
pub parameters: Option<Vec<String>>,
}
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
/// VMKernel contains information about the kernel to use for a virtual machine.
pub struct VMKernel {
/// Path is the host path to the kernel used to boot the virtual machine.
pub path: PathBuf,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Parameters specifies parameters to pass to the kernel.
pub parameters: Option<Vec<String>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// InitRD is the host path to an initial ramdisk to be used by the kernel.
pub initrd: Option<String>,
}
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
/// VMImage contains information about the virtual machine root image.
pub struct VMImage {
/// Path is the host path to the root image that the VM kernel would boot into.
pub path: PathBuf,
/// Format is the root image format type (e.g. "qcow2", "raw", "vhd", etc).
pub format: String,
}

View File

@ -1,152 +0,0 @@
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
/// Windows defines the runtime configuration for Windows based containers, including Hyper-V
/// containers.
pub struct Windows {
/// LayerFolders contains a list of absolute paths to directories containing image layers.
pub layer_folders: Vec<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Devices are the list of devices to be mapped into the container.
pub devices: Option<Vec<WindowsDevice>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Resources contains information for handling resource constraints for the container.
pub resources: Option<WindowsResources>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// CredentialSpec contains a JSON object describing a group Managed Service Account (gMSA)
/// specification.
pub credential_spec: Option<HashMap<String, Option<serde_json::Value>>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Servicing indicates if the container is being started in a mode to apply a Windows Update
/// servicing operation.
pub servicing: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// IgnoreFlushesDuringBoot indicates if the container is being started in a mode where disk
/// writes are not flushed during its boot process.
pub ignore_flushes_during_boot: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// HyperV contains information for running a container with Hyper-V isolation.
pub hyperv: Option<WindowsHyperV>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Network restriction configuration.
pub network: Option<WindowsNetwork>,
}
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
/// WindowsDevice represents information about a host device to be mapped into the container.
pub struct WindowsDevice {
/// Device identifier: interface class GUID, etc..
pub id: String,
/// Device identifier type: "class", etc..
pub id_type: String,
}
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
pub struct WindowsResources {
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Memory restriction configuration.
pub memory: Option<WindowsMemoryResources>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// CPU resource restriction configuration.
pub cpu: Option<WindowsCPUResources>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Storage restriction configuration.
pub storage: Option<WindowsStorageResources>,
}
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
/// WindowsMemoryResources contains memory resource management settings.
pub struct WindowsMemoryResources {
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Memory limit in bytes.
pub limit: Option<u64>,
}
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
/// WindowsCPUResources contains CPU resource management settings.
pub struct WindowsCPUResources {
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Number of CPUs available to the container.
pub count: Option<u64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// CPU shares (relative weight to other containers with cpu shares).
pub shares: Option<u16>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Specifies the portion of processor cycles that this container can use as a percentage times
/// 100.
pub maximum: Option<u16>,
}
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
/// WindowsStorageResources contains storage resource management settings.
pub struct WindowsStorageResources {
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Specifies maximum Iops for the system drive.
pub iops: Option<u64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Specifies maximum bytes per second for the system drive.
pub bps: Option<u64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Sandbox size specifies the minimum size of the system drive in bytes.
pub sandbox_size: Option<u64>,
}
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
/// WindowsHyperV contains information for configuring a container to run with Hyper-V isolation.
pub struct WindowsHyperV {
#[serde(default, skip_serializing_if = "Option::is_none")]
/// UtilityVMPath is an optional path to the image used for the Utility VM.
pub utility_vm_path: Option<String>,
}
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
/// WindowsNetwork contains network settings for Windows containers.
pub struct WindowsNetwork {
#[serde(default, skip_serializing_if = "Option::is_none")]
/// List of HNS endpoints that the container should connect to.
pub endpoint_list: Option<Vec<String>>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
rename = "allowUnqualifiedDNSQuery"
)]
/// Specifies if unqualified DNS name resolution is allowed.
pub allow_unqualified_dns_query: Option<bool>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
rename = "DNSSearchList"
)]
/// Comma separated list of DNS suffixes to use for name resolution.
pub dns_search_list: Option<Vec<String>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Name (ID) of the container that we will share with the network stack.
pub network_shared_container_name: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
/// name (ID) of the network namespace that will be used for the container.
pub network_namespace: Option<String>,
}