fix: restart Dever releases at 0.0.1 with complete signed assets

This commit is contained in:
Codex committed 2026-10-12 07:31:28 +00:00
1 parent 5589b657db
commit faf8b168a7
22 files changed
+582 -94

No files matched your search

@@ -0,0 +1,95 @@
use super::Stage;
use std::collections::BTreeMap;
use std::fs;
use std::os::unix::fs::MetadataExt;
#[allow(dead_code)]
#[path = "support/native_elf.rs"]
mod elf;
fn prepared(files: &BTreeMap<String, (Vec<u8>, bool)>) -> Stage {
let stage = Stage::new().unwrap();
for (path, (bytes, executable)) in files {
stage
.write(&format!("input/{path}"), bytes, *executable)
.unwrap();
}
stage
}
#[test]
fn signed_tool_libraries_share_bytes_without_replacing_host_glibc() {
let names = [
"libbfd.so",
"libstdc++.so.6",
"libgcc_s.so.1",
"libc.so.6",
"libm.so.6",
"libmvec.so.1",
"libanl.so.1",
"libdl.so.2",
"libpthread.so.0",
"librt.so.1",
"libutil.so.1",
"libresolv.so.2",
"ld-linux-x86-64.so.2",
"ld-linux-aarch64.so.1",
];
let files = names
.into_iter()
.map(|name| {
(
format!("rootfs/usr/lib/fixture/{name}"),
(elf::library(name, &[]), false),
)
})
.collect();
let stage = prepared(&files);
stage.link_tool_libraries(&files).unwrap();
for name in names {
let destination = stage.0.join("input/lib").join(name);
if matches!(name, "libbfd.so" | "libstdc++.so.6" | "libgcc_s.so.1") {
let source = stage.0.join("input/rootfs/usr/lib/fixture").join(name);
assert_eq!(
fs::metadata(&source).unwrap().ino(),
fs::metadata(&destination).unwrap().ino()
);
assert_eq!(fs::read(source).unwrap(), fs::read(destination).unwrap());
} else {
assert!(!destination.exists());
}
}
}
#[test]
fn duplicate_sonames_require_identical_signed_bytes() {
let original = elf::library("libfixture.so", &[]);
let mut files = BTreeMap::from([
("rootfs/usr/lib/first.so".into(), (original.clone(), false)),
("rootfs/usr/lib/second.so".into(), (original, false)),
]);
let stage = prepared(&files);
stage.link_tool_libraries(&files).unwrap();
files.get_mut("rootfs/usr/lib/second.so").unwrap().0 =
elf::library("libfixture.so", &["libc.so.6"]);
let stage = prepared(&files);
assert!(
stage
.link_tool_libraries(&files)
.unwrap_err()
.contains("conflicting SONAMEs")
);
}
#[test]
fn tool_library_names_cannot_escape_the_owned_search_directory() {
for name in ["../escape.so", "/escape.so", "nested/escape.so"] {
let files = BTreeMap::from([(
"rootfs/usr/lib/fixture.so".into(),
(elf::library(name, &[]), false),
)]);
let stage = prepared(&files);
assert!(stage.link_tool_libraries(&files).is_err());
assert!(!stage.0.join("input/escape.so").exists());
}
}
@@ -177,9 +177,9 @@ fn signed_installed_versions_keep_their_original_bootstrap_service_template() {
}
#[test]
fn signed_historical_bootstrap_profiles_are_read_only_and_version_bound() {
fn historical_bootstrap_profiles_are_rejected_regardless_of_version_number() {
use dever_cli::toolchain::{Artifact, Layout, MachineManager, Version};
for release_version in ["0.1.4", "0.1.5"] {
for release_version in ["0.0.1", "0.1.4", "0.1.6"] {
let mut author = Author::new();
author.settings["version"] = json!(release_version);
add_bootstrap(&mut author);
@@ -220,26 +220,12 @@ fn signed_historical_bootstrap_profiles_are_read_only_and_version_bound() {
)
.unwrap();
let manager = MachineManager::new(layout);
if release_version == "0.1.4" {
assert_eq!(
manager.resolve_core(&version).unwrap(),
installed.join("dever-core")
);
fs::write(profile, b"unsigned change").unwrap();
assert!(
manager
.resolve_core(&version)
.unwrap_err()
.contains("integrity verification")
);
} else {
assert!(
manager
.resolve_core(&version)
.unwrap_err()
.contains("unsupported artifact")
);
}
assert!(
manager
.resolve_core(&version)
.unwrap_err()
.contains("unsupported artifact")
);
}
}
+14 -17
View File
@@ -4,12 +4,12 @@ use dever_runtime::config::RuntimeProfile;
#[test]
#[cfg(target_arch = "x86_64")]
fn target_resource_namespaces_are_bound_to_the_signed_release_version() {
fn target_resource_namespaces_do_not_depend_on_release_version_numbers() {
use dever_cli::toolchain::{
Artifact, Extension, ExtensionKind, ReleaseManifest, Version, validate_catalog,
};
let mut manifest = ReleaseManifest::new(
Version::parse("0.1.4").unwrap(),
Version::parse("0.0.1").unwrap(),
vec![Artifact {
path: "dever-core".into(),
bytes: 1,
@@ -25,21 +25,18 @@ fn target_resource_namespaces_are_bound_to_the_signed_release_version() {
sha256: "0".repeat(64),
}],
});
validate_catalog(&manifest).unwrap();
manifest.version = Version::parse("0.1.5").unwrap();
assert!(
validate_catalog(&manifest)
.unwrap_err()
.contains("resource namespace")
);
manifest.extensions[0].artifacts[0].path = "process-runtime/linux-aarch64/lib/libc.so.6".into();
validate_catalog(&manifest).unwrap();
manifest.version = Version::parse("0.1.4").unwrap();
assert!(
validate_catalog(&manifest)
.unwrap_err()
.contains("resource namespace")
);
for version in ["0.0.1", "0.1.4", "0.1.6", "1.0.0"] {
manifest.version = Version::parse(version).unwrap();
manifest.extensions[0].artifacts[0].path = "sandbox/linux-aarch64/lib/libc.so.6".into();
assert!(
validate_catalog(&manifest)
.unwrap_err()
.contains("resource namespace")
);
manifest.extensions[0].artifacts[0].path =
"process-runtime/linux-aarch64/lib/libc.so.6".into();
validate_catalog(&manifest).unwrap();
}
}
#[cfg(target_arch = "x86_64")]
pub(super) fn cross_author() -> Author {