feat(artifacts): add bounded reconciliation

This commit is contained in:
2026-08-27 07:04:22 +03:00
parent 38ba898b72
commit 889b1bdb57
5 changed files with 985 additions and 9 deletions
+14 -5
View File
@@ -16,6 +16,7 @@ use sha2::{Digest, Sha256};
use crate::{ArtifactError, ArtifactRef, MAX_ARTIFACT_BYTES, RegisteredArtifact, StoredArtifact};
const SHA_DIR: &[u8] = b"sha256";
pub(crate) const QUARANTINE_DIR: &[u8] = b"quarantine";
const TEMP_PREFIX: &str = ".crank-artifact-tmp-v1-";
const RESOLVE_NO_SYMLINKS: u64 = 0x04;
static TEMP_SEQUENCE: AtomicU64 = AtomicU64::new(0);
@@ -382,7 +383,7 @@ fn check_private_dir(stat: &libc::stat) -> Result<(), ArtifactError> {
}
Ok(())
}
fn stat_fd(fd: i32) -> Result<libc::stat, ArtifactError> {
pub(crate) fn stat_fd(fd: i32) -> Result<libc::stat, ArtifactError> {
let mut stat = unsafe { std::mem::zeroed() };
if unsafe { libc::fstat(fd, &mut stat) } != 0 {
Err(ArtifactError::Storage)
@@ -390,7 +391,7 @@ fn stat_fd(fd: i32) -> Result<libc::stat, ArtifactError> {
Ok(stat)
}
}
fn check_file(stat: &libc::stat) -> Result<(), ArtifactError> {
pub(crate) fn check_file(stat: &libc::stat) -> Result<(), ArtifactError> {
if (stat.st_mode & libc::S_IFMT) != libc::S_IFREG
|| stat.st_uid != unsafe { libc::geteuid() }
|| stat.st_nlink != 1
@@ -508,7 +509,7 @@ fn write_all(fd: &OwnedFd, bytes: &[u8]) -> Result<(), ArtifactError> {
/// Debug/test-only fault seam coupled to one syscall wrapper. `Fail` models a
/// syscall that did not run; crash/hold actions happen only after success.
fn checkpointed<T>(
pub(crate) fn checkpointed<T>(
stage: &str,
operation: impl FnOnce() -> Result<T, ArtifactError>,
) -> Result<T, ArtifactError> {
@@ -608,14 +609,22 @@ fn chmod_read_only(fd: i32) -> Result<(), ArtifactError> {
}
}
fn rename_no_replace(parent: i32, old: &[u8], new: &[u8]) -> Result<bool, ArtifactError> {
rename_no_replace_at(parent, old, parent, new)
}
pub(crate) fn rename_no_replace_at(
old_parent: i32,
old: &[u8],
new_parent: i32,
new: &[u8],
) -> Result<bool, ArtifactError> {
let old = c_name(old)?;
let new = c_name(new)?;
let result = unsafe {
libc::syscall(
libc::SYS_renameat2,
parent,
old_parent,
old.as_ptr(),
parent,
new_parent,
new.as_ptr(),
libc::RENAME_NOREPLACE,
)