feat: update depot version to 0.11.1 and enhance permission handling for package extraction

This commit is contained in:
2026-03-09 01:14:10 -05:00
parent b50745a67a
commit 63e7daa479
4 changed files with 89 additions and 2 deletions
Generated
+1 -1
View File
@@ -382,7 +382,7 @@ checksum = "807800ff3288b621186fe0a8f3392c4652068257302709c24efd918c3dffcdc2"
[[package]] [[package]]
name = "depot" name = "depot"
version = "0.11.0" version = "0.11.1"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"ar", "ar",
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "depot" name = "depot"
version = "0.11.0" version = "0.11.1"
edition = "2024" edition = "2024"
[lints.rust] [lints.rust]
+70
View File
@@ -199,6 +199,7 @@ fn load_package_archive_into_staging(
let zstd_decoder = zstd::stream::read::Decoder::new(file) let zstd_decoder = zstd::stream::read::Decoder::new(file)
.with_context(|| format!("Failed to read zstd stream {}", archive_path.display()))?; .with_context(|| format!("Failed to read zstd stream {}", archive_path.display()))?;
let mut archive = tar::Archive::new(zstd_decoder); let mut archive = tar::Archive::new(zstd_decoder);
archive.set_preserve_permissions(true);
archive.unpack(&extract_dir).with_context(|| { archive.unpack(&extract_dir).with_context(|| {
format!( format!(
"Failed to extract package archive {} into {}", "Failed to extract package archive {} into {}",
@@ -289,6 +290,7 @@ fn extract_package_archive_to_staging(
let zstd_decoder = zstd::stream::read::Decoder::new(file) let zstd_decoder = zstd::stream::read::Decoder::new(file)
.with_context(|| format!("Failed to read zstd stream {}", archive_path.display()))?; .with_context(|| format!("Failed to read zstd stream {}", archive_path.display()))?;
let mut archive = tar::Archive::new(zstd_decoder); let mut archive = tar::Archive::new(zstd_decoder);
archive.set_preserve_permissions(true);
archive.unpack(&extract_dir).with_context(|| { archive.unpack(&extract_dir).with_context(|| {
format!( format!(
"Failed to extract package archive {} into {}", "Failed to extract package archive {} into {}",
@@ -2891,6 +2893,74 @@ mod tests {
Ok(()) Ok(())
} }
#[test]
#[cfg(unix)]
fn binary_archive_install_preserves_setuid_permissions() -> Result<()> {
use std::os::unix::fs::PermissionsExt;
let rootfs = tempfile::tempdir().context("Failed to create temp rootfs")?;
let pkg_dir = tempfile::tempdir().context("Failed to create temp package dir")?;
let archive_path = pkg_dir.path().join("sudo-1.0-1-x86_64.depot.pkg.tar.zst");
let file = fs::File::create(&archive_path)
.with_context(|| format!("Failed to create {}", archive_path.display()))?;
let encoder =
zstd::stream::write::Encoder::new(file, 3).context("Failed to create zstd encoder")?;
let mut tar = tar::Builder::new(encoder);
let payload = b"sudo";
let mut header = tar::Header::new_gnu();
header.set_path("bin/sudo").unwrap();
header.set_size(payload.len() as u64);
header.set_mode(0o4755);
header.set_cksum();
tar.append(&header, &payload[..]).unwrap();
let encoder = tar.into_inner().unwrap();
encoder.finish().unwrap();
let mut cfg = config::Config::for_rootfs(rootfs.path());
cfg.build_dir = rootfs.path().join("var/cache/depot/build");
cfg.db_dir = rootfs.path().join("var/lib/depot");
let staged = extract_package_archive_to_staging(&cfg, &archive_path)?;
let staged_mode = fs::metadata(staged.path().join("bin/sudo"))?
.permissions()
.mode()
& 0o7777;
assert_eq!(staged_mode, 0o4755);
let record = db::repo::BinaryRepoPackageRecord {
repo_name: "core".into(),
name: "sudo".into(),
version: "1.0".into(),
revision: 1,
filename: archive_path
.file_name()
.and_then(|f| f.to_str())
.unwrap_or_default()
.to_string(),
size: payload.len() as u64,
sha256: String::new(),
sha512: String::new(),
description: Some("sudo".into()),
homepage: Some("https://example.test".into()),
license: Some("ISC".into()),
provides: Vec::new(),
runtime_dependencies: Vec::new(),
optional_dependencies: Vec::new(),
};
let spec = package_spec_from_repo_record(&record);
let installed =
install_package_outputs_to_rootfs(&spec, staged.path(), rootfs.path(), &cfg)?;
assert_eq!(installed.len(), 1);
let root_mode = fs::metadata(rootfs.path().join("bin/sudo"))?
.permissions()
.mode()
& 0o7777;
assert_eq!(root_mode, 0o4755);
Ok(())
}
#[test] #[test]
fn merge_missing_dependencies_preserves_order_and_uniqueness() { fn merge_missing_dependencies_preserves_order_and_uniqueness() {
let merged = merge_missing_dependencies( let merged = merge_missing_dependencies(
+17
View File
@@ -214,6 +214,21 @@ fn append_os_suffix(path: &Path, suffix: &str) -> PathBuf {
PathBuf::from(s) PathBuf::from(s)
} }
#[cfg(unix)]
fn apply_unix_mode(dst: &Path, metadata: &fs::Metadata) -> Result<()> {
use std::os::unix::fs::PermissionsExt;
let mode = metadata.permissions().mode() & 0o7777;
fs::set_permissions(dst, fs::Permissions::from_mode(mode))
.with_context(|| format!("Failed to set permissions on {}", dst.display()))?;
Ok(())
}
#[cfg(not(unix))]
fn apply_unix_mode(_dst: &Path, _metadata: &fs::Metadata) -> Result<()> {
Ok(())
}
fn is_elf_file(path: &Path) -> Result<bool> { fn is_elf_file(path: &Path) -> Result<bool> {
let mut file = let mut file =
fs::File::open(path).with_context(|| format!("Failed to open {}", path.display()))?; fs::File::open(path).with_context(|| format!("Failed to open {}", path.display()))?;
@@ -647,6 +662,7 @@ pub fn install_atomic(
let dest_path = rootfs.join(rel_path); let dest_path = rootfs.join(rel_path);
if !dest_path.exists() { if !dest_path.exists() {
fs::create_dir_all(&dest_path)?; fs::create_dir_all(&dest_path)?;
apply_unix_mode(&dest_path, &src_path.symlink_metadata()?)?;
} }
} }
@@ -730,6 +746,7 @@ pub fn install_atomic(
} else { } else {
fs::copy(src_path, &dest_path) fs::copy(src_path, &dest_path)
.with_context(|| format!("Failed to install: {}", install_rel_path))?; .with_context(|| format!("Failed to install: {}", install_rel_path))?;
apply_unix_mode(&dest_path, &metadata)?;
} }
} }