helm: add zddc-server-cache example chart + ZDDC_NO_AUTH on prod/dev
New chart helm/zddc-server-cache/ deploys zddc-server in client mode against an upstream master. Mirrors the prod chart's source-build-via- init-container pattern but with: - ZDDC_UPSTREAM, ZDDC_MODE, ZDDC_BEARER_FILE, ZDDC_NO_AUTH, ZDDC_SKIP_TLS_VERIFY, ZDDC_MIRROR_SUBTREE, ZDDC_MIRROR_MIN_INTERVAL wired from values.yaml. Mirror-only env vars conditionally rendered (only when mode=mirror) to keep the rendered manifest minimal. - Bearer token mounted from a separately-created Kubernetes Secret (defaultMode 0400) at /etc/zddc/bearer/token. values.yaml.example documents the secret-creation flow but contains no token. Secret reference can be set to "" to disable bearer auth (only valid for upstreams running --no-auth). - Recreate strategy + replicaCount: 1 (multiple replicas would race the cache directory and double the upstream walker traffic). - TCP-socket probes instead of HTTP — HTTP probes against / would fail when both upstream is unreachable AND the cache is empty (the cache layer returns 503 + offline header in that state), causing crashloops. TCP verifies process liveness without depending on upstream reachability or cache contents. - Mounts a separate cache PVC (operator-provided, like the master's data PVC). Sized to the working set you expect to mirror; can be much smaller than the master's data volume. Existing prod and dev charts gain optional ZDDC_NO_AUTH wired from zddc.env.noAuth (default false → no change to existing rendered manifests). Useful for trusted-LAN or genuinely-public master deployments. Updated docs: helm/README.md gains the cache row in the chart table, the cache-install quickstart with the secret-creation flow, and the cache-specific structural notes (Recreate / TCP probes / single- instance). CLAUDE.md and ARCHITECTURE.md updated to reflect three charts instead of two. Verified with helm template rendering: ZDDC_NO_AUTH only renders when noAuth: true; ZDDC_MIRROR_SUBTREE / ZDDC_MIRROR_MIN_INTERVAL only render when mode: mirror; bearer volume + ZDDC_BEARER_FILE only render when bearer.secretName is non-empty. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
8a049ca2a4
commit
55852a9efb
13 changed files with 498 additions and 7 deletions
|
|
@ -66,7 +66,7 @@ Website files (what `zddc.varasys.io` serves) live on a **separate Codeberg repo
|
||||||
|
|
||||||
Every URL under `/releases/` resolves directly via the symlink chain — no `manifest.json`, no Caddy regex-rewrite, no JavaScript indirection, no third-party mirror. Caddy serves these as plain static files. The Docker-tag pattern: `:1.2.3` is pinned, `:1.2` floats, `:1` floats further, `:stable` floats furthest, and `:beta` / `:alpha` are mutable channel mirrors that overwrite in place.
|
Every URL under `/releases/` resolves directly via the symlink chain — no `manifest.json`, no Caddy regex-rewrite, no JavaScript indirection, no third-party mirror. Caddy serves these as plain static files. The Docker-tag pattern: `:1.2.3` is pinned, `:1.2` floats, `:1` floats further, `:stable` floats furthest, and `:beta` / `:alpha` are mutable channel mirrors that overwrite in place.
|
||||||
|
|
||||||
**zddc-server binaries are reproducible from a tag, not in git** — `./build alpha|beta|release` cross-compiles them into `dist/release-output/`, `./deploy` rsyncs them to `/srv/zddc/releases/`, Caddy serves from there. Older versions: `git checkout zddc-server-v0.0.8 && ./build release 0.0.8`. The `helm/zddc-server-{prod,dev}/` charts build from source via init container, but operators who want a prebuilt binary just `curl -O https://zddc.varasys.io/releases/zddc-server_stable_linux-amd64`. The single cell link per release points at `zddc-server_<X>.html`, a small generated stub that surfaces all four platform downloads.
|
**zddc-server binaries are reproducible from a tag, not in git** — `./build alpha|beta|release` cross-compiles them into `dist/release-output/`, `./deploy` rsyncs them to `/srv/zddc/releases/`, Caddy serves from there. Older versions: `git checkout zddc-server-v0.0.8 && ./build release 0.0.8`. The `helm/zddc-server-{prod,dev,cache}/` charts build from source via init container, but operators who want a prebuilt binary just `curl -O https://zddc.varasys.io/releases/zddc-server_stable_linux-amd64`. The single cell link per release points at `zddc-server_<X>.html`, a small generated stub that surfaces all four platform downloads.
|
||||||
|
|
||||||
To preview a build locally, open `dist/tool.html` directly via the dev server. To publish on `zddc.varasys.io`, cut a release with `./build alpha|beta|release` and then `./deploy`.
|
To preview a build locally, open `dist/tool.html` directly via the dev server. To publish on `zddc.varasys.io`, cut a release with `./build alpha|beta|release` and then `./deploy`.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ This is a **monorepo of independent tools**, not one application:
|
||||||
- `zddc/` — Go HTTP server (separate sub-project; Go 1.24+). Two deployment shapes from the same binary: (1) **master** — owns a file tree under `ZDDC_ROOT`, applies `.zddc` ACL cascades, serves files / app HTML / archive listings. Two auth paths on master: `Authorization: Bearer <token>` validated against self-issued tokens at `<ZDDC_ROOT>/.zddc.d/tokens/<sha256-hex>` for CLI/scripted callers, or `X-Auth-Request-Email` injected by an upstream proxy for browser sessions. Self-service token UI at `/.tokens` + JSON API at `/.api/tokens`. (2) **client** — when `--upstream <url>` is set, the binary becomes a downstream proxy/cache/mirror (`zddc/internal/cache/`); master-side machinery is bypassed and `--root` becomes the cache directory. Three sub-modes via `--mode proxy|cache|mirror` (mirror is phase 3). Cache layout is a normal ZDDC root, so the cache dir can be served as a plain master if you unset `--upstream`. Marker file `.zddc-upstream` records provenance. `--no-auth` skips ACL enforcement entirely on this instance (distinct from `--insecure` which only relaxes the no-root-`.zddc` startup check); `--skip-tls-verify` is a separate flag for self-signed upstream certs. Cross-compiled binaries are produced by `./build` and live in `dist/release-output/` (gitignored); `./deploy` rsyncs them to `/srv/zddc/releases/` on the deploy host (Caddy serves them at `https://zddc.varasys.io/releases/`). The `helm/` charts in this repo build from source at deploy time.
|
- `zddc/` — Go HTTP server (separate sub-project; Go 1.24+). Two deployment shapes from the same binary: (1) **master** — owns a file tree under `ZDDC_ROOT`, applies `.zddc` ACL cascades, serves files / app HTML / archive listings. Two auth paths on master: `Authorization: Bearer <token>` validated against self-issued tokens at `<ZDDC_ROOT>/.zddc.d/tokens/<sha256-hex>` for CLI/scripted callers, or `X-Auth-Request-Email` injected by an upstream proxy for browser sessions. Self-service token UI at `/.tokens` + JSON API at `/.api/tokens`. (2) **client** — when `--upstream <url>` is set, the binary becomes a downstream proxy/cache/mirror (`zddc/internal/cache/`); master-side machinery is bypassed and `--root` becomes the cache directory. Three sub-modes via `--mode proxy|cache|mirror` (mirror is phase 3). Cache layout is a normal ZDDC root, so the cache dir can be served as a plain master if you unset `--upstream`. Marker file `.zddc-upstream` records provenance. `--no-auth` skips ACL enforcement entirely on this instance (distinct from `--insecure` which only relaxes the no-root-`.zddc` startup check); `--skip-tls-verify` is a separate flag for self-signed upstream certs. Cross-compiled binaries are produced by `./build` and live in `dist/release-output/` (gitignored); `./deploy` rsyncs them to `/srv/zddc/releases/` on the deploy host (Caddy serves them at `https://zddc.varasys.io/releases/`). The `helm/` charts in this repo build from source at deploy time.
|
||||||
- `shared/` — `base.css` plus shared JS modules (`zddc.js`, `hash.js`, `zddc-filter.js`, `theme.js`, `help.js`) included by every tool's build, and `build-lib.sh` (POSIX sh helpers sourced by every tool's `build.sh` AND by the top-level `build` for lockstep release helpers).
|
- `shared/` — `base.css` plus shared JS modules (`zddc.js`, `hash.js`, `zddc-filter.js`, `theme.js`, `help.js`) included by every tool's build, and `build-lib.sh` (POSIX sh helpers sourced by every tool's `build.sh` AND by the top-level `build` for lockstep release helpers).
|
||||||
- **Two-repo + deploy-host model.** Source code lives here (`codeberg.org/VARASYS/ZDDC`). Hand-edited website content lives in a separate repo (`codeberg.org/VARASYS/ZDDC-website`, typically cloned at `~/src/zddc-website/` — just `index.html`, `reference.html`, `css/`, `js/`, `img/`; no releases, no LFS). The live site at `zddc.varasys.io` is served from `/srv/zddc/` on the deploy host: Caddy bind-mounts that path, and it's populated by `./deploy` from this repo's `dist/release-output/` plus `~/src/zddc-website/`. **Releases are NOT in any git history** — they're reproducible from this repo's `<tool>-vX.Y.Z` tags by checking out the tag and running `./build release X.Y.Z`. Per-version files (`<tool>_v<X.Y.Z>.html`) are immutable; partial-version pins (`<tool>_v<X.Y>.html`, `<tool>_v<X>.html`) and channel mirrors (`<tool>_{stable,beta,alpha}.html`) are symlinks; zddc-server has analogous `zddc-server_v<X.Y.Z>_<platform>` per-version binaries plus channel/partial-version symlinks plus `zddc-server_<X>.html` stub pages that fan out the four-platform download in one cell. **Install model:** local use is a download from `/releases/`. Server use is `zddc-server`, which has the current-stable build of all six tools baked in via `//go:embed` (compile-time default). Tools auto-served at folder-name-driven paths: `archive` everywhere, `classifier` in `Incoming`/`Working`/`Staging` subtrees, `mdedit` in `Working` subtrees, `transmittal` in `Staging` subtrees, `landing` only at root. Override via `.zddc apps:` cascade entry (channel/version/URL/path) — fetched once, cached at `<ZDDC_ROOT>/_app/`. Drop a real `.html` file at any path to override.
|
- **Two-repo + deploy-host model.** Source code lives here (`codeberg.org/VARASYS/ZDDC`). Hand-edited website content lives in a separate repo (`codeberg.org/VARASYS/ZDDC-website`, typically cloned at `~/src/zddc-website/` — just `index.html`, `reference.html`, `css/`, `js/`, `img/`; no releases, no LFS). The live site at `zddc.varasys.io` is served from `/srv/zddc/` on the deploy host: Caddy bind-mounts that path, and it's populated by `./deploy` from this repo's `dist/release-output/` plus `~/src/zddc-website/`. **Releases are NOT in any git history** — they're reproducible from this repo's `<tool>-vX.Y.Z` tags by checking out the tag and running `./build release X.Y.Z`. Per-version files (`<tool>_v<X.Y.Z>.html`) are immutable; partial-version pins (`<tool>_v<X.Y>.html`, `<tool>_v<X>.html`) and channel mirrors (`<tool>_{stable,beta,alpha}.html`) are symlinks; zddc-server has analogous `zddc-server_v<X.Y.Z>_<platform>` per-version binaries plus channel/partial-version symlinks plus `zddc-server_<X>.html` stub pages that fan out the four-platform download in one cell. **Install model:** local use is a download from `/releases/`. Server use is `zddc-server`, which has the current-stable build of all six tools baked in via `//go:embed` (compile-time default). Tools auto-served at folder-name-driven paths: `archive` everywhere, `classifier` in `Incoming`/`Working`/`Staging` subtrees, `mdedit` in `Working` subtrees, `transmittal` in `Staging` subtrees, `landing` only at root. Override via `.zddc apps:` cascade entry (channel/version/URL/path) — fetched once, cached at `<ZDDC_ROOT>/_app/`. Drop a real `.html` file at any path to override.
|
||||||
- `helm/` — example Helm charts for zddc-server (`zddc-server-prod/`, `zddc-server-dev/`). Both compile from source via init container. Operators copy `values.yaml.example` and customize. No secrets in repo.
|
- `helm/` — example Helm charts for zddc-server. Three flavors: `zddc-server-prod/` (production master), `zddc-server-dev/` (development master with OverlayFS isolation), `zddc-server-cache/` (downstream client running in proxy/cache/mirror mode against an upstream master, with bearer token from a Kubernetes Secret). All compile from source via init container. Operators copy `values.yaml.example` and customize. No secrets in repo — the cache chart references a separately-created Secret for the bearer token.
|
||||||
- `tests/` — Playwright specs (Chromium only, requires File System Access API). `tests/schema.spec.js` validates `transmittal.schema.json` against canonical fixtures via `ajv` (only dev dep besides Playwright)
|
- `tests/` — Playwright specs (Chromium only, requires File System Access API). `tests/schema.spec.js` validates `transmittal.schema.json` against canonical fixtures via `ajv` (only dev dep besides Playwright)
|
||||||
|
|
||||||
## Most-used commands
|
## Most-used commands
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
# Helm charts
|
# Helm charts
|
||||||
|
|
||||||
Two example charts for deploying [zddc-server](../zddc/) on Kubernetes.
|
Three example charts for deploying [zddc-server](../zddc/) on Kubernetes.
|
||||||
Both compile zddc-server from source via an init container — no
|
All compile zddc-server from source via an init container — no
|
||||||
container image needs to be pulled from a registry, and no binary needs
|
container image needs to be pulled from a registry, and no binary needs
|
||||||
to be built ahead of time. The init container clones the repo at a
|
to be built ahead of time. The init container clones the repo at a
|
||||||
configured git ref and runs `go build`; the main container is plain
|
configured git ref and runs `go build`; the main container is plain
|
||||||
|
|
@ -11,16 +11,24 @@ alpine + the freshly built static binary.
|
||||||
|
|
||||||
| Chart | When to use |
|
| Chart | When to use |
|
||||||
|---|---|
|
|---|---|
|
||||||
| **`zddc-server-prod/`** | Production. Pin `zddc.gitRef` to a stable tag (`zddc-server-vX.Y.Z`). Slower probe cadence; image-pull policy `IfNotPresent`. Mounts the data PVC directly RW at `ZDDC_ROOT`. |
|
| **`zddc-server-prod/`** | Production **master**. Pin `zddc.gitRef` to a stable tag (`zddc-server-vX.Y.Z`). Slower probe cadence; image-pull policy `IfNotPresent`. Mounts the data PVC directly RW at `ZDDC_ROOT`. The token system is enabled automatically (tokens persist on the data PVC at `<ZDDC_ROOT>/.zddc.d/tokens/`); operators visit `/.tokens` to issue them. |
|
||||||
| **`zddc-server-dev/`** | Development / soak. Tracks `main` by default; `helm upgrade` triggers a pod recreate so each rollout pulls the latest commit. Faster probes; debug-level logging (request headers logged — sensitive). Wraps the data PVC in **OverlayFS** (lower = PVC mounted RO, upper = ephemeral `emptyDir`) so dev-side writes never mutate the underlying store. Use this shape when the dev replica points at the same data as prod. |
|
| **`zddc-server-dev/`** | Development / soak **master**. Tracks `main` by default; `helm upgrade` triggers a pod recreate so each rollout pulls the latest commit. Faster probes; debug-level logging (request headers logged — sensitive). Wraps the data PVC in **OverlayFS** (lower = PVC mounted RO, upper = ephemeral `emptyDir`) so dev-side writes never mutate the underlying store. Use this shape when the dev replica points at the same data as prod. |
|
||||||
|
| **`zddc-server-cache/`** | Downstream **client** (proxy / cache / mirror) of an upstream master. Set `zddc.upstream.url` + `zddc.upstream.mode`; the binary skips master-side machinery and forwards all requests to the master, persisting responses under the cache PVC (in cache or mirror modes). Bearer auth via a separately-created Kubernetes Secret. Use cases: corporate-master → DR-mirror, vendor-scoped mirror in a vendor's own cluster, regional edge cache, dev environment that mirrors prod read-only. Mirror mode adds an access-triggered subtree walker. |
|
||||||
|
|
||||||
The chart values are nearly identical between the two; the differences
|
The prod and dev chart values are nearly identical; the differences
|
||||||
are encoded as defaults in each chart's `values.yaml.example`. The
|
are encoded as defaults in each chart's `values.yaml.example`. The
|
||||||
dev chart's overlay-isolation layer is a structural difference, not a
|
dev chart's overlay-isolation layer is a structural difference, not a
|
||||||
values-level toggle — see `zddc-server-dev/templates/deployment.yaml`
|
values-level toggle — see `zddc-server-dev/templates/deployment.yaml`
|
||||||
for the privileged init container and the `data-readonly` /
|
for the privileged init container and the `data-readonly` /
|
||||||
`overlay-scratch` / `data` volume sandwich.
|
`overlay-scratch` / `data` volume sandwich.
|
||||||
|
|
||||||
|
The cache chart shares the same source-build pattern but adds
|
||||||
|
client-mode env wiring (`ZDDC_UPSTREAM`, `ZDDC_MODE`, `ZDDC_BEARER_FILE`,
|
||||||
|
`ZDDC_NO_AUTH`, `ZDDC_SKIP_TLS_VERIFY`, mirror-mode subtree config),
|
||||||
|
a Recreate strategy (single-instance — multiple replicas would race
|
||||||
|
the cache directory), and TCP-socket probes (HTTP probes against `/`
|
||||||
|
would fail when both upstream is down AND the cache is empty).
|
||||||
|
|
||||||
## Quick start
|
## Quick start
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
|
|
@ -48,6 +56,30 @@ helm install zddc-server-dev helm/zddc-server-dev/ -f my-dev-values.yaml
|
||||||
|
|
||||||
# Trigger a rebuild from latest main HEAD (dev chart)
|
# Trigger a rebuild from latest main HEAD (dev chart)
|
||||||
helm upgrade zddc-server-dev helm/zddc-server-dev/ -f my-dev-values.yaml
|
helm upgrade zddc-server-dev helm/zddc-server-dev/ -f my-dev-values.yaml
|
||||||
|
|
||||||
|
# Cache install (downstream client of an upstream master)
|
||||||
|
#
|
||||||
|
# 1) Issue a bearer token on the master at https://<master>/.tokens
|
||||||
|
# 2) Create the Secret (do NOT put the token in values.yaml):
|
||||||
|
kubectl create secret generic zddc-cache-bearer \
|
||||||
|
--from-literal=token=<paste-token-here>
|
||||||
|
|
||||||
|
# 3) Create a cache PVC (separate from the master's data PVC; can
|
||||||
|
# be smaller — sized to the working set you expect to mirror):
|
||||||
|
kubectl apply -f - <<'PVC'
|
||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata: { name: zddc-cache }
|
||||||
|
spec:
|
||||||
|
accessModes: [ReadWriteOnce]
|
||||||
|
resources: { requests: { storage: 50Gi } }
|
||||||
|
storageClassName: your-block-storage
|
||||||
|
PVC
|
||||||
|
|
||||||
|
# 4) Install the chart, pointing at your master:
|
||||||
|
cp helm/zddc-server-cache/values.yaml.example my-cache-values.yaml
|
||||||
|
$EDITOR my-cache-values.yaml # set zddc.upstream.url, mode, etc.
|
||||||
|
helm install zddc-server-cache helm/zddc-server-cache/ -f my-cache-values.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
## What the chart does and doesn't do
|
## What the chart does and doesn't do
|
||||||
|
|
@ -107,8 +139,12 @@ for tracking-main convenience).
|
||||||
```sh
|
```sh
|
||||||
helm lint helm/zddc-server-prod/
|
helm lint helm/zddc-server-prod/
|
||||||
helm lint helm/zddc-server-dev/
|
helm lint helm/zddc-server-dev/
|
||||||
|
helm lint helm/zddc-server-cache/
|
||||||
|
|
||||||
# Render to inspect (uses default values from values.yaml.example):
|
# Render to inspect (uses default values from values.yaml.example):
|
||||||
helm template test-prod helm/zddc-server-prod/ \
|
helm template test-prod helm/zddc-server-prod/ \
|
||||||
--values helm/zddc-server-prod/values.yaml.example
|
--values helm/zddc-server-prod/values.yaml.example
|
||||||
|
|
||||||
|
helm template test-cache helm/zddc-server-cache/ \
|
||||||
|
--values helm/zddc-server-cache/values.yaml.example
|
||||||
```
|
```
|
||||||
|
|
|
||||||
32
helm/zddc-server-cache/Chart.yaml
Normal file
32
helm/zddc-server-cache/Chart.yaml
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
apiVersion: v2
|
||||||
|
name: zddc-server-cache
|
||||||
|
description: |
|
||||||
|
Downstream cache / mirror deployment of zddc-server. Compiles from
|
||||||
|
source via an init container at deploy time (no image pull from a
|
||||||
|
registry); the main container is alpine + the freshly-built binary.
|
||||||
|
Runs in client mode against an upstream zddc-server master, caching
|
||||||
|
every accessed file (and, in mirror mode, proactively walking
|
||||||
|
configured subtrees).
|
||||||
|
|
||||||
|
Use cases: corporate-master → DR-mirror, vendor-scoped mirror in a
|
||||||
|
vendor's own cluster, regional edge cache, dev/staging environment
|
||||||
|
that mirrors prod. Distinct from `zddc-server-prod` (which IS a
|
||||||
|
master) and `zddc-server-dev` (a master with overlay isolation).
|
||||||
|
|
||||||
|
TLS upstream is verified by default (set --skip-tls-verify only for
|
||||||
|
self-signed dev masters or internal CAs you haven't yet added to
|
||||||
|
the trust store).
|
||||||
|
type: application
|
||||||
|
version: 0.1.0
|
||||||
|
appVersion: "0.0.7" # zddc-server git tag this chart was last verified against
|
||||||
|
home: https://zddc.varasys.io/
|
||||||
|
sources:
|
||||||
|
- https://codeberg.org/VARASYS/ZDDC
|
||||||
|
maintainers:
|
||||||
|
- name: VARASYS
|
||||||
|
keywords:
|
||||||
|
- zddc
|
||||||
|
- cache
|
||||||
|
- mirror
|
||||||
|
- file-server
|
||||||
|
- document-control
|
||||||
33
helm/zddc-server-cache/templates/_helpers.tpl
Normal file
33
helm/zddc-server-cache/templates/_helpers.tpl
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
{{/*
|
||||||
|
Common labels and the fullname helper. Stays minimal; chart consumers
|
||||||
|
who want richer labels can override via metadata.labels in their
|
||||||
|
values.yaml or post-render kustomize.
|
||||||
|
*/}}
|
||||||
|
|
||||||
|
{{- define "zddc-server.name" -}}
|
||||||
|
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- define "zddc-server.fullname" -}}
|
||||||
|
{{- if .Values.fullnameOverride -}}
|
||||||
|
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
|
||||||
|
{{- else -}}
|
||||||
|
{{- $name := default .Chart.Name .Values.nameOverride -}}
|
||||||
|
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- define "zddc-server.labels" -}}
|
||||||
|
app.kubernetes.io/name: {{ include "zddc-server.name" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
app.kubernetes.io/version: {{ .Values.zddc.gitRef | quote }}
|
||||||
|
app.kubernetes.io/component: cache
|
||||||
|
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||||
|
helm.sh/chart: {{ printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" }}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- define "zddc-server.selectorLabels" -}}
|
||||||
|
app.kubernetes.io/name: {{ include "zddc-server.name" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
app.kubernetes.io/component: cache
|
||||||
|
{{- end -}}
|
||||||
162
helm/zddc-server-cache/templates/deployment.yaml
Normal file
162
helm/zddc-server-cache/templates/deployment.yaml
Normal file
|
|
@ -0,0 +1,162 @@
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: {{ include "zddc-server.fullname" . }}
|
||||||
|
labels:
|
||||||
|
{{- include "zddc-server.labels" . | nindent 4 }}
|
||||||
|
spec:
|
||||||
|
replicas: {{ .Values.replicaCount }}
|
||||||
|
# Cache writes serialize through the local filesystem; running two
|
||||||
|
# replicas would race the cache directory + double the upstream
|
||||||
|
# walker traffic. Recreate strategy ensures only one pod holds the
|
||||||
|
# cache PVC at a time.
|
||||||
|
strategy:
|
||||||
|
type: Recreate
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
{{- include "zddc-server.selectorLabels" . | nindent 6 }}
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
{{- include "zddc-server.selectorLabels" . | nindent 8 }}
|
||||||
|
spec:
|
||||||
|
{{- with .Values.imagePullSecrets }}
|
||||||
|
imagePullSecrets:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
volumes:
|
||||||
|
- name: zddc-bin
|
||||||
|
emptyDir: {}
|
||||||
|
- name: data
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: {{ .Values.data.pvcName }}
|
||||||
|
{{- if .Values.bearer.secretName }}
|
||||||
|
- name: bearer
|
||||||
|
secret:
|
||||||
|
secretName: {{ .Values.bearer.secretName | quote }}
|
||||||
|
defaultMode: 0400
|
||||||
|
items:
|
||||||
|
- key: {{ .Values.bearer.secretKey | quote }}
|
||||||
|
path: token
|
||||||
|
{{- end }}
|
||||||
|
initContainers:
|
||||||
|
# Build zddc-server from the pinned git ref. Same flow as the
|
||||||
|
# master charts — the binary is the same; client mode is
|
||||||
|
# selected at runtime via ZDDC_UPSTREAM.
|
||||||
|
- name: build-zddc-server
|
||||||
|
image: {{ printf "%s:%s" .Values.buildImage.repository .Values.buildImage.tag | quote }}
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
command: ["/bin/sh", "-c"]
|
||||||
|
args:
|
||||||
|
- |
|
||||||
|
set -eu
|
||||||
|
apk add --no-cache git
|
||||||
|
git clone --depth 1 --branch "$GIT_REF" "$GIT_REPO" /workspace
|
||||||
|
cd /workspace/zddc
|
||||||
|
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \
|
||||||
|
go build -trimpath \
|
||||||
|
-ldflags="-s -w -X main.version=$GIT_REF" \
|
||||||
|
-o /out/zddc-server \
|
||||||
|
./cmd/zddc-server
|
||||||
|
echo "built /out/zddc-server from $GIT_REF"
|
||||||
|
env:
|
||||||
|
- name: GIT_REPO
|
||||||
|
value: {{ .Values.zddc.gitRepo | quote }}
|
||||||
|
- name: GIT_REF
|
||||||
|
value: {{ .Values.zddc.gitRef | quote }}
|
||||||
|
volumeMounts:
|
||||||
|
- name: zddc-bin
|
||||||
|
mountPath: /out
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 200m
|
||||||
|
memory: 256Mi
|
||||||
|
limits:
|
||||||
|
cpu: 1000m
|
||||||
|
memory: 512Mi
|
||||||
|
containers:
|
||||||
|
- name: zddc-server
|
||||||
|
image: {{ printf "%s:%s" .Values.runtimeImage.repository .Values.runtimeImage.tag | quote }}
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
command: ["/zddc/zddc-server"]
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
containerPort: 8080
|
||||||
|
protocol: TCP
|
||||||
|
env:
|
||||||
|
- name: ZDDC_ROOT
|
||||||
|
value: {{ .Values.zddc.env.rootPath | quote }}
|
||||||
|
- name: ZDDC_ADDR
|
||||||
|
value: {{ .Values.zddc.env.addr | quote }}
|
||||||
|
- name: ZDDC_TLS_CERT
|
||||||
|
value: "none"
|
||||||
|
- name: ZDDC_INSECURE_DIRECT
|
||||||
|
value: "1"
|
||||||
|
- name: ZDDC_EMAIL_HEADER
|
||||||
|
value: {{ .Values.zddc.env.emailHeader | quote }}
|
||||||
|
- name: ZDDC_CORS_ORIGIN
|
||||||
|
value: {{ .Values.zddc.env.corsOrigin | quote }}
|
||||||
|
- name: ZDDC_LOG_LEVEL
|
||||||
|
value: {{ .Values.zddc.env.logLevel | quote }}
|
||||||
|
- name: ZDDC_INDEX_PATH
|
||||||
|
value: {{ .Values.zddc.env.indexPath | quote }}
|
||||||
|
{{- if .Values.zddc.env.noAuth }}
|
||||||
|
- name: ZDDC_NO_AUTH
|
||||||
|
value: "1"
|
||||||
|
{{- end }}
|
||||||
|
# Client-mode flags. ZDDC_UPSTREAM activates client mode
|
||||||
|
# in cmd/zddc-server/main.go's runClient short-circuit.
|
||||||
|
- name: ZDDC_UPSTREAM
|
||||||
|
value: {{ .Values.zddc.upstream.url | quote }}
|
||||||
|
- name: ZDDC_MODE
|
||||||
|
value: {{ .Values.zddc.upstream.mode | quote }}
|
||||||
|
{{- if .Values.zddc.upstream.skipTLSVerify }}
|
||||||
|
- name: ZDDC_SKIP_TLS_VERIFY
|
||||||
|
value: "1"
|
||||||
|
{{- end }}
|
||||||
|
{{- if .Values.bearer.secretName }}
|
||||||
|
- name: ZDDC_BEARER_FILE
|
||||||
|
value: "/etc/zddc/bearer/token"
|
||||||
|
{{- end }}
|
||||||
|
{{- if eq .Values.zddc.upstream.mode "mirror" }}
|
||||||
|
{{- with .Values.zddc.upstream.mirrorSubtree }}
|
||||||
|
- name: ZDDC_MIRROR_SUBTREE
|
||||||
|
value: {{ . | quote }}
|
||||||
|
{{- end }}
|
||||||
|
{{- with .Values.zddc.upstream.mirrorMinInterval }}
|
||||||
|
- name: ZDDC_MIRROR_MIN_INTERVAL
|
||||||
|
value: {{ . | quote }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
volumeMounts:
|
||||||
|
- name: zddc-bin
|
||||||
|
mountPath: /zddc
|
||||||
|
- name: data
|
||||||
|
mountPath: {{ .Values.zddc.env.rootPath }}
|
||||||
|
{{- with .Values.data.subPath }}
|
||||||
|
subPath: {{ . | quote }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if .Values.bearer.secretName }}
|
||||||
|
- name: bearer
|
||||||
|
mountPath: /etc/zddc/bearer
|
||||||
|
readOnly: true
|
||||||
|
{{- end }}
|
||||||
|
resources:
|
||||||
|
{{- toYaml .Values.resources | nindent 12 }}
|
||||||
|
# TCP-socket probes only — HTTP probes against `/` would
|
||||||
|
# fail when both upstream is unreachable AND the cache is
|
||||||
|
# empty (the cache layer returns 503 in that state). TCP
|
||||||
|
# probes verify the server process is alive without
|
||||||
|
# depending on upstream reachability or cache contents.
|
||||||
|
livenessProbe:
|
||||||
|
tcpSocket:
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
periodSeconds: 30
|
||||||
|
timeoutSeconds: 5
|
||||||
|
readinessProbe:
|
||||||
|
tcpSocket:
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 2
|
||||||
|
periodSeconds: 10
|
||||||
|
timeoutSeconds: 3
|
||||||
29
helm/zddc-server-cache/templates/ingress.yaml
Normal file
29
helm/zddc-server-cache/templates/ingress.yaml
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
{{- if .Values.ingress.enabled -}}
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: {{ include "zddc-server.fullname" . }}
|
||||||
|
labels:
|
||||||
|
{{- include "zddc-server.labels" . | nindent 4 }}
|
||||||
|
spec:
|
||||||
|
{{- with .Values.ingress.className }}
|
||||||
|
ingressClassName: {{ . }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if .Values.ingress.tls.enabled }}
|
||||||
|
tls:
|
||||||
|
- hosts:
|
||||||
|
- {{ .Values.ingress.host }}
|
||||||
|
secretName: {{ .Values.ingress.tls.secretName }}
|
||||||
|
{{- end }}
|
||||||
|
rules:
|
||||||
|
- host: {{ .Values.ingress.host }}
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: {{ include "zddc-server.fullname" . }}
|
||||||
|
port:
|
||||||
|
number: {{ .Values.service.port }}
|
||||||
|
{{- end }}
|
||||||
15
helm/zddc-server-cache/templates/service.yaml
Normal file
15
helm/zddc-server-cache/templates/service.yaml
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: {{ include "zddc-server.fullname" . }}
|
||||||
|
labels:
|
||||||
|
{{- include "zddc-server.labels" . | nindent 4 }}
|
||||||
|
spec:
|
||||||
|
type: {{ .Values.service.type }}
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
port: {{ .Values.service.port }}
|
||||||
|
targetPort: http
|
||||||
|
protocol: TCP
|
||||||
|
selector:
|
||||||
|
{{- include "zddc-server.selectorLabels" . | nindent 4 }}
|
||||||
150
helm/zddc-server-cache/values.yaml.example
Normal file
150
helm/zddc-server-cache/values.yaml.example
Normal file
|
|
@ -0,0 +1,150 @@
|
||||||
|
# values.yaml.example — zddc-server-cache
|
||||||
|
#
|
||||||
|
# Copy to values.yaml (or pass via --values) and customize for your
|
||||||
|
# environment. Contains NO secrets — the upstream bearer token MUST be
|
||||||
|
# provided via a separately-created Kubernetes Secret (see `bearer:`
|
||||||
|
# below). Do not paste the token value here.
|
||||||
|
|
||||||
|
# Source-build configuration. The init container clones the repo at
|
||||||
|
# `gitRef` and compiles cmd/zddc-server. Pin gitRef to a stable tag
|
||||||
|
# (zddc-server-vX.Y.Z) for production caches; tracking main is fine
|
||||||
|
# for dev mirrors.
|
||||||
|
zddc:
|
||||||
|
gitRepo: https://codeberg.org/VARASYS/ZDDC.git
|
||||||
|
gitRef: zddc-server-v0.0.7 # pin to a stable tag
|
||||||
|
|
||||||
|
# ZDDC environment-variable contract — see zddc/README.md "Client mode".
|
||||||
|
env:
|
||||||
|
# Local cache directory (mounted from the cache PVC; see `data:`
|
||||||
|
# below). The cache layer writes files here as they're fetched.
|
||||||
|
rootPath: /srv
|
||||||
|
|
||||||
|
# Listening address for incoming requests to this cache instance.
|
||||||
|
# Plain HTTP — ingress / mesh terminates TLS upstream of the pod.
|
||||||
|
addr: ":8080"
|
||||||
|
|
||||||
|
# Email-header convention from your authenticating reverse proxy.
|
||||||
|
# Used for AccessLog only in client mode (auth flows to upstream
|
||||||
|
# as a bearer; the cache layer doesn't enforce ACL locally when
|
||||||
|
# noAuth: true).
|
||||||
|
emailHeader: X-Auth-Request-Email
|
||||||
|
|
||||||
|
# CORS allowlist for the local instance. Same semantics as the
|
||||||
|
# master chart — empty disables CORS, which is the right default
|
||||||
|
# for embedded-tools / same-origin browsing.
|
||||||
|
corsOrigin: ""
|
||||||
|
|
||||||
|
# info / warn / error / debug.
|
||||||
|
logLevel: info
|
||||||
|
|
||||||
|
indexPath: ".archive"
|
||||||
|
|
||||||
|
# Skip ACL enforcement on incoming requests. Almost always true
|
||||||
|
# for a personal/field-engineer cache (the laptop is single-user-
|
||||||
|
# trust and the upstream master already filtered). Set to false
|
||||||
|
# only if you've put your own auth proxy in front of this cache
|
||||||
|
# AND want it to re-evaluate ACLs against cached `.zddc` files.
|
||||||
|
noAuth: true
|
||||||
|
|
||||||
|
# Upstream master configuration.
|
||||||
|
upstream:
|
||||||
|
# The master URL. Required. Don't include a trailing slash.
|
||||||
|
url: "https://zddc.example.com"
|
||||||
|
|
||||||
|
# proxy / cache / mirror.
|
||||||
|
# proxy — forward live, no disk persistence
|
||||||
|
# cache — persist responses on access (default; field-engineer use)
|
||||||
|
# mirror — cache + access-triggered subtree warmer (vendor /
|
||||||
|
# backup / complete-offline use)
|
||||||
|
mode: cache
|
||||||
|
|
||||||
|
# Accept self-signed / untrusted upstream TLS certs. Distinct from
|
||||||
|
# noAuth. Use only for dev masters with self-signed certs or for
|
||||||
|
# internal CAs your cluster's trust store doesn't yet have.
|
||||||
|
skipTLSVerify: false
|
||||||
|
|
||||||
|
# Mirror-mode only. Comma-separated URL subtrees the access-
|
||||||
|
# triggered walker keeps current. Empty + mode=mirror = full
|
||||||
|
# mirror ("/"). Ignored when mode != mirror.
|
||||||
|
mirrorSubtree: ""
|
||||||
|
|
||||||
|
# Mirror-mode only. Min gap between walks of the same subtree.
|
||||||
|
# Idle subtrees generate zero upstream traffic until next access.
|
||||||
|
# Default 1h.
|
||||||
|
mirrorMinInterval: 1h
|
||||||
|
|
||||||
|
# Bearer token — required when the upstream master enforces auth.
|
||||||
|
# Create a Secret separately (do NOT paste the token here):
|
||||||
|
#
|
||||||
|
# 1. On the master, sign in via your auth proxy and visit
|
||||||
|
# https://<master>/.tokens to issue a token.
|
||||||
|
# 2. Wrap it in a Kubernetes Secret:
|
||||||
|
#
|
||||||
|
# kubectl create secret generic zddc-cache-bearer \
|
||||||
|
# --from-literal=token=<paste-token-here>
|
||||||
|
#
|
||||||
|
# 3. Reference the Secret here.
|
||||||
|
#
|
||||||
|
# Set `secretName: ""` to disable bearer auth (only valid when the
|
||||||
|
# upstream is `--no-auth` or behind your own auth proxy that doesn't
|
||||||
|
# require bearer auth from internal callers).
|
||||||
|
bearer:
|
||||||
|
secretName: zddc-cache-bearer
|
||||||
|
secretKey: token
|
||||||
|
|
||||||
|
# Cache-storage PVC. Sized for the working set you expect to mirror —
|
||||||
|
# can be smaller than the master's data volume since only accessed
|
||||||
|
# files (or, in mirror mode, files under configured subtrees) get
|
||||||
|
# cached. Operators provision the PVC themselves; this chart only
|
||||||
|
# references it by name. ReadWriteOnce is fine — the cache is single-
|
||||||
|
# instance by design.
|
||||||
|
data:
|
||||||
|
pvcName: zddc-cache # name of an existing PersistentVolumeClaim
|
||||||
|
subPath: ""
|
||||||
|
|
||||||
|
# Service exposure. The cache listens on a plain HTTP port; ingress
|
||||||
|
# (or mesh sidecar) terminates TLS and forwards to this service.
|
||||||
|
service:
|
||||||
|
type: ClusterIP
|
||||||
|
port: 8080
|
||||||
|
|
||||||
|
# Ingress is optional — disabled by default since most cache
|
||||||
|
# deployments wire into an existing ingress / auth-proxy stack.
|
||||||
|
ingress:
|
||||||
|
enabled: false
|
||||||
|
className: ""
|
||||||
|
host: zddc-cache.example.com
|
||||||
|
tls:
|
||||||
|
enabled: false
|
||||||
|
secretName: zddc-cache-tls
|
||||||
|
|
||||||
|
# Pod resource limits. Cache instances are mostly I/O bound; the
|
||||||
|
# defaults below suit a small mirror (~1k files in working set).
|
||||||
|
# Bump cpu/memory for mirror mode against larger trees.
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 100m
|
||||||
|
memory: 128Mi
|
||||||
|
limits:
|
||||||
|
cpu: 500m
|
||||||
|
memory: 512Mi
|
||||||
|
|
||||||
|
# Replicas. Cache instances are single-instance by design — multiple
|
||||||
|
# replicas would race on writes to the same cache directory and
|
||||||
|
# duplicate the upstream walker traffic. Use a separate cache
|
||||||
|
# deployment per region/tenant if you need fan-out.
|
||||||
|
replicaCount: 1
|
||||||
|
|
||||||
|
# Build-stage Go image (init container).
|
||||||
|
buildImage:
|
||||||
|
repository: docker.io/golang
|
||||||
|
tag: 1.24-alpine
|
||||||
|
|
||||||
|
# Runtime image (main container).
|
||||||
|
runtimeImage:
|
||||||
|
repository: docker.io/alpine
|
||||||
|
tag: "3.19"
|
||||||
|
|
||||||
|
# Image pull credentials, if your registry requires them.
|
||||||
|
imagePullSecrets: []
|
||||||
|
# - name: regcred
|
||||||
|
|
@ -147,6 +147,10 @@ spec:
|
||||||
value: {{ .Values.zddc.env.logLevel | quote }}
|
value: {{ .Values.zddc.env.logLevel | quote }}
|
||||||
- name: ZDDC_INDEX_PATH
|
- name: ZDDC_INDEX_PATH
|
||||||
value: {{ .Values.zddc.env.indexPath | quote }}
|
value: {{ .Values.zddc.env.indexPath | quote }}
|
||||||
|
{{- if .Values.zddc.env.noAuth }}
|
||||||
|
- name: ZDDC_NO_AUTH
|
||||||
|
value: "1"
|
||||||
|
{{- end }}
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: zddc-bin
|
- name: zddc-bin
|
||||||
mountPath: /zddc
|
mountPath: /zddc
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,15 @@ zddc:
|
||||||
logLevel: debug # full request headers logged; sensitive!
|
logLevel: debug # full request headers logged; sensitive!
|
||||||
indexPath: ".archive"
|
indexPath: ".archive"
|
||||||
|
|
||||||
|
# Skip ACL enforcement entirely. Useful in trusted-LAN dev clusters
|
||||||
|
# where authentication isn't needed and you want to iterate without
|
||||||
|
# configuring an upstream auth proxy. Default false.
|
||||||
|
noAuth: false
|
||||||
|
|
||||||
|
# Token system: enabled automatically — tokens persist at
|
||||||
|
# <ZDDC_ROOT>/.zddc.d/tokens/ on the data PVC. Sign in via your
|
||||||
|
# cluster's auth proxy and visit /.tokens to issue one.
|
||||||
|
|
||||||
data:
|
data:
|
||||||
pvcName: zddc-root-dev # name of an existing PVC in your dev namespace
|
pvcName: zddc-root-dev # name of an existing PVC in your dev namespace
|
||||||
subPath: ""
|
subPath: ""
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,10 @@ spec:
|
||||||
value: {{ .Values.zddc.env.logLevel | quote }}
|
value: {{ .Values.zddc.env.logLevel | quote }}
|
||||||
- name: ZDDC_INDEX_PATH
|
- name: ZDDC_INDEX_PATH
|
||||||
value: {{ .Values.zddc.env.indexPath | quote }}
|
value: {{ .Values.zddc.env.indexPath | quote }}
|
||||||
|
{{- if .Values.zddc.env.noAuth }}
|
||||||
|
- name: ZDDC_NO_AUTH
|
||||||
|
value: "1"
|
||||||
|
{{- end }}
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: zddc-bin
|
- name: zddc-bin
|
||||||
mountPath: /zddc
|
mountPath: /zddc
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,23 @@ zddc:
|
||||||
# collision with a real directory named ".archive".
|
# collision with a real directory named ".archive".
|
||||||
indexPath: ".archive"
|
indexPath: ".archive"
|
||||||
|
|
||||||
|
# Skip ACL enforcement entirely on this instance. Anyone hitting
|
||||||
|
# the port reads everything in scope. Only enable for genuinely-
|
||||||
|
# public archives (and even then, only behind an authenticating
|
||||||
|
# ingress that doesn't gate on identity for /). Distinct from
|
||||||
|
# --insecure (which gates the startup check requiring a root .zddc).
|
||||||
|
# Default false.
|
||||||
|
noAuth: false
|
||||||
|
|
||||||
|
# Bearer-token system. Master automatically self-issues tokens via
|
||||||
|
# /.tokens (browser) and /.api/tokens (JSON). The token store lives
|
||||||
|
# at <ZDDC_ROOT>/.zddc.d/tokens/<sha256> on the data PVC; no Helm
|
||||||
|
# configuration required. Operators sign in via the upstream auth
|
||||||
|
# proxy, visit /.tokens, copy the displayed token into a 0600 file,
|
||||||
|
# and pass --bearer-file to any CLI / cache / mirror that needs to
|
||||||
|
# authenticate against this master. See zddc/README.md "Bearer
|
||||||
|
# tokens" for the full lifecycle.
|
||||||
|
|
||||||
# Persistent storage for ZDDC_ROOT. Operators provide their own PVC,
|
# Persistent storage for ZDDC_ROOT. Operators provide their own PVC,
|
||||||
# typically backed by a shared filesystem (NFS, CephFS, SMB) so multiple
|
# typically backed by a shared filesystem (NFS, CephFS, SMB) so multiple
|
||||||
# replicas of zddc-server (and your sync tooling) see the same tree.
|
# replicas of zddc-server (and your sync tooling) see the same tree.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue