backup: make create transparent to sync/autopass
CI / Build & Test (push) Successful in 4m16s

- Stop calling closeSyncForBackup() during backup create so sync and
  autopass keep running; backup already excludes autopass/ from the
  archive.
- Restore still quiesces sync and removes autopass/ so storage can be
  replaced safely; sync reconnects on next use.
- Clarify setSyncManager comment (restore-only). Update BACKUP.md,
  SYNC.md, and ARCHITECTURE.md accordingly.
This commit is contained in:
Raven Scott
2026-03-15 16:56:20 -04:00
parent fd5ebdae99
commit 6067aadcce
4 changed files with 8 additions and 17 deletions
+2 -2
View File
@@ -80,8 +80,8 @@ Holesail Browser is composed of three parts: a browser extension, a native host
| File | Purpose |
|------|---------|
| `certificate-authority.js` | Generates a 2048-bit RSA root CA (10-year validity) using `node-forge`. Signs per-TLD wildcard domain certs on demand (1-year). Installs the CA into the OS trust store. Fingerprint-verifies to detect stale entries. |
| `backup-manager.js` | Creates/restores `tar.gz` backups of storage (state, `autopass-identity.json` when linked; **excludes** `autopass/` directory) and all certificates. Quiesces sync before copy/restore; after restore removes `autopass/` so autopass can recreate it from the identity. Supports create, list, restore, delete, and auto-prune by retention count. |
| `sync-manager.js` | Syncs state (excluding certs) across linked devices via autopass. One device is the Master (creator of the sync group); any peer can create invites for the same group (e.g. when Master is offline). Handles `getSyncStatus` (includes `isMaster`), `createSyncInvite` (same group when linked, new group when not), `pairWithInvite`; pushes state on save, pulls on autopass `update` and applies incrementally. At pair time the joining device retries until it receives a non-empty snapshot so the masters state is preserved; when applying remote updates, skips only when the incoming snapshot is empty and local state has content (so all live adds, edits, and deletions sync). Exposes `closeSyncForBackup()` for backup-manager. |
| `backup-manager.js` | Creates/restores `tar.gz` backups of storage (state, `autopass-identity.json` when linked; **excludes** `autopass/` directory) and all certificates. Backup **create** does not quiesce sync; backup **restore** quiesces sync so storage and `autopass/` can be replaced, then sync reconnects on next use. Supports create, list, restore, delete, and auto-prune by retention count. |
| `sync-manager.js` | Syncs state (excluding certs) across linked devices via autopass. One device is the Master (creator of the sync group); any peer can create invites for the same group (e.g. when Master is offline). Handles `getSyncStatus` (includes `isMaster`), `createSyncInvite` (same group when linked, new group when not), `pairWithInvite`; pushes state on save, pulls on autopass `update` and applies incrementally. At pair time the joining device retries until it receives a non-empty snapshot so the masters state is preserved; when applying remote updates, skips only when the incoming snapshot is empty and local state has content (so all live adds, edits, and deletions sync). Exposes `closeSyncForBackup()` for backup-manager restore only. |
| `ssh-manager.js` | Per SSH session: starts a Holesail client tunnel, spawns `ssh` with a real PTY via `tt-native` (`forkpty`), starts a `bare-ws` WebSocket server, and bridges PTY ↔ WebSocket. SSH is spawned only after the browser WebSocket client connects and sends a ready-signal. Password delivery uses `SSH_ASKPASS` + a named FIFO — public key auth is tried first; a password prompt appears in xterm.js only if key auth fails and no password is saved. |
| `rdp-manager.js` | Per RDP/VNC session: starts a Holesail client tunnel, starts a WebSocket server. VNC: transparent byte pipe. RDP: `node-rdpjs-2` client, converts bitmap updates to JSON. |
+3 -3
View File
@@ -15,9 +15,9 @@ Each backup archive contains:
| `certs/wildcard.hole.sail/` | Wildcard cert for the default `.hole.sail` TLD |
| `certs/wildcard.<parent>/` | One directory per custom TLD parent (e.g. `wildcard.my.internal/`, `wildcard.haha.wooo/`) |
The entire `holesail-browser-certs/` directory is archived — all wildcard cert directories are included, not just the default one. The entire `holesail-browser-storage/` directory is archived except the `backups/` subdirectory and the **`autopass/`** directory. So `state.json` and `autopass-identity.json` are included when present; the `autopass/` directory (Corestore data) is **not** backed up because it may be read or written during the backup and cannot be safely copied. Autopass will recreate the corestore from the restored identity when sync is next used. Backups do **not** include the binary itself, the log file, or other backup archives.
The entire `holesail-browser-certs/` directory is archived — all wildcard cert directories are included, not just the default one. The entire `holesail-browser-storage/` directory is archived except the `backups/` subdirectory and the **`autopass/`** directory. So `state.json` and `autopass-identity.json` are included when present; the `autopass/` directory (Corestore data) is **not** backed up and does not need to be — sync keeps running during backup create, and after a restore autopass recreates the corestore from the restored identity when you next open the Sync page or use sync. Backups do **not** include the binary itself, the log file, or other backup archives.
**Sync and backup:** Creating or restoring a backup temporarily **pauses sync** so state and identity are not written during the copy. After restore, the `autopass/` directory is removed so autopass can recreate it from the restored identity when you next open the Sync page or use sync. To sync state across devices without copying certificates, see [Device sync](SYNC.md).
**Sync and backup:** **Creating** a backup does **not** pause sync; sync and autopass keep running so backups are transparent. **Restoring** a backup temporarily pauses sync so storage can be overwritten and the `autopass/` directory removed; sync reconnects when you next open the Sync page or use sync. To sync state across devices without copying certificates, see [Device sync](SYNC.md).
The default backup retention is **5 backups** (configurable in Settings via `backupRetention`).
@@ -48,7 +48,7 @@ holesail-backup-2026-02-28_12-00-00.tar.gz
1. Open the dashboard → **Backups**
2. Find the backup you want to restore
3. Click **Restore**
4. The native host pauses sync, extracts the archive (overwriting current state, certs, and `autopass-identity.json` when present), removes any `autopass/` directory so autopass can recreate it from the identity, then reloads state from disk. Sync reconnects the next time you open the Sync page.
4. The native host briefly pauses sync, extracts the archive (overwriting current state, certs, and `autopass-identity.json` when present), removes any `autopass/` directory so autopass can recreate it from the identity, then reloads state from disk. Sync reconnects the next time you open the Sync page.
> After restoring a backup that contains different certificates, you may need to reinstall the root CA (dashboard → Proxy & CA → Install Root CA) and restart Chrome.
+1 -1
View File
@@ -64,7 +64,7 @@ To stop syncing, remove or rename the `autopass` directory and `autopass-identit
## Backups and sync
Backups (Dashboard → Backups) **include** `autopass-identity.json` when linked (so sync identity is never lost) but **do not** include the `autopass/` directory — corestore data may be in use during backup and is recreated from the identity when sync is used after a restore. Restoring a backup removes any existing `autopass/` directory so autopass can recreate it from the restored identity. Use backups for full local or cross-machine snapshots; use sync for live replication across devices (state only, no certs). See [Backups](BACKUP.md).
Backups (Dashboard → Backups) **include** `autopass-identity.json` when linked (so sync identity is never lost) but **do not** include the `autopass/` directory. Creating a backup does not pause sync; restoring briefly pauses sync then reconnects on next use. Use backups for full local or cross-machine snapshots; use sync for live replication across devices (state only, no certs). See [Backups](BACKUP.md).
## Troubleshooting