Reference

Quick lookups for paths, APIs, services, and validation rules. Pages under Architecture / Operations / Configuration link back here rather than duplicating these tables.

Paths (master and runner)

  • Master envs: /var/jenkins_home/qa-data/envs/<env>/

  • Master shared library: /var/jenkins_home/qa-data/shared-lib/

  • Master services: /var/jenkins_home/qa-data/shared-lib/resources/services/

  • Master schemas: /var/jenkins_home/qa-data/shared-lib/resources/schemas/

  • Runner envs: /opt/qa-envs/<env>/ (default of QAConfig.Paths.AGENT_ENVS_DIR)

QAConfig constants

Table 1. QAConfig.Paths
Field Default Env override

MASTER_SHARED_LIB

/var/jenkins_home/qa-data/shared-lib

QA_MASTER_SHARED_LIB

MASTER_ENVS_DIR

/var/jenkins_home/qa-data/envs

QA_MASTER_ENVS_DIR

MASTER_SERVICES_DIR

${MASTER_SHARED_LIB}/resources/services

QA_MASTER_SERVICES_DIR

MASTER_META_DIR

/var/jenkins_home/qa-data/meta

QA_MASTER_META_DIR

MASTER_SCHEMAS_DIR

${MASTER_SHARED_LIB}/resources/schemas

QA_MASTER_SCHEMAS_DIR

MASTER_BACKUPS_DIR

${MASTER_ENVS_DIR}/.backups

QA_MASTER_BACKUPS_DIR

MASTER_EXPORTS_DIR

${MASTER_SHARED_LIB}/exports

QA_MASTER_EXPORTS_DIR

MASTER_ENV_TEMPLATES_DIR

${MASTER_SHARED_LIB}/env-templates

QA_MASTER_ENV_TEMPLATES_DIR

MASTER_OPERATION_LOG

${MASTER_ENVS_DIR}/.operation-log.ndjson

(derived)

MASTER_AUDIT_LOG

${MASTER_ENVS_DIR}/.audit-log.ndjson

(derived)

MASTER_SNAPSHOTS_DIR

${MASTER_ENVS_DIR}/.snapshots

QA_MASTER_SNAPSHOTS_DIR

AGENT_ENVS_DIR

/opt/qa-envs

QA_AGENT_ENVS_DIR

DEPENDENCIES_YAML

${MASTER_SHARED_LIB}/resources/schemas/dependencies.yaml

(derived)

TEMPLATES_DIR

${MASTER_SHARED_LIB}/resources/templates

(derived; legacy)

Table 2. QAConfig.Status / QAConfig.TTL

Status.CONFIGURED / DEPLOYED / STOPPED / FAILED / UNKNOWN

String constants used for meta.status.

TTL.ONE_DAY / THREE_DAYS / ONE_WEEK / ONE_MONTH / TWO_MONTHS / THREE_MONTHS / ONE_YEAR / INFINITY

Allowed values for meta.ttl; TTL.isValid(s) / TTL.ALL available.

Table 3. QAConfig.Defaults
Field Default Env override

RUNNER

built-in

QA_DEFAULT_RUNNER

TTL

infinity

QA_DEFAULT_TTL

DATABASE_TYPE

mysql

QA_DEFAULT_DATABASE

NETWORK_NAME_SUFFIX

_net

(compile-time)

Table 4. QAConfig.Registry
Field Default Env override

HARBOR_URL

hub.friendly-tech.com

HARBOR_URL

HARBOR_CREDENTIAL_ID

harbor-cred

HARBOR_CREDENTIAL_ID

Table 5. QAConfig.Validation

ENV_NAME_PATTERN

^[a-z0-9][a-z0-9-]{2,49}$ — 3–50 chars, lowercase letters / digits / hyphen. May start with a digit (commit 83b82f9).

ENV_NAME_MIN_LENGTH / ENV_NAME_MAX_LENGTH

3 / 50.

MAX_NAME_GENERATION_ATTEMPTS

15.

RESERVED_NAMES

master, main, test, default, prod, null, built-in, all, temp, tmp, none.

PORT_MIN / PORT_MAX

1024 / 65535.

PASSWORD_MIN_LENGTH

8.

SENSITIVE_PATTERN

(?i).(PASSWORD|SECRET|TOKEN|_KEY|API_KEY|CREDENTIAL). — drives isSensitiveVariable and maskSensitiveValues.

Table 6. QAConfig.Limits
Field Default Env override

MAX_ENVS_PER_USER

5

QA_MAX_ENVS_PER_USER

MAX_ENVS_PER_AGENT

10

QA_MAX_ENVS_PER_AGENT

MAX_SERVICES_PER_ENV

20

QA_MAX_SERVICES_PER_ENV

MAX_OWNERS_PER_ENV

5

QA_MAX_OWNERS_PER_ENV

MAX_DISK_MB

51200 (50 GiB)

QA_MAX_DISK_MB

Table 7. QAConfig.RBAC
Field Default Env override

ENABLED

true

QA_RBAC_ENABLED

ADMIN_USERS

[admin]

QA_ADMIN_USERS (comma-separated)

ADMIN_GROUP

qa-admins

QA_ADMIN_GROUP

Table 8. QAConfig.Timeouts (seconds)
Field Default Env override

DEPLOYMENT

600

QA_DEPLOYMENT_TIMEOUT

HEALTH_CHECK

300

QA_HEALTH_CHECK_TIMEOUT

CONTAINER_STARTUP

10

(compile-time)

PORT_CHECK

5

(compile-time)

Pipeline steps (vars/)

File Role

createEnvStep.groovy

Create-Environment wizard — constellation name, services, DB, image tags, GLOBAL_VARIABLES, TTL; renders the env to MASTER_ENVS_DIR/<env>/.

updateEnvStep.groovy

Update-Environment — change services, versions, vars, or target runner on an existing env. Strips profiles from services in the target compose file (commit cc8566b).

manageEnvStep.groovy

Manage-Environment dispatcher — actions start, stop, restart, delete, manage-owners. manage-owners is the only action that bypasses the duplicate-audit path (commit 867752a).

deployEnvStep.groovy

Deploy-Environment — stash on master, unstash on runner, port-conflict check via ss, docker compose up -d, update meta.runner / meta.status.

deleteEnvStep.groovy

Thin wrapper over manageEnvStep(action: 'delete') kept for backwards compatibility. Not wired to a standalone Jenkins job in v2.6.0.

restoreEnvStep.groovy

Shared-library step that brings a stopped / failed env back up. Not wired to a standalone Jenkins job in v2.6.0 — end users reach the same outcome through Manage-EnvironmentACTION=start (same runner) or Deploy-Environment (different runner).

rollbackEnvStep.groovy

Rollback using backup snapshots created by createSnapshot.

switchDatabaseStep.groovy

Swap the DB backend (mysqloraclepostgres) for an existing env.

listEnvsStep.groovy

List-Environments — inventory with status, TTL, runner, services; RBAC-aware filtering.

cleanupEnvsStep.groovy

TTL-based sweep. Non-admin actors only see and act on their own envs; cron runs bypass the RBAC check.

composeStep.groovy

Thin wrapper over docker compose on the runner.

serviceComposer.groovy

Builds the per-env compose file from the resources/services/compose-{db}.yml bundle by filtering services and stripping profiles.

qaUiScripts.groovy

Build-time factory for the Active Choices parameter scripts (see qaUiScripts — Build-time Active Choices Factory).

utils.groovy

Shared helpers: logging DSL, validation, env-file helpers, RBAC, port scanning, YAML/JSON plumbing (see utils.* helpers).

syncSharedLibStep.groovy

Rsync workspace → /var/jenkins_home/qa-data/shared-lib/.

syncNodesConfigStep.groovy

Propagate node config to agents.

upgradeSchemasStep.groovy

Migrate existing envs to a new schema / compose layout.

schemaManager.groovy

Template-management helper shared by the legacy schema steps.

addSchemaStep.groovy / editSchemaStep.groovy / listSchemasStep.groovy / deleteStep.groovy / updateStep.groovy

Legacy schema flow predating the consolidated compose bundles. Kept for backwards compatibility.

utils.* helpers

Method Signature Purpose

failureHints

(errorMessage, baseHints, context)

Print an actionable diagnostic block on step failure.

toBasic

(Object) → Object (@NonCPS)

Convert SnakeYAML LazyMap / lazy lists into plain LinkedHashMap / ArrayList so they round-trip through Jenkins serialisation and writeJSON.

escapeHtml

(String) → String (@NonCPS)

Escape HTML entities for inlining into Active Choices HTML.

