Point media apps at the real mediafs library via a static CephFS PV
Why: The media apps must serve and manage the actual media library, not empty volumes. That library already exists on the puppet-managed CephFS filesystem mediafs (mounted by the VM/incus instances at /shared/media) and is in active use, so the k8s apps must mount it in place rather than provision fresh storage. How: - Replace the two fresh movies/tvseries PVCs with one static CephFS PersistentVolume bound to mediafs and a single RWX media-library claim the whole stack shares. - Set the PV reclaim policy to Retain and mark it staticVolume so ceph-csi only mounts the pre-existing storage and can never provision or reclaim it; deleting the PVC or PV cannot destroy the underlying library. - Reuse the live csi-cephfs cluster parameters (clusterID cephfs_csi_ssd_ec_4_1 for mon discovery, csi-cephfs/csi-cephfs-secret node-stage secret) with fsName mediafs and rootPath / (the mediafs root that maps to /shared/media). - Mount the library into each app by subPath so the tree matches the VM layout: sonarr /mnt/tvseries (tvseries), radarr /mnt/movies (movies), jellyfin and nzbget both subtrees; prowlarr keeps no library mount. The jellyfin transcode PVC stays a fresh scratch volume. - Whitelist PersistentVolume in the media AppProject so the cluster-scoped PV can sync.
This commit is contained in:
@@ -76,10 +76,12 @@ spec:
|
|||||||
mountPath: /cache
|
mountPath: /cache
|
||||||
- name: transcode
|
- name: transcode
|
||||||
mountPath: /transcode
|
mountPath: /transcode
|
||||||
- name: movies
|
- name: media-library
|
||||||
mountPath: /mnt/movies
|
mountPath: /mnt/movies
|
||||||
- name: tvseries
|
subPath: movies
|
||||||
|
- name: media-library
|
||||||
mountPath: /mnt/tvseries
|
mountPath: /mnt/tvseries
|
||||||
|
subPath: tvseries
|
||||||
volumes:
|
volumes:
|
||||||
- name: config
|
- name: config
|
||||||
persistentVolumeClaim:
|
persistentVolumeClaim:
|
||||||
@@ -90,9 +92,6 @@ spec:
|
|||||||
- name: transcode
|
- name: transcode
|
||||||
persistentVolumeClaim:
|
persistentVolumeClaim:
|
||||||
claimName: jellyfin-transcode
|
claimName: jellyfin-transcode
|
||||||
- name: movies
|
- name: media-library
|
||||||
persistentVolumeClaim:
|
persistentVolumeClaim:
|
||||||
claimName: movies
|
claimName: media-library
|
||||||
- name: tvseries
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: tvseries
|
|
||||||
|
|||||||
@@ -6,5 +6,5 @@ resources:
|
|||||||
- namespace.yaml
|
- namespace.yaml
|
||||||
- serviceaccount.yaml
|
- serviceaccount.yaml
|
||||||
- vaultauth.yaml
|
- vaultauth.yaml
|
||||||
- pvc_movies.yaml
|
- pv_media-library.yaml
|
||||||
- pvc_tvseries.yaml
|
- pvc_media-library.yaml
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
---
|
||||||
|
# Static CephFS PersistentVolume bound to the pre-existing, ACTIVELY-USED
|
||||||
|
# puppet media library (ceph filesystem "mediafs", mounted by the VM/incus
|
||||||
|
# instances at /shared/media). ceph-csi only mounts this volume; staticVolume
|
||||||
|
# tells it the storage pre-exists and it must never provision or delete it.
|
||||||
|
#
|
||||||
|
# reclaimPolicy MUST stay Retain: deleting this PV or its PVC must NEVER be able
|
||||||
|
# to reclaim or destroy the underlying CephFS data that the VM instances use.
|
||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolume
|
||||||
|
metadata:
|
||||||
|
name: media-apps-media-library
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteMany
|
||||||
|
capacity:
|
||||||
|
storage: 10Ti
|
||||||
|
# Load-bearing safety control. Do not change to Delete.
|
||||||
|
persistentVolumeReclaimPolicy: Retain
|
||||||
|
storageClassName: ""
|
||||||
|
volumeMode: Filesystem
|
||||||
|
# Pre-bind to the media-library claim so nothing else can grab this PV.
|
||||||
|
claimRef:
|
||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
name: media-library
|
||||||
|
namespace: media-apps
|
||||||
|
csi:
|
||||||
|
driver: cephfs.csi.ceph.com
|
||||||
|
volumeHandle: media-apps-media-library-static
|
||||||
|
nodeStageSecretRef:
|
||||||
|
name: csi-cephfs-secret
|
||||||
|
namespace: csi-cephfs
|
||||||
|
volumeAttributes:
|
||||||
|
# clusterID maps (in the csi-cephfs ceph-csi-config) to the mon set that
|
||||||
|
# also serves mediafs; for a static volume only the mon lookup is used.
|
||||||
|
clusterID: cephfs_csi_ssd_ec_4_1
|
||||||
|
fsName: mediafs
|
||||||
|
staticVolume: "true"
|
||||||
|
# Filesystem-internal root of the library (mediafs root == /shared/media).
|
||||||
|
rootPath: /
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
---
|
||||||
|
# Claim bound to the static mediafs PV. RWX so every app in the stack shares the
|
||||||
|
# one library. storageClassName "" + volumeName pin it to the static PV (no
|
||||||
|
# dynamic provisioning). Deleting this claim cannot reclaim the data (PV is
|
||||||
|
# Retain).
|
||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: media-library
|
||||||
|
namespace: media-apps
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteMany
|
||||||
|
storageClassName: ""
|
||||||
|
volumeName: media-apps-media-library
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 10Ti
|
||||||
|
volumeMode: Filesystem
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
---
|
|
||||||
# Shared movies library, read-write-many across the *arr stack and jellyfin.
|
|
||||||
# Greenfield-empty: a fresh CephFS volume, not the puppet mediafs library.
|
|
||||||
apiVersion: v1
|
|
||||||
kind: PersistentVolumeClaim
|
|
||||||
metadata:
|
|
||||||
name: movies
|
|
||||||
namespace: media-apps
|
|
||||||
spec:
|
|
||||||
accessModes:
|
|
||||||
- ReadWriteMany
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
storage: 500Gi
|
|
||||||
storageClassName: cephfs-raid5-retain
|
|
||||||
volumeMode: Filesystem
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
---
|
|
||||||
# Shared tvseries library, read-write-many across the *arr stack and jellyfin.
|
|
||||||
# Greenfield-empty: a fresh CephFS volume, not the puppet mediafs library.
|
|
||||||
apiVersion: v1
|
|
||||||
kind: PersistentVolumeClaim
|
|
||||||
metadata:
|
|
||||||
name: tvseries
|
|
||||||
namespace: media-apps
|
|
||||||
spec:
|
|
||||||
accessModes:
|
|
||||||
- ReadWriteMany
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
storage: 500Gi
|
|
||||||
storageClassName: cephfs-raid5-retain
|
|
||||||
volumeMode: Filesystem
|
|
||||||
@@ -65,17 +65,16 @@ spec:
|
|||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: config
|
- name: config
|
||||||
mountPath: /config
|
mountPath: /config
|
||||||
- name: movies
|
- name: media-library
|
||||||
mountPath: /mnt/movies
|
mountPath: /mnt/movies
|
||||||
- name: tvseries
|
subPath: movies
|
||||||
|
- name: media-library
|
||||||
mountPath: /mnt/tvseries
|
mountPath: /mnt/tvseries
|
||||||
|
subPath: tvseries
|
||||||
volumes:
|
volumes:
|
||||||
- name: config
|
- name: config
|
||||||
persistentVolumeClaim:
|
persistentVolumeClaim:
|
||||||
claimName: nzbget-config
|
claimName: nzbget-config
|
||||||
- name: movies
|
- name: media-library
|
||||||
persistentVolumeClaim:
|
persistentVolumeClaim:
|
||||||
claimName: movies
|
claimName: media-library
|
||||||
- name: tvseries
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: tvseries
|
|
||||||
|
|||||||
@@ -78,8 +78,9 @@ spec:
|
|||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: config
|
- name: config
|
||||||
mountPath: /config
|
mountPath: /config
|
||||||
- name: movies
|
- name: media-library
|
||||||
mountPath: /mnt/movies
|
mountPath: /mnt/movies
|
||||||
|
subPath: movies
|
||||||
- name: exportarr
|
- name: exportarr
|
||||||
image: ghcr.io/onedr0p/exportarr:latest
|
image: ghcr.io/onedr0p/exportarr:latest
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
@@ -134,6 +135,6 @@ spec:
|
|||||||
- name: config-template
|
- name: config-template
|
||||||
configMap:
|
configMap:
|
||||||
name: radarr-config-xml
|
name: radarr-config-xml
|
||||||
- name: movies
|
- name: media-library
|
||||||
persistentVolumeClaim:
|
persistentVolumeClaim:
|
||||||
claimName: movies
|
claimName: media-library
|
||||||
|
|||||||
@@ -78,8 +78,9 @@ spec:
|
|||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: config
|
- name: config
|
||||||
mountPath: /config
|
mountPath: /config
|
||||||
- name: tvseries
|
- name: media-library
|
||||||
mountPath: /mnt/tvseries
|
mountPath: /mnt/tvseries
|
||||||
|
subPath: tvseries
|
||||||
- name: exportarr
|
- name: exportarr
|
||||||
image: ghcr.io/onedr0p/exportarr:latest
|
image: ghcr.io/onedr0p/exportarr:latest
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
@@ -134,6 +135,6 @@ spec:
|
|||||||
- name: config-template
|
- name: config-template
|
||||||
configMap:
|
configMap:
|
||||||
name: sonarr-config-xml
|
name: sonarr-config-xml
|
||||||
- name: tvseries
|
- name: media-library
|
||||||
persistentVolumeClaim:
|
persistentVolumeClaim:
|
||||||
claimName: tvseries
|
claimName: media-library
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ spec:
|
|||||||
clusterResourceWhitelist:
|
clusterResourceWhitelist:
|
||||||
- group: ''
|
- group: ''
|
||||||
kind: Namespace
|
kind: Namespace
|
||||||
|
- group: ''
|
||||||
|
kind: PersistentVolume
|
||||||
namespaceResourceWhitelist:
|
namespaceResourceWhitelist:
|
||||||
- group: '*'
|
- group: '*'
|
||||||
kind: '*'
|
kind: '*'
|
||||||
|
|||||||
Reference in New Issue
Block a user