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

nordisk/holger

.nornir/embed-guide.md

Embed holger in your own process — guide

Class: guide · Function: embed. Architecture: embed-design.md. You don't have to run holger as a server — link holger-server-lib, parse (or generate) a RON config, and drive it through the Holger functional API. No gRPC, no socket. This is exactly what nornir's embed-holger feature does.

Generate the dev-pair config and wire it

use holger_server_lib::{read_ron_config, wire_holger, Holger};
use holger_server_lib::dev_pair_ron;   // re-exported from lib root
use std::path::Path;

// One writable cache mirror (/cache) + one rehearsal registry (/sparring),
// both backed by on-disk .znippy archives under `data_dir`.
let ron = dev_pair_ron(Path::new("/tmp/holger-dev"), "127.0.0.1:50051", "127.0.0.1:8080");
std::fs::write("/tmp/holger-dev/holger.ron", &ron)?;

let mut holger: Holger = read_ron_config("/tmp/holger-dev/holger.ron")?;
wire_holger(&mut holger)?;             // resolves the repo→endpoint→storage graph

Drive it directly — no network

use holger_server_lib::ArtifactId;     // re-exported for in-process consumers

// names of the configured repos: ["crates-io", "cache", "sparring"]
for name in holger.list_repositories() { println!("repo: {name}"); }

// store + fetch bytes through a writable repo's backend
let id = ArtifactId { namespace: None, name: "serde".into(), version: "1.0.0".into() };
holger.put("sparring", &id, b"...crate bytes...")?;
let bytes = holger.fetch("sparring", &id)?;     // Some(...) — read-only repos error on put

Enumerate a repo's contents (the viz-pane path)

fetch/put are by-id. To list what's in a repo, reach the backend directly — it's an Arc<dyn RepositoryBackendTrait>, and the trait + entry types are re-exported so you need no separate holger-traits dep:

use holger_server_lib::{RepositoryBackendTrait, ArtifactEntry};

for repo in &holger.repositories {
    if let Some(backend) = &repo.backend_repository {
        let entries: Vec<ArtifactEntry> = backend.list(None, 100)?;      // crates in the .znippy
        let files:   Vec<String>        = backend.archive_files(None)?;  // raw archive paths
        // ...
    }
}

Writable-repo gotcha (fixed in 8c9e458): list/archive_files now read via open_reader(), so a writable dev-mode repo (/cache, /sparring) enumerates its on-disk crates. If you fork an older holger, port that fix or your dev-pair will look empty.

When to embed vs run a server

Embed when the consumer is the security boundary (a single process that wants a registry without a socket) — the host owns auth/transport. Run holger-server when independent clients over the network must reach it. The embedded path adds no egress of its own unless the embedded config wires a writable+upstream repo (the dev-pair /cache deliberately does, for the dev-mirror use case).