mirror of
https://github.com/sredevopsorg/deepseek-kubernetes-sandbox.git
synced 2026-11-03 01:13:24 +00:00
* feat(repo)!: restructure around the dsh-harness image and one example per implementation
- the root Dockerfile is the primary artifact; versions.env is the single source of truth
- merge gateway-api/dsh-demo into examples/dsh-agents-as-a-service (manifests/, exposure variants)
- move the single-tenant template into examples/minimal-single-tenant
- publish the gateway as a nested package under the repository image
- mirror the DSH ref for release identities (first release dsh-v0.2.1-rc.2-r2)
- CI: lint/python/manifests/gateway-image, reusable multi-arch build, tag-driven release, weekly e2e
- docs: README, docs/{main-image,examples,gitflow,versioning}, example READMEs, AGENTS.md, governance
- SSO is opt-in again; gateway pull policy and cookie defaults match the documented demo
BREAKING CHANGE: example manifest paths, the gateway image name, and the removal
of deploy/ and gateway-api/ affect existing deployments; see the migration table
in README.md.
* docs(changelog): generate initial changelog from history
* fix(scripts): make set-version update Dockerfile and sample revision pins
* build(hadolint): document intentional lint exceptions for the main image
---------
Co-authored-by: SREDevOpsAgents <agents@sredevops.org>
150 lines
6.5 KiB
Markdown
150 lines
6.5 KiB
Markdown
# Example contract
|
|
|
|
Every implementation in this repository is a **self-contained example** under
|
|
[`examples/<name>/`](../examples/). Examples demonstrate how to run the main
|
|
DSH Web image (and, when needed, auxiliary components such as the
|
|
agents-as-a-service gateway) on Kubernetes. They are reference material, not
|
|
libraries: each one is applied with plain `kubectl`, documented end to end, and
|
|
deletable in one command.
|
|
|
|
[`examples/README.md`](../examples/README.md) is the index. If an example is not
|
|
listed there, it does not exist as far as `make check` is concerned.
|
|
|
|
## Required layout
|
|
|
|
```
|
|
examples/<name>/
|
|
+-- README.md # required: what it demonstrates, prerequisites,
|
|
| # ordered steps, troubleshooting, cleanup
|
|
+-- manifests/ # required
|
|
| +-- NN-*.yaml # numbered top-level manifests, plain kubectl
|
|
| +-- exposure/ # optional exposure variants
|
|
| +-- README.md # required when exposure/ exists
|
|
| +-- <variant>/NN-*.yaml # e.g. ingress/, gateway-api-sso/
|
|
+-- scripts/ # optional
|
|
| +-- *.sh # executable, idempotent, self-cleaning
|
|
+-- docs/ # optional deeper material (architecture, ADRs)
|
|
+-- <component>/ # optional published component
|
|
+-- Dockerfile
|
|
+-- README.md # required whenever a Dockerfile exists
|
|
+-- tests...
|
|
```
|
|
|
|
### Rules the CI enforces
|
|
|
|
[scripts/check-examples.sh](../scripts/check-examples.sh) fails the build when:
|
|
|
|
- `examples/README.md` is missing or does not mention `examples/<name>/` for every
|
|
example directory;
|
|
- an example has no `README.md` or no `manifests/` directory;
|
|
- `manifests/` contains no top-level `*.yaml` files;
|
|
- a `*.yaml` file sits at the example root instead of under `manifests/`;
|
|
- `manifests/exposure/` exists without a `manifests/exposure/README.md` describing
|
|
the variants;
|
|
- a subdirectory with a `Dockerfile` has no `README.md`;
|
|
- a file in `scripts/` is not executable.
|
|
|
|
[scripts/check-manifests.py](../scripts/check-manifests.py) additionally parses
|
|
every `manifests/**/*.yaml` and requires `apiVersion`, `kind` and
|
|
`metadata.name`. CI also runs a server-side dry-run against the real
|
|
agent-sandbox CRDs on a throwaway kind cluster.
|
|
|
|
Run both locally with:
|
|
|
|
```bash
|
|
make check
|
|
```
|
|
|
|
## Manifests
|
|
|
|
- **Numbered and ordered.** `NN-*.yaml` files are applied in filename order and
|
|
read as a walkthrough: `00-prereqs.yaml`, `10-sandboxtemplate.yaml`,
|
|
`20-sandboxwarmpool.yaml`, ... Keep the numbering stable; it is referenced from
|
|
the example README.
|
|
- **Plain kubectl.** No Helm, Kustomize, or custom installer. `kubectl apply -f`
|
|
against a namespace the example creates is the whole interface.
|
|
- **Safe by default.** Never ship a usable Secret. Secret-shaped manifests are
|
|
`*.yaml.example` files with obvious placeholders and an inline creation
|
|
command; real values are generated per install.
|
|
- **Cluster-specific state stays out.** Node affinity, replica counts tuned for a
|
|
cluster, and similar fields belong in a local patch, not in the shipped
|
|
manifest.
|
|
- **Placeholders are explicit.** Hostnames, GitHub orgs and TLS material use
|
|
values like `dsh.example.com` / `your-github-org` with a TODO comment.
|
|
|
|
## Exposure variants
|
|
|
|
An example that can be reached from outside the cluster puts each option under
|
|
`manifests/exposure/<variant>/` and describes the trade-offs in
|
|
`manifests/exposure/README.md`. Variants are alternatives, not a stack: apply one.
|
|
`dsh-agents-as-a-service` currently ships:
|
|
|
|
| Variant | Path | What it gives you |
|
|
| --- | --- | --- |
|
|
| Ingress | `manifests/exposure/ingress/` | Traefik-style Ingress + TLS; the gateway does its own session auth. |
|
|
| Gateway API + SSO | `manifests/exposure/gateway-api-sso/` | Gateway API `Gateway`/`HTTPRoute` in front of oauth2-proxy (GitHub OAuth); the gateway inherits `X-Forwarded-User` via `AUTH_PROXY_HEADER`. |
|
|
|
|
## Components
|
|
|
|
A component is a program the example needs beyond the main image: today only the
|
|
agents-as-a-service gateway. A component lives in its own subdirectory with:
|
|
|
|
- `Dockerfile` — its image build;
|
|
- `README.md` — purpose, API/config reference, local development, limitations;
|
|
- tests — unit tests that run without a cluster, plus whatever else applies.
|
|
|
|
Component images are published as **nested packages below the repository image**:
|
|
|
|
```
|
|
<registry>/<owner>/<repo>/<example>/<component>
|
|
```
|
|
|
|
so the gateway is
|
|
`ghcr.io/sredevopsorg/deepseek-kubernetes-sandbox/dsh-agents-as-a-service/gateway`.
|
|
Never create an unrelated top-level package; `check-versions.sh` verifies the
|
|
nesting.
|
|
|
|
## Scripts
|
|
|
|
`scripts/*.sh` must be:
|
|
|
|
- **executable** (the CI checks the mode bit);
|
|
- **idempotent** — safe to re-run, cleaning up before creating;
|
|
- **self-cleaning** — a trap removes the namespace, port-forwards and temp files,
|
|
even on failure;
|
|
- **non-interactive** — usable in CI, with environment-variable knobs instead of
|
|
prompts.
|
|
|
|
`examples/dsh-agents-as-a-service/scripts/e2e-kind.sh` is the reference
|
|
implementation: it runs the README walkthrough and deletes everything it created.
|
|
|
|
## Documentation
|
|
|
|
- The example `README.md` is the walkthrough. Keep it runnable: every command
|
|
block should work when pasted in order.
|
|
- Deeper material (architecture, sequence diagrams, ADRs) belongs in the
|
|
example's `docs/`, not in the repository-level [docs/](../docs/).
|
|
- Repository-wide docs describe the container and the repo rules; example docs
|
|
describe one implementation.
|
|
|
|
## Adding a new example
|
|
|
|
1. Create `examples/<name>/` with the layout above.
|
|
2. Write `README.md` first: what it demonstrates, prerequisites, numbered steps,
|
|
troubleshooting, limitations, cleanup.
|
|
3. Add `manifests/NN-*.yaml`; keep secrets as `*.yaml.example`.
|
|
4. If a component needs an image, publish it under
|
|
`<registry>/<owner>/<repo>/<example>/<component>`.
|
|
5. Add an entry to [`examples/README.md`](../examples/README.md) using the literal
|
|
`examples/<name>/` path.
|
|
6. Run `make check` and, if you added a component, `make test` and `make lint`.
|
|
7. If the example is expensive to run (kind, images, cluster CRDs), ship a
|
|
`scripts/e2e-kind.sh` and wire it into CI.
|
|
|
|
## Current examples
|
|
|
|
| Example | Demonstrates |
|
|
| --- | --- |
|
|
| [`examples/dsh-agents-as-a-service/`](../examples/dsh-agents-as-a-service/) | The full multi-tenant platform pattern: SandboxTemplate, warm pool, per-user claims, suspend/resume, and the browser gateway. |
|
|
| [`examples/minimal-single-tenant/`](../examples/minimal-single-tenant/) | A single DSH Web sandbox: one SandboxTemplate and a claim. |
|