| 1 | # evil.inc Forgejo cutover |
| 2 | |
| 3 | Zenith's Forgejo database is 21 MB; its app directory is about 14 GB. The VM Forgejo has the same usernames for all seven numeric user IDs referenced by the imported HedgeDoc OAuth profiles. This checks identity continuity without inspecting private repository contents. The app directory must move with the database because it holds Git objects, LFS data, attachments, avatars, and indexes. |
| 4 | |
| 5 | Snow Globe generates a new automation account password, but the imported Forgejo database needs the old signing and security keys. The named secret import preserves Snow Globe's automation password while replacing only the legacy values. With `STUDIO_DEPLOY_HOST` and `STUDIO_DEPLOY_PORT` pointing at the production host, run: |
| 6 | |
| 7 | ```sh |
| 8 | bash tools/import-legacy-secrets.sh evil-forgejo \ |
| 9 | mailer_address=MAILER_ADDRESS \ |
| 10 | mailer_username=MAILER_USERNAME \ |
| 11 | mailer_password=MAILER_PASSWORD \ |
| 12 | lfs_jwt=EVIL_FORGEJO_SERVER_LFS_JWT_SECRET \ |
| 13 | oauth_jwt=EVIL_FORGEJO_OAUTH2_JWT_SECRET \ |
| 14 | security_key=EVIL_FORGEJO_SECURITY_SECRET_KEY \ |
| 15 | internal_token=EVIL_FORGEJO_SECURITY_INTERNAL_TOKEN \ |
| 16 | anubis_key=ANUBIS_PRIVATE_KEY |
| 17 | ``` |
| 18 | |
| 19 | The source `.env` contains one unquoted value for each named key. The importer streams them through stdin and checks the destination field names against the service definition. Stop the old Forgejo and HedgeDoc before the final database and app-directory copy, and keep both stopped until the new Forgejo and HedgeDoc identities are checked. Do not switch the public route before the repository data and database have been restored together. |
| 20 | |
| 21 | For a same-machine OS replacement, use the [legacy PostgreSQL handoff](legacy-handoff.md) before reboot. After the encrypted apps dataset is mounted on NixOS, import the original Forgejo secrets with `STUDIO_LEGACY_HANDOFF` set, stop the Snow Globe Forgejo job, then run `bash tools/import-evil-forgejo.sh`. It checks the retained database dump and secret fingerprints, copies `/mnt/storage1/apps/evil-infra/forgejo` directly into the managed service dataset, compares a content digest without exposing file contents, restores the database, and checks user/repository counts. It keeps the new job stopped and prints the pre-import ZFS snapshot and database dump for recovery. The 14 GB production copy has not run on the VM. |
| 22 | |
| 23 | A read-only Zenith `pg_dump` restored into a disposable VM PostgreSQL database on 2026-09-26. The source and restored database both had 10 users and 15 repositories; the disposable database was removed afterward. No repository contents were opened or copied. This verifies the logical database restore separately from the 14 GB file transfer. |
| 24 | |
| 25 | A disposable VM fixture also passed the importer's `rsync -aH --numeric-ids --one-file-system --delete` copy and `tree-hash.py` comparison, including a hardlink, symlink, owner, group, and mode. The production 14 GB transfer remains untested. |
| 26 | |
| 27 | After a database import, Snow Globe's saved HedgeDoc OAuth application ID may point to a different legacy client. The provider now checks the client ID before updating an application and creates a fresh OAuth client when the saved one is missing or belongs to another client. A VM probe used a real ID collision: the unrelated client remained unchanged, the replacement client was created, and the temporary replacement was deleted after the check. |