Default profiles to persistent system paths
This commit is contained in:
parent
09dae24f52
commit
acd0b4cc8c
5 changed files with 36 additions and 3 deletions
|
|
@ -5,6 +5,7 @@ pub const STORAGE_CATALOG_SCHEMA_ID: &str = "lazaret-storage-catalog-v1";
|
|||
pub const DOMAIN_STORE_SCHEMA_VERSION: u32 = 1;
|
||||
pub const STORAGE_CATALOG_SCHEMA_VERSION: u32 = 1;
|
||||
pub const TRUSTED_HOST_CONFIGURATION_SCHEMA_ID: &str = "lazaret-trusted-host-config-v1";
|
||||
pub const DEFAULT_PERSISTENT_DIRS: [&str; 5] = ["/root", "/usr", "/var", "/etc", "/opt"];
|
||||
|
||||
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
|
|
@ -74,7 +75,7 @@ pub struct ProfileConfigurationV1 {
|
|||
pub image: String,
|
||||
#[serde(default = "default_isolate_gitignored")]
|
||||
pub isolate_gitignored: bool,
|
||||
#[serde(default)]
|
||||
#[serde(default = "default_persistent_dirs")]
|
||||
pub persistent_dirs: Vec<String>,
|
||||
#[serde(default)]
|
||||
pub allow_egress: Vec<String>,
|
||||
|
|
@ -92,6 +93,10 @@ const fn default_isolate_gitignored() -> bool {
|
|||
true
|
||||
}
|
||||
|
||||
fn default_persistent_dirs() -> Vec<String> {
|
||||
DEFAULT_PERSISTENT_DIRS.map(str::to_owned).into()
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct TrustedHostConfigurationV1 {
|
||||
#[serde(rename = "schema")]
|
||||
|
|
|
|||
|
|
@ -137,7 +137,10 @@ image = "example.invalid/agent:v1"
|
|||
let parsed = parse_trusted_configuration(minimal.as_bytes()).unwrap();
|
||||
let profile = &parsed.profiles()["default"];
|
||||
assert!(profile.isolate_gitignored);
|
||||
assert!(profile.persistent_dirs.is_empty());
|
||||
assert_eq!(
|
||||
profile.persistent_dirs,
|
||||
["/root", "/usr", "/var", "/etc", "/opt"]
|
||||
);
|
||||
assert!(profile.allow_egress.is_empty());
|
||||
assert!(profile.deny_egress.is_empty());
|
||||
assert!(profile.env.is_empty());
|
||||
|
|
@ -148,6 +151,23 @@ image = "example.invalid/agent:v1"
|
|||
assert!(parsed.network().default_allow.is_empty());
|
||||
assert!(parsed.network().default_deny.is_empty());
|
||||
|
||||
for (value, expected) in [
|
||||
("[]", Vec::<String>::new()),
|
||||
("[\"/nix\"]", vec!["/nix".to_owned()]),
|
||||
] {
|
||||
let explicit = minimal.replace(
|
||||
"image = \"example.invalid/agent:v1\"",
|
||||
&format!("image = \"example.invalid/agent:v1\"\npersistent_dirs = {value}"),
|
||||
);
|
||||
assert_eq!(
|
||||
parse_trusted_configuration(explicit.as_bytes())
|
||||
.unwrap()
|
||||
.profiles()["default"]
|
||||
.persistent_dirs,
|
||||
expected
|
||||
);
|
||||
}
|
||||
|
||||
for invalid in [
|
||||
minimal.replace("schema", "unknown"),
|
||||
format!("{minimal}unknown = true\n"),
|
||||
|
|
@ -271,6 +291,10 @@ fn repository_example_loads_with_ipv4_normalization_and_private_denies() {
|
|||
let config = write_configuration(&tree, include_str!("../../../docs/example.toml"));
|
||||
let resolved = load_trusted_configuration(request(&tree, config, BTreeMap::new())).unwrap();
|
||||
assert_eq!(resolved.selected_profile(), "default");
|
||||
assert_eq!(
|
||||
resolved.fingerprint_record().persistent_dirs,
|
||||
["/root", "/usr", "/var", "/etc", "/opt"]
|
||||
);
|
||||
assert!(
|
||||
resolved
|
||||
.effective_allow_prefixes()
|
||||
|
|
|
|||
|
|
@ -558,6 +558,7 @@ fn every_schema_shape_round_trips_and_rejects_malformed_or_unknown_versions() {
|
|||
br#"schema = "lazaret-trusted-host-config-v1"
|
||||
[profiles.trusted]
|
||||
image = "example.invalid/agent:v1"
|
||||
persistent_dirs = []
|
||||
"#,
|
||||
)
|
||||
.unwrap(),
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ default_allow = ["192.0.2.53/32", "198.51.100.53/32"]
|
|||
[profiles.default]
|
||||
image = "docker.io/library/debian:trixie"
|
||||
isolate_gitignored = true
|
||||
persistent_dirs = ["/root"]
|
||||
allow_egress = ["203.0.113.10/32"]
|
||||
volumes = [
|
||||
{ host = "{profile_dir}/agent-state", container = "/root/.local/state/agent", kind = "directory", access = "read-write", create = true },
|
||||
|
|
|
|||
|
|
@ -295,6 +295,10 @@ later product mounts, and a layout cannot be constructed without `/workspace`.
|
|||
Bundle construction, rather than trusted-host configuration syntax, owns the
|
||||
exact destination choices and transient-child classification.
|
||||
|
||||
An omitted profile `persistent_dirs` field selects `/root`, `/usr`, `/var`,
|
||||
`/etc`, and `/opt`. An explicit list replaces that default in full, including an
|
||||
empty list or paths used by an unorthodox distribution.
|
||||
|
||||
The loader resolves environment references only after structural, path, and
|
||||
network validation. A missing, non-UTF-8, or NUL-containing host value refuses
|
||||
the selected profile. Resolved values live only in one move-owned,
|
||||
|
|
|
|||
Loading…
Reference in a new issue