Files
harbor-net/docs/recovery/state-recovery.md
Dmitriy Petrov 1304a22f1f
All checks were successful
Build and Deploy Gateway / build-and-push (push) Successful in 14s
Build and Deploy Gateway / deploy (push) Successful in 13s
Add enabled local routing rules and gateway version reporting
2026-07-11 22:14:43 +03:00

2.1 KiB

Harbor state recovery

Harbor keeps the existing data paths and volumes. state.json now uses schemaVersion: 3; subscription cache, generated sing-box config and HWID keep their existing filenames. Schema v2 introduced locally managed domain routing rules. Schema v3 adds the enabled state and migrates the former code-owned .ru exception into the first ordinary enabled rule.

Atomic writes

Persistent files are written to a unique temporary file in the same directory, flushed with fsync, closed and atomically renamed over the target. A failure before rename leaves the previous target untouched and removes the temporary file.

Migration

On startup, a legacy state.json without schemaVersion, or any v1/v2 state, is normalized and migrated to the current schema. Existing custom rules are preserved, default to enabled: true, and follow the new ordinary .ru rule. A v3 state may keep, disable, or delete that rule without Harbor recreating it. Before replacement Harbor saves the original beside it:

state.json.backup-v0-2026-07-11T12-00-00-000Z

The migration preserves existing fields, adds normalized revision, selection and server fields, and does not rename the volume. The backup is the safest rollback source because builds that only understand schema v2 do not know the per-rule enabled state.

Corrupt JSON

If state.json cannot be parsed, Harbor renames the exact damaged bytes to:

state.json.corrupt-2026-07-11T12-00-00-000Z

It then creates a valid empty current-schema state and reports storage-recovery through snapshot.operation. A corrupt subscription cache is preserved with the same suffix and reported in control logs.

Recovery should be performed while Harbor is stopped:

  1. Copy the whole data directory before changing anything.
  2. Inspect a backup with jq . <backup-file>.
  3. Restore only a valid JSON backup to the original filename.
  4. Start Harbor and verify GET /api/state before applying or importing anything.

Generated config rollback also uses the atomic writer. No automatic recovery tries to guess missing subscription credentials or repair semantically invalid sing-box configuration.