Repository navigation
DUPLOAI-3742: run the extension installer beside the studio - #25
duplodavid wants to merge 3 commits into
Conversation
e3e5e60 to
5aa14c5
Compare
devkit runs the extension installer beside the studio, so a build in `extensions/[name]/dist/` installs on its own. - Add an `installer` service on `quay.io/duplocloud/helpdesk-installer`, pinned by `INSTALLER_TAG` in `.env.example`, which every user's `.env` adopts on the next `./run.sh` - Point the studio at it through `Extensions__InstallerUrl`, and hand it the JWT secret and the license token from `.env` and none of its LLM, AWS or admin credentials - Leave the license-server catalog off unless `LICENSE_SERVER_URL` is set - Send the bundled sample through `deploy-extension.sh`, since that build never reaches the installer. A pass with no selection key installs nothing - The Available tab hands Install to this installer only once the UI tag and the studio tag in `.env.example` are images that do that. The tags pinned there predate that handoff
0d0a0c3 to
49d4932
Compare
Keep the installer and the agent's dind sidecar: both volumes, and both names in the logs service list.
| docker compose start duplo-ai-studio | ||
| ``` | ||
|
|
||
| To install a fixed build, run `./scripts/remove-extension.sh [id]` and then rebuild. The rebuild has to differ in |
There was a problem hiding this comment.
remove-extension.sh deletes the row but leaves the zip in dist/, and for a local build the installer reads "no row + a build in dist/" as an install (the table only returns not-requested when there's no LocalPath). Removal doesn't change the fingerprint, so nothing happens right away, but the extension comes back on the next trigger: any other build, a studio restart, or the next ./run.sh. The only ways to keep it gone are disabling it in the UI, deleting dist/, or EXTENSIONS_EXCLUDE. Worth saying here, or better, have the local source only install a zip that changed while the installer was watching rather than every zip on disk.
There was a problem hiding this comment.
Fixed in the installer the second way you suggested, and cd37817 documents it in the README. The installer now installs a dist/ build only once its zip changes while it runs, so a removed extension stays gone until its next rebuild. The image INSTALLER_TAG pins predates that, so devkit picks it up when a follow-up bumps the pin.
| # The studio service's image, which the status record reports and holds are keyed on. | ||
| - INSTALLER_BACKEND_IMAGE=quay.io/duplocloud/backend:${STUDIO_TAG} | ||
| - INSTALLER_STATE_DIR=/var/lib/installer | ||
| - INSTALLER_LOCAL_DIR=/extensions |
There was a problem hiding this comment.
The local source takes ownership of every installed id that has a build in dist/, whatever version is installed, and the table then installs whenever the installed version differs from the dist version. It never checks which is newer. So if v1.2 was loaded another way (Extension Studio's in-platform flow, or a zip outside dist/), a stale v1.1 zip left in dist/ rolls it back on the next pass. Can the local source skip a build older than the current row?
There was a problem hiding this comment.
Fixed in the installer, and cd37817 documents it. It skips a dist/ build older than a working installed version, with a detail naming both, and deploy-extension.sh loads it if you hand it that build on purpose. A newer version that failed to load still takes the older build, so rebuilding back to a working version needs no extra step. The image INSTALLER_TAG pins predates that, so devkit picks it up when a follow-up bumps the pin.
| - CHANNELS_BASE_URL=${CHANNELS_BASE_URL:-} | ||
| - CHANNELS_BUCKET=${CHANNELS_BUCKET:-} | ||
| volumes: | ||
| # The status record. A named volume, so it survives a recreate and goes with the database on `down -v`. |
There was a problem hiding this comment.
Since this volume goes with down -v, ./run.sh --reset now wipes the installer's state along with Mongo, and the first pass after the studio comes up loads every extensions/*/dist/extension.zip. Anyone resetting to get an empty platform gets all their old builds back about 20 seconds later. Either document that, or don't treat zips that were already on disk at startup as install requests.
There was a problem hiding this comment.
Fixed in the installer the second way, and cd37817 documents it. A build already in dist/ when the installer starts waits for its next rebuild, so ./run.sh --reset comes up empty. The image INSTALLER_TAG pins predates that, so devkit picks it up when a follow-up bumps the pin.
An agent running `deploy-extension.sh` beside the installer raced its pass, and a same-version rebuild afterwards read as already installed, so the agent could test an older build without knowing it. - `deploy-extension.sh` on a build under `extensions/` waits for the installer's status record to show that zip's digest, and exits non-zero with the installer's reason when it does not install it. It still POSTs for a build the installer leaves alone, a zip elsewhere, a remote target, or with the installer stopped - `docker-compose.yml` defaults `INSTALLER_TAG` to the `.env.example` pin, so `docker compose up` before the next `./run.sh` still starts - The README says which `dist/` builds the installer leaves alone, and troubleshooting covers a build that never loads, with how to read the installer's status record
What this changes
DUPLOAI-3742: devkit runs the extension installer beside the studio, so a build in
extensions/[name]/dist/installs on its own.installerservice onquay.io/duplocloud/helpdesk-installer, pinned byINSTALLER_TAGin.env.example, which every user's.envadopts on the next./run.sh. The compose file defaults to that pin, sodocker compose upbefore then still startsExtensions__InstallerUrl, and hands it the JWT secret and the license token from.envand none of its LLM, AWS or admin credentialsLICENSE_SERVER_URLis setdeploy-extension.shon a build underextensions/hands it to the installer while it runs, waits for the installer to report that zip, and exits non-zero with the installer's reason. It posts the zip itself only for a build the installer leaves alone, a zip elsewhere, a remote target, or with the installer stopped, so the agent skill's deploy step no longer races the installerdist/build only once it changes while the installer runs, so a build on disk at start (as after./run.sh --reset), a removed extension, and a build older than a working installed version stay as they are. The imageINSTALLER_TAGpins predates that, so this holds once a follow-up moves the pindeploy-extension.sh, since that build never reaches the installer. A pass with no selection key installs nothing. The docs also cover the manual recovery when a build hangs the studio at load, and how to read the installer's status when a build never loads.env.exampleare images that do that. The tags pinned there predate that handoffHow it was verified
./run.sh --reset, then built and deployed a sample end to end./scripts/build-extension.shon the affected sample, then deployed it and created one in the UInpm ci && npm run buildin the affectedfrontend/./stop.sh --wipe && ./run.shfrom a clean slate/duplo-extensionand confirmed the guidance still matches realityOutput
Blast radius
.env.example- image tags or ports here are adopted into every user's.envon their next./run.shafter an upgrade. Say so plainly above.scripts/upgrade_dev_kit.shorscripts/init-project.sh- the adoption path.github/workflows/Checks
.env, tokens, keys, or customer identifiers in the diffdist/,node_modules/,**/bin/,**/obj/,backend/sdk-packages/ng-common-libtarball was added or bumped, itsNOTICEsits beside it