diff --git a/lib/crates/fabro-cli/src/commands/install.rs b/lib/crates/fabro-cli/src/commands/install.rs index 39f3d6a4b..a425daacc 100644 --- a/lib/crates/fabro-cli/src/commands/install.rs +++ b/lib/crates/fabro-cli/src/commands/install.rs @@ -139,16 +139,17 @@ fn generate_mtls_certs(dir: &Path) -> Result<()> { let server_key_path = dir.join("server.key"); std::fs::write(&server_key_path, &server_key)?; - let csr = run_openssl_with_stdin( + let csr = run_openssl( &[ "req", "-new", "-key", - "/dev/stdin", + server_key_path + .to_str() + .context("server key path is not valid UTF-8")?, "-subj", "/CN=localhost", ], - &server_key, "generate server CSR", )?; diff --git a/lib/crates/fabro-test/src/lib.rs b/lib/crates/fabro-test/src/lib.rs index 28aab0c78..44efc1c0b 100644 --- a/lib/crates/fabro-test/src/lib.rs +++ b/lib/crates/fabro-test/src/lib.rs @@ -262,13 +262,23 @@ fn ensure_parent_dir(path: &Path) { } fn with_session_lock(root: &Path, f: impl FnOnce() -> T) -> T { - std::fs::create_dir_all(root) - .unwrap_or_else(|err| panic!("failed to create {}: {err}", root.display())); let lock_path = session_lock_path(root); - ensure_parent_dir(&lock_path); - let lock_file = File::create(&lock_path) - .unwrap_or_else(|err| panic!("failed to create {}: {err}", lock_path.display())); + // Retry create-dir + create-file as a unit: another process's + // cleanup_session_root can remove_dir_all between the two calls. let deadline = std::time::Instant::now() + SESSION_LOCK_TIMEOUT; + let lock_file = loop { + std::fs::create_dir_all(root) + .unwrap_or_else(|err| panic!("failed to create {}: {err}", root.display())); + ensure_parent_dir(&lock_path); + match File::create(&lock_path) { + Ok(f) => break f, + Err(err) if std::time::Instant::now() < deadline => { + std::thread::sleep(Duration::from_millis(10)); + continue; + } + Err(err) => panic!("failed to create {}: {err}", lock_path.display()), + } + }; while !fabro_proc::try_flock_exclusive(&lock_file) .unwrap_or_else(|err| panic!("failed to lock {}: {err}", lock_path.display())) {