use crate::error::{oci_error, OciSpecError};
use derive_builder::Builder;
use getset::{CopyGetters, Getters};
use serde::{Deserialize, Serialize};
use std::{collections::HashMap, convert::TryFrom, path::PathBuf};
#[derive(Builder, Clone, Debug, Deserialize, Eq, Getters, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
#[builder(
default,
pattern = "owned",
setter(into, strip_option),
build_fn(error = "OciSpecError")
)]
#[getset(get = "pub")]
pub struct Linux {
#[serde(default, skip_serializing_if = "Option::is_none")]
uid_mappings: Option<Vec<LinuxIdMapping>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
gid_mappings: Option<Vec<LinuxIdMapping>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
sysctl: Option<HashMap<String, String>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
resources: Option<LinuxResources>,
#[serde(default, skip_serializing_if = "Option::is_none")]
cgroups_path: Option<PathBuf>,
#[serde(default, skip_serializing_if = "Option::is_none")]
namespaces: Option<Vec<LinuxNamespace>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
devices: Option<Vec<LinuxDevice>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
seccomp: Option<LinuxSeccomp>,
#[serde(default, skip_serializing_if = "Option::is_none")]
rootfs_propagation: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
masked_paths: Option<Vec<String>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
readonly_paths: Option<Vec<String>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
mount_label: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
intel_rdt: Option<LinuxIntelRdt>,
#[serde(default, skip_serializing_if = "Option::is_none")]
personality: Option<LinuxPersonality>,
}
impl Default for Linux {
fn default() -> Self {
Linux {
uid_mappings: Default::default(),
gid_mappings: Default::default(),
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(),
memory: Default::default(),
cpu: Default::default(),
pids: Default::default(),
block_io: Default::default(),
hugepage_limits: Default::default(),
network: Default::default(),
rdma: Default::default(),
unified: Default::default(),
}),
cgroups_path: Default::default(),
namespaces: get_default_namespaces().into(),
devices: Default::default(),
rootfs_propagation: Default::default(),
masked_paths: get_default_maskedpaths().into(),
readonly_paths: get_default_readonly_paths().into(),
mount_label: Default::default(),
seccomp: None,
intel_rdt: None,
personality: None,
}
}
}
#[derive(
Builder, Clone, Copy, CopyGetters, Debug, Default, Deserialize, Eq, PartialEq, Serialize,
)]
#[serde(rename_all = "camelCase")]
#[builder(
default,
pattern = "owned",
setter(into, strip_option),
build_fn(error = "OciSpecError")
)]
#[getset(get_copy = "pub")]
pub struct LinuxIdMapping {
#[serde(default, rename = "hostID")]
host_id: u32,
#[serde(default, rename = "containerID")]
container_id: u32,
#[serde(default)]
size: u32,
}
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum LinuxDeviceType {
A,
B,
C,
U,
P,
}
impl Default for LinuxDeviceType {
fn default() -> LinuxDeviceType {
LinuxDeviceType::A
}
}
impl LinuxDeviceType {
pub fn as_str(&self) -> &str {
match self {
Self::A => "a",
Self::B => "b",
Self::C => "c",
Self::U => "u",
Self::P => "p",
}
}
}
#[derive(
Builder, Clone, CopyGetters, Debug, Default, Deserialize, Eq, Getters, PartialEq, Serialize,
)]
#[builder(
default,
pattern = "owned",
setter(into, strip_option),
build_fn(error = "OciSpecError")
)]
pub struct LinuxDeviceCgroup {
#[serde(default)]
#[getset(get_copy = "pub")]
allow: bool,
#[serde(default, rename = "type")]
#[getset(get_copy = "pub")]
typ: Option<LinuxDeviceType>,
#[getset(get_copy = "pub")]
major: Option<i64>,
#[getset(get_copy = "pub")]
minor: Option<i64>,
#[serde(default)]
#[getset(get = "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(
Builder, Clone, Copy, CopyGetters, Debug, Default, Deserialize, Eq, PartialEq, Serialize,
)]
#[serde(rename_all = "camelCase")]
#[builder(
default,
pattern = "owned",
setter(into, strip_option),
build_fn(error = "OciSpecError")
)]
#[getset(get_copy = "pub")]
pub struct LinuxMemory {
#[serde(skip_serializing_if = "Option::is_none")]
limit: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
reservation: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
swap: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
kernel: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none", rename = "kernelTCP")]
kernel_tcp: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
swappiness: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none", rename = "disableOOMKiller")]
disable_oom_killer: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
use_hierarchy: Option<bool>,
}
#[derive(
Builder, Clone, CopyGetters, Debug, Default, Deserialize, Eq, Getters, PartialEq, Serialize,
)]
#[serde(rename_all = "camelCase")]
#[builder(
default,
pattern = "owned",
setter(into, strip_option),
build_fn(error = "OciSpecError")
)]
pub struct LinuxCpu {
#[serde(skip_serializing_if = "Option::is_none")]
#[getset(get_copy = "pub")]
shares: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
#[getset(get_copy = "pub")]
quota: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
#[getset(get_copy = "pub")]
period: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
#[getset(get_copy = "pub")]
realtime_runtime: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
#[getset(get_copy = "pub")]
realtime_period: Option<u64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[getset(get = "pub")]
cpus: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[getset(get = "pub")]
mems: Option<String>,
}
#[derive(Builder, Clone, Copy, Debug, Default, Deserialize, Eq, Getters, PartialEq, Serialize)]
#[builder(
default,
pattern = "owned",
setter(into, strip_option),
build_fn(error = "OciSpecError")
)]
#[getset(get_copy = "pub")]
pub struct LinuxPids {
#[serde(default)]
limit: i64,
}
#[derive(
Builder, Clone, Copy, CopyGetters, Debug, Default, Deserialize, Eq, PartialEq, Serialize,
)]
#[serde(rename_all = "camelCase")]
#[builder(
default,
pattern = "owned",
setter(into, strip_option),
build_fn(error = "OciSpecError")
)]
#[getset(get_copy = "pub")]
pub struct LinuxWeightDevice {
#[serde(default)]
major: i64,
#[serde(default)]
minor: i64,
#[serde(skip_serializing_if = "Option::is_none")]
weight: Option<u16>,
#[serde(skip_serializing_if = "Option::is_none")]
leaf_weight: Option<u16>,
}
#[derive(
Builder, Clone, Copy, CopyGetters, Debug, Default, Deserialize, Eq, PartialEq, Serialize,
)]
#[builder(
default,
pattern = "owned",
setter(into, strip_option),
build_fn(error = "OciSpecError")
)]
#[getset(get_copy = "pub")]
pub struct LinuxThrottleDevice {
#[serde(default)]
major: i64,
#[serde(default)]
minor: i64,
#[serde(default)]
rate: u64,
}
#[derive(
Builder, Clone, CopyGetters, Debug, Default, Deserialize, Eq, Getters, PartialEq, Serialize,
)]
#[serde(rename_all = "camelCase")]
#[builder(
default,
pattern = "owned",
setter(into, strip_option),
build_fn(error = "OciSpecError")
)]
pub struct LinuxBlockIo {
#[serde(skip_serializing_if = "Option::is_none")]
#[getset(get_copy = "pub")]
weight: Option<u16>,
#[serde(skip_serializing_if = "Option::is_none")]
#[getset(get_copy = "pub")]
leaf_weight: Option<u16>,
#[serde(skip_serializing_if = "Option::is_none")]
#[getset(get = "pub")]
weight_device: Option<Vec<LinuxWeightDevice>>,
#[serde(skip_serializing_if = "Option::is_none")]
#[getset(get = "pub")]
throttle_read_bps_device: Option<Vec<LinuxThrottleDevice>>,
#[serde(skip_serializing_if = "Option::is_none")]
#[getset(get = "pub")]
throttle_write_bps_device: Option<Vec<LinuxThrottleDevice>>,
#[serde(skip_serializing_if = "Option::is_none")]
#[getset(get = "pub")]
throttle_read_iops_device: Option<Vec<LinuxThrottleDevice>>,
#[serde(skip_serializing_if = "Option::is_none")]
#[getset(get = "pub")]
throttle_write_iops_device: Option<Vec<LinuxThrottleDevice>>,
}
#[derive(
Builder, Clone, CopyGetters, Debug, Default, Deserialize, Eq, Getters, PartialEq, Serialize,
)]
#[serde(rename_all = "camelCase")]
#[builder(
default,
pattern = "owned",
setter(into, strip_option),
build_fn(error = "OciSpecError")
)]
pub struct LinuxHugepageLimit {
#[serde(default)]
#[getset(get = "pub")]
page_size: String,
#[serde(default)]
#[getset(get_copy = "pub")]
limit: i64,
}
#[derive(
Builder, Clone, CopyGetters, Debug, Default, Deserialize, Eq, Getters, PartialEq, Serialize,
)]
#[builder(
default,
pattern = "owned",
setter(into, strip_option),
build_fn(error = "OciSpecError")
)]
pub struct LinuxInterfacePriority {
#[serde(default)]
#[getset(get = "pub")]
name: String,
#[serde(default)]
#[getset(get_copy = "pub")]
priority: u32,
}
impl ToString for LinuxInterfacePriority {
fn to_string(&self) -> String {
format!("{} {}\n", self.name, self.priority)
}
}
#[derive(
Builder, Clone, CopyGetters, Debug, Default, Deserialize, Eq, Getters, PartialEq, Serialize,
)]
#[builder(
default,
pattern = "owned",
setter(into, strip_option),
build_fn(error = "OciSpecError")
)]
pub struct LinuxNetwork {
#[serde(skip_serializing_if = "Option::is_none", rename = "classID")]
#[getset(get_copy = "pub")]
class_id: Option<u32>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[getset(get = "pub")]
priorities: Option<Vec<LinuxInterfacePriority>>,
}
#[derive(
Builder, Clone, CopyGetters, Debug, Default, Deserialize, Eq, Getters, PartialEq, Serialize,
)]
#[serde(rename_all = "camelCase")]
#[builder(
default,
pattern = "owned",
setter(into, strip_option),
build_fn(error = "OciSpecError")
)]
pub struct LinuxResources {
#[serde(default, skip_serializing_if = "Option::is_none")]
#[getset(get = "pub")]
devices: Option<Vec<LinuxDeviceCgroup>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[getset(get_copy = "pub")]
memory: Option<LinuxMemory>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[getset(get = "pub")]
cpu: Option<LinuxCpu>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[getset(get_copy = "pub")]
pids: Option<LinuxPids>,
#[serde(default, skip_serializing_if = "Option::is_none", rename = "blockIO")]
#[getset(get = "pub")]
block_io: Option<LinuxBlockIo>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[getset(get = "pub")]
hugepage_limits: Option<Vec<LinuxHugepageLimit>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[getset(get = "pub")]
network: Option<LinuxNetwork>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[getset(get = "pub")]
rdma: Option<HashMap<String, LinuxRdma>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[getset(get = "pub")]
unified: Option<HashMap<String, String>>,
}
#[derive(
Builder, Clone, Copy, CopyGetters, Debug, Default, Deserialize, Eq, PartialEq, Serialize,
)]
#[serde(rename_all = "camelCase")]
#[builder(
default,
pattern = "owned",
setter(into, strip_option),
build_fn(error = "OciSpecError")
)]
#[getset(get_copy = "pub")]
pub struct LinuxRdma {
#[serde(skip_serializing_if = "Option::is_none")]
hca_handles: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
hca_objects: Option<u32>,
}
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize, Hash)]
#[serde(rename_all = "snake_case")]
pub enum LinuxNamespaceType {
Mount = 0x00020000,
Cgroup = 0x02000000,
Uts = 0x04000000,
Ipc = 0x08000000,
User = 0x10000000,
Pid = 0x20000000,
Network = 0x40000000,
}
impl TryFrom<&str> for LinuxNamespaceType {
type Error = OciSpecError;
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),
_ => Err(oci_error(format!(
"unknown namespace {}, could not convert",
namespace
))),
}
}
}
impl Default for LinuxNamespaceType {
fn default() -> Self {
Self::Pid
}
}
#[derive(
Builder, Clone, CopyGetters, Debug, Default, Deserialize, Eq, Getters, PartialEq, Serialize,
)]
#[builder(
default,
pattern = "owned",
setter(into, strip_option),
build_fn(error = "OciSpecError")
)]
pub struct LinuxNamespace {
#[serde(rename = "type")]
#[getset(get_copy = "pub")]
typ: LinuxNamespaceType,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[getset(get = "pub")]
path: Option<PathBuf>,
}
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(
Builder, Clone, CopyGetters, Debug, Default, Deserialize, Eq, Getters, PartialEq, Serialize,
)]
#[serde(rename_all = "camelCase")]
#[builder(
default,
pattern = "owned",
setter(into, strip_option),
build_fn(error = "OciSpecError")
)]
pub struct LinuxDevice {
#[serde(default)]
#[getset(get = "pub")]
path: PathBuf,
#[serde(rename = "type")]
#[getset(get_copy = "pub")]
typ: LinuxDeviceType,
#[serde(default)]
#[getset(get_copy = "pub")]
major: i64,
#[serde(default)]
#[getset(get_copy = "pub")]
minor: i64,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[getset(get_copy = "pub")]
file_mode: Option<u32>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[getset(get_copy = "pub")]
uid: Option<u32>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[getset(get_copy = "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(
Builder, Clone, CopyGetters, Debug, Default, Deserialize, Eq, Getters, PartialEq, Serialize,
)]
#[serde(rename_all = "camelCase")]
#[builder(
default,
pattern = "owned",
setter(into, strip_option),
build_fn(error = "OciSpecError")
)]
pub struct LinuxSeccomp {
#[getset(get_copy = "pub")]
default_action: LinuxSeccompAction,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[getset(get = "pub")]
architectures: Option<Vec<Arch>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[getset(get = "pub")]
flags: Option<Vec<String>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[getset(get = "pub")]
syscalls: Option<Vec<LinuxSyscall>>,
}
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
#[repr(u32)]
pub enum LinuxSeccompAction {
ScmpActKill = 0x00000000,
ScmpActKillProcess = 0x80000000,
ScmpActTrap = 0x00030000,
ScmpActErrno = 0x00050001,
ScmpActNotify = 0x7fc00000,
ScmpActTrace = 0x7ff00001,
ScmpActLog = 0x7ffc0000,
ScmpActAllow = 0x7fff0000,
}
impl Default for LinuxSeccompAction {
fn default() -> Self {
Self::ScmpActAllow
}
}
#[allow(clippy::enum_clike_unportable_variant)]
#[derive(Clone, Copy, 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, Copy, 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,
}
impl Default for LinuxSeccompOperator {
fn default() -> Self {
Self::ScmpCmpEq
}
}
#[derive(
Builder, Clone, CopyGetters, Debug, Default, Deserialize, Eq, Getters, PartialEq, Serialize,
)]
#[builder(
default,
pattern = "owned",
setter(into, strip_option),
build_fn(error = "OciSpecError")
)]
pub struct LinuxSyscall {
#[getset(get = "pub")]
names: Vec<String>,
#[getset(get_copy = "pub")]
action: LinuxSeccompAction,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[getset(get_copy = "pub")]
errno_ret: Option<u32>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[getset(get = "pub")]
args: Option<Vec<LinuxSeccompArg>>,
}
#[derive(
Builder, Clone, Copy, CopyGetters, Debug, Default, Deserialize, Eq, PartialEq, Serialize,
)]
#[serde(rename_all = "camelCase")]
#[builder(
default,
pattern = "owned",
setter(into, strip_option),
build_fn(error = "OciSpecError")
)]
#[getset(get_copy = "pub")]
pub struct LinuxSeccompArg {
index: usize,
value: u64,
#[serde(default, skip_serializing_if = "Option::is_none")]
value_two: Option<u64>,
op: LinuxSeccompOperator,
}
pub fn get_default_maskedpaths() -> Vec<String> {
vec![
"/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(),
]
}
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(Builder, Clone, Debug, Default, Deserialize, Eq, Getters, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
#[builder(
default,
pattern = "owned",
setter(into, strip_option),
build_fn(error = "OciSpecError")
)]
#[getset(get = "pub")]
pub struct LinuxIntelRdt {
#[serde(default, skip_serializing_if = "Option::is_none")]
clos_id: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
l3_cache_schema: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
mem_bw_schema: Option<String>,
}
#[derive(
Builder, Clone, CopyGetters, Debug, Default, Deserialize, Eq, Getters, PartialEq, Serialize,
)]
#[builder(
default,
pattern = "owned",
setter(into, strip_option),
build_fn(error = "OciSpecError")
)]
pub struct LinuxPersonality {
#[getset(get_copy = "pub")]
domain: LinuxPersonalityDomain,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[getset(get = "pub")]
flags: Option<Vec<String>>,
}
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub enum LinuxPersonalityDomain {
#[serde(rename = "LINUX")]
PerLinux,
#[serde(rename = "LINUX32")]
PerLinux32,
}
impl Default for LinuxPersonalityDomain {
fn default() -> Self {
Self::PerLinux
}
}
#[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 = ["a", "b", "c", "u", "p"];
let typ_chosen = g.choose(&typ_choices).unwrap();
let typ = match typ_chosen.to_string().as_str() {
"a" => LinuxDeviceType::A,
"b" => LinuxDeviceType::B,
"c" => LinuxDeviceType::C,
"u" => LinuxDeviceType::U,
"p" => LinuxDeviceType::P,
_ => 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),
}
}
}