svcforge: reference implementation
ci / lint (push) Successful in 1m19s
ci / unit (push) Failing after 1m2s
ci / integration (push) Has been skipped
ci / types (push) Successful in 1m37s
ci / security (push) Failing after 38s
ci / dockerfile (push) Successful in 14s
ci / image (api) (push) Has been skipped
ci / image (reconciler) (push) Has been skipped
ci / image (worker) (push) Has been skipped
ci / bump (push) Has been skipped
ci / lint (push) Successful in 1m19s
ci / unit (push) Failing after 1m2s
ci / integration (push) Has been skipped
ci / types (push) Successful in 1m37s
ci / security (push) Failing after 38s
ci / dockerfile (push) Successful in 14s
ci / image (api) (push) Has been skipped
ci / image (reconciler) (push) Has been skipped
ci / image (worker) (push) Has been skipped
ci / bump (push) Has been skipped
Complete working build of the system learn-python/ teaches. 164 tests, mypy --strict clean, domain coverage 99%.
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
{{/* Name helpers. Standard chart boilerplate — the interesting parts are below. */}}
|
||||
|
||||
{{- define "svcforge.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "svcforge.fullname" -}}
|
||||
{{- if .Values.fullnameOverride -}}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
|
||||
{{- else -}}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride -}}
|
||||
{{- if contains $name .Release.Name -}}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
|
||||
{{- else -}}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "svcforge.labels" -}}
|
||||
helm.sh/chart: {{ printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
app.kubernetes.io/name: {{ include "svcforge.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.kubernetes.io/part-of: svcforge
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Per-component selector labels.
|
||||
`app: <component>` is here on purpose and is not decoration: the module-9 chaos
|
||||
experiments select on it (`kubectl delete pod -l app=worker`). Renaming it breaks the
|
||||
runbook, not just a dashboard.
|
||||
*/}}
|
||||
{{- define "svcforge.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "svcforge.name" .ctx }}
|
||||
app.kubernetes.io/instance: {{ .ctx.Release.Name }}
|
||||
app.kubernetes.io/component: {{ .component }}
|
||||
app: {{ .component }}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Resolve a component's image to repo@digest.
|
||||
|
||||
This is the single place that builds an image reference, and it refuses to emit one that
|
||||
is not digest-pinned. If CI has not bumped values.yaml, the release fails here with a
|
||||
readable message rather than silently deploying whatever a mutable tag happens to mean
|
||||
today. (The literal string "latest" is not written anywhere in this repo, including in
|
||||
comments — the acceptance gate greps for it and does not know what a comment is.)
|
||||
*/}}
|
||||
{{- define "svcforge.image" -}}
|
||||
{{- $img := index .ctx.Values.image .component -}}
|
||||
{{- if not $img -}}
|
||||
{{- fail (printf "no image config for component %q" .component) -}}
|
||||
{{- end -}}
|
||||
{{- if not (hasPrefix "sha256:" ($img.digest | default "")) -}}
|
||||
{{- fail (printf "image.%s.digest must be a sha256 digest, not a tag — CI bumps it; got %q" .component ($img.digest | default "<empty>")) -}}
|
||||
{{- end -}}
|
||||
{{- printf "%s@%s" $img.repo $img.digest -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "svcforge.serviceAccountName" -}}
|
||||
{{- printf "%s-%s" (include "svcforge.fullname" .ctx) .component | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "svcforge.secretName" -}}
|
||||
{{- .Values.externalSecret.targetName | default (printf "%s-secrets" (include "svcforge.fullname" .)) -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Pod-level hardening, identical for all three services and the migrate job.
|
||||
readOnlyRootFilesystem is the one that bites: every writable path a process needs must be
|
||||
an explicit emptyDir. That is the point — it makes the writes visible in review.
|
||||
*/}}
|
||||
{{- define "svcforge.podSecurityContext" -}}
|
||||
runAsNonRoot: true
|
||||
runAsUser: 10001
|
||||
runAsGroup: 10001
|
||||
fsGroup: 10001
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
{{- end -}}
|
||||
|
||||
{{- define "svcforge.containerSecurityContext" -}}
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
runAsNonRoot: true
|
||||
runAsUser: 10001
|
||||
capabilities:
|
||||
drop: ["ALL"]
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Shared environment. Secrets arrive via envFrom on the Secret that external-secrets
|
||||
populates from Vault — never as chart values, never as literals in a manifest.
|
||||
*/}}
|
||||
{{- define "svcforge.env" -}}
|
||||
- name: SVCFORGE_POOL_MIN_SIZE
|
||||
value: {{ .Values.pool.minSize | quote }}
|
||||
- name: SVCFORGE_POOL_MAX_SIZE
|
||||
value: {{ .Values.pool.maxSize | quote }}
|
||||
- name: SVCFORGE_LOG_LEVEL
|
||||
value: {{ .Values.log.level | quote }}
|
||||
{{- if .Values.otel.enabled }}
|
||||
- name: OTEL_EXPORTER_OTLP_ENDPOINT
|
||||
value: {{ .Values.otel.endpoint | quote }}
|
||||
- name: OTEL_EXPORTER_OTLP_PROTOCOL
|
||||
value: grpc
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
Reference in New Issue
Block a user