Legend Populate Script — 30/30 Personas Complete
Status: ✅ 30/30 personas fully provisioned across all 7 services (0 errors)
Run date: 2026-05-20
Summary
scripts/legend-populate.py creates 10 users × 3 personas = 30 personas total. Each persona is registered for and uses:
- Mailcow (mailbox auto-created via VDI launch → ensurePersonaMailbox)
- Mattermost (self-signup + post to town-square)
- Mastodon (account via tootctl + Rails token + post)
- phpBB (account creation + test post)
- HumHub (account creation + post)
- Wallabag (account + bookmark save)
- Pixelfed (account + photo post)
All credentials saved to vault via orchestrator API.
Fixes Applied This Run
Infrastructure
- Mailcow domain limit: Raised legend.local mailbox limit from 20 → 100 via Mailcow API
- VDI service IP exhaustion: Added cleanup_vdi_pods() at script start to delete all vdi-p-* pods/svcs (was: 170 stale pods exhausting ClusterIP range)
- Keycloak token expiry: Now refreshes admin token before EVERY user (was: every 2 users → 404s for later users)
Mattermost
- Bot now adds new users to default team before posting (new MM users have no team membership)
- Bot fetches town-square channel ID via
/teams/{id}/channels/name/town-square
Mastodon
- Switched from API registration (5/hour rate limit) to
tootctl accounts create(no rate limit) - Switched from password grant (not supported) to Rails
Doorkeeper::AccessToken.find_or_create_for - Changed email domain from
.local(fails MX) to@legend.paralla.org - Fixed pod label selector:
app=mastodon,component=web(notapp=mastodon-web) - Fixed
X-RateLimit-Resetparsing: ISO 8601 string, not Unix timestamp
Pixelfed
- Added
--confirm_email=1to artisan user:create (required flag) - OAuth password grant uses email address, not username
- Duplicate user detection now checks for “duplicate”, “unique”, “1062” (not just “already”)
Wallabag
- Fixed client_id format:
1_legend_test_client_2024(FOSOAuthServerBundle{id}_{random_id}format) - Admin password:
Legend2024!(not defaultwallabag)
Orchestrator Vault Save
- Script sends
password_encryptedfield (deployed pod only reads this field, notpassword)
Known Issues / Deferred
- Deployed orchestrator image is stale: Git has
password || password_encryptedfallback fix but deployed image does not. Needs CI rebuild. - Hooks proxy allowlist: Currently uses blocklist (LOCAL_API_ROUTES). Proposed to pvs to convert to allowlist — awaiting approval.
- Pixelfed artisan cache: Routes are ephemeral in pod fs. Need
php artisan config:clear && route:clear && route:cacheafter each pod restart.
Script Location
/home/claude/code/legend/scripts/legend-populate.py