//! `/api/agents/{name}/limits`, and the `limits` of `POST /api/agents`. use serde::{Deserialize, Serialize}; /// One agent's caps. A field left out is not capped by the swarm. /// /// Each value is stored as given, and only in a form systemd applies: a value /// systemd ignores ("Invalid …, ignoring") would leave the agent uncapped, /// since a swarm cap replaces the hive's answer. #[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)] #[cfg_attr(feature = "schema", derive(utoipa::ToSchema))] #[serde(deny_unknown_fields)] pub struct Caps { /// systemd `CPUQuota=`: digits, optionally `.` and one or two digits, then /// `%`; above zero and at most `21474836.47%`. `"100%"` is one core. #[serde(default, skip_serializing_if = "Option::is_none")] #[cfg_attr(feature = "schema", schema(example = "400%"))] pub cpu_quota: Option, /// systemd `MemoryMax=`: `infinity`; a percentage of physical memory /// written as for `cpu_quota`, above zero and at most `100%`; or a size: /// digits, optionally `.` and digits, then nothing, `B` or one of /// `K`/`M`/`G`/`T` (1024-based, upper case), at least one byte and below /// 2^64 - 1 bytes. #[serde(default, skip_serializing_if = "Option::is_none")] #[cfg_attr(feature = "schema", schema(example = "8G"))] pub memory_max: Option, } #[cfg(test)] mod tests { use super::Caps; #[test] fn caps_round_trip() { let wire = r#"{"cpu_quota":"400%","memory_max":"8G"}"#; let caps = Caps { cpu_quota: Some("400%".to_owned()), memory_max: Some("8G".to_owned()), }; assert_eq!(serde_json::to_string(&caps).unwrap(), wire); assert_eq!(serde_json::from_str::(wire).unwrap(), caps); assert_eq!(serde_json::to_string(&Caps::default()).unwrap(), "{}"); assert!(serde_json::from_str::(r#"{"cpu":"1%"}"#).is_err()); } }