swarm-builder: an agent option whose eval failed is left out of the reply, not read as its default
This commit is contained in:
parent
cd1b77b078
commit
5d2b0c9a54
4 changed files with 340 additions and 158 deletions
|
|
@ -173,8 +173,8 @@ mod tests {
|
|||
system: "x86_64-linux".to_owned(),
|
||||
built_unix: 1,
|
||||
cached,
|
||||
private_users: false,
|
||||
nix_builds: hive_types::NixBuilds::Host,
|
||||
private_users: Some(false),
|
||||
nix_builds: Some(hive_types::NixBuilds::Host),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -245,8 +245,8 @@ mod tests {
|
|||
system: "x86_64-linux".to_owned(),
|
||||
built_unix: 1,
|
||||
cached: true,
|
||||
private_users: false,
|
||||
nix_builds: hive_types::NixBuilds::Host,
|
||||
private_users: Some(false),
|
||||
nix_builds: Some(hive_types::NixBuilds::Host),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -274,8 +274,8 @@ fn closure(cached: bool) -> AgentClosure {
|
|||
system: "x86_64-linux".to_owned(),
|
||||
built_unix: 1,
|
||||
cached,
|
||||
private_users: false,
|
||||
nix_builds: hive_types::NixBuilds::Host,
|
||||
private_users: Some(false),
|
||||
nix_builds: Some(hive_types::NixBuilds::Host),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -518,13 +518,14 @@ fn socket_bind(agent_name: &str, socket_dir: &Path, private_users: Option<bool>)
|
|||
}
|
||||
|
||||
/// What hive-priv is told about the agent's user namespace: the record's flag,
|
||||
/// or `None` (leave the agent as it is) when there is no record or it cannot be
|
||||
/// read, so a swarm outage never turns a namespaced agent off or on.
|
||||
/// or `None` (leave the agent as it is) when there is no record, it cannot be
|
||||
/// read, or it carries no flag because the builder could not read the option,
|
||||
/// so neither a swarm outage nor a failed eval turns a namespaced agent off or on.
|
||||
fn private_users_of(
|
||||
record: &Result<Option<swarm_wire::agent_closures::AgentClosure>>,
|
||||
) -> Option<bool> {
|
||||
match record {
|
||||
Ok(record) => record.as_ref().map(|r| r.private_users),
|
||||
Ok(record) => record.as_ref().and_then(|r| r.private_users),
|
||||
Err(e) => {
|
||||
tracing::warn!(error = %format!("{e:#}"), "closure record unreadable; the agent's user namespace is left as it is");
|
||||
None
|
||||
|
|
@ -533,13 +534,15 @@ fn private_users_of(
|
|||
}
|
||||
|
||||
/// What hive-priv is told about the agent's nix builds: the record's mode, or
|
||||
/// `None` (leave the agent as the last write set it) when there is no record or
|
||||
/// it cannot be read, so a swarm outage never turns an agent's host builds on.
|
||||
/// `None` (leave the agent as the last write set it) when there is no record,
|
||||
/// it cannot be read, or it carries no mode because the builder could not read
|
||||
/// the option, so neither a swarm outage nor a failed eval turns an agent's
|
||||
/// host builds on.
|
||||
fn nix_builds_of(
|
||||
record: &Result<Option<swarm_wire::agent_closures::AgentClosure>>,
|
||||
) -> Option<NixBuilds> {
|
||||
match record {
|
||||
Ok(record) => record.as_ref().map(|r| r.nix_builds),
|
||||
Ok(record) => record.as_ref().and_then(|r| r.nix_builds),
|
||||
Err(e) => {
|
||||
tracing::warn!(error = %format!("{e:#}"), "closure record unreadable; the agent's nix builds are left as they are");
|
||||
None
|
||||
|
|
@ -579,13 +582,13 @@ mod tests {
|
|||
use crate::coordinator::HiveEnv;
|
||||
use hive_types::NixBuilds;
|
||||
|
||||
fn record_with(private_users: bool) -> swarm_wire::agent_closures::AgentClosure {
|
||||
record_with_builds(private_users, NixBuilds::Host)
|
||||
fn record_with(private_users: Option<bool>) -> swarm_wire::agent_closures::AgentClosure {
|
||||
record_with_builds(private_users, Some(NixBuilds::Host))
|
||||
}
|
||||
|
||||
fn record_with_builds(
|
||||
private_users: bool,
|
||||
nix_builds: NixBuilds,
|
||||
private_users: Option<bool>,
|
||||
nix_builds: Option<NixBuilds>,
|
||||
) -> swarm_wire::agent_closures::AgentClosure {
|
||||
swarm_wire::agent_closures::AgentClosure {
|
||||
meta_rev: "a".repeat(40),
|
||||
|
|
@ -613,48 +616,58 @@ mod tests {
|
|||
assert!(!b.read_only);
|
||||
}
|
||||
|
||||
/// The flag in the record is what hive-priv is told, both ways. No record
|
||||
/// and an unreadable one say nothing, so a swarm outage changes no agent's
|
||||
/// namespace; a record from before the field reads false.
|
||||
/// The flag in the record is what hive-priv is told, both ways. No record,
|
||||
/// an unreadable one, and a record whose builder could not read the option
|
||||
/// (or that predates the field) say nothing, so neither a swarm outage nor
|
||||
/// a failed eval changes an agent's namespace.
|
||||
#[test]
|
||||
fn the_records_flag_is_what_the_start_path_passes() {
|
||||
assert_eq!(
|
||||
super::private_users_of(&Ok(Some(record_with(true)))),
|
||||
Some(true)
|
||||
);
|
||||
assert_eq!(
|
||||
super::private_users_of(&Ok(Some(record_with(false)))),
|
||||
Some(false)
|
||||
);
|
||||
for flag in [true, false] {
|
||||
assert_eq!(
|
||||
super::private_users_of(&Ok(Some(record_with(Some(flag))))),
|
||||
Some(flag)
|
||||
);
|
||||
}
|
||||
assert_eq!(super::private_users_of(&Ok(None)), None);
|
||||
assert_eq!(super::private_users_of(&Err(anyhow::anyhow!("down"))), None);
|
||||
assert_eq!(
|
||||
super::private_users_of(&Ok(Some(record_with(None)))),
|
||||
None,
|
||||
"an unread flag keeps the last write"
|
||||
);
|
||||
let old = serde_json::json!({
|
||||
"meta_rev": "a", "store_path": "/nix/store/x",
|
||||
"system": "s", "built_unix": 1,
|
||||
});
|
||||
let old = serde_json::from_value(old).expect("decodes");
|
||||
assert_eq!(super::private_users_of(&Ok(Some(old))), Some(false));
|
||||
assert_eq!(super::private_users_of(&Ok(Some(old))), None);
|
||||
}
|
||||
|
||||
/// The record's mode is what hive-priv is told, both ways. No record and an
|
||||
/// unreadable one say nothing, so a swarm outage changes no agent; a record
|
||||
/// from before the field reads as host builds.
|
||||
/// The record's mode is what hive-priv is told, both ways. No record, an
|
||||
/// unreadable one, and a record whose builder could not read the option (or
|
||||
/// that predates the field) say nothing, so neither a swarm outage nor a
|
||||
/// failed eval changes an agent.
|
||||
#[test]
|
||||
fn the_records_nix_builds_is_what_the_start_path_passes() {
|
||||
for mode in [NixBuilds::Host, NixBuilds::Disabled] {
|
||||
assert_eq!(
|
||||
super::nix_builds_of(&Ok(Some(record_with_builds(false, mode)))),
|
||||
super::nix_builds_of(&Ok(Some(record_with_builds(None, Some(mode))))),
|
||||
Some(mode)
|
||||
);
|
||||
}
|
||||
assert_eq!(super::nix_builds_of(&Ok(None)), None);
|
||||
assert_eq!(super::nix_builds_of(&Err(anyhow::anyhow!("down"))), None);
|
||||
assert_eq!(
|
||||
super::nix_builds_of(&Ok(Some(record_with_builds(None, None)))),
|
||||
None,
|
||||
"an unread mode keeps the last write"
|
||||
);
|
||||
let old = serde_json::json!({
|
||||
"meta_rev": "a", "store_path": "/nix/store/x",
|
||||
"system": "s", "built_unix": 1,
|
||||
});
|
||||
let old = serde_json::from_value(old).expect("decodes");
|
||||
assert_eq!(super::nix_builds_of(&Ok(Some(old))), Some(NixBuilds::Host));
|
||||
assert_eq!(super::nix_builds_of(&Ok(Some(old))), None);
|
||||
// A mode a newer swarm wrote, which this build does not know, decodes
|
||||
// and builds nothing.
|
||||
let newer = serde_json::json!({
|
||||
|
|
|
|||
Loading…
Reference in a new issue