Holesail URL Persist
This commit is contained in:
@@ -5,6 +5,7 @@ Authoritative **version alignment** with protocol and telemetry schema numbers l
|
||||
## Maintenance
|
||||
|
||||
- **`bare-os-www` initd** — Stock static HTTP server for **`~/.www`** on **`127.0.0.1:8088`** ( **`bare-os-www-initd.js`**, **`bare-os-www-holesail.js`** ); managed **Holesail** entry **`bare-www-<port>`** with **`host: 127.0.0.1`**; **`ensureBareOsWwwHomeDefaults`** after **`login`** (creates **`~/.www`** when missing); **`maybeRestartBareOsWwwAfterIdentity`** restarts the unit after unlock/register/`applyLoginKeys` and after **`logout`** so the listener tracks the current session **`HOME`** (not a stale closed-over **`ctx`**). Handbook [ch.4 § bare-os-www](../../handbook/04-the-booter-runtime.md#bare-os-www-static-http-for-www); env **`BARE_OS_WWW_*`** in [environment appendix](../../docs/reference/environment-and-posix-appendix.md).
|
||||
- **Managed Holesail (`bare-holesail-managed.js`)** — When a **server** row in **`~/.holesail/state.json`** has no **`key`**, the booter persists the minted **`hs://…`** URL from the running **`Holesail`** instance after **`ready()`**, and **`holesail start …`** backfills the same when the process was already live. Restores stable tunnel URLs across boot and login.
|
||||
- **Shell completion / Fish REPL:** canonical documentation is [`docs/reference/shell-completion-and-repl-editor.md`](../../docs/reference/shell-completion-and-repl-editor.md) (engine in **`lib/completion-engine.js`**, UI in **`lib/fish-readline.js`**, **`BARE_OS_FISH`**, **`BARE_OS_COMPACT_MENU`**).
|
||||
- **`baretop` snapshot**: **`ctx.bareOsReadBareTopSnapshot({ lite: true })`** returns a reduced **`files`** map (see **`BARE_TOP_SNAPSHOT_LITE_ENTRIES`** in **`packages/bare-os-coreutils/lib/baretop-snapshot.js`**). Full batch includes **`securityPosture`** → **`/proc/bare_os/security_posture.json`**. **`metrics_live`** JSON uses **`schema: 4`** with embedded **`processTable`** when present; kernel counters include optional **`vfs.readfile.samples`** ( **`BARE_OS_VFS_READ_METRICS`** ), **`initd.unit_failed_final`**, and **`shell.pipeline_last_stages`** gauge from the shell.
|
||||
- **`/proc/bare_os/net_summary.json`**: **`schemaVersion` 2** adds scalar **`replicationQueueDepth`**, firewall session totals, optional **`BARE_OS_BSD_SOCKET_BRIDGE_STATS_JSON`** merge into **`bsdSocketGuestBridge`**; **`peer_firewall_stats`** field alignment documented in **`bare-os-protocol`** channel handler.
|
||||
|
||||
@@ -187,6 +187,32 @@ export function bareHolesailManagedDebugEnabled(ctx, env) {
|
||||
return bareHolesailEnvTruthy(env.BARE_OS_HOLESAIL_DEBUG)
|
||||
}
|
||||
|
||||
/**
|
||||
* After a managed **server** is in `managedInstances`, write the minted `hs://…` URL into
|
||||
* `state.json` when `key` is missing so reboot / login restores the same tunnel identity.
|
||||
* @param {Record<string, unknown>} ctx
|
||||
* @param {Record<string, string | undefined>} env
|
||||
* @param {string} id
|
||||
*/
|
||||
async function persistManagedServerHsUrlIfMissing(ctx, env, id) {
|
||||
const url = bareHolesailManagedRuntimeUrl(id).trim()
|
||||
if (!url) return
|
||||
const { state } = await bareHolesailManagedReadState(ctx, env)
|
||||
const cur = state.connections[id]
|
||||
if (!cur || typeof cur !== 'object') return
|
||||
const row = /** @type {Record<string, unknown>} */ (cur)
|
||||
if (!bareHolesailEnvTruthy(row.server)) return
|
||||
if (String(row.key ?? '').trim()) return
|
||||
row.key = url
|
||||
state.connections[id] = row
|
||||
await bareHolesailManagedWriteState(ctx, env, state)
|
||||
const rec = managedInstances.get(id)
|
||||
if (rec && rec.entry && typeof rec.entry === 'object') {
|
||||
/** @type {Record<string, unknown>} */ (rec.entry).key = url
|
||||
}
|
||||
logLine(ctx, `managed: persisted server key for ${id}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Record<string, unknown>} ctx
|
||||
* @param {string} id
|
||||
@@ -202,6 +228,14 @@ async function startManagedInstance(ctx, env, id, entry) {
|
||||
const hs = new Holesail(norm.entry)
|
||||
await hs.ready()
|
||||
managedInstances.set(id, { hs, entry: norm.entry })
|
||||
if (norm.entry.server) {
|
||||
try {
|
||||
await persistManagedServerHsUrlIfMissing(ctx, env, id)
|
||||
} catch (e) {
|
||||
const msg = (e && /** @type {{ message?: string }} */ (e).message) || String(e)
|
||||
logLine(ctx, `managed: persist key ${id} skipped: ${msg}`)
|
||||
}
|
||||
}
|
||||
logLine(ctx, `managed: started ${id}`)
|
||||
if (bareHolesailManagedDebugEnabled(ctx, env)) {
|
||||
try {
|
||||
@@ -355,6 +389,14 @@ export async function bareHolesailManagedStartOne(ctx, env, id) {
|
||||
if (!norm.ok) throw new Error(norm.err)
|
||||
if (!norm.entry.enabled) throw new Error(`holesail: ${idOk.id} is disabled`)
|
||||
await startManagedInstance(ctx, env, idOk.id, norm.entry)
|
||||
if (norm.entry.server) {
|
||||
try {
|
||||
await persistManagedServerHsUrlIfMissing(ctx, env, idOk.id)
|
||||
} catch (e) {
|
||||
const msg = (e && /** @type {{ message?: string }} */ (e).message) || String(e)
|
||||
logLine(ctx, `managed: persist key ${idOk.id} (startOne): ${msg}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -21,7 +21,7 @@ Use when the user asks about **Holesail** in this repo: exposing TCP/UDP through
|
||||
|
||||
## Managed vs single-tunnel mode
|
||||
|
||||
- **Managed (default)** — **`BARE_OS_HOLESAIL_MANAGED=1`**. Persisted tunnel list in **`BARE_OS_HOLESAIL_STATE`** (default **`~/.holesail/state.json`**, on the **personal** drive under the session **`$HOME`**). On unit start, each **enabled** entry gets its own **`holesail`** instance. Operator CLI: **`holesail list`**, **`add`**, **`remove`**, **`start`**, **`stop`**, **`restart`**, **`enable`**, **`disable`**, plus **`path`** (prints resolved state path) and **`help`**.
|
||||
- **Managed (default)** — **`BARE_OS_HOLESAIL_MANAGED=1`**. Persisted tunnel list in **`BARE_OS_HOLESAIL_STATE`** (default **`~/.holesail/state.json`**, on the **personal** drive under the session **`$HOME`**). On unit start, each **enabled** entry gets its own **`holesail`** instance. **Server** rows without **`key`** receive the minted **`hs://…`** string in **`state.json`** after **`ready()`** so the URL survives reboot/login (**`bare-holesail-managed.js`**). Operator CLI: **`holesail list`**, **`add`**, **`remove`**, **`start`**, **`stop`**, **`restart`**, **`enable`**, **`disable`**, plus **`path`** (prints resolved state path) and **`help`**.
|
||||
- **Single tunnel** — Set **`BARE_OS_HOLESAIL_MANAGED=0`**, then exactly one of **`BARE_OS_HOLESAIL_SERVER=1`** or **`BARE_OS_HOLESAIL_CLIENT=1`**, and in client mode **`BARE_OS_HOLESAIL_KEY=…`**. Optional: **`BARE_OS_HOLESAIL_SECURE`**, **`PORT`**, **`HOST`**, **`UDP`**, **`LOG`**.
|
||||
|
||||
## Early booter (“kernel-path”) instance
|
||||
|
||||
@@ -21,7 +21,7 @@ Use when the user asks about **Holesail** in this repo: exposing TCP/UDP through
|
||||
|
||||
## Managed vs single-tunnel mode
|
||||
|
||||
- **Managed (default)** — **`BARE_OS_HOLESAIL_MANAGED=1`**. Persisted tunnel list in **`BARE_OS_HOLESAIL_STATE`** (default **`~/.holesail/state.json`**, on the **personal** drive under the session **`$HOME`**). On unit start, each **enabled** entry gets its own **`holesail`** instance. Operator CLI: **`holesail list`**, **`add`**, **`remove`**, **`start`**, **`stop`**, **`restart`**, **`enable`**, **`disable`**, plus **`path`** (prints resolved state path) and **`help`**.
|
||||
- **Managed (default)** — **`BARE_OS_HOLESAIL_MANAGED=1`**. Persisted tunnel list in **`BARE_OS_HOLESAIL_STATE`** (default **`~/.holesail/state.json`**, on the **personal** drive under the session **`$HOME`**). On unit start, each **enabled** entry gets its own **`holesail`** instance. **Server** rows without **`key`** receive the minted **`hs://…`** string in **`state.json`** after **`ready()`** so the URL survives reboot/login (**`bare-holesail-managed.js`**). Operator CLI: **`holesail list`**, **`add`**, **`remove`**, **`start`**, **`stop`**, **`restart`**, **`enable`**, **`disable`**, plus **`path`** (prints resolved state path) and **`help`**.
|
||||
- **Single tunnel** — Set **`BARE_OS_HOLESAIL_MANAGED=0`**, then exactly one of **`BARE_OS_HOLESAIL_SERVER=1`** or **`BARE_OS_HOLESAIL_CLIENT=1`**, and in client mode **`BARE_OS_HOLESAIL_KEY=…`**. Optional: **`BARE_OS_HOLESAIL_SECURE`**, **`PORT`**, **`HOST`**, **`UDP`**, **`LOG`**.
|
||||
|
||||
## Early booter (“kernel-path”) instance
|
||||
|
||||
Reference in New Issue
Block a user