feat: add repo planning/binary repo support and Meson build integration
- add repos.toml source/binary repo configuration with arch overrides and priorities - add dependency planner/execution plan flow with interactive provider selection and --yes support - expand binary repo DB metadata (sha512, dependencies, file lists) and repo owns/search helpers - add rootfs-scoped fd locking and minisign detached signing/verification helpers - add Meson build/test support for the project with builddir-local CARGO_HOME/CARGO_TARGET_DIR - install contrib example configs into sysconfdir (/etc/depot.d layout) via Meson - improve builder env handling (sanitized PATH, tool env passthrough, CXXFLAGS support) - support += appends in package specs and add build.flags.cxxflags parsing - prompt for git credentials when private repo auth is required - update docs/examples and dependency setup (system libs, zstdmt, tempfile pin)
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
//! Rootfs-scoped advisory locking helpers.
|
||||
|
||||
use crate::config::Config;
|
||||
use anyhow::{Context, Result};
|
||||
use fd_lock::{RwLock, RwLockReadGuard, RwLockWriteGuard};
|
||||
use std::fs::{self, File, OpenOptions};
|
||||
use std::io::ErrorKind;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
/// Return the rootfs-scoped lock file path.
|
||||
pub(crate) fn lock_path(config: &Config) -> PathBuf {
|
||||
config.db_dir.join("lock")
|
||||
}
|
||||
|
||||
/// Open the rootfs-scoped lock file as an fd-lock reader/writer.
|
||||
pub(crate) fn open_lock(config: &Config) -> Result<RwLock<File>> {
|
||||
let path = lock_path(config);
|
||||
if let Some(parent) = path.parent() {
|
||||
fs::create_dir_all(parent)
|
||||
.with_context(|| format!("Failed to create lock dir {}", parent.display()))?;
|
||||
}
|
||||
let file = OpenOptions::new()
|
||||
.create(true)
|
||||
.read(true)
|
||||
.write(true)
|
||||
.truncate(false)
|
||||
.open(&path)
|
||||
.with_context(|| format!("Failed to open lock file {}", path.display()))?;
|
||||
Ok(RwLock::new(file))
|
||||
}
|
||||
|
||||
/// Acquire a shared/read lock without blocking.
|
||||
pub(crate) fn try_read<'a>(
|
||||
lock: &'a RwLock<File>,
|
||||
path: &Path,
|
||||
command_name: &str,
|
||||
) -> Result<RwLockReadGuard<'a, File>> {
|
||||
lock.try_read().map_err(|e| {
|
||||
if e.kind() == ErrorKind::WouldBlock {
|
||||
anyhow::anyhow!(
|
||||
"Depot is busy (lock held by another process). Command '{}' needs a shared lock on {}",
|
||||
command_name,
|
||||
path.display()
|
||||
)
|
||||
} else {
|
||||
anyhow::anyhow!(e).context(format!(
|
||||
"Failed to acquire shared lock for '{}' on {}",
|
||||
command_name,
|
||||
path.display()
|
||||
))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Acquire an exclusive/write lock without blocking.
|
||||
pub(crate) fn try_write<'a>(
|
||||
lock: &'a mut RwLock<File>,
|
||||
path: &Path,
|
||||
command_name: &str,
|
||||
) -> Result<RwLockWriteGuard<'a, File>> {
|
||||
lock.try_write().map_err(|e| {
|
||||
if e.kind() == ErrorKind::WouldBlock {
|
||||
anyhow::anyhow!(
|
||||
"Depot is busy (lock held by another process). Command '{}' needs an exclusive lock on {}",
|
||||
command_name,
|
||||
path.display()
|
||||
)
|
||||
} else {
|
||||
anyhow::anyhow!(e).context(format!(
|
||||
"Failed to acquire exclusive lock for '{}' on {}",
|
||||
command_name,
|
||||
path.display()
|
||||
))
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user