Compose selected State Anchor paths over prepared roots
This commit is contained in:
parent
71b0266cf2
commit
4dd2b150d2
2 changed files with 1575 additions and 163 deletions
|
|
@ -1,9 +1,9 @@
|
|||
use std::collections::BTreeMap;
|
||||
use std::ffi::OsString;
|
||||
use std::fs;
|
||||
use std::fs::{self, File};
|
||||
use std::os::unix::ffi::OsStringExt;
|
||||
use std::os::unix::fs::MetadataExt;
|
||||
use std::path::PathBuf;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::atomic::{AtomicU64, Ordering};
|
||||
|
||||
use lazaret_core::configuration::{
|
||||
|
|
@ -80,22 +80,193 @@ fn inherited_runtime_authority_accepts_only_the_exact_prepared_lower() {
|
|||
let expected = launch.expected_lower();
|
||||
RuntimeStateAnchorAuthority::from_inherited(
|
||||
launch.lower_fd(),
|
||||
launch.lower_label(),
|
||||
launch.persistent_root_fd(),
|
||||
launch.persistent_anchor_fd(),
|
||||
launch.persistent_anchor_label(),
|
||||
launch.runtime_root_fd(),
|
||||
launch.runtime_anchor_fd(),
|
||||
launch.runtime_anchor_label(),
|
||||
expected,
|
||||
)
|
||||
.unwrap();
|
||||
assert!(
|
||||
RuntimeStateAnchorAuthority::from_inherited(
|
||||
launch.lower_fd(),
|
||||
launch.lower_label(),
|
||||
launch.persistent_root_fd(),
|
||||
launch.persistent_anchor_fd(),
|
||||
launch.persistent_anchor_label(),
|
||||
launch.runtime_root_fd(),
|
||||
launch.runtime_anchor_fd(),
|
||||
launch.runtime_anchor_label(),
|
||||
(expected.0, expected.1 + 1),
|
||||
)
|
||||
.is_err()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn retained_prepared_lower_authority_refuses_a_replacement_descriptor() {
|
||||
let tree = TestTree::new();
|
||||
let configuration = configuration(&tree);
|
||||
let layout = StateAnchorLayout::create(&configuration).unwrap();
|
||||
let lower = tree.path.join("prepared-lower");
|
||||
let replacement = tree.path.join("replacement-lower");
|
||||
fs::create_dir(&lower).unwrap();
|
||||
fs::create_dir(&replacement).unwrap();
|
||||
let metadata = lower.metadata().unwrap();
|
||||
let artifact = PreparedArtifact {
|
||||
prepared_artifact_id: PreparedArtifactId::new([8; 32]),
|
||||
source_identity: SourceIdentity::new(b"fixture".to_vec()),
|
||||
selected_manifest_digest: SelectedManifestDigest::new([9; 32]),
|
||||
policy_id: PolicyId::new([10; 32]),
|
||||
id_map_digest: IdMapDigest::new([11; 32]),
|
||||
path: HostPath::new(b"artifacts/fixture".to_vec()),
|
||||
device: DeviceId::new(metadata.dev()),
|
||||
inode: InodeId::new(metadata.ino()),
|
||||
state: ArtifactState::Available,
|
||||
};
|
||||
let exact = File::open(&lower).unwrap();
|
||||
StateAnchorLaunchAuthority::capture_retained(&layout, &artifact, &lower, &exact).unwrap();
|
||||
let replacement = File::open(&replacement).unwrap();
|
||||
assert!(
|
||||
StateAnchorLaunchAuthority::capture_retained(&layout, &artifact, &lower, &replacement)
|
||||
.is_err()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn namespace_local_rebound_refuses_a_replaced_state_anchor() {
|
||||
let tree = TestTree::new();
|
||||
let configuration = configuration(&tree);
|
||||
let layout = StateAnchorLayout::create(&configuration).unwrap();
|
||||
let lower = tree.path.join("prepared-lower");
|
||||
fs::create_dir(&lower).unwrap();
|
||||
let artifact = prepared_artifact(&lower);
|
||||
let launch = StateAnchorLaunchAuthority::capture(&layout, &artifact).unwrap();
|
||||
let anchor = launch.runtime_anchor_label().to_owned();
|
||||
fs::rename(&anchor, anchor.with_extension("retained")).unwrap();
|
||||
fs::create_dir(&anchor).unwrap();
|
||||
|
||||
assert!(
|
||||
RuntimeStateAnchorAuthority::from_inherited(
|
||||
launch.lower_fd(),
|
||||
launch.lower_label(),
|
||||
launch.persistent_root_fd(),
|
||||
launch.persistent_anchor_fd(),
|
||||
launch.persistent_anchor_label(),
|
||||
launch.runtime_root_fd(),
|
||||
launch.runtime_anchor_fd(),
|
||||
launch.runtime_anchor_label(),
|
||||
launch.expected_lower(),
|
||||
)
|
||||
.is_err()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn namespace_local_rebound_refuses_a_replaced_prepared_lower() {
|
||||
let tree = TestTree::new();
|
||||
let configuration = configuration(&tree);
|
||||
let layout = StateAnchorLayout::create(&configuration).unwrap();
|
||||
let lower = tree.path.join("prepared-lower");
|
||||
fs::create_dir(&lower).unwrap();
|
||||
let artifact = prepared_artifact(&lower);
|
||||
let launch = StateAnchorLaunchAuthority::capture(&layout, &artifact).unwrap();
|
||||
fs::rename(&lower, lower.with_extension("retained")).unwrap();
|
||||
fs::create_dir(&lower).unwrap();
|
||||
|
||||
assert!(
|
||||
RuntimeStateAnchorAuthority::from_inherited(
|
||||
launch.lower_fd(),
|
||||
launch.lower_label(),
|
||||
launch.persistent_root_fd(),
|
||||
launch.persistent_anchor_fd(),
|
||||
launch.persistent_anchor_label(),
|
||||
launch.runtime_root_fd(),
|
||||
launch.runtime_anchor_fd(),
|
||||
launch.runtime_anchor_label(),
|
||||
launch.expected_lower(),
|
||||
)
|
||||
.is_err()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn namespace_local_rebound_refuses_a_replaced_persistent_anchor() {
|
||||
let tree = TestTree::new();
|
||||
let configuration = configuration(&tree);
|
||||
let layout = StateAnchorLayout::create(&configuration).unwrap();
|
||||
let lower = tree.path.join("prepared-lower");
|
||||
fs::create_dir(&lower).unwrap();
|
||||
let artifact = prepared_artifact(&lower);
|
||||
let launch = StateAnchorLaunchAuthority::capture(&layout, &artifact).unwrap();
|
||||
let anchor = launch.persistent_anchor_label().to_owned();
|
||||
fs::rename(&anchor, anchor.with_extension("retained")).unwrap();
|
||||
fs::create_dir(&anchor).unwrap();
|
||||
|
||||
assert!(
|
||||
RuntimeStateAnchorAuthority::from_inherited(
|
||||
launch.lower_fd(),
|
||||
launch.lower_label(),
|
||||
launch.persistent_root_fd(),
|
||||
launch.persistent_anchor_fd(),
|
||||
launch.persistent_anchor_label(),
|
||||
launch.runtime_root_fd(),
|
||||
launch.runtime_anchor_fd(),
|
||||
launch.runtime_anchor_label(),
|
||||
launch.expected_lower(),
|
||||
)
|
||||
.is_err()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn namespace_local_rebound_refuses_a_state_anchor_symlink() {
|
||||
let tree = TestTree::new();
|
||||
let configuration = configuration(&tree);
|
||||
let layout = StateAnchorLayout::create(&configuration).unwrap();
|
||||
let lower = tree.path.join("prepared-lower");
|
||||
fs::create_dir(&lower).unwrap();
|
||||
let artifact = prepared_artifact(&lower);
|
||||
let launch = StateAnchorLaunchAuthority::capture(&layout, &artifact).unwrap();
|
||||
let anchor = launch.runtime_anchor_label().to_owned();
|
||||
let retained = anchor.with_extension("retained");
|
||||
fs::rename(&anchor, &retained).unwrap();
|
||||
std::os::unix::fs::symlink(&retained, &anchor).unwrap();
|
||||
|
||||
assert!(
|
||||
RuntimeStateAnchorAuthority::from_inherited(
|
||||
launch.lower_fd(),
|
||||
launch.lower_label(),
|
||||
launch.persistent_root_fd(),
|
||||
launch.persistent_anchor_fd(),
|
||||
launch.persistent_anchor_label(),
|
||||
launch.runtime_root_fd(),
|
||||
launch.runtime_anchor_fd(),
|
||||
launch.runtime_anchor_label(),
|
||||
launch.expected_lower(),
|
||||
)
|
||||
.is_err()
|
||||
);
|
||||
}
|
||||
|
||||
fn prepared_artifact(lower: &Path) -> PreparedArtifact {
|
||||
let metadata = lower.metadata().unwrap();
|
||||
PreparedArtifact {
|
||||
prepared_artifact_id: PreparedArtifactId::new([8; 32]),
|
||||
source_identity: SourceIdentity::new(b"fixture".to_vec()),
|
||||
selected_manifest_digest: SelectedManifestDigest::new([9; 32]),
|
||||
policy_id: PolicyId::new([10; 32]),
|
||||
id_map_digest: IdMapDigest::new([11; 32]),
|
||||
path: HostPath::new(lower.as_os_str().as_encoded_bytes().to_vec()),
|
||||
device: DeviceId::new(metadata.dev()),
|
||||
inode: InodeId::new(metadata.ino()),
|
||||
state: ArtifactState::Available,
|
||||
}
|
||||
}
|
||||
|
||||
struct TestTree {
|
||||
path: PathBuf,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,8 +82,13 @@ fn run() -> io::Result<()> {
|
|||
StateAnchorLaunchAuthority::capture(&layout, &artifact).map_err(io::Error::other)?;
|
||||
let runtime_authority = RuntimeStateAnchorAuthority::from_inherited(
|
||||
launch.lower_fd(),
|
||||
launch.lower_label(),
|
||||
launch.persistent_root_fd(),
|
||||
launch.persistent_anchor_fd(),
|
||||
launch.persistent_anchor_label(),
|
||||
launch.runtime_root_fd(),
|
||||
launch.runtime_anchor_fd(),
|
||||
launch.runtime_anchor_label(),
|
||||
launch.expected_lower(),
|
||||
)
|
||||
.map_err(io::Error::other)?;
|
||||
|
|
|
|||
Loading…
Reference in a new issue