Refactor VPN proxy components and update related behavior
Build and Deploy Gateway / build-and-push (push) Successful in 20s
Build and Deploy Gateway / deploy (push) Successful in 13s

This commit is contained in:
2026-08-11 01:27:46 +03:00
parent c89e56942a
commit aa9c959368
58 changed files with 4234 additions and 2755 deletions
+25 -13
View File
@@ -1,36 +1,48 @@
# Harbor state recovery
Harbor keeps the existing data paths and volumes. `state.json` now uses `schemaVersion: 4`; subscription cache, generated sing-box config and HWID keep their existing filenames. Schema v2 introduced locally managed domain routing rules. Schema v3 added rule `enabled` state. Schema v4 adds stable server IDs and migrates an unambiguous legacy `selectedTag` to `selectedServerId`.
Harbor keeps the existing data directory and `state.json` path. The current persisted format is `schemaVersion: 5`: schema v2 introduced local route rules, v3 added rule enabled state, v4 added stable server IDs, and v5 embeds the canonical `profiles[]` collection with desired/applied profile identity.
## 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
Profile/server switching prepares candidate config and runtime before the final state publication. If any later step fails, Harbor restores the previous config, runtime and canonical state.
On startup, a legacy `state.json` without `schemaVersion`, or any v1-v3 state, is normalized and migrated to the current schema. Existing custom rules are preserved. Server identity is derived from protocol, host and port; a unique legacy tag keeps selection, while duplicate or missing matches require a new explicit choice. Before replacement Harbor saves the original beside it:
## Migration to profiles
On startup, a legacy state is normalized before the process starts. Harbor creates one profile named `Основной`, moves the provider URL/config and metadata into it, and preserves unambiguous desired/applied server identity. A legacy state explicitly marked stopped clears stale applied residue.
Before replacing state Harbor saves the original beside it:
```text
state.json.backup-v0-2026-07-11T12-00-00-000Z
state.json.backup-v4-2026-08-11T12-00-00-000Z
```
The migration preserves compatibility aliases, adds normalized revision, selection and server fields, and does not rename the volume. Subscription cache keeps the raw provider config so older builds can still use its original outbound tags. The backup remains the safest manual recovery source.
After a valid profile has been committed, the raw legacy cache is saved and removed as a second owner:
```text
subscription-cache.json.backup-v1-2026-08-11T12-00-00-000Z
```
An invalid legacy provider config is backed up but not started. Harbor removes stale generated config and returns to a stopped first-run state.
## Corrupt JSON
If `state.json` cannot be parsed, Harbor renames the exact damaged bytes to:
```text
state.json.corrupt-2026-07-11T12-00-00-000Z
state.json.corrupt-2026-08-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.
It then creates a valid empty current-schema state and reports storage recovery. A corrupt legacy subscription cache is preserved with the same suffix and is never used to start stale config.
Recovery should be performed while Harbor is stopped:
## Manual recovery and downgrade
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.
Perform recovery while Harbor is stopped:
Generated config rollback also uses the atomic writer. No automatic recovery tries to guess missing subscription credentials or repair semantically invalid sing-box configuration.
1. Copy the whole data directory.
2. Inspect the intended backup with `jq . <backup-file>`.
3. Restore only matching state/cache backups to their original filenames.
4. Start Harbor and verify `GET /api/state` before applying a profile.
A pre-v5 binary cannot interpret canonical profiles. Downgrade therefore requires both pre-migration backups; deploying old code alone is not a safe rollback.