apiVersion: batch/v1 kind: CronJob metadata: name: media-hardlink-router namespace: default spec: schedule: "*/5 * * * *" concurrencyPolicy: Forbid jobTemplate: spec: template: spec: containers: - name: hardlink-router image: alpine:latest command: - /bin/sh - -c - | echo "Starting companion ebook routing..." # Paths mapped entirely within the clean media tree AUDIO_DIR="/yarr/media/audiobooks" BOOK_INGEST="/yarr/media/books/calibre-ingest" LOG_FILE="/yarr/media/books/.calibre_sidecars_linked.log" touch "$LOG_FILE" # Scan pristine audiobook folders for companion ebooks if [ -d "$AUDIO_DIR" ]; then find "$AUDIO_DIR" -type f \( -iname \*.epub -o -iname \*.azw3 -o -iname \*.cbz -o -iname \*.pdf \) -exec sh -c ' BOOK_INGEST="$1" LOG_FILE="$2" shift 2 for file do filename=$(basename "$file") dest_calibre="$BOOK_INGEST/$filename" # Verify against log to prevent Calibre re-import loops if ! grep -qxF "$file" "$LOG_FILE"; then if [ ! -f "$dest_calibre" ]; then ln "$file" "$dest_calibre" echo "$file" >> "$LOG_FILE" echo "Linked clean companion ebook to Calibre: $filename" fi fi done ' sh "$BOOK_INGEST" "$LOG_FILE" {} + fi echo "Routing complete." volumeMounts: - name: yarr-volume mountPath: /yarr restartPolicy: OnFailure volumes: - name: yarr-volume nfs: server: robin.home.nest path: /yarr