Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/edda

crates/estate-front/src/lib.rs

//! # estate-front — what an estate's FRONT (vm1) does that is no product's
//!
//! The estate is three VMs: vm1 the front, vm2 the product's primary, vm3 its
//! twin. gunnar built its front first (`gunnar-front`, gunnar `gunnar-live`
//! 4c3d24d); when holger's estate grew a front of its own (holger
//! `holger-estate-front`, 2026-09-27; owner: "IF YOU CAN FIND COMMON CODE MOVE
//! IT TO EDDA"), every piece of gunnar-front that knows nothing of either
//! product moved here, AS IS, gunnar's names removed:
//!
//! | module | what | from gunnar-front |
//! |---|---|---|
//! | [`web`] | the front's own HTTPS: the certificate served (fed, kept 0600, or ACME HTTP-01 in-process), the hand-over to the successor, :80 challenge + redirect, :443 swapped live, callback-only hosts, a payment vendor's `POST /callback/<vendor>[/<instance>]` carried to monetize | `src/web/{mod,acme,certs,serve,tests}.rs` |
//! | [`route`] | a product's repository carried through :443 to the primary's utility address (HTTP/1.1, and gRPC over h2c by content-type), from the feed's `repo_hosts` | the `front-product-key` lane's `repo_route.rs` |
//! | [`forward`] | a plain TCP port forwarded to the primary, re-targeted live (gunnar's tcp/2222 forge door) | `src/forward.rs` |
//! | [`relay`] | the estate's WireGuard relay on udp/51820 with the front's own tunnel key, each fed box listed once by its overlay /32 | the relay half of `gunnar-pairing-door/src/front.rs` |
//!
//! What stays with the product: its console, what it offers the installer,
//! its certification of the twin (`nordisk-twin`'s `Boxes` over its own
//! control plane), its feed keys. The installer's view of vm1 (`Vm`, kind
//! `front`) is Skidbladnir `nordisk-pairing::frontside`; the bare monetize
//! the paid front hosts is monetize's `monetize-front`. gunnar keeps its own
//! copies until it adopts these.

pub mod forward;
pub mod relay;
pub mod route;
pub mod web;

use std::path::Path;


/// **Write `text` to `<root>/<rel>`, owner-only (0600), atomically**: staged in
/// the same directory, synced, renamed, the directory synced — a key or an ACME
/// account is never half on disk and never readable by another user. The
/// directory is created 0700. (gunnar-server's `pairing::write_secret`, the one
/// call the web half made into a product.)
pub fn write_secret(root: &Path, rel: &str, text: &str) -> std::io::Result<()> {
    use std::io::Write as _;
    use std::os::unix::fs::{DirBuilderExt as _, OpenOptionsExt as _};
    let path = root.join(rel);
    let dir = path.parent().unwrap_or(root);
    std::fs::DirBuilder::new().recursive(true).mode(0o700).create(dir)?;
    let mut tmp = path.clone().into_os_string();
    tmp.push(".staging");
    let _ = std::fs::remove_file(&tmp);
    let mut f = std::fs::OpenOptions::new().write(true).create_new(true).mode(0o600).open(&tmp)?;
    f.write_all(text.as_bytes())?;
    f.sync_all()?;
    drop(f);
    std::fs::rename(&tmp, &path)?;
    if let Ok(d) = std::fs::File::open(dir) {
        let _ = d.sync_all();
    }
    Ok(())
}