initStorage

()

Ensure MASTER_ENVS_DIR, MASTER_BACKUPS_DIR, MASTER_SNAPSHOTS_DIR exist.

validateName

(String, String)

Generic name validator (used for env names and backup names).

validateEnvName

(String, boolean checkExists = true)

Fail fast if the env name is reserved, malformed, or collides with an existing env.

validatePorts

(List<Integer>) (@NonCPS)

Ensure every port sits in [PORT_MIN, PORT_MAX].

logOperation

(action, envName, details)

Append an NDJSON record to MASTER_OPERATION_LOG.

validateOwners

(newOwners, meta, currentUser, adminUsers, knownJenkinsLogins) → List (@NonCPS)

Validate the proposed meta.owners[] update — non-empty, includes self unless admin, respects MAX_OWNERS_PER_ENV, drops unknown logins.

atomicWriteMeta

(metaPath, metaData)

Write meta.json via tmp-file + mv to avoid torn reads.

checkOwnership

(meta, currentUser)

Fail-fast guard at step entry. No-op when QA_RBAC_ENABLED=false.

estimateResources

(List<String>) → Map (@NonCPS)

Sum CPU / RAM / disk budgets from QAConfig.Resources.SERVICE_RESOURCES.

findMissingMandatoryDeps

(selectedServices, databaseType) → Map<String, List<String>>

Resolve the dependencies.yaml graph for the selection, handle oneOf database resolution, return {service: [missing_deps]} where non-empty.

applyServiceVarsOverlay

(envDir, serviceVarsJson, databaseType) → List

Apply the JSON overlay submitted by the SERVICE_VARIABLES parameter to per-service .env files. Returns a structured change log.

maskSensitiveValues

(String) → String (@NonCPS)

Replace values of sensitive keys (see Validation.SENSITIVE_PATTERN) with *.

isSensitiveVariable

(String) → boolean (@NonCPS)

Whether a variable name matches the sensitive pattern.

parseEnvFileComments

(String) → Map (@NonCPS)

Preserve comments and blank lines around KEY=val entries for lossless rewrites.

splitConcatenatedAssignments

(String) → List<String> (@NonCPS)

Split DRP-joined .env lines back into discrete assignments (fixes the trailing-comma / concat trap).

updateEnvVariables

(envContent, varsToUpdate) → String (@NonCPS)

Rewrite KEY=val lines in a .env blob while preserving layout.

extractEnvKeys

(String) → Set<String> (@NonCPS)

Extract the set of KEY names from a .env blob.

createSnapshot / restoreFromSnapshot / listSnapshots

(String envName, …​)

Roll-back support; snapshots live under MASTER_SNAPSHOTS_DIR.

loadJson / saveJson

(path[, data])

Thin wrappers over readJSON / writeJSON with error handling.

getAppConfigsChoices

() → List (@NonCPS)

Enumerate configurable service .env.<db> bundles for Active Choices.

syncSharedLibrary

()

Rsync the workspace into /var/jenkins_home/qa-data/shared-lib/ so Jenkins picks up new vars/, resources/, and src/.

substituteVariables

(text, binding) → String

Resolve ${VAR:-default} placeholders with the given binding (service env → global env → template default).

cleanupTempEnvDirs

()

Remove stale /tmp/qa-env-* work dirs.

getDeployEnvParametersScript

() → String

Build-time Active Choices script for the Deploy-Environment parameter form.

getAgentDetectionScript

() → String

Build-time Active Choices script that enumerates online agents for DEPLOY_RUNNER.

extractHostPorts

(composeFile) → List<Integer>

Parse ports: entries via yq -I=0 (compact JSON); skipped on agent side.

findPortOwners

(runner, ports, currentEnvName) → Map

Return envs that already claim any of the given host ports on runner.

logInit / stage / step / ok / warn / err / detail / group / silentSh / silentShOut / archiveLogOnFailure / exists

see Logging DSL

Logging DSL — documented separately.

qaUiScripts.* factories

Method Mode-parameter Purpose

sharedCssJs()

no

The CSS+JS superset injected via the hidden _UI_STATE parameter. Every reactive panel leans on these classes.

envGateHtml(body)

no

Wrap a panel body in the "pick an env name first" gate used by updateEnvStep, deployEnvStep, and manageEnvStep.

envGateChoices(body)

