chore: initialize from backend template 0a6dd0e
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
# Storage certification job.
|
||||
#
|
||||
# A PersistentVolumeClaim is not a filesystem contract. Whether an atomic rename, a same-file-store
|
||||
# guarantee, or symlink refusal actually holds depends on the CSI driver, the StorageClass, the
|
||||
# access mode, the backend, and the mount options — so this job records all five alongside the probe
|
||||
# result. A certification without that tuple is not transferable to another cluster.
|
||||
#
|
||||
# The job writes a machine-readable result to the claim itself so the evidence lives with the volume
|
||||
# it describes.
|
||||
#
|
||||
# kubectl apply -f infra/fileserver/kubernetes/pvc-certification-job.yaml
|
||||
# kubectl logs job/fileserver-pvc-certification
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: fileserver-certification
|
||||
labels:
|
||||
app.kubernetes.io/name: fileserver
|
||||
app.kubernetes.io/component: certification
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
# Left unset on purpose: the certification is only meaningful for the class it actually ran on,
|
||||
# so the operator names it explicitly rather than inheriting a cluster default.
|
||||
storageClassName: ""
|
||||
---
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: fileserver-pvc-certification
|
||||
labels:
|
||||
app.kubernetes.io/name: fileserver
|
||||
app.kubernetes.io/component: certification
|
||||
spec:
|
||||
backoffLimit: 0
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: fileserver
|
||||
app.kubernetes.io/component: certification
|
||||
spec:
|
||||
restartPolicy: Never
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 10001
|
||||
fsGroup: 10001
|
||||
containers:
|
||||
- name: certify
|
||||
image: eclipse-temurin:21-jdk
|
||||
env:
|
||||
- name: FILESERVER_STORAGE_ROOT
|
||||
value: /var/lib/backend/files
|
||||
- name: KUBERNETES_VERSION
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.annotations['certification.fileserver/kubernetes-version']
|
||||
- name: CSI_DRIVER
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.annotations['certification.fileserver/csi-driver']
|
||||
- name: STORAGE_CLASS
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.annotations['certification.fileserver/storage-class']
|
||||
- name: ACCESS_MODE
|
||||
value: ReadWriteOnce
|
||||
command:
|
||||
- /bin/bash
|
||||
- -c
|
||||
- |
|
||||
set -euo pipefail
|
||||
ROOT="${FILESERVER_STORAGE_ROOT}"
|
||||
mkdir -p "${ROOT}/staging" "${ROOT}/content"
|
||||
|
||||
# Atomic rename within one file store is the property the publish path depends on.
|
||||
echo probe > "${ROOT}/staging/probe"
|
||||
if mv "${ROOT}/staging/probe" "${ROOT}/content/probe" 2>/dev/null; then
|
||||
ATOMIC_MOVE=true
|
||||
else
|
||||
ATOMIC_MOVE=false
|
||||
fi
|
||||
|
||||
# Same device means a rename is a metadata operation rather than a copy.
|
||||
STAGING_DEV=$(stat -c %d "${ROOT}/staging")
|
||||
CONTENT_DEV=$(stat -c %d "${ROOT}/content")
|
||||
[ "${STAGING_DEV}" = "${CONTENT_DEV}" ] && SAME_STORE=true || SAME_STORE=false
|
||||
|
||||
# O_EXCL create is what makes a publish create-only rather than an overwrite.
|
||||
if (set -o noclobber; echo x > "${ROOT}/content/excl") 2>/dev/null; then
|
||||
ATOMIC_CREATE=true
|
||||
else
|
||||
ATOMIC_CREATE=false
|
||||
fi
|
||||
|
||||
cat > "${ROOT}/certification-result.json" <<RESULT
|
||||
{
|
||||
"kubernetesVersion": "${KUBERNETES_VERSION:-unknown}",
|
||||
"csiDriver": "${CSI_DRIVER:-unknown}",
|
||||
"storageClass": "${STORAGE_CLASS:-unknown}",
|
||||
"accessMode": "${ACCESS_MODE}",
|
||||
"backend": "$(stat -f -c %T "${ROOT}")",
|
||||
"mountOptions": "$(findmnt -no OPTIONS --target "${ROOT}" || echo unknown)",
|
||||
"atomicMove": ${ATOMIC_MOVE},
|
||||
"sameFileStore": ${SAME_STORE},
|
||||
"atomicCreate": ${ATOMIC_CREATE}
|
||||
}
|
||||
RESULT
|
||||
cat "${ROOT}/certification-result.json"
|
||||
|
||||
# Fail closed: a volume that cannot publish atomically must not be certified silently.
|
||||
[ "${SAME_STORE}" = "true" ] || { echo "staging and content are on different stores"; exit 1; }
|
||||
volumeMounts:
|
||||
- name: storage
|
||||
mountPath: /var/lib/backend/files
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
capabilities:
|
||||
drop: ["ALL"]
|
||||
volumes:
|
||||
- name: storage
|
||||
persistentVolumeClaim:
|
||||
claimName: fileserver-certification
|
||||
Reference in New Issue
Block a user