v0.40.0: bootstrap pull+merge onboarding (controller pulls config from hub)
Fix the onboarding 401: instead of seeding controller.yaml from the agent's HOST hub key (which the hub's customer-scoped /api/v1/report rejects), the controller now PULLS its full controller.yaml from the hub on first boot using the bootstrap's retrieval passphrase (yielding the customer-scoped key) and MERGES in the per-guest local_api block. - internal/bootstrap: contract v1->v2 (customer.id + hub.url + hub.retrieval_password + local_api; drop host key/identity). MaybeIngest gains an injected PullFunc (keeps bootstrap free of the heavy report package), pulls with bounded transient-only retry, merges local_api at YAML-map level (preserves all hub-emitted fields), idempotent + fail-safe + never-crash. - main.go: wire report.PullConfig as the pull adapter (maps ErrHubUnreachable -> ErrPullTransient; auth/not-found permanent). - Lockstep with felhom-agent v0.19.0. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,7 @@ package main
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -75,12 +76,21 @@ func main() {
|
||||
|
||||
logger, logBuffer := setupLogger(cfg)
|
||||
|
||||
// --- Bootstrap ingestion (slice 8A, doc 03 §6) ---
|
||||
// --- Bootstrap ingestion (slice 8A → v0.40.0 onboarding, doc 03 §6) ---
|
||||
// On first run, if this controller is not yet configured AND the host agent's provisioning
|
||||
// back-half attached a bootstrap.json config mount, seed controller.yaml from it and come up
|
||||
// CONFIGURED — skipping setup mode. Idempotent (never clobbers an existing controller.yaml)
|
||||
// and fail-safe (a malformed/absent bootstrap leaves us in setup mode).
|
||||
cfg = bootstrap.MaybeIngest(*configPath, cfg, logger)
|
||||
// back-half attached a bootstrap.json config mount, PULL the full controller.yaml from the hub
|
||||
// (using the bootstrap's retrieval passphrase), merge in the per-guest local_api block, and come
|
||||
// up CONFIGURED — skipping setup mode. Idempotent (never clobbers an existing controller.yaml)
|
||||
// and fail-safe (a malformed/absent bootstrap, or a hub outage at first boot, leaves us in setup
|
||||
// mode). The adapter marks a transient hub-unreachable error as retryable (the rest are permanent).
|
||||
pull := func(hubURL, customerID, retrievalPassword string) (string, error) {
|
||||
y, perr := report.PullConfig(hubURL, customerID, retrievalPassword)
|
||||
if perr != nil && errors.Is(perr, report.ErrHubUnreachable) {
|
||||
return "", fmt.Errorf("%w: %w", bootstrap.ErrPullTransient, perr)
|
||||
}
|
||||
return y, perr
|
||||
}
|
||||
cfg = bootstrap.MaybeIngest(*configPath, cfg, logger, pull)
|
||||
|
||||
// --- Wire system package debug logging ---
|
||||
if cfg.Logging.Level == "debug" {
|
||||
|
||||
Reference in New Issue
Block a user