no

Same gate for CascadeChoice parameters (radio / dropdown / checkbox sources).

depGraphScript()

no

SVG dependency-graph renderer driven by SELECTED_SERVICES and DATABASE_TYPE.

serviceVariablesScript(String mode)

create / update

Per-service .env editor. update mode overlays the current env’s existing values on top.

resourceEstimateScript()

no

CPU / RAM / disk estimate summed from QAConfig.Resources.SERVICE_RESOURCES.

finalPreviewScript(String mode)

create / update

Validation banner + summary. update mode additionally references the CHANGE_DIFF derived parameter.

allowMissingDepsScript()

no

Opt-in checkbox surfaced when findMissingMandatoryDeps() returns non-empty — lets the operator proceed at their own risk.

globalVariablesScript(String mode)

create / update

Rich .env editor. update mode preloads the env’s existing .env.<db> content.

ownersListScript()

no

Multi-checkbox picker of Jenkins logins for manage-owners. Uses a CascadeChoiceParameter + PT_CHECKBOX under the hood.

ownersPreviewScript()

no

Live HTML diff of proposed vs saved meta.owners[].

Build-time vs runtime

These methods run on the Jenkins master during setupParameters() — the shared library is available there. The Active Choices sandbox that executes the returned body later has no access to the shared library. Any utils.* call inside the returned string is a runtime MissingPropertyException.

Service catalogue

Group Service Purpose Gated by profiles:

Database (MySQL bundle)

mysql

Primary RDBMS for the FTACS stack; MySQL 8.0 image built from mysql/mysql.Dockerfile.

no

Database (Oracle bundle)

oracle

Oracle 19c backend swapped in place of MySQL for the Oracle bundle.

no

Database (optional)

postgres

PostgreSQL replacement available in both bundles, gated by a Compose profile.

yes

Data infrastructure

clickhouse

OLAP datastore for telemetry/metrics ingestion.

no

Data infrastructure

jdbc-bridge

ClickHouse ↔ RDBMS JDBC bridge; health endpoint is /ping.

no

Caching / clustering

hazelcast

In-memory data grid used by FTACS and companion APIs.

no

Core application

ftacs

FTACS ACS server; the functional centre of every stack.

no

Identity

keycloak

Optional OIDC identity provider for the web portals (manual opt-in; not in any preset). Imports the oneiot-sc / oneiot-mc realms + clients from resources/services/keycloak/import/ on first boot. See that dir’s README.md.

yes

API

ui-backend

Aggregation backend for the main UI portals.

yes

API

northbound-api

NBI REST surface for external integrations.

yes

API

service-api

Internal service-to-service API.

yes

API

provision-api

Device provisioning REST API.

yes

Web UI

provision-portal

Provisioning operator UI.

yes

Web UI

portals

Bundled customer/operator portals.

yes

Device plane

ft-device-network-service

Device-network orchestration service.

yes

Device plane

ft-qoe-web

QoE web application (Spring Boot, layered .env).

yes

Device plane

ft-system-metrics

System-level metrics collector.

yes

AI

ui-ai-agent

UI-side AI assistant.

yes

Emulators

tr069-emulator

TR-069 CPE emulator for pipeline tests.

yes

Emulators

iot-emulator

LwM2M / IoT device emulator (see architecture).

yes

Configuration

ft-configs-service

Config-management backend.

yes

Configuration

ft-configs-ui

Config-management UI.

yes

Monitoring

prometheus

Metrics scraper.

yes

Monitoring

grafana

Dashboards on top of Prometheus.

yes

Testing snippets

List agents (Jenkins Script Console):

def jenkins = jenkins.model.Jenkins.instance
jenkins.computers.each { c ->
    def n = c.node
    if (n != null) {
        def name = n.name ?: 'master'
        println "${name} - ${c.isOnline() ? 'online' : 'offline'} - ${n.labelString ?: '(no labels)'}"
    }
}

Verify an env on a runner:

cd /opt/qa-envs/<env>
docker compose ps
docker compose logs --no-color --tail=200

Check the current env-name regex from a running Jenkins (Script Console):

println com.qa.config.QAConfig.Validation.ENV_NAME_PATTERN
println com.qa.config.QAConfig.Validation.isValidEnvName('0neiot-qa-01')
// prints ^[a-z0-9][a-z0-9-]{2,49}$
// true