mirror of
https://github.com/immich-app/yucca.git
synced 2026-09-30 13:33:00 +08:00
92 lines
4.0 KiB
YAML
92 lines
4.0 KiB
YAML
{{- if .Values.loopDevice.enabled }}
|
|
# DEV ONLY. k3d nodes have no spare block device, and Rook OSDs need raw block
|
|
# storage (k3d's local-path provisioner is filesystem-only). This privileged
|
|
# DaemonSet creates a sparse image on the node and losetup-attaches it to the
|
|
# loop device (storage.device) that the CephCluster names explicitly. The
|
|
# container stays alive so the attachment persists.
|
|
#
|
|
# It runs on cephImage rather than something small like alpine because every
|
|
# OSD in the cluster is blocked on this attachment: a registry the node has to
|
|
# reach for this pod alone is a single point of failure, and a hung pull of one
|
|
# surfaced half an hour later as an unrelated yucca-michael config error. This
|
|
# image the node must pull anyway, and Tilt prepulls it the moment the cluster
|
|
# exists. It carries losetup/truncate/mknod, so nothing has to be installed.
|
|
apiVersion: apps/v1
|
|
kind: DaemonSet
|
|
metadata:
|
|
name: {{ .Values.clusterName }}-loop-device
|
|
labels:
|
|
app.kubernetes.io/name: rook-ceph-loop-device
|
|
spec:
|
|
selector:
|
|
matchLabels:
|
|
app.kubernetes.io/name: rook-ceph-loop-device
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app.kubernetes.io/name: rook-ceph-loop-device
|
|
spec:
|
|
hostPID: true
|
|
containers:
|
|
- name: loop-device
|
|
image: {{ .Values.cephImage }}
|
|
securityContext:
|
|
privileged: true
|
|
command: ["/bin/sh", "-c"]
|
|
args:
|
|
- |
|
|
set -eu
|
|
IMG="{{ .Values.loopDevice.path }}"
|
|
DEV="{{ .Values.storage.device }}"
|
|
mkdir -p "$(dirname "$IMG")"
|
|
[ -f "$IMG" ] || truncate -s {{ .Values.loopDevice.sizeGiB }}G "$IMG"
|
|
# Loop attachments live in the HOST kernel, shared by every k3d
|
|
# cluster on it, and outlive the cluster that made them. One whose
|
|
# image is deleted belongs to a torn-down cluster (a k3d:reset, or
|
|
# a finished CI run on the same host) and would also make Rook skip
|
|
# the device for its stale bluestore signature.
|
|
for d in $(losetup -a | grep -F "($IMG (deleted))" | cut -d: -f1); do
|
|
losetup -d "$d" || true
|
|
done
|
|
# Every cluster's image has the same path, so BACK-FILE cannot tell
|
|
# ours from a live neighbour's; -j matches by inode. Sharing a
|
|
# neighbour's device leaves this cluster with no OSD and surfaces
|
|
# half an hour later as an unrelated timeout, so fail here instead.
|
|
if losetup "$DEV" >/dev/null 2>&1 && ! losetup -j "$IMG" | cut -d: -f1 | grep -qx "$DEV"; then
|
|
echo "$DEV is attached to another live cluster's image; give this cluster its own storage.device" >&2
|
|
exit 1
|
|
fi
|
|
# our image attached on some other device = corruption hazard
|
|
for d in $(losetup -j "$IMG" | cut -d: -f1); do
|
|
[ "$d" = "$DEV" ] || losetup -d "$d" || true
|
|
done
|
|
if ! losetup "$DEV" >/dev/null 2>&1; then
|
|
[ -e "$DEV" ] || mknod "$DEV" b 7 "${DEV#/dev/loop}"
|
|
losetup "$DEV" "$IMG"
|
|
fi
|
|
echo "loop device for Rook OSD: $(losetup -j "$IMG" | cut -d: -f1) ($IMG)"
|
|
# keep the container (and thus the loop attachment) alive
|
|
while true; do sleep 3600; done
|
|
readinessProbe:
|
|
exec:
|
|
command:
|
|
- /bin/sh
|
|
- -c
|
|
- 'losetup -j "{{ .Values.loopDevice.path }}" | cut -d: -f1 | grep -qx "{{ .Values.storage.device }}"'
|
|
periodSeconds: 5
|
|
volumeMounts:
|
|
- name: dev
|
|
mountPath: /dev
|
|
mountPropagation: Bidirectional
|
|
- name: rook-data
|
|
mountPath: {{ dir .Values.loopDevice.path }}
|
|
volumes:
|
|
- name: dev
|
|
hostPath:
|
|
path: /dev
|
|
- name: rook-data
|
|
hostPath:
|
|
path: {{ dir .Values.loopDevice.path }}
|
|
type: DirectoryOrCreate
|
|
{{- end }}
|