Files
helm-charts/calibre-web-automated/templates/calibre-web-automated.sfs.yaml
T
jklein 6c04a68763 calibre-web-automated: strict schema, ingress gate and null-safe hardening
Three changes, all about values that do not do what they promise:

1. values.schema.json (#68): additionalProperties: false on every
   chart-owned object level.

2. Ingress gate (#93): the Ingress template is wrapped in
   {{- if .Values.ingress.enabled }} and the key is added to values.yaml
   with default true, so behaviour is unchanged.

   The domain checkpoint from rallly ran over values.yaml and templates
   and came back empty here: ingress.domain is read nowhere but in the
   Ingress template. Unlike rallly, zipline, voucher-vault and outline,
   this gate therefore frees both domain and clusterIssuer, and no extra
   required() is needed.

3. Null-safety for hardening, probes and resources (#99).

   This chart's hardening is a documented deviation from the repo
   standard, and the fallbacks reproduce it exactly instead of restoring
   the standard: no runAs* values (s6-overlay boots as root and drops to
   PUID/PGID 1000), readOnlyRootFilesystem stays false (read-only mode
   disables the PUID/PGID remapping, silently moving the runtime uid from
   1000 to 911 and breaking existing volume data), and capabilities.add
   keeps its six entries that the s6 init and supervision need. A
   "cleaned up" standard default here would not be tidier, it would be an
   outage.

cwa.storage stays deliberately not null-safe: an erased value yields an
invalid PVC, which is the loud class #99 excludes.

Rendering with normal values is byte-identical to 4.0.0.
2026-08-23 21:34:32 +02:00

109 lines
4.4 KiB
YAML

apiVersion: apps/v1
kind: StatefulSet
metadata:
name: {{ .Release.Name }}-{{ .Chart.Name }}-sfs
labels:
app: {{ .Release.Name }}-{{ .Chart.Name }}-sfs
spec:
serviceName: {{ .Release.Name }}-{{ .Chart.Name }}-service
replicas: {{ include "calibre-web-automated.replicas" (dict "scaleDown" .Values.scaleDown "replicas" .Values.cwa.replicas) }}
selector:
matchLabels:
app: {{ .Release.Name }}-{{ .Chart.Name }}-sfs
template:
metadata:
name: {{ .Release.Name }}-{{ .Chart.Name }}-sfs
labels:
app: {{ .Release.Name }}-{{ .Chart.Name }}-sfs
spec:
automountServiceAccountToken: false
securityContext:
{{- include "calibre-web-automated.podSecurityContext" .Values.cwa.securityContext | nindent 8 }}
containers:
- name: {{ .Release.Name }}-{{ .Chart.Name }}-container
image: "ghcr.io/crocodilestick/calibre-web-automated:{{ .Chart.AppVersion }}"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8083
name: http
protocol: TCP
env:
- name: TZ
value: "{{ .Values.cwa.timezone }}"
- name: PUID
value: "1000"
- name: PGID
value: "1000"
- name: HARDCOVER_TOKEN
valueFrom:
secretKeyRef:
name: {{ .Release.Name }}-{{ .Chart.Name }}-secret
key: hardcover-api-token
- name: CALIBRE_CONFIG_DIR
value: "/config/.config/calibre"
- name: NETWORK_SHARE_MODE
value: "false"
{{- range $value := .Values.cwa.env }}
{{- if $value.value }}
- name: {{ $value.name | quote }}
value: {{ tpl $value.value $ | quote }}
{{- else if $value.valueFrom }}
{{- if $value.valueFrom.secretKeyRef }}
- name: {{ $value.name }}
valueFrom:
secretKeyRef:
name: {{ tpl $value.valueFrom.secretKeyRef.name $ | quote }}
key: {{ tpl $value.valueFrom.secretKeyRef.key $ | quote }}
{{- else if $value.valueFrom.configMapKeyRef }}
- name: {{ $value.name }}
valueFrom:
configMapKeyRef:
name: {{ tpl $value.valueFrom.configMapKeyRef.name $ | quote }}
key: {{ tpl $value.valueFrom.configMapKeyRef.key $ | quote }}
{{- end }}
{{- end }}
{{- end }}
volumeMounts:
- mountPath: "/config"
name: cwa
subPath: config/
- mountPath: "/calibre-library"
name: cwa
subPath: calibre-library/
- mountPath: "/config/.config/calibre/plugins"
name: cwa
subPath: calibre-plugins/
- mountPath: "/config/.config/calibre/customize.py.json"
name: cwa-plugins-config
subPath: customize.py.json
- mountPath: "/cwa-book-ingest"
name: cwa-consume
livenessProbe:
{{- include "calibre-web-automated.livenessProbe" .Values.cwa.livenessProbe | nindent 12 }}
readinessProbe:
{{- include "calibre-web-automated.readinessProbe" .Values.cwa.readinessProbe | nindent 12 }}
startupProbe:
{{- include "calibre-web-automated.startupProbe" .Values.cwa.startupProbe | nindent 12 }}
resources:
{{- include "calibre-web-automated.effectiveResources" .Values.cwa.resources | nindent 12 }}
securityContext:
{{- include "calibre-web-automated.containerSecurityContext" .Values.cwa.securityContext | nindent 12 }}
restartPolicy: Always
volumes:
# Deliberate naming exception (see README): both PVCs keep their
# historical <chart>-<release>-cwa-* names — renaming a PVC would
# provision a new, empty volume and orphan the existing data.
- name: cwa
persistentVolumeClaim:
claimName: {{ .Chart.Name }}-{{ .Release.Name }}-cwa-pvc
- name: cwa-consume
persistentVolumeClaim:
claimName: {{ .Chart.Name }}-{{ .Release.Name }}-cwa-consume-pvc
- name: cwa-plugins-config
secret:
secretName: {{ .Release.Name }}-{{ .Chart.Name }}-secret
items:
- key: calibre-plugins
path: customize.py.json
mode: 0644