Automation¶
l8k is designed for both interactive operators and automated systems.
For repository-provided AI-agent playbooks, see AI Skills.
GitOps Pattern¶
Choose the owners before building a pipeline: who renders, who manages the Network Operator Helm release, who applies custom resources, and who signs off the validation report. A GitOps controller is an external apply owner; its ordering, readiness, retry, and pruning policy must satisfy the generated resources' dependencies. This repository does not claim an Argo CD or Flux integration.
- Pin the installed
l8kversion and selected Network Operator release. Review discovery output and commit the intendedcluster-config.yaml. Archive the exact referenced Spectrum-X profile, topology, preset/template override, and custom workload files or immutable revisions. Review network addresses, target cohort, credentials, and ownership before CI renders. - Render offline in CI where inputs allow it. Capture output and diagnostics separately and fail the job with the original CLI status:
status=0
l8k generate --user-config ./cluster-config.yaml \
--save-deployment-files ./deployment --output json \
>generation.json 2>generation.log || status=$?
if [ "$status" -ne 0 ]; then
cat generation.log >&2
exit "$status"
fi
jq . generation.json
Pass the same pinned profile, --config-dir, topology, and workload options used in the approved input record. Offline generation with a preset does not qualify live hardware; compare the preset against the target cluster before apply.
3. Review the complete deployment/ output, especially .l8k/resolved-config.yaml, resource identities, Helm values, selectors, addresses, driver/maintenance settings, and resources that would disappear. Retain the whole directory as one immutable artifact. Publishing only network-operator/ loses generation-time overrides and exact effective configuration.
4. Create a separate apply set for the external controller. values.yaml is Helm input for the Helm owner; .l8k/ is metadata for Launch Kit; *example*.yaml files are validation fixtures. Apply only approved operational Kubernetes resources in dependency order. If Helm is externally owned, set networkOperator.skipHelmChart: true before generation. Avoid a controller prune policy that could delete other cohorts or manually owned resources; compare the complete desired/live inventory.
5. After the external controller reports reconciliation, retrieve the same complete artifact and run l8k validate --deployment-files ./deployment --wait 10m. Omit --user-config so validation uses the saved effective configuration. Keep the HTML report and apply the acceptance outcomes; process success alone can leave incomplete connectivity coverage.
The reproduction record should contain the CLI version/build, selected operator release, source configuration, every referenced profile/topology/workload file, preset or template revision/digest, all render options, complete generated bundle and sidecar, apply owner/revision, and validation report. Mutable local paths alone cannot reproduce a render. The site follows development main; use the documentation at the installed release's tag or commit when operating an older binary.
JSON Mode¶
Use JSON mode when a pipeline or agent needs structured output. Capture the command and check its status before parsing, as in the GitOps recipe and validation capture.
Output contracts differ by command:
| Command | Successful stdout with --output json |
|---|---|
Root pipeline, discover, generate |
One JSONResult envelope, including collected messages. |
clean |
One result with a cleanup summary. |
Standalone deploy |
No finalized success JSON envelope. Use the process exit status; progress is sent to stderr. |
validate |
A sequence of JSON objects: manifest/version summary when full validation runs, connectivity when run, and reportPath when the HTML report is written. Do not parse the stream as one document. |
schema |
One capability object; this command always emits JSON. |
version |
One version/build object. |
preset list, preset update, sosreport |
Text output; these commands do not provide a JSON success contract despite accepting the inherited flag. |
Lifecycle JSON mode sends human-readable progress to stderr and auto-confirms prompts. Structured error objects may be emitted on failures; early Cobra flag parse errors can instead write text to stderr. Validation can emit partial results before a failure. Always check the process exit status.
--yes is root-only. Use --output json for non-interactive lifecycle
subcommands, with particular care for destructive cleanup and deployment.
Capture Results Without Losing The Exit Status¶
Capture the command first, then parse its output. This works without relying on shell pipeline options and preserves diagnostic stderr:
status=0
l8k validate --deployment-files ./deployment --output json \
>validation.jsonl 2>validation.log || status=$?
if [ "$status" -ne 0 ]; then
cat validation.log >&2
exit "$status"
fi
jq -s . validation.jsonl >validation-results.json
# Read reportPath from whichever object carries it.
jq -r 'select(has("reportPath")) | .reportPath' validation.jsonl
An empty stream or absence of a reportPath is possible on an early failure.
The manifest object's summary.success covers that summary, not later
connectivity or every final acceptance gate. Inspect the HTML report and
coverage outcomes as well as the
exit status. Interactive display pipelines can use set -o pipefail in Bash. CI examples above preserve the command status explicitly and keep diagnostic stderr.
Structured Results¶
A successful generation or root pipeline result can include its phase, resolved profile, generated files, deploy/dry-run status, and messages:
{
"success": true,
"phase": "generate",
"profile": {
"fabric": "ethernet",
"deployment": "sriov"
},
"generatedFiles": [
"deployment/network-operator/values.yaml"
],
"deployed": false,
"messages": []
}
A structured failure includes a stable category and retry guidance:
{
"success": false,
"error": {
"code": "CLUSTER_ERROR",
"message": "failed to connect to cluster",
"category": "cluster",
"transient": true,
"suggestion": "Check kubeconfig and API server connectivity"
},
"deployed": false,
"messages": []
}
Use error.transient to decide whether retry is appropriate. Treat suggestion as operator guidance, not a command to execute without review. The process exit code remains authoritative even when a JSON object is emitted.
Cleanup returns a command-specific summary:
{
"success": true,
"phase": "clean",
"deployed": false,
"cleanup": {
"namespace": "nvidia-network-operator",
"customResourcesDeleted": 12,
"helmReleaseRemoved": true,
"keepHelmChart": false
},
"messages": []
}
cleanup.keepHelmChart reports the effective retention policy. It is true
when either networkOperator.skipHelmChart in the resolved config or the
explicit --keep-helm-chart flag retains the release.
l8k clean --output json auto-confirms an irreversible cluster mutation and
has no dry-run mode. Automation must pin the intended kubeconfig and should
pass --network-operator-namespace explicitly after independently checking
the target.
Capability Discovery¶
The schema includes command descriptions, supported fabrics and deployment types, supported Network Operator release lines, exit codes, and automation-relevant flags.
Exit Codes¶
| Code | Meaning |
|---|---|
0 |
Success |
1 |
General error |
2 |
Validation error, bad flags, or invalid config |
3 |
Cluster error |
4 |
Deployment or validation failure |
5 |
Partial success |
Validation uses exit 4 when an acceptance gate fails, including release or manifest drift, preset topology deviation, and gating connectivity failures.
Logging¶
Keep JSON on stdout and direct diagnostic logging separately:
Without --log-file, logs use stderr. Do not merge stderr into stdout in a parser-facing pipeline.
Offline Preset Pattern¶
For known SKUs, avoid cluster access during render:
l8k generate \
--for ThinkSystem-SR680a-V3-H200 \
--node-selector "nvidia.com/gpu.product=NVIDIA-H200" \
--fabric ethernet \
--deployment-type sriov \
--network-operator-release 26.4 \
--save-deployment-files ./deployment \
--output json >generation.json 2>generation.log &&
jq . generation.json
The && preserves a failed generation status and avoids parsing a partial
result. Retain generation.log on failure; use the fuller capture pattern
in CI. Use --config-dir to test a custom preset catalog in CI.
Release Selection¶
Pin the target Network Operator line in the config or CLI:
The selected release fills image tags, component versions, the DOCA driver version, Helm repository URL, and profile gates.