Conventions for working in this repo. Keep changes consistent with these rules.
A local Kubernetes demo lab: one shared kind cluster hosts several
independent scenarios that each showcase a cloud-native feature. Kueue is the
first focus (queueing, quotas, fair sharing, preemption, TAS, DRA), but the lab
is meant to grow to other components (LeaderWorkerSet, DRA drivers, and more) on
the same cluster. No real workloads (pods are pause/agnhost placeholders) and
no real GPUs (nodes advertise fake nvidia.com/gpu). A single demo.sh CLI
drives everything.
demo.sh # CLI: run <scenario> | list | clean <scenario> | down
lib/common.sh # shared helpers: install, job builder, inspectors
cluster/kind-cluster.yaml # 1 control-plane + 8 labelled workers (cluster name: gpu-lab)
base/
flavors.yaml # shared gpu-flavor (TAS Topology/flavor live in kueue-tas)
kueue-values.yaml # Kueue Helm values (fairSharing + DRA integration)
scenarios/<name>/
scenario.sh # hook functions (see contract below)
manifests/*.yaml # scenario-specific Kueue objects & workloads
README.md # what THIS scenario tests, how, what to look for
Each scenarios/<name>/scenario.sh sources lib/common.sh and defines hook
functions. demo.sh calls them in this order:
describe— one line, used bydemo.sh list. Required.pre_run— install prerequisites (e.g. a driver). Optional.apply— create the scenario's Kueue objects + workloads. Required.inspect— print the interesting state. Required.post_run— tear down whatpre_runinstalled. Optional.cleanup— remove the scenario's resources (used bydemo.sh clean). Optional but expected.
install_base (cluster + cert-manager + LWS + Kueue + base/flavors.yaml) runs
before every scenario, so hooks can assume the base is present.
- Always go through the context wrappers:
kubectl_ctx/helm_ctx(defined inlib/common.sh). Never call barekubectl/helm— they must target the pinnedkind-${CLUSTER_NAME}context. - Install via Helm, not raw manifests: cert-manager, LWS, and Kueue are Helm
charts (
install_cert_manager/install_lws/install_kueue). Kueue config (fair sharing, DRA gate, integrations) lives inbase/kueue-values.yaml. - Pinned versions live at the top of
lib/common.sh(KUEUE_VERSION,LWS_VERSION,CERT_MANAGER_VERSION,GROVE_VERSION,CLUSTER_NAME) and are stored without a leadingv(the Helm--versionflags use them directly; cert-manager's and Grove's chart tags are prefixed withvininstall_cert_manager/install_grove). - Fake GPUs: use the extended resource
nvidia.com/gpu; nodes are patched to8each (64 total). Reuse the sharedgpu_jobbuilder inlib/common.shfor pause-pod jobs. - Scenario isolation: each scenario uses its own namespace(s), ClusterQueue,
LocalQueue, and (where needed) uniquely-named
WorkloadPriorityClassobjects. All scenarios draw from the same 64 GPUs, socleanone before running another. - Never hardcode the cluster name/context inside a scenario; derive from the
lib/common.shvariables.
- Put named config constants at the top (namespaces, queue/CQ names, job counts, per-job GPU count). No magic numbers in the middle of the logic.
- Reuse the shared helpers in
lib/common.sh(e.g.submit_gpu_jobs,gpu_job, theinspect_*family) instead of re-implementing them per scenario. - Extract remaining scenario-specific logic into small, clearly named helpers
(e.g.
_wait_for_admitted). Prefix internal, single-scenario helpers with_. - Derive log messages from the constants so counts stay in sync.
- Add a short comment only where the why is non-obvious (async waits, holds, preemption timing). Don't narrate obvious code.
- Keep it POSIX-ish bash under
set -euo pipefail(inherited fromlib/common.sh); syntax-check withbash -n scenarios/<name>/scenario.sh.
./demo.sh list
./demo.sh <scenario> # ensure cluster + base, run & inspect
FORCE_RECREATE=1 ./demo.sh <scenario> # rebuild the cluster first
CLUSTER_NAME=<other> ./demo.sh ... # target a different kind cluster
./demo.sh clean <scenario>
./demo.sh downChanges to cluster/kind-cluster.yaml or base/kueue-values.yaml only take
effect on a fresh install, so verify those with FORCE_RECREATE=1.
- Every scenario has a
README.md(What it tests → How it works → Run → What to look for). Update it when you change a scenario. docs/superpowers/is gitignored (local working notes); don't rely on it.
- Every commit must be DCO signed off:
git commit -s. - Only commit when explicitly asked.
- Use Conventional Commits (e.g.
feat:,fix:,docs:,refactor:,chore:), optionally scoped (e.g.feat(kueue-dra): ...). - Only commit a feature once it is complete and validated - never commit something that has not been run and verified to work.