Watch
0
0
Fork
You've already forked hyperhive
0

remove the hive-c0re forge-credential chain nothing reads any more

With no nix build on the hive, the boot publish of the forge token for nix has no reader. Removes the ForgeSweep node, the token file, the git credential helper and hive-c0re's forge gitconfig sections.
This commit is contained in:
atlas 2026-10-29 22:55:31 +01:00
commit 221c3f35a1

View file

@ -1,14 +1,6 @@
//! The credential this hive reads the forge with: its own read-only account,
//! whose token `swarm-controller` mints into the store at
//! `swarm/hives/<hive>/forge/token`.
//!
//! nix's `git` cannot reach the store, so [`ReaderToken::publish_for_nix`]
//! copies the token to a runtime file that `git-credential-hive-forge`
//! (`nix/host-modules/lib/hive-forge-git.nix`) reads.
use std::path::Path;
use anyhow::Result;
use super::basic_auth_header;
@ -39,30 +31,6 @@ impl ReaderToken {
pub(crate) fn api(&self) -> anyhow::Result<forgejo_api::Forgejo> {
super::api(&self.value)
}
/// Copy this token to the file nix's `git` authenticates from
/// ([`crate::paths::FORGE_HIVE_TOKEN`]). Whether the file now holds it; a
/// failed write is logged and leaves the file as it was.
pub(crate) fn publish_for_nix(&self) -> bool {
let path = Path::new(crate::paths::FORGE_HIVE_TOKEN);
match self.write_credential(path) {
Ok(()) => true,
Err(e) => {
tracing::warn!(path = %path.display(), error = ?e, "forge: could not write the nix forge credential");
false
}
}
}
/// Login on the first line, token on the second. Written only when the
/// content differs, so a build's resolve is not a disk write.
fn write_credential(&self, path: &Path) -> Result<()> {
let content = format!("{}\n{}\n", self.login, self.value);
if std::fs::read(path).is_ok_and(|have| have == content.as_bytes()) {
return Ok(());
}
crate::secret_file::write_secret_0600(path, content.as_bytes())
}
}
/// The token to read the forge with, or `None` when the store holds none for
@ -77,16 +45,6 @@ pub async fn reader_token() -> Option<ReaderToken> {
token
}
/// Publish this hive's read token for nix; see [`ReaderToken::publish_for_nix`].
/// Whether the file holds a token.
pub async fn publish_nix_credential() -> bool {
let Some(token) = reader_token().await else {
tracing::debug!("forge: no hive read token in the store; nix has no forge credential");
return false;
};
token.publish_for_nix()
}
/// This hive's token from the store, under the hive's own identity.
///
/// `None`, never an error, for every way it can come up empty — no hive name,
@ -131,8 +89,6 @@ async fn stored_reader_token() -> Option<ReaderToken> {
#[cfg(test)]
mod tests {
use super::*;
use std::os::unix::fs::PermissionsExt as _;
fn stored() -> ReaderToken {
ReaderToken {
login: "hive-alpha".to_owned(),
@ -140,73 +96,6 @@ mod tests {
}
}
fn mode(path: &Path) -> u32 {
std::fs::metadata(path).expect("stat").permissions().mode() & 0o777
}
#[test]
fn the_nix_credential_is_the_hives_login_then_its_token_at_0600() {
let dir = tempfile::tempdir().expect("tempdir");
let path = dir.path().join("forge-hive-token");
stored().write_credential(&path).expect("written");
assert_eq!(
std::fs::read_to_string(&path).expect("read"),
"hive-alpha\nfrom-the-store\n"
);
assert_eq!(mode(&path), 0o600);
}
#[test]
fn a_rotated_token_replaces_the_nix_credential() {
let dir = tempfile::tempdir().expect("tempdir");
let path = dir.path().join("forge-hive-token");
stored().write_credential(&path).expect("first");
let rotated = ReaderToken {
login: "hive-alpha".to_owned(),
value: "rotated".to_owned(),
};
rotated.write_credential(&path).expect("second");
assert_eq!(
std::fs::read_to_string(&path).expect("read"),
"hive-alpha\nrotated\n"
);
assert_eq!(mode(&path), 0o600);
}
#[test]
fn an_unchanged_credential_is_not_rewritten() {
let dir = tempfile::tempdir().expect("tempdir");
let path = dir.path().join("forge-hive-token");
stored().write_credential(&path).expect("first");
// A rewrite goes through a sibling temp file and a rename, which
// gives the file a new inode.
let before = std::fs::metadata(&path).expect("stat");
stored().write_credential(&path).expect("second");
let after = std::fs::metadata(&path).expect("stat");
assert_eq!(
std::os::unix::fs::MetadataExt::ino(&before),
std::os::unix::fs::MetadataExt::ino(&after)
);
}
/// `hive-forge-git.nix`'s credential helper names this path as a literal.
#[test]
fn the_nix_credential_lives_on_the_runtime_tmpfs_where_the_helper_reads_it() {
assert_eq!(
crate::paths::FORGE_HIVE_TOKEN,
"/run/hyperhive/forge-hive-token"
);
assert!(crate::paths::FORGE_HIVE_TOKEN.starts_with(crate::paths::RUNTIME_ROOT));
}
#[test]
fn a_path_that_cannot_be_written_is_an_error_not_a_panic() {
let dir = tempfile::tempdir().expect("tempdir");
let file = dir.path().join("a-file");
std::fs::write(&file, "").expect("file");
assert!(stored().write_credential(&file.join("sub")).is_err());
}
#[test]
fn the_header_names_the_tokens_own_account() {
use base64::Engine as _;