Fixing _instanceRewriteTools does nothing for an instance already on disk, and a clone from the old code is broken in ways that never announce themselves: every Tools action answers "App '<slug>' has no tool '<id>'" because dockerAppRunTool wants app<Ucfirst><Pascal>; `authPersistCfg <type>` writes the instance's new admin credential into the BASE app's config; and the clone defines the base app's adapter and tool names while its bodies exec against the instance's container, so the loader keeps whichever it sourced last and the base app's user tools can end up administering the instance — decided by nothing but find(1) order. Seen on a live install: the generated manifest resolved [appBookstackListUsers] to bookstack_test's copy. libreportal instance repair [slug] [--dry-run] Rewrites the template dir only — no container is touched, nothing reinstalled, so it does not route through the task system the way create/remove do. Idempotent by construction. Two of the three renames match their own output (appMattermost_teest… still starts with appMattermost), and a clone from the old code is only PARTLY wrong — its suffix hooks were always correct and end at the slug with no trailing underscore, which the infix rule would otherwise read as type + id + () and append the id twice (appSetupComposeTags_nextcloud_family_family). Three sentinels park the already-correct spellings before the rewrite and restore them after, so a healthy instance is a no-op and an interrupted run can just be re-run. Verified against fixtures built with the old rule set for all five multi-instance apps that ship tools: after repair each tree is byte-identical to a fresh clone from the fixed cloner, a second pass reports "already correct", and --dry-run leaves checksums untouched. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
36 lines
2.3 KiB
Bash
36 lines
2.3 KiB
Bash
#!/bin/bash
|
|
|
|
# Instance Commands Header
|
|
# Shows available instance commands and help information
|
|
|
|
cliShowInstanceHelp()
|
|
{
|
|
echo ""
|
|
echo "Available Instance Commands (* is required):"
|
|
echo ""
|
|
echo " Run more than one copy of a multi-instance-capable app (e.g. two"
|
|
echo " Bookstack/WordPress sites). Each instance is a full, isolated app:"
|
|
echo " its own data, DB, subdomain, backups and update cadence. Only apps"
|
|
echo " with CFG_<TYPE>_MULTI_INSTANCE=true can be instanced."
|
|
echo ""
|
|
echo " libreportal instance create [type*] [name*] [domain#] [subdomain] [--local]"
|
|
echo " - Provision + install a new instance."
|
|
echo " type = base app slug (e.g. bookstack)"
|
|
echo " name - instance name (e.g. blog)"
|
|
echo " domain# - which CFG_DOMAIN_n to route on (default 1)"
|
|
echo " subdomain- host label (default <type>-<name>)"
|
|
echo " --local - LAN only: no Traefik router, served"
|
|
echo " on its own port. Implied when no"
|
|
echo " CFG_DOMAIN_n is configured."
|
|
echo " libreportal instance remove [slug*] - Uninstall + remove an instance (e.g. bookstack_blog)"
|
|
echo " libreportal instance list [type] - List instances (all, or just for one app type)"
|
|
echo " libreportal instance repair [slug] [--dry-run]"
|
|
echo " - Fix instances cloned before the tool/auth"
|
|
echo " renames landed: their Tools actions error with"
|
|
echo " 'has no tool', and their admin-password resets"
|
|
echo " write to the BASE app's config. Rewrites the"
|
|
echo " template only — no container is touched. Safe"
|
|
echo " to run repeatedly; healthy instances are a no-op."
|
|
echo ""
|
|
}
|