kub-cli is a thin Python client that exposes stable native commands for KUB tools while executing the real logic inside container images.
kub-datasetkub-simulatekub-dashboardkub-img
The wrapper does not reimplement dataset/simulation/dashboard business logic. It resolves configuration, builds runtime commands, and executes them.
License: Apache-2.0.
kub-cli provides a consistent command-line UX across laptops, workstations, CI, and HPC environments.
Supported runtimes:
apptainerdockerauto
Policy:
- Apptainer remains the preferred runtime for HPC / Slurm / MPI-oriented execution.
- Docker is supported for local/workstation/CI usage.
autoprefers Apptainer when configured and available, then falls back to Docker.
Default behavior:
- Default runtime is
auto. - In
auto, kub-cli checks Apptainer first, then Docker. - If neither runtime is installed, kub-cli reports how to install them.
python -m pip install .python -m pip install -e .[dev]Set runtime and images:
export KUB_RUNTIME=auto
export KUB_IMAGE_DOCKER=ghcr.io/feelpp/ktirio-urban-building:master
export KUB_IMAGE_APPTAINER=/path/to/ktirio-urban-building.sifThen use wrapper commands:
kub-simulate --runtime docker -- run case.yaml
kub-dataset --runtime apptainer -- push ./data
kub-dashboard --runtime auto -- serve ./resultsFor Apptainer runtime:
apptainer run [common options] --app <wrapped-app> <local-sif-image> [forwarded args...]
For Docker runtime:
docker run --rm [common options] <docker-image> <wrapped-app> [forwarded args...]
Mappings:
kub-dataset->kub-datasetkub-simulate->kub-simulatekub-dashboard->kub-dashboard
All non-wrapper arguments are forwarded transparently to the in-container app.
Available on all three wrapper commands:
--runtime {auto,apptainer,docker}--image IMAGE--bind SRC:DST(repeatable)--pwd PATH--runner PATH--apptainer-flag FLAG(repeatable)--docker-flag FLAG(repeatable)--env KEY=VALUE(repeatable)--dry-run--verbose / --no-verbose--show-config--version
Wrapper options must be placed before the forwarded in-container command arguments.
Use -- to force all remaining arguments to be forwarded:
kub-simulate --runtime docker -- --helpCanonical upstream reference is Docker/OCI.
Example Docker image:
ghcr.io/feelpp/ktirio-urban-building:master
Derived Apptainer remote source:
oras://ghcr.io/feelpp/ktirio-urban-building:master-sif
Default image references used when no explicit image is configured:
- Docker:
ghcr.io/feelpp/ktirio-urban-building:master - Apptainer:
oras://ghcr.io/feelpp/ktirio-urban-building:master-sif
Other tags are supported (for example pr-<nnn>), e.g.:
- Docker:
ghcr.io/feelpp/ktirio-urban-building:pr-456 - Apptainer source:
oras://ghcr.io/feelpp/ktirio-urban-building:pr-456-sif
Important:
- For Apptainer download/pull, use
oras://.... - Do not use
docker://...for Apptainer pulls in this workflow.
kub-img is the image utility command used by kub-cli internals for image pull/info workflows.
Subcommands:
kub-img pull [SOURCE] [--runtime ...] [--image ...]kub-img info [--runtime ...] [--image ...] [--json]kub-img apps(Apptainer runtime)kub-img path
Examples:
# Docker pull
kub-img pull --runtime docker --image ghcr.io/feelpp/ktirio-urban-building:master
# Apptainer pull with ORAS source
kub-img pull oras://ghcr.io/feelpp/ktirio-urban-building:master-sif \
--runtime apptainer \
--image ./ktirio-urban-building.sif
# Runtime-aware image info
kub-img info --runtime docker --image ghcr.io/feelpp/ktirio-urban-building:master --json
kub-img info --runtime apptainer --image ./ktirio-urban-building.sifPrecedence (highest to lowest):
- CLI options
- Environment variables
- Project config:
.kub-cli.tomlin current working directory - User config:
~/.config/kub-cli/config.toml - Built-in defaults
KUB_RUNTIME:auto|apptainer|dockerKUB_IMAGE_DOCKER: Docker image referenceKUB_IMAGE_APPTAINER: Apptainer image path (local SIF)KUB_IMAGE: legacy generic image fallback (backward compatibility)KUB_BIND: additional binds, comma- or semicolon-separatedKUB_WORKDIR: runtime working directoryKUB_APP_RUNNER: generic runner overrideKUB_APPTAINER_RUNNER: Apptainer runner overrideKUB_DOCKER_RUNNER: Docker runner overrideKUB_VERBOSE: boolean (true/false,1/0,yes/no,on/off)KUB_APPTAINER_FLAGS: extra Apptainer flags (shell-split)KUB_DOCKER_FLAGS: extra Docker flags (shell-split)
You can place config at:
~/.config/kub-cli/config.toml.kub-cli.toml
Keys may be top-level or under [kub_cli].
[kub_cli]
runtime = "auto"
workdir = "/work"
verbose = false
[kub_cli.image]
docker = "ghcr.io/feelpp/ktirio-urban-building:master"
apptainer = "./ktirio-urban-building.sif"
[kub_cli.env]
OMP_NUM_THREADS = "8"kub-cli keeps compatibility with existing Apptainer-centric usage:
- Existing
KUB_IMAGEstill works as a fallback image setting. - Existing Apptainer command flow remains unchanged when runtime resolves to
apptainer. - Existing wrapper UX and argument forwarding semantics are preserved.
For explicit multi-runtime setups, prefer KUB_IMAGE_DOCKER and KUB_IMAGE_APPTAINER.
- Docker runtime selected but Docker missing: install Docker or set
--runner. - Apptainer runtime selected but Apptainer missing: install Apptainer or set
--runner. - No image configured for selected runtime: set
--image, runtime-specific env vars, or config. - Need to inspect resolved command: use
--dry-run.
uv venv .venv
. .venv/bin/activate
uv pip install -e '.[dev]'
pytestVersion bumping for maintainers:
# bump patch/minor/major from pyproject version
kub-cli bump patch
kub-cli bump minor
kub-cli bump major
# explicit target version
kub-cli bump patch --to 0.2.0
# preview only
kub-cli bump patch --dry-runkub-cli bump updates pyproject.toml, fallback src/kub_cli/__init__.py, and rotates CHANGELOG.md by converting ## Unreleased into the new released section.
Release versioning policy:
kub-cliuses SemVer (MAJOR.MINOR.PATCH).- Release tags must be
vMAJOR.MINOR.PATCH. - The tag version must match
project.versioninpyproject.toml.
PyPI publishing via GitHub environment:
- Workflow:
.github/workflows/publish.yml - Trigger: publish a GitHub Release (SemVer tag, for example
v0.2.0) or runworkflow_dispatch. - Publish job uses GitHub
environment: pypiand OpenID Connect trusted publishing (no PyPI API token needed in GitHub secrets). - Publishing is restricted to the official repository
feelpp/kub-cli.
One-time setup:
- In GitHub repository settings, create environment
pypi. - In PyPI Organizations, ensure project
kub-clibelongs to organizationfeelpp. - In the
kub-cliPyPI project settings (under organizationfeelpp), add a trusted publisher bound to:- owner/repository:
feelpp/kub-cli - workflow:
publish.yml - environment:
pypi
- owner/repository:
- Ensure the first trusted release tag already exists in the repository.
Release steps:
# 1) bump version in source tree
kub-cli bump patch
# 2) commit + tag matching SemVer version
git add pyproject.toml src/kub_cli/__init__.py
git commit -m "Release 0.1.1"
git tag v0.1.1
git push origin main --tags
# 3) publish GitHub Release (this triggers PyPI workflow)
gh release create v0.1.1 --generate-notesThe workflow validates the tag format and checks that it matches pyproject.toml before building and publishing to PyPI.
This project is licensed under the Apache License 2.0. See LICENSE.