Skip to content

Commit 6053d1c

Browse files
committed
Add replay-mounter daemonset
1 parent d6f57b2 commit 6053d1c

8 files changed

Lines changed: 139 additions & 6 deletions

File tree

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,7 @@ spicy-secrets/**
1111

1212
tilt_config.json
1313
.local-data/
14-
.helm-cache/
14+
.helm-cache/
15+
16+
# Script related stuff
17+
**/.gradle

README.MD

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,14 @@ kubectl apply -f app-set-test.yaml
5252

5353
Many apps will fail to start, because the lack the secrets that will be generated by infisical. But infiscal needs be setup too.
5454
We use the cloud edition, but there is also a self hosted one we do not cover here.
55-
For our stack you need to create a service token in the web ui and add this as a secret in all affected namespaces:
55+
For our stack you need to create a machine identity in the web ui and add its credentials as a secret in all affected namespaces:
5656

5757
```sh
58-
for namespace in "faf-apps faf-ops argocd"; do
59-
kubectl create secret generic "infisical-service-token" \
58+
for namespace in faf-apps faf-ops argocd replay-mounter; do
59+
kubectl create secret generic infisical-machine-identity \
6060
-n "$namespace" \
61-
--from-literal=infisicalToken=<your-token-here>
61+
--from-literal=clientId=<your-client-id-here> \
62+
--from-literal=clientSecret=<your-client-secret-here>
6263
done
6364
```
6465

cluster/namespaces.yaml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,10 @@ metadata:
1919
apiVersion: v1
2020
kind: Namespace
2121
metadata:
22-
name: traefik
22+
name: traefik
23+
24+
---
25+
apiVersion: v1
26+
kind: Namespace
27+
metadata:
28+
name: replay-mounter

cluster/replay-mounter/Chart.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
apiVersion: v2
2+
name: replay-mounter
3+
version: 1.0.0
4+
description: CIFS/SMB mount watchdog for the faf-replays hostPath PV
5+
6+
dependencies:
7+
- name: infisical-secret
8+
version: 1.0.0
9+
repository: file://../../common/infisical-secret
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
{{- if .Values.cifsMount.enabled }}
2+
apiVersion: apps/v1
3+
kind: DaemonSet
4+
metadata:
5+
name: replay-mounter
6+
namespace: replay-mounter
7+
spec:
8+
selector:
9+
matchLabels:
10+
app: replay-mounter
11+
template:
12+
metadata:
13+
labels:
14+
app: replay-mounter
15+
spec:
16+
nodeSelector:
17+
openebs.io/nodeid: {{ .Values.zfs.nodeId }}
18+
terminationGracePeriodSeconds: 30
19+
containers:
20+
- name: replay-mounter
21+
image: {{ .Values.cifsMount.image }}
22+
securityContext:
23+
privileged: true
24+
env:
25+
- name: CIFS_SERVER
26+
valueFrom:
27+
secretKeyRef:
28+
name: {{ .Values.cifsMount.credentialsSecret }}
29+
key: CIFS_SERVER
30+
- name: CIFS_USERNAME
31+
valueFrom:
32+
secretKeyRef:
33+
name: {{ .Values.cifsMount.credentialsSecret }}
34+
key: CIFS_USERNAME
35+
- name: CIFS_PASSWORD
36+
valueFrom:
37+
secretKeyRef:
38+
name: {{ .Values.cifsMount.credentialsSecret }}
39+
key: CIFS_PASSWORD
40+
- name: MOUNT_TARGET
41+
value: "{{ .Values.cifsMount.mountPath }}"
42+
volumeMounts:
43+
- name: host-base
44+
mountPath: "{{ .Values.cifsMount.hostBasePath }}"
45+
mountPropagation: Bidirectional
46+
command:
47+
- /bin/sh
48+
- -c
49+
- |
50+
echo "Installing cifs-utils..."
51+
apk add --no-cache cifs-utils
52+
echo "cifs-utils installed."
53+
54+
cleanup() {
55+
echo "Shutting down, unmounting $MOUNT_TARGET..."
56+
umount "$MOUNT_TARGET" 2>/dev/null || \
57+
umount -l "$MOUNT_TARGET" 2>/dev/null || true
58+
exit 0
59+
}
60+
trap cleanup TERM INT
61+
62+
mount_cifs() {
63+
mkdir -p "$MOUNT_TARGET"
64+
echo "Mounting $CIFS_SERVER -> $MOUNT_TARGET..."
65+
mount -t cifs "$CIFS_SERVER" "$MOUNT_TARGET" \
66+
-o "username=$CIFS_USERNAME,password=$CIFS_PASSWORD,{{ .Values.cifsMount.mountOptions }}"
67+
}
68+
69+
is_mounted() { grep -q " $MOUNT_TARGET cifs " /proc/mounts; }
70+
71+
if is_mounted; then
72+
echo "Mount already present, skipping initial mount."
73+
else
74+
echo "Mount not present, mounting..."
75+
until mount_cifs; do echo "Mount failed, retrying in 10s..."; sleep 10; done
76+
echo "Mount successful."
77+
fi
78+
79+
echo "Entering watchdog loop (30s interval)..."
80+
# Watchdog: kernel CIFS handles transient reconnects automatically;
81+
# remount only if the mount fully disappears from /proc/mounts
82+
while true; do
83+
sleep 30 &
84+
wait $!
85+
if ! is_mounted; then
86+
echo "Mount lost, remounting..."
87+
umount -l "$MOUNT_TARGET" 2>/dev/null || true
88+
mount_cifs || true
89+
fi
90+
done
91+
volumes:
92+
- name: host-base
93+
hostPath:
94+
path: "{{ .Values.cifsMount.hostBasePath }}"
95+
type: Directory
96+
{{- end }}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
cifsMount:
2+
enabled: true
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
cifsMount:
2+
enabled: true

cluster/replay-mounter/values.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
cifsMount:
2+
enabled: false
3+
mountPath: "/opt/faf/data/replays-old"
4+
hostBasePath: "/opt/faf/data" # parent dir shared via Bidirectional propagation
5+
credentialsSecret: "cifs-credentials"
6+
mountOptions: "ro,vers=3.0,uid=1000,gid=1000,file_mode=0644,dir_mode=0755"
7+
image: "alpine:3.21"
8+
9+
# zfs.nodeId injected from config/prod.yaml
10+
# infisical-secret.enabled injected from config/prod.yaml
11+
infisical-secret:
12+
name: cifs-credentials
13+
secretNamespace: replay-mounter # namespace where infisical-machine-identity lives
14+
overrideSecretPath: "/replay-mounter"

0 commit comments

Comments
 (0)