From 9ee9abeadfc23be5a0860d0aee6e59c8dbd2e995 Mon Sep 17 00:00:00 2001 From: Morten Olsen Date: Sat, 3 Jan 2026 13:03:31 +0100 Subject: [PATCH] add cups --- apps/charts/cups/Chart.yaml | 7 + apps/charts/cups/templates/deployment.yaml | 1 + apps/charts/cups/templates/pvc.yaml | 1 + .../templates/secret-external-secrets.yaml | 1 + .../templates/secret-password-generators.yaml | 1 + apps/charts/cups/templates/service.yaml | 1 + .../cups/templates/virtual-service.yaml | 53 +++++ apps/charts/cups/values.yaml | 218 ++++++++++++++++++ apps/common/README.md | 14 +- apps/common/templates/_helpers.tpl | 6 + 10 files changed, 302 insertions(+), 1 deletion(-) create mode 100644 apps/charts/cups/Chart.yaml create mode 100644 apps/charts/cups/templates/deployment.yaml create mode 100644 apps/charts/cups/templates/pvc.yaml create mode 100644 apps/charts/cups/templates/secret-external-secrets.yaml create mode 100644 apps/charts/cups/templates/secret-password-generators.yaml create mode 100644 apps/charts/cups/templates/service.yaml create mode 100644 apps/charts/cups/templates/virtual-service.yaml create mode 100644 apps/charts/cups/values.yaml diff --git a/apps/charts/cups/Chart.yaml b/apps/charts/cups/Chart.yaml new file mode 100644 index 0000000..4110aa9 --- /dev/null +++ b/apps/charts/cups/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v2 +version: 1.0.0 +name: cups +dependencies: + - name: common + version: 1.0.0 + repository: file://../../common diff --git a/apps/charts/cups/templates/deployment.yaml b/apps/charts/cups/templates/deployment.yaml new file mode 100644 index 0000000..4508e33 --- /dev/null +++ b/apps/charts/cups/templates/deployment.yaml @@ -0,0 +1 @@ +{{ include "common.deployment" . }} diff --git a/apps/charts/cups/templates/pvc.yaml b/apps/charts/cups/templates/pvc.yaml new file mode 100644 index 0000000..379bad9 --- /dev/null +++ b/apps/charts/cups/templates/pvc.yaml @@ -0,0 +1 @@ +{{ include "common.pvc" . }} diff --git a/apps/charts/cups/templates/secret-external-secrets.yaml b/apps/charts/cups/templates/secret-external-secrets.yaml new file mode 100644 index 0000000..de340c4 --- /dev/null +++ b/apps/charts/cups/templates/secret-external-secrets.yaml @@ -0,0 +1 @@ +{{ include "common.externalSecrets.externalSecrets" . }} diff --git a/apps/charts/cups/templates/secret-password-generators.yaml b/apps/charts/cups/templates/secret-password-generators.yaml new file mode 100644 index 0000000..2183e0a --- /dev/null +++ b/apps/charts/cups/templates/secret-password-generators.yaml @@ -0,0 +1 @@ +{{ include "common.externalSecrets.passwordGenerators" . }} diff --git a/apps/charts/cups/templates/service.yaml b/apps/charts/cups/templates/service.yaml new file mode 100644 index 0000000..f024c64 --- /dev/null +++ b/apps/charts/cups/templates/service.yaml @@ -0,0 +1 @@ +{{ include "common.service" . }} diff --git a/apps/charts/cups/templates/virtual-service.yaml b/apps/charts/cups/templates/virtual-service.yaml new file mode 100644 index 0000000..201036c --- /dev/null +++ b/apps/charts/cups/templates/virtual-service.yaml @@ -0,0 +1,53 @@ +{{- if and .Values.virtualService.enabled .Values.subdomain (hasKey .Values.globals "domain") (ne .Values.globals.domain "") }} +{{- if and .Values.virtualService.gateways.public (hasKey .Values.globals "istio") (hasKey .Values.globals.istio "gateways") (hasKey .Values.globals.istio.gateways "public") (ne .Values.globals.istio.gateways.public "") }} +apiVersion: networking.istio.io/v1 +kind: VirtualService +metadata: + name: {{ include "common.fullname" . }}-public + namespace: {{ .Release.Namespace }} + labels: + {{- include "common.labels" . | nindent 4 }} +spec: + gateways: + - {{ .Values.globals.istio.gateways.public | quote }} + - mesh + hosts: + - {{ include "common.domain" . }} + - mesh + http: + - match: + - uri: + prefix: "/" + route: + - destination: + host: {{ include "common.fullname" . }} + port: + number: {{ .Values.virtualService.servicePort | default 631 }} +--- +{{- end }} +{{- if and .Values.virtualService.gateways.private (hasKey .Values.globals "istio") (hasKey .Values.globals.istio "gateways") (hasKey .Values.globals.istio.gateways "private") (ne .Values.globals.istio.gateways.private "") }} +apiVersion: networking.istio.io/v1 +kind: VirtualService +metadata: + name: {{ include "common.fullname" . }}-private + namespace: {{ .Release.Namespace }} + labels: + {{- include "common.labels" . | nindent 4 }} +spec: + gateways: + - {{ .Values.globals.istio.gateways.private | quote }} + - mesh + hosts: + - {{ include "common.domain" . }} + - mesh + http: + - match: + - uri: + prefix: "/" + route: + - destination: + host: {{ include "common.fullname" . }} + port: + number: {{ .Values.virtualService.servicePort | default 631 }} +{{- end }} +{{- end }} diff --git a/apps/charts/cups/values.yaml b/apps/charts/cups/values.yaml new file mode 100644 index 0000000..baeb151 --- /dev/null +++ b/apps/charts/cups/values.yaml @@ -0,0 +1,218 @@ +image: + repository: olbat/cupsd + tag: latest + pullPolicy: IfNotPresent + +# Command to initialize and start CUPS +command: + - /bin/sh + - -c +args: + - | + echo "Starting CUPS initialization..." + mkdir -p /etc/cups/ssl /var/spool/cups/tmp /var/log/cups /var/cache/cups /var/run + chmod 755 /etc/cups /var/spool/cups 2>&1 || true + + if [ ! -f /etc/cups/cupsd.conf ]; then + echo "CUPS config not found, creating configuration with web access..." + { + echo "Listen *:631" + echo "ServerRoot /etc/cups" + echo "StateDir /var/spool/cups" + echo "CacheDir /var/cache/cups" + echo "DataDir /usr/share/cups" + echo "AccessLog /var/log/cups/access_log" + echo "ErrorLog /var/log/cups/error_log" + echo "LogLevel warn" + echo "MaxLogSize 0" + echo "SystemGroup lpadmin" + echo "User root" + echo "Group lp" + echo "ServerAdmin root" + echo "" + echo "# Network printer discovery" + echo "BrowseLocalProtocols dnssd" + echo "BrowseRemoteProtocols dnssd" + echo "BrowseAddress @LOCAL" + echo "BrowsePoll 192.168.0.0/16" + echo "BrowsePoll 192.168.1.0/24" + echo "BrowsePoll 192.168.10.0/24" + echo "BrowsePoll 192.168.20.0/24" + echo "BrowsePoll 192.168.30.0/24" + echo "" + echo "" + echo " Order allow,deny" + echo " Allow all" + echo "" + echo "" + echo "" + echo " Order allow,deny" + echo " Allow all" + echo "" + echo "" + echo "" + echo " AuthType Default" + echo " Require user @SYSTEM" + echo " Order allow,deny" + echo " Allow all" + echo "" + echo "" + echo "" + echo " JobPrivateAccess default" + echo " JobPrivateValues default" + echo " SubscriptionPrivateAccess default" + echo " SubscriptionPrivateValues default" + echo " " + echo " Require user @OWNER @SYSTEM" + echo " " + echo " " + echo " Require user @OWNER @SYSTEM" + echo " " + echo " " + echo " Require user @SYSTEM" + echo " " + echo " " + echo " Require user @SYSTEM" + echo " " + echo " " + echo " Order deny,allow" + echo " " + echo "" + } > /etc/cups/cupsd.conf + echo "Created CUPS configuration file" + else + echo "CUPS config already exists, ensuring access controls and discovery are present..." + # Add network discovery settings if not present + if ! grep -q "BrowseLocalProtocols" /etc/cups/cupsd.conf; then + { + echo "" + echo "# Network printer discovery" + echo "BrowseLocalProtocols dnssd" + echo "BrowseRemoteProtocols dnssd" + echo "BrowseAddress @LOCAL" + echo "BrowsePoll 192.168.0.0/16" + echo "BrowsePoll 192.168.1.0/24" + echo "BrowsePoll 192.168.10.0/24" + echo "BrowsePoll 192.168.20.0/24" + echo "BrowsePoll 192.168.30.0/24" + } >> /etc/cups/cupsd.conf + echo "Added network discovery settings" + fi + # Always ensure Location sections exist for web access + if ! grep -q "" /etc/cups/cupsd.conf; then + { + echo "" + echo "" + echo " Order allow,deny" + echo " Allow all" + echo "" + echo "" + echo "" + echo " Order allow,deny" + echo " Allow all" + echo "" + echo "" + echo "" + echo " AuthType Default" + echo " Require user @SYSTEM" + echo " Order allow,deny" + echo " Allow all" + echo "" + } >> /etc/cups/cupsd.conf + echo "Added access control sections to existing config" + fi + fi + + echo "Testing CUPS configuration..." + /usr/sbin/cupsd -t 2>&1 || echo "Config test warnings (may be normal)" + + echo "Starting CUPS daemon in foreground..." + exec /usr/sbin/cupsd -f + +subdomain: cups + +# Deployment configuration +deployment: + strategy: Recreate + replicas: 1 + revisionHistoryLimit: 0 + hostNetwork: true # Required for printer discovery and Android device access + dnsPolicy: ClusterFirstWithHostNet + +# Container configuration +container: + ports: + - name: ipp + port: 631 + protocol: TCP + healthProbe: + type: tcpSocket + port: ipp + securityContext: + privileged: false + runAsUser: 0 # CUPS typically needs root for printer access + +# Service configuration +service: + ports: + - name: ipp + port: 631 + targetPort: 631 + protocol: TCP + type: ClusterIP + # Note: With hostNetwork, the service is mainly for service discovery + # CUPS will be accessible directly on node IP:631 + +# Volume configuration +volumes: + - name: config + mountPath: /etc/cups + persistentVolumeClaim: cups-config + - name: spool + mountPath: /var/spool/cups + persistentVolumeClaim: cups-spool + +# Persistent volume claims +persistentVolumeClaims: + - name: config + size: 1Gi + - name: spool + size: 5Gi + +# VirtualService configuration (for web UI) +# Enables access via https://cups.{domain} for administration +# IPP printing can still work via direct node IP or through the service +virtualService: + enabled: true + gateways: + public: true + private: true + servicePort: 631 + +# OIDC client configuration (disabled with hostNetwork) +# Web UI will be accessible directly via node IP +oidc: + enabled: false + +# External Secrets configuration +externalSecrets: + - name: "{release}-secrets" + passwords: + - name: cupspassword + length: 16 + allowRepeat: true + encoding: hex + secretKeys: + - cupspassword + +# Environment variables +env: + TZ: + value: "{timezone}" + CUPSADMIN: + value: admin + CUPSPASSWORD: + valueFrom: + secretKeyRef: + name: "{release}-secrets" + key: cupspassword diff --git a/apps/common/README.md b/apps/common/README.md index da34f47..f1bbdc8 100644 --- a/apps/common/README.md +++ b/apps/common/README.md @@ -107,6 +107,18 @@ container: runAsUser: 1000 runAsGroup: 1000 +# Command and args (optional) +# Override the container's default command/entrypoint +# Useful for initialization scripts or custom startup logic +command: + - /bin/sh + - -c +args: + - | + echo "Running initialization..." + # Your custom startup logic here + exec /app/start.sh + # Service configuration service: # Single service (simple case) @@ -447,7 +459,7 @@ env: The library provides full resource templates that can be included directly: -- `common.deployment` - Full Deployment resource with all standard configurations +- `common.deployment` - Full Deployment resource with all standard configurations (supports custom command/args) - `common.service` - Full Service resource(s) - supports multiple services - `common.pvc` - Full PVC resources - supports multiple PVCs - `common.virtualService` - Full VirtualService resources (public + private gateways) diff --git a/apps/common/templates/_helpers.tpl b/apps/common/templates/_helpers.tpl index d517a97..17a6bda 100644 --- a/apps/common/templates/_helpers.tpl +++ b/apps/common/templates/_helpers.tpl @@ -312,6 +312,12 @@ spec: - name: {{ .Chart.Name }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" imagePullPolicy: {{ .Values.image.pullPolicy | default "IfNotPresent" }} + {{- if .Values.command }} + command: {{- toYaml .Values.command | nindent 12 }} + {{- end }} + {{- if .Values.args }} + args: {{- toYaml .Values.args | nindent 12 }} + {{- end }} ports: {{ include "common.containerPorts" . | indent 12 }} {{- if .Values.container.healthProbe }}