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:
commit
befc5c0ded
|
@ -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",
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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 +0,0 @@
|
|||
/target
|
|
@ -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"
|
|
@ -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"
|
|
@ -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>,
|
||||
}
|
|
@ -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(())
|
||||
}
|
||||
}
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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(),
|
||||
},
|
||||
]
|
||||
}
|
|
@ -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(),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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>,
|
||||
}
|
|
@ -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");
|
||||
}
|
|
@ -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,
|
||||
}
|
|
@ -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>,
|
||||
}
|
Loading…
Reference in New Issue