Known Issues
Rough edges you will run into sooner or later. This page is intentionally short; ongoing work goes into the project’s issue tracker, not here.
TTL cleanup is not automatic
Cleanup-Environments must be triggered manually or wired to a Jenkins cron trigger. The library does not schedule it. If no one runs it, envs with expired TTL stay on disk and continue consuming runner capacity.
Workaround: add a time-based trigger (triggers { cron('H 4 * * *') }) to the Cleanup-Environments job, or schedule it via the multibranch / organisation folder pipeline that owns it.
Cycle detection warns but does not block
createEnvStep runs DFS cycle detection over the effective depends_on graph. On a cycle it prints a warning and continues; Compose itself refuses to start on circular depends_on.
Workaround: treat the warning as a build error. The small window where a cycle is desirable (because service_healthy breaks it) is rare — inspect the warning explicitly when it fires.
Agent capabilities not validated
deployEnvStep assumes every online non-master agent has:
-
Docker Engine reachable by the
jenkinsuser. -
Docker Compose V2 (
docker compose, notdocker-compose). -
/opt/qa-envs/(or the value ofQA_AGENT_ENVS_DIR) writable byjenkins. -
yq,ss,rsyncinstalled.
There is no pre-flight check. A missing tool produces a failure deep inside docker compose up -d or the port-scan step.
Workaround: include a one-liner check in agent provisioning (yq --version && docker compose version).
Active Choices fallback hides approval errors
Scripts that are not yet approved in Manage Jenkins → In-process Script Approval render the fallback HTML silently. There is no banner, no console message, no System Log line unless you filter on ScriptApproval.
Workaround: always check approval first when a panel suddenly shows the fallback.
Re-running a failed create leaves artifacts
If createEnvStep fails after meta.json is written (rare, but possible during a docker compose build crash), the env directory stays behind in state configured with status: failed. The name is then reserved and utils.validateEnvName(…, checkExists=true) rejects it.
Workaround: Manage-Environment → delete on the failed env, or remove ${MASTER_ENVS_DIR}/<env> manually.
DATA_FOLDER must be a relative path
Compose bind mounts expand ${DATA_FOLDER:-.} relative to the docker-compose.yml. Setting DATA_FOLDER=/opt/qa-envs/foo via the Active Choices form works but silently duplicates the absolute path for every bind mount and breaks on the runner if the master ever renders a path that does not exist there.
Workaround: leave DATA_FOLDER unset unless you have a specific reason. The default (the env’s own directory) is almost always right.
Concurrent manage-owners races are possible
atomicWriteMeta protects against torn reads, not against two admins submitting manage-owners at the same second. The last submission wins.
Workaround: manage-owners is low-frequency by nature; if it matters, coordinate on Slack or gate the action behind a Jenkins lock.
SERVICE_VARIABLES values are visible on the build’s Parameters page
SERVICE_VARIABLES is a real build parameter, so the submitted JSON is stored in the build’s ParametersAction and rendered in plain text on the Parameters page. utils.maskSensitiveValues protects the console and .qa-build.log, not that page. This affects every service variable routed through the form, keystore passwords included.
Workaround: treat anything entered there as visible to everyone who can read the job. Use QA fixtures, never a production secret, and rotate the value afterwards if it ever mattered.
A per-service .env fix never reaches an existing environment
updateEnvStep bootstraps <env>/<svc>/.env from the shared-lib template only when the file is absent, and Update-Environment regenerates docker-compose.yml but not the per-service .env files. A corrected template — for example the DEV-2849 change of HTTP_PORT to 8080 and SERVER_SSL_ENABLED to SSL_ENABLED in ft-qoe-web — therefore applies to newly created environments only. Existing ones keep the old values indefinitely, through any number of Update and Deploy runs.
Workaround: edit <env>/ft-qoe-web/.env on the master by hand, or delete that file and run Update-Environment so the template is laid down again (this discards the env’s other customisations in that file), or re-create the environment.
ft-qoe-web sessions on legacy environments lack the Secure cookie flag
An environment created before DEV-2849 still carries SERVER_SSL_ENABLED in <env>/ft-qoe-web/.env. That key turns TLS on, but the session cookie’s Secure flag is bound to SSL_ENABLED alone — so with SSL enabled the cookie is issued without it and can travel over the published plain-HTTP fallback port.
Workaround: rename the key to SSL_ENABLED in that file (see the previous entry for how a per-service .env is updated). New environments are unaffected.
Empty debug-port mappings publish on a random host port
ftacs and ui-backend carry - "${DEBUG_PORT_FTACS:-}:5005" / - "${DEBUG_PORT_UI_BACKEND:-}:5005". With the variable unset the entry renders as ":5005", whose empty host part Compose reads as "publish on an ephemeral host port" rather than as an error. Nothing listens on 5005 today because no image in the stack starts a JDWP agent by default, so the mapping forwards to a closed port — but DEBUG_PORT is operator-editable through the service-variables form, and the images' debug behaviour is not verified from this repository.
Workaround: leave the debug variables unset unless you are actively debugging; when you are, set DEBUG_PORT_FTACS / DEBUG_PORT_UI_BACKEND explicitly so the binding is known, and clear them again afterwards.
Portals /nginx_status is world-readable by default
The portals image’s own nginx.conf hardcodes allow 127.0.0.1, allow 10.0.0.0/8 and allow 172.16.0.0/12, then allow ${METRICS_ALLOW_IP}; deny all;. resources/services/portals/.env sets METRICS_ALLOW_IP=0.0.0.0/0, which makes /nginx_status world-readable on the published portals HTTP and HTTPS ports — including over IPv6 DNAT on an IPv6-enabled agent, where a host firewall covering IPv4 only does not apply. This is the behaviour QA environments had before DEV-3218; the key was previously unset and the image’s own default is the same 0.0.0.0/0, so the entry now states it explicitly rather than changing it.
Workaround: set METRICS_ALLOW_IP=127.0.0.1 in <env>/portals/.env (any value other than 0.0.0.0/0 closes it) and redeploy. Prometheus scraping from another agent then needs that agent’s CIDR instead.
The DEV-3218 portals .env fix reaches new environments only
resources/services/portals/.env gained FT_UI_BACKEND_URL, FT_AI_AGENT_URL, FT_GRAFANA_API_URL, METRICS_ALLOW_IP, FT_BRANDING_DIR and FT_COMPANY_NAME, and lost the dead FT_UI_HOST plus the two inert host-port keys. Like every per-service .env change it lands at create time only — see the entry above on why Update and Deploy never overwrite an existing file.
Workaround: copy resources/services/portals/.env into <env>/portals/ on the master, then run Deploy-Environment with RESET_CONFIGS so the agent copy is replaced rather than skipped by the rsync --ignore-existing. Re-apply any per-env customisation afterwards.
|
Operator pre-sync step before
syncSharedLibStepThe Jenkins master’s shared-lib copy at Diff the master copy against the new repository file first, fold anything genuinely needed into git, and only then run |