fix(fips,iso): match upstream fips schema + guard ISO against stale binary

1. FIPS daemon config schema drifted: upstream jmcorgan/fips now takes
   `node.identity.persistent: true` (keys read from config-dir/fips.key)
   and `transports.udp.bind_addr: "0.0.0.0:PORT"` instead of
   `identity.key_file/pub_file` + `transports.udp.enabled/port`. The
   `tor:` transport was dropped entirely; archipelago handles Tor
   fallback itself. fips.yaml generated by archipelago::fips::config
   now matches the upstream schema, and archipelago-fips.service stops
   crashlooping on Activate. Observed on .198: 52 restarts with
   "data did not match any variant of untagged enum TransportInstances
   at line 7 column 3".

2. ISO backend-binary capture didn't verify that the captured binary
   matched the checked-out Cargo.toml version. Today's 14:40 ISO
   shipped a stale 1.4.0 binary because `core/target/release/archipelago`
   pre-dated the 1.5.0-alpha bump — the build grabbed it via the
   first-priority "local release build" path without looking at it.
   All four capture sources now go through verify_backend_version()
   which greps the binary for the expected version string; mismatches
   are skipped so the build falls through to the source-build path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-04-19 15:19:56 -04:00
parent 3441ea2459
commit fe963a1a8b
2 changed files with 58 additions and 24 deletions

View File

@@ -24,26 +24,28 @@ use super::{DAEMON_CONFIG_PATH, DAEMON_KEY_PATH, DAEMON_PUB_PATH, DEFAULT_UDP_PO
/// IPv6 TUN + DNS on defaults. Static peer list is empty — archipelago
/// feeds peers dynamically via federation updates.
pub fn render_config_yaml() -> String {
// Schema matches upstream jmcorgan/fips as of 2026-04. With
// `node.identity.persistent: true` the daemon reuses the key file at
// config-dir/fips.key (= DAEMON_KEY_PATH). Transports take `bind_addr`
// rather than `enabled: true / port: N`, and the upstream no longer
// has a `tor:` transport — archipelago's own Tor fallback handles that.
format!(
"# Generated by archipelago — do not edit by hand.\n\
# Regenerated on every key change and daemon upgrade.\n\
identity:\n \
key_file: {key_path}\n \
pub_file: {pub_path}\n\
transports:\n \
udp:\n \
enabled: true\n \
port: {port}\n \
tor:\n \
enabled: true\n\
node:\n \
identity:\n \
persistent: true\n\
tun:\n \
enabled: true\n\
enabled: true\n \
name: fips0\n \
mtu: 1280\n\
dns:\n \
enabled: true\n \
suffix: .fips\n\
bind_addr: \"127.0.0.1\"\n\
transports:\n \
udp:\n \
bind_addr: \"0.0.0.0:{port}\"\n\
peers: []\n",
key_path = DAEMON_KEY_PATH,
pub_path = DAEMON_PUB_PATH,
port = DEFAULT_UDP_PORT,
)
}
@@ -125,14 +127,16 @@ mod tests {
use super::*;
#[test]
fn test_rendered_yaml_contains_paths_and_port() {
fn test_rendered_yaml_matches_upstream_schema() {
let yaml = render_config_yaml();
assert!(yaml.contains(DAEMON_KEY_PATH));
assert!(yaml.contains(DAEMON_PUB_PATH));
assert!(yaml.contains(&DEFAULT_UDP_PORT.to_string()));
assert!(yaml.contains("persistent: true"));
assert!(yaml.contains(&format!("0.0.0.0:{}", DEFAULT_UDP_PORT)));
assert!(yaml.contains("udp:"));
assert!(yaml.contains("tor:"));
assert!(yaml.contains("tun:"));
assert!(yaml.contains("name: fips0"));
// Upstream fips dropped the `tor:` transport variant; archipelago
// handles Tor fallback itself. Make sure we didn't regress.
assert!(!yaml.contains("tor:"));
}
#[tokio::test]