DTaaS Services Codebase
This page describes the code of the dtaas-services CLI, which sets up
and runs the DTaaS platform services.
Location and Purpose
Source package:
deploy/services/cli
The CLI:
- generates a services project structure that is ready to run,
- sets up certificates and service permissions,
- installs, starts, stops, restarts, removes and cleans service containers,
- runs the post-start setup for ThingsBoard and GitLab,
- creates users and resets service passwords from the CSV and environment configuration.
Runtime Command Surface
Every command follows the grammar dtaas-services <noun> <verb>. The
entry point is dtaas_services/cmd.py, which registers the nouns in
install order:
project generatehost setupservice install,service start,service stop,service restart,service status,service remove,service cleanuser adduser reset-password
The old top-level spellings (generate-project, setup, start and so
on) are registered by commands/aliases.py. They print a deprecation
warning and forward to the <noun> <verb> command.
Poetry script mapping (pyproject.toml):
Package Layout
Layered Design
Command Layer
The files in dtaas_services/commands/ define the Click commands and
the high-level flows:
project_ops.py: project scaffold generation (project generate).host_ops.py: TLS certificate and permission setup (host setup).service_ops.py: the service verbs (install,start,stop,restart,status,remove,clean).install_helpers.py: selector validation and the ThingsBoard and GitLab install flows used byservice install.user_ops.py: user provisioning and password reset.aliases.py: deprecated top-level spellings that warn and forward to their<noun> <verb>replacement.
Core Library Layer
The files in dtaas_services/pkg/ hold reusable logic:
config.py: environment and configuration loading.template.py: project scaffolding and template copying.force_overwrite.py: whatproject generate --forcemay replace, what it must never replace, and copies that preserve permissions.cert.py: certificate placement and normalization.password_store.py: tracks the current admin password of each supported service.lib/*: compose command execution and service state management.
Service Modules Layer
dtaas_services/pkg/services/ implements service-specific behaviour:
gitlab/: health checks, root password setup, PAT creation, OAuth application setup and GitLab user provisioning.thingsboard/: setup, sysadmin and tenant workflows, and user setup from the credentials file.influxdb/,rabbitmq.py,mongodb.py,postgres/: permissions, readiness checks and account bootstrap routines.
Shared GitLab Layer
gitlab_common holds GitLab operations that do not depend on the
deployment (get_gitlab_client, validate_user_row, create_user,
create_user_pat, revoke_user_pats, with_hint). Every function takes
explicit arguments and changes no environment, filesystem, console or
process-global state.
Its single source of truth is lib/gitlab_common/, a standalone Poetry
package with its own tests. Each consumer copies it into its own
tree instead of depending on it:
Run poetry run python -m dtaas_services.pkg.build before testing or
packaging. CI does this through run-build-script: true. It is a plain
script, not a Poetry build hook, because a hook makes poetry-core emit a
platform-specific wheel instead of py3-none-any. Copying the code
instead of using a path dependency keeps dtaas-services and the DTaaS
CLI independent of each other. It also keeps local paths out of the
published wheel metadata, which PyPI rejects.
Deployment-specific glue stays in pkg/services/gitlab/: URL derivation
from GITLAB_PORT and HOSTNAME, token-file persistence, docker health
checks and Rich console output. Two consequences are deliberate:
pkg/services/gitlab/_api.pysuppresses urllib3'sInsecureRequestWarningwhenSSL_VERIFY=false.gitlab_commondoes not, so importing the shared module never silences warnings for unrelated consumers.gitlab_commondefaults Personal Access Tokens to least-privilege repository-only scopes.pkg/services/gitlab/users.pyasks for the broaderapiscope explicitly throughPatOptions.
Configuration Inputs
A generated project is driven by:
config/services.env: ports, hostnames, SSL behaviour and service credentials.config/credentials.csv: user list (username,password,email).- TLS certificates copied into the generated
certs/layout.
The main GitLab-related environment variables are HOSTNAME,
GITLAB_PORT, SSL_VERIFY and GITLAB_ROOT_NEW_PASSWORD.
Typical Workflow
- Generate project files:
dtaas-services project generate- Edit configuration:
config/services.envconfig/credentials.csv- Set up certs and permissions:
dtaas-services host setup- Start selected services:
dtaas-services service start [-s ...]- Run post-install setup where needed:
dtaas-services service install -s thingsboarddtaas-services service install -s gitlab- Provision users:
dtaas-services user add
Testing and Quality
The package uses pytest with strict markers, and test discovery starts
in deploy/services/cli/tests.
Run the checks from deploy/services/cli:
The build step vendors gitlab_common; without it the tests cannot be
collected. The CLI checks for root before it validates arguments, so a
non-root run needs CI=true. The tests in tests/system_tests call
docker and are excluded here.
Contributor Notes
- Keep command modules thin and put business logic in
pkg/. - Add service-specific behaviour in
pkg/services/<service>/or peer modules, not in generic command handlers. - Commands should print messages the user can act on, and should not leave partial side effects without reporting them.
- When adding service operations, include tests under
tests/test_servicesand command-level tests undertests/test_commands.