Skip to main content

Tools system architecture

How the ./uis tools subsystem is wired and how to add a new optional CLI to the catalogue.

Looking for the user-facing list of what's available and how to install it? See reference/tools.md. This page is for contributors editing the system itself.

Two tiers

The container ships with a small built-in set and a larger installable on demand catalogue.

TierWhere it's definedWhen it's available
Built-inBUILTIN_TOOLS in provision-host/uis/lib/tool-installation.sh:22Baked into the image at build time. Always present.
InstallableOne install-<id>.sh script per tool under provision-host/uis/tools/Added on demand by ./uis tools install <id>. Lives in the container's writable layer; lost on docker rm.

Built-ins are kept intentionally tiny (kubectl k9s helm ansible) — anything every UIS deploy needs. Everything else is opt-in to keep the image small.

Discovery

get_all_tool_ids() in tool-installation.sh:26 is the single entry point that the runtime CLI and the docs generator both use:

  1. Emit each ID in BUILTIN_TOOLS.
  2. Glob provision-host/uis/tools/install-*.sh and read TOOL_ID= from each script header.

That's it — there is no manifest file. Adding an install-<id>.sh with the right header makes the tool show up in ./uis tools list automatically.

The install-script contract

Every installable tool is a single bash script under provision-host/uis/tools/ named install-<tool-id>.sh. It has two parts: a metadata header and two functions.

Metadata header

TOOL_ID="opentofu"
TOOL_NAME="OpenTofu"
TOOL_DESCRIPTION="Open-source infrastructure-as-code (Terraform fork)"
TOOL_CATEGORY="CLOUD_TOOLS"
TOOL_CHECK_COMMAND="command -v tofu"
TOOL_SIZE="~30MB"
TOOL_WEBSITE="https://opentofu.org/"
FieldRequiredUsed by
TOOL_IDyesDiscovery, dispatch (./uis tools install <id>)
TOOL_NAMEyes./uis tools list display, docs generation
TOOL_DESCRIPTIONyes./uis tools list display, docs generation
TOOL_CATEGORYyesGrouping (current categories: BUILTIN, CLOUD_TOOLS)
TOOL_CHECK_COMMANDyesis_tool_installed — must succeed only when the tool is actually installed
TOOL_SIZErecommendedSets user expectations on download size
TOOL_WEBSITErecommendedUpstream link in docs

The header is parsed by line-prefix matching (get_tool_value in tool-installation.sh:98), so keep each metadata line as a simple KEY="value" assignment — no shell expansion, no multi-line strings.

Required functions

do_install() {
# Install the tool. Should be idempotent — running it twice must not fail.
# Runs as root inside the container ($EUID -eq 0); the sudo branch is for
# tooling that runs the script outside the container.
...
}

do_uninstall() {
# Reverse do_install. Used by the future ./uis tools uninstall flow.
...
}

Look at provision-host/uis/tools/install-opentofu.sh as the canonical minimal example — it delegates to the upstream installer, handles the root/sudo split, and includes a matching do_uninstall.

install_tool() in tool-installation.sh:184 sources the script in a subshell and calls do_install, then re-runs is_tool_installed to verify. If TOOL_CHECK_COMMAND returns non-zero after a successful install, the install is reported as failed — get the check command right.

How tools.json is generated

reference/tools.md is hand-maintained, but the canonical machine-readable index is website/src/data/tools.json, regenerated by provision-host/uis/manage/uis-docs.sh:329 (generate_tools_json). It walks the same install-*.sh files and emits a JSON array of { id, name, description, category, size, website, check_command }. Run provision-host/uis/manage/uis-docs.sh after adding or changing a tool to refresh it.

Adding a new installable tool

  1. Create provision-host/uis/tools/install-<tool-id>.sh modelled on install-opentofu.sh (single-file delegation to an upstream installer is the preferred shape — keep it small).
  2. Fill in the metadata header. TOOL_ID must match the filename suffix.
  3. Implement do_install (idempotent) and do_uninstall.
  4. Make sure TOOL_CHECK_COMMAND succeeds only after install — command -v <binary> is usually enough.
  5. Mark it executable: chmod +x install-<tool-id>.sh.
  6. Run ./uis build and verify in a fresh container:
    ./uis tools list                    # new tool shows ❌ Not installed
    ./uis tools install <tool-id> # do_install runs
    ./uis tools list # flips to ✅ Installed
    ./uis exec <binary> --version # smoke test
  7. Run provision-host/uis/manage/uis-docs.sh to regenerate website/src/data/tools.json.
  8. Add a row to the user-facing table in website/docs/reference/tools.md (and the "When you need a specific tool" section if it ties to a workflow).