-
Notifications
You must be signed in to change notification settings - Fork 155
Description
A chroot store is located in a directory with a nonempty prefix before /nix/store (though the logical paths, which are actually embedded in the binaries, don't include that prefix). They can be enabled with e.g. NIX_CONFIG="store = /foo/bar"; note that the path passed is the prefix, and does not include /nix/store.
attic watch-store , however, doesn't know about this logical/physical path distinction. Firstly, it doesn't manage to watch the right directory, and then secondly it filters out the notifications of new entries in the directory due to not matching the pattern of /nix/store/*.
Here's an unsuitable patch that I used to hack around the problem:
diff --git a/client/src/command/watch_store.rs b/client/src/command/watch_store.rs
index 24eaf7a..dd208e2 100644
--- a/client/src/command/watch_store.rs
+++ b/client/src/command/watch_store.rs
@@ -1,3 +1,4 @@
+use std::ffi::OsString;
use std::path::{Path, PathBuf};
use std::sync::Arc;
@@ -38,6 +39,10 @@ pub struct WatchStore {
/// Always send the upload info as part of the payload.
#[clap(long, hide = true)]
force_preamble: bool,
+
+ /// Prefix for store directory paths.
+ #[clap(long, default_value = "")]
+ root: OsString,
}
pub async fn run(opts: Opts) -> Result<()> {
@@ -49,7 +54,10 @@ pub async fn run(opts: Opts) -> Result<()> {
let config = Config::load()?;
let store = Arc::new(NixStore::connect()?);
- let store_dir = store.store_dir().to_owned();
+ // Go through OsString, to avoid PathBuf::push's replacing-with-absolute-paths behaviour
+ let mut store_dir = sub.root.clone();
+ store_dir.push(store.store_dir());
+ let store_dir: PathBuf = store_dir.into();
let (server_name, server, cache) = config.resolve_cache(&sub.cache)?;
let mut api = ApiClient::from_server_config(server.clone())?;
@@ -108,7 +116,11 @@ pub async fn run(opts: Opts) -> Result<()> {
.iter()
.filter_map(|p| {
let base = strip_lock_file(p)?;
- store.parse_store_path(base).ok()
+ let logical_relative = base.strip_prefix(&sub.root).ok()?;
+ let mut logical: OsString = "/".into();
+ logical.push(logical_relative);
+ let logical: PathBuf = logical.into();
+ store.parse_store_path(logical).ok()
})
.collect::<Vec<StorePath>>();This is obviously not suitable for merging, because there surely must be some way of discovering the prefix from CppNix (which knows full well where the store is, since it can put things in there!), but I got lost trying to figure out how to do it and the ugly hack of explicitly passing it to Attic worked well enough in the moment. With that said, I think the changes to the actual logic (as opposed to the plumbing of configuration) are fine.