feat: update depot version to 0.11.1 and enhance permission handling for package extraction
This commit is contained in:
Generated
+1
-1
@@ -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
@@ -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]
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user