diff --git a/cluster/apps/kustomization.yaml b/cluster/apps/kustomization.yaml
index 936ab8e3d..f707ef02c 100644
--- a/cluster/apps/kustomization.yaml
+++ b/cluster/apps/kustomization.yaml
@@ -12,6 +12,7 @@ resources:
- kube-tools
#- logs
- media
+ - media-automation
- monitoring
- networking
- storage
diff --git a/cluster/apps/media-automation/bazarr/helm-release.yaml b/cluster/apps/media-automation/bazarr/helm-release.yaml
new file mode 100644
index 000000000..aa99c6b8d
--- /dev/null
+++ b/cluster/apps/media-automation/bazarr/helm-release.yaml
@@ -0,0 +1,80 @@
+---
+apiVersion: helm.toolkit.fluxcd.io/v2beta1
+kind: HelmRelease
+metadata:
+ name: &app bazarr
+ namespace: default
+spec:
+ interval: 15m
+ chart:
+ spec:
+ chart: app-template
+ version: 0.1.1
+ sourceRef:
+ kind: HelmRepository
+ name: bjw-s-charts
+ namespace: flux-system
+ install:
+ createNamespace: true
+ remediation:
+ retries: 5
+ upgrade:
+ remediation:
+ retries: 5
+ values:
+ image:
+ repository: ghcr.io/onedr0p/bazarr
+ tag: 1.1.1@sha256:cbeb7cc09c7689e8e26b55d74160b10f4030d3436fa9f160f09fed901cf28388
+ env:
+ TZ: "${TIMEZONE}"
+ envFrom:
+ - secretRef:
+ name: *app
+ service:
+ main:
+ ports:
+ http:
+ port: *port
+ ingress:
+ main:
+ enabled: true
+ ingressClassName: "nginx"
+ annotations:
+ auth.home.arpa/enabled: "true"
+ nginx.ingress.kubernetes.io/configuration-snippet: |
+ proxy_set_header Accept-Encoding "";
+ sub_filter '' '';
+ sub_filter_once on;
+ hosts:
+ - host: *host
+ paths:
+ - path: /
+ pathType: Prefix
+ tls:
+ - hosts:
+ - *host
+ podSecurityContext:
+ runAsUser: 568
+ runAsGroup: 568
+ fsGroup: 568
+ fsGroupChangePolicy: "OnRootMismatch"
+ supplementalGroups:
+ - 100
+ persistence:
+ config:
+ enabled: true
+ existingClaim: bazarr-config
+ video:
+ enabled: true
+ type: nfs
+ server: "${LOCAL_LAN_TRUENAS}"
+ path: /mnt/storage/video
+ mountPath: /mnt/storage/video
+ podAnnotations:
+ secret.reloader.stakater.com/reload: *app
+ resources:
+ requests:
+ cpu: 100m
+ memory: 256Mi
+ limits:
+ memory: 1Gi
diff --git a/cluster/apps/media-automation/bazarr/kustomization.yaml b/cluster/apps/media-automation/bazarr/kustomization.yaml
new file mode 100644
index 000000000..3f4009405
--- /dev/null
+++ b/cluster/apps/media-automation/bazarr/kustomization.yaml
@@ -0,0 +1,8 @@
+---
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+namespace: default
+resources:
+ - secret.sops.yaml
+ - volume.yaml
+ - helm-release.yaml
diff --git a/cluster/apps/media-automation/bazarr/secret.sops.yaml b/cluster/apps/media-automation/bazarr/secret.sops.yaml
new file mode 100644
index 000000000..f6d744786
--- /dev/null
+++ b/cluster/apps/media-automation/bazarr/secret.sops.yaml
@@ -0,0 +1,29 @@
+# yamllint disable
+apiVersion: v1
+kind: Secret
+metadata:
+ name: radarr
+ namespace: default
+type: Opaque
+stringData:
+ BAZARR__API_KEY: ENC[AES256_GCM,data:JP0q+GSWGKQsAWAL+vOpJUzWVNcG6ncjHxiZ8vplk1o=,iv:rUxiwvF1kyTX9SHrAMmml9lmbKhRqXYYFZ2djWlUsaU=,tag:xSPaQCULmLvFy08QgCV1kQ==,type:str]
+sops:
+ kms: []
+ gcp_kms: []
+ azure_kv: []
+ hc_vault: []
+ age:
+ - recipient: age1hhurqwmfvl9m3vh3hk8urulfzcdsrep2ax2neazqt435yhpamu3qj20asg
+ enc: |
+ -----BEGIN AGE ENCRYPTED FILE-----
+ YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBJaU16anJNV2pBZmxPR3h2
+ bWREUnpjcTFvd05ZQ2E4VVBDdm1FL2k4WEYwCkdQSStTNWtpdjNkUW51WS9MekdC
+ VkpTUUFjSjY2a1JMOUtqOVh5M0JRR2sKLS0tIDRmcWpJSEVvaUp4U1lsaTZYZGNw
+ OGVKWU0zNUZJSFh4aFJxQWFsYm1VeFkKaDeI/hl7z0Qh8t5W39Kxu9ert1dt4xo+
+ LX+MjpVqxiZNcfwROD4bkWeQSN+VsxoGOOyj4L15BlggNnlg+L7Hww==
+ -----END AGE ENCRYPTED FILE-----
+ lastmodified: "2022-09-15T04:23:13Z"
+ mac: ENC[AES256_GCM,data:pwRm4JVQSu13DID8hTFWIn0sYEmnGbW7trFDXxmsyMu2dYr5ryGrk/t/BVHUZTY/dnp67/xW3xPF+XYoOiVJ7qceMqoxK3j3UDOuDFJfgRbQEFyfNvdXxtqLA3odTxjvuLqWFu1nQ1V5285qdiHpxP3Tksrdt41QFD0R4EwR3Tg=,iv:v3J1y74gux95tXBELhqfelVj4dewq651zQZxSIfcsZo=,tag:yUF/Zitk0Me2x0NJ4PGP9w==,type:str]
+ pgp: []
+ encrypted_regex: ^(data|stringData)$
+ version: 3.7.3
diff --git a/cluster/apps/media-automation/bazarr/volume.yaml b/cluster/apps/media-automation/bazarr/volume.yaml
new file mode 100644
index 000000000..bab7a1cf9
--- /dev/null
+++ b/cluster/apps/media-automation/bazarr/volume.yaml
@@ -0,0 +1,17 @@
+---
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ name: bazarr-config
+ namespace: default
+ labels:
+ app.kubernetes.io/name: &name bazarr
+ app.kubernetes.io/instance: *name
+ kasten-io/backup: "true"
+spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 1Gi
+ storageClassName: rook-ceph-block
diff --git a/cluster/apps/media-automation/kustomization.yaml b/cluster/apps/media-automation/kustomization.yaml
new file mode 100644
index 000000000..533f945e1
--- /dev/null
+++ b/cluster/apps/media-automation/kustomization.yaml
@@ -0,0 +1,12 @@
+---
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+namespace: default
+resources:
+ - bazarr
+ - lidarr
+ - prowlarr
+ - radarr
+ - readarr
+ - recyclarr
+ - sonarr
diff --git a/cluster/apps/media-automation/lidarr/helm-release.yaml b/cluster/apps/media-automation/lidarr/helm-release.yaml
new file mode 100644
index 000000000..2c4cdfb96
--- /dev/null
+++ b/cluster/apps/media-automation/lidarr/helm-release.yaml
@@ -0,0 +1,90 @@
+---
+apiVersion: helm.toolkit.fluxcd.io/v2beta1
+kind: HelmRelease
+metadata:
+ name: &app lidarr
+ namespace: default
+spec:
+ interval: 15m
+ chart:
+ spec:
+ chart: app-template
+ version: 0.1.1
+ sourceRef:
+ kind: HelmRepository
+ name: bjw-s-charts
+ namespace: flux-system
+ install:
+ createNamespace: true
+ remediation:
+ retries: 5
+ upgrade:
+ remediation:
+ retries: 5
+ values:
+ image:
+ repository: ghcr.io/onedr0p/lidarr-develop
+ tag: 1.1.0.2649@sha256:76d9ab6175e98edfb6429984be48c307914a69b235445ba9f93298fd6ec3c75e
+ env:
+ TZ: "${TIMEZONE}"
+ LIDARR__INSTANCE_NAME: Lidarr
+ LIDARR__PORT: &port 80
+ LIDARR__LOG_LEVEL: info
+ envFrom:
+ - secretRef:
+ name: *app
+ service:
+ main:
+ ports:
+ http:
+ port: *port
+ ingress:
+ main:
+ enabled: true
+ ingressClassName: "nginx"
+ annotations:
+ auth.home.arpa/enabled: "true"
+ nginx.ingress.kubernetes.io/configuration-snippet: |
+ proxy_set_header Accept-Encoding "";
+ sub_filter '' '';
+ sub_filter_once on;
+ hosts:
+ - host: &host "{{ .Release.Name }}.${SECRET_CLUSTER_DOMAIN}"
+ paths:
+ - path: /
+ pathType: Prefix
+ tls:
+ - hosts:
+ - *host
+ podSecurityContext:
+ runAsUser: 568
+ runAsGroup: 568
+ fsGroup: 568
+ fsGroupChangePolicy: "OnRootMismatch"
+ supplementalGroups:
+ - 100
+ persistence:
+ config:
+ enabled: true
+ existingClaim: lidarr-config
+ mountPath: /config
+ music:
+ enabled: true
+ type: nfs
+ server: "${LOCAL_LAN_TRUENAS}"
+ path: /mnt/storage/music
+ mountPath: /mnt/storage/music
+ downloads:
+ enabled: true
+ type: nfs
+ server: "${LOCAL_LAN_TRUENAS}"
+ path: /mnt/storage/downloads
+ mountPath: /mnt/storage/downloads
+ podAnnotations:
+ secret.reloader.stakater.com/reload: *app
+ resources:
+ requests:
+ cpu: 10m
+ memory: 250Mi
+ limits:
+ memory: 2000Mi
diff --git a/cluster/apps/media-automation/lidarr/kustomization.yaml b/cluster/apps/media-automation/lidarr/kustomization.yaml
new file mode 100644
index 000000000..2b83e0b01
--- /dev/null
+++ b/cluster/apps/media-automation/lidarr/kustomization.yaml
@@ -0,0 +1,7 @@
+---
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+resources:
+ - volume.yaml
+ - secret.sops.yaml
+ - helm-release.yaml
diff --git a/cluster/apps/media-automation/lidarr/secret.sops.yaml b/cluster/apps/media-automation/lidarr/secret.sops.yaml
new file mode 100644
index 000000000..1bc7be365
--- /dev/null
+++ b/cluster/apps/media-automation/lidarr/secret.sops.yaml
@@ -0,0 +1,29 @@
+# yamllint disable
+apiVersion: v1
+kind: Secret
+metadata:
+ name: lidarr
+ namespace: default
+type: Opaque
+stringData:
+ LIDARR__API_KEY: ENC[AES256_GCM,data:DuE9DXc6hYZn1mL5BPuvzFY94SKHnm0Q5UtFiHYre0g=,iv:5/PWpqpeKBK6eqzQ8/1b14m8c+ZiVfpDfzE/mm0FITE=,tag:P6aRHxO6cmduylFvNOgxDg==,type:str]
+sops:
+ kms: []
+ gcp_kms: []
+ azure_kv: []
+ hc_vault: []
+ age:
+ - recipient: age1hhurqwmfvl9m3vh3hk8urulfzcdsrep2ax2neazqt435yhpamu3qj20asg
+ enc: |
+ -----BEGIN AGE ENCRYPTED FILE-----
+ YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA3dDVhQnh6WHlrSU1DVndU
+ VGRXdUtLUjQxT21rUHQ3YmtsMllYQWlLRkVVCmM2VVNqTFZrLyswSllPR3ZNaVM3
+ S21SQ01Wei9PU1FJU2h3NzBEQVdKNEUKLS0tIHhXandQa2xiUFZLRDFxaVZveGRV
+ T21JelR0V0Q0NlJidTZhV3JkbTlkc0kKHsDVi+zO23YBslrf+MXhLfNF5U+AQvMv
+ L6kCzz+h1RmLrleC/8cJ9/n4wo1FZZqGXFZHAjLTRGESA7ccWc+DSw==
+ -----END AGE ENCRYPTED FILE-----
+ lastmodified: "2022-09-15T03:56:24Z"
+ mac: ENC[AES256_GCM,data:tDosIpLi/N/8NAsVctp4zTyIQlcQt+JnJpyp+J1dsSFG4ERAwpe9taD3VUwlMim2VccRKUtnEgES3H66sFB9iAhuf/txMbNTd22DWauBiFMoqPjAU8GyvPgwFdWjSSW71CrOLjOlpdMUxV3DKjLjwQDQ/aRJ/oqxNeV90KcU/BU=,iv:3bmvzERWc8u/7sEwlmbEozPmR4gwnemzmF7YkIMDcc4=,tag:RVA4y7nz5MaWXgRJWWhPzA==,type:str]
+ pgp: []
+ encrypted_regex: ^(data|stringData)$
+ version: 3.7.3
diff --git a/cluster/apps/media-automation/lidarr/volume.yaml b/cluster/apps/media-automation/lidarr/volume.yaml
new file mode 100644
index 000000000..8189a1a33
--- /dev/null
+++ b/cluster/apps/media-automation/lidarr/volume.yaml
@@ -0,0 +1,17 @@
+---
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ name: lidarr-config
+ namespace: default
+ labels:
+ app.kubernetes.io/name: &name lidarr
+ app.kubernetes.io/instance: *name
+ kasten-io/backup: "true"
+spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 10Gi
+ storageClassName: rook-ceph-block
diff --git a/cluster/apps/media-automation/prowlarr/helm-release.yaml b/cluster/apps/media-automation/prowlarr/helm-release.yaml
new file mode 100644
index 000000000..35397996c
--- /dev/null
+++ b/cluster/apps/media-automation/prowlarr/helm-release.yaml
@@ -0,0 +1,75 @@
+---
+apiVersion: helm.toolkit.fluxcd.io/v2beta1
+kind: HelmRelease
+metadata:
+ name: &app prowlarr
+ namespace: default
+spec:
+ interval: 15m
+ chart:
+ spec:
+ chart: app-template
+ version: 0.1.1
+ sourceRef:
+ kind: HelmRepository
+ name: bjw-s-charts
+ namespace: flux-system
+ install:
+ createNamespace: true
+ remediation:
+ retries: 5
+ upgrade:
+ remediation:
+ retries: 5
+ values:
+ image:
+ repository: ghcr.io/onedr0p/prowlarr-nightly
+ tag: 0.4.6.1969@sha256:7c6ab158fe8ba9488caf1e822165dad85302e017fdf550c9c3cf51bbf2a0bdb1
+ env:
+ TZ: "${TIMEZONE}"
+ PROWLARR__INSTANCE_NAME: Prowlarr
+ PROWLARR__PORT: &port 80
+ PROWLARR__LOG_LEVEL: info
+ envFrom:
+ - secretRef:
+ name: *app
+ service:
+ main:
+ ports:
+ http:
+ port: *port
+ ingress:
+ main:
+ enabled: true
+ ingressClassName: "nginx"
+ annotations:
+ auth.home.arpa/enabled: "true"
+ nginx.ingress.kubernetes.io/configuration-snippet: |
+ proxy_set_header Accept-Encoding "";
+ sub_filter '' '';
+ sub_filter_once on;
+ hosts:
+ - host: &host "{{ .Release.Name }}.${SECRET_CLUSTER_DOMAIN}"
+ paths:
+ - path: /
+ pathType: Prefix
+ tls:
+ - hosts:
+ - *host
+ podSecurityContext:
+ runAsUser: 568
+ runAsGroup: 568
+ fsGroup: 568
+ fsGroupChangePolicy: "OnRootMismatch"
+ persistence:
+ config:
+ enabled: true
+ existingClaim: prowlarr-config
+ podAnnotations:
+ secret.reloader.stakater.com/reload: *app
+ resources:
+ requests:
+ cpu: 100m
+ memory: 100Mi
+ limits:
+ memory: 500Mi
diff --git a/cluster/apps/media-automation/prowlarr/kustomization.yaml b/cluster/apps/media-automation/prowlarr/kustomization.yaml
new file mode 100644
index 000000000..2b83e0b01
--- /dev/null
+++ b/cluster/apps/media-automation/prowlarr/kustomization.yaml
@@ -0,0 +1,7 @@
+---
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+resources:
+ - volume.yaml
+ - secret.sops.yaml
+ - helm-release.yaml
diff --git a/cluster/apps/media-automation/prowlarr/secret.sops.yaml b/cluster/apps/media-automation/prowlarr/secret.sops.yaml
new file mode 100644
index 000000000..d54ec4ab4
--- /dev/null
+++ b/cluster/apps/media-automation/prowlarr/secret.sops.yaml
@@ -0,0 +1,29 @@
+# yamllint disable
+apiVersion: v1
+kind: Secret
+metadata:
+ name: prowlarr
+ namespace: default
+type: Opaque
+stringData:
+ PROWLARR__API_KEY: ENC[AES256_GCM,data:wHw+BL6aLWhVecJ2Pr0qEtdI6VIK3kG0Xa75WWgKy5g=,iv:TclbMhXHpV66KX5Pf8J0JUun2NfRYYFpENUfw3WFKUU=,tag:IntUJuSu7mExXZAyT1daqw==,type:str]
+sops:
+ kms: []
+ gcp_kms: []
+ azure_kv: []
+ hc_vault: []
+ age:
+ - recipient: age1hhurqwmfvl9m3vh3hk8urulfzcdsrep2ax2neazqt435yhpamu3qj20asg
+ enc: |
+ -----BEGIN AGE ENCRYPTED FILE-----
+ YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkaC9OUGczTHBOSmtHT3Q5
+ Z0dsQWc3TCs1N2lPbWtOWU5jVW5SaHJ5Sm4wClRldUlHTnJOVGMyVUI4T0F1Snd0
+ TmY1N3RQUFIyTkd4OWg1VGtCOVBoSXcKLS0tIDJWdGI1S0hPVEN0UTF5OVZINll2
+ cFg3Y2RVMjNGSUo4YTNHcUJwTFBhcUEKdDUnJq4rf8fxsHm+Ftt7kHdIKkvnj9Sv
+ kHrE4pYYDOzY19GUHuRlhRWXZxsymgfEEb162C3IWRek/AP9njYzHQ==
+ -----END AGE ENCRYPTED FILE-----
+ lastmodified: "2022-09-15T04:02:46Z"
+ mac: ENC[AES256_GCM,data:U4eOLJRlSshwVbJyECusFoYeLP+HZUsAEDXj8Tur/8f43oe4zIChfND+h8yG8c7hLir9rhGy9rDfb7fGHV5gL+v2FSoC2m/YYU+V9gJmFAUzg6c+4TR+3EOQdsuNGqkcsA/SVts08W+9K501VsaOXujMVzoZvtGYxqjIDZHhmBE=,iv:OLMzqFKB38FFYslh4KSLtrDKDeK4wc9NN3li31YNsrk=,tag:vyXftB8iKCY3Z27bZ3fQPw==,type:str]
+ pgp: []
+ encrypted_regex: ^(data|stringData)$
+ version: 3.7.3
diff --git a/cluster/apps/media-automation/prowlarr/volume.yaml b/cluster/apps/media-automation/prowlarr/volume.yaml
new file mode 100644
index 000000000..70ec2e654
--- /dev/null
+++ b/cluster/apps/media-automation/prowlarr/volume.yaml
@@ -0,0 +1,17 @@
+---
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ name: prowlarr-config
+ namespace: default
+ labels:
+ app.kubernetes.io/name: &name prowlarr
+ app.kubernetes.io/instance: *name
+ kasten-io/backup: "true"
+spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 2Gi
+ storageClassName: rook-ceph-block
diff --git a/cluster/apps/media-automation/radarr/helm-release.yaml b/cluster/apps/media-automation/radarr/helm-release.yaml
new file mode 100644
index 000000000..595626d6a
--- /dev/null
+++ b/cluster/apps/media-automation/radarr/helm-release.yaml
@@ -0,0 +1,102 @@
+---
+apiVersion: helm.toolkit.fluxcd.io/v2beta1
+kind: HelmRelease
+metadata:
+ name: &app radarr
+ namespace: default
+spec:
+ interval: 15m
+ chart:
+ spec:
+ chart: app-template
+ version: 0.1.1
+ sourceRef:
+ kind: HelmRepository
+ name: bjw-s-charts
+ namespace: flux-system
+ install:
+ createNamespace: true
+ remediation:
+ retries: 5
+ upgrade:
+ remediation:
+ retries: 5
+ values:
+ image:
+ repository: ghcr.io/onedr0p/radarr-develop
+ tag: 4.2.3.6575@sha256:c18425b9a0e0871141db3d7e8892806df53376f682559d62b6f8c25bb9009d86
+ env:
+ TZ: "${TIMEZONE}"
+ PUSHOVER_DEBUG: "false"
+ PUSHOVER_APP_URL: &host "{{ .Release.Name }}.${SECRET_CLUSTER_DOMAIN}"
+ RADARR__INSTANCE_NAME: Radarr
+ RADARR__PORT: &port 80
+ RADARR__APPLICATION_URL: "https://{{ .Release.Name }}.${SECRET_CLUSTER_DOMAIN}"
+ RADARR__LOG_LEVEL: info
+ envFrom:
+ - secretRef:
+ name: *app
+ service:
+ main:
+ ports:
+ http:
+ port: *port
+ ingress:
+ main:
+ enabled: true
+ ingressClassName: "nginx"
+ annotations:
+ auth.home.arpa/enabled: "true"
+ nginx.ingress.kubernetes.io/configuration-snippet: |
+ proxy_set_header Accept-Encoding "";
+ sub_filter '' '';
+ sub_filter_once on;
+ hosts:
+ - host: *host
+ paths:
+ - path: /
+ pathType: Prefix
+ tls:
+ - hosts:
+ - *host
+ podSecurityContext:
+ runAsUser: 568
+ runAsGroup: 568
+ fsGroup: 568
+ fsGroupChangePolicy: "OnRootMismatch"
+ supplementalGroups:
+ - 100
+ persistence:
+ config:
+ enabled: true
+ existingClaim: radarr-config
+ mountPath: /config
+ downloads:
+ enabled: true
+ type: nfs
+ server: "${LOCAL_LAN_TRUENAS}"
+ path: /mnt/storage/downloads
+ mountPath: /mnt/storage/downloads
+ video:
+ enabled: true
+ type: nfs
+ server: "${LOCAL_LAN_TRUENAS}"
+ path: /mnt/storage/video
+ mountPath: /mnt/storage/video
+ scripts:
+ enabled: true
+ type: configMap
+ name: radarr-pushover
+ subPath: pushover-notify.sh
+ mountPath: /scripts/pushover-notify.sh
+ defaultMode: 0775
+ readOnly: true
+ podAnnotations:
+ configmap.reloader.stakater.com/reload: radarr-pushover
+ secret.reloader.stakater.com/reload: *app
+ resources:
+ requests:
+ cpu: 500m
+ memory: 500Mi
+ limits:
+ memory: 2000Mi
diff --git a/cluster/apps/media-automation/radarr/kustomization.yaml b/cluster/apps/media-automation/radarr/kustomization.yaml
new file mode 100644
index 000000000..4beeda20f
--- /dev/null
+++ b/cluster/apps/media-automation/radarr/kustomization.yaml
@@ -0,0 +1,16 @@
+---
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+namespace: default
+resources:
+ - secret.sops.yaml
+ - volume.yaml
+ - helm-release.yaml
+configMapGenerator:
+ - name: radarr-pushover
+ files:
+ - ./scripts/pushover-notify.sh
+generatorOptions:
+ disableNameSuffixHash: true
+ annotations:
+ kustomize.toolkit.fluxcd.io/substitute: disabled
diff --git a/cluster/apps/media-automation/radarr/scripts/pushover-notify.sh b/cluster/apps/media-automation/radarr/scripts/pushover-notify.sh
new file mode 100755
index 000000000..ab7b770b8
--- /dev/null
+++ b/cluster/apps/media-automation/radarr/scripts/pushover-notify.sh
@@ -0,0 +1,105 @@
+#!/usr/bin/env bash
+
+PUSHOVER_DEBUG="${PUSHOVER_DEBUG:-"true"}"
+# kubectl port-forward service/radarr -n default 7878:7878
+# export PUSHOVER_STARR_INSTANCE_NAME=Radarr;
+# export PUSHOVER_APP_URL="";
+# export PUSHOVER_TOKEN="";
+# export PUSHOVER_USER_KEY="";
+# export radarr_eventtype=Download;
+# ./notify.sh
+
+CONFIG_FILE="/config/config.xml" && [[ "${PUSHOVER_DEBUG}" == "true" ]] && CONFIG_FILE="config.xml"
+ERRORS=()
+
+#
+# Discoverable variables
+#
+# shellcheck disable=SC2086
+PUSHOVER_STARR_PORT="$(xmlstarlet sel -t -v "//Port" -nl ${CONFIG_FILE})" && [[ -z "${PUSHOVER_STARR_PORT}" ]] && ERRORS+=("PUSHOVER_STARR_PORT not defined")
+PUSHOVER_STARR_APIKEY="$(xmlstarlet sel -t -v "//ApiKey" -nl ${CONFIG_FILE})" && [[ -z "${PUSHOVER_STARR_APIKEY}" ]] && ERRORS+=("PUSHOVER_STARR_APIKEY not defined")
+PUSHOVER_STARR_INSTANCE_NAME="$(xmlstarlet sel -t -v "//InstanceName" -nl ${CONFIG_FILE})" && [[ -z "${PUSHOVER_STARR_INSTANCE_NAME}" ]] && ERRORS+=("PUSHOVER_STARR_INSTANCE_NAME not defined")
+
+#
+# Configurable variables
+#
+# Required
+PUSHOVER_APP_URL="${PUSHOVER_APP_URL:-}" && [[ -z "${PUSHOVER_APP_URL}" ]] && ERRORS+=("PUSHOVER_APP_URL not defined")
+PUSHOVER_USER_KEY="${PUSHOVER_USER_KEY:-}" && [[ -z "${PUSHOVER_USER_KEY}" ]] && ERRORS+=("PUSHOVER_USER_KEY not defined")
+PUSHOVER_TOKEN="${PUSHOVER_TOKEN:-}" && [[ -z "${PUSHOVER_TOKEN}" ]] && ERRORS+=("PUSHOVER_TOKEN not defined")
+# Optional
+PUSHOVER_DEVICE="${PUSHOVER_DEVICE:-}"
+PUSHOVER_PRIORITY="${PUSHOVER_PRIORITY:-"-2"}"
+PUSHOVER_SOUND="${PUSHOVER_SOUND:-}"
+
+#
+# Print defined variables
+#
+for pushover_vars in ${!PUSHOVER_*}
+do
+ declare -n var="${pushover_vars}"
+ [[ -n "${var}" && "${PUSHOVER_DEBUG}" = "true" ]] && printf "%s - %s=%s\n" "$(date)" "${!var}" "${var}"
+done
+
+#
+# Validate required variables are set
+#
+if [ ${#ERRORS[@]} -gt 0 ]; then
+ for err in "${ERRORS[@]}"; do printf "%s - Undefined variable %s\n" "$(date)" "${err}" >&2; done
+ exit 1
+fi
+
+#
+# Send Notification on Test
+#
+if [[ "${radarr_eventtype:-}" == "Test" ]]; then
+ PUSHOVER_TITLE="Test Notification"
+ PUSHOVER_MESSAGE="Howdy this is a test notification from ${PUSHOVER_STARR_INSTANCE_NAME}"
+fi
+
+#
+# Send notification on Download or Upgrade
+#
+if [[ "${radarr_eventtype:-}" == "Download" ]]; then
+ printf -v PUSHOVER_TITLE "%s (%s) [%s]" \
+ "${radarr_movie_title:-"The Lord of the Rings: The Return of the King"}" \
+ "${radarr_movie_year:-"2003"}" \
+ "${radarr_moviefile_quality:-"Bluray-1080p"}"
+ printf -v PUSHOVER_MESSAGE "%s" \
+ "$(curl --silent --header "X-Api-Key:${PUSHOVER_STARR_APIKEY}" "http://localhost:${PUSHOVER_STARR_PORT}/api/v3/movie/${radarr_movie_id:-"2619"}" \
+ | jq -r ".overview")"
+ printf -v PUSHOVER_URL "https://%s/movie/%s" \
+ "${PUSHOVER_APP_URL}" \
+ "${radarr_movie_tmdbid:-"122"}"
+ printf -v PUSHOVER_URL_TITLE "View movie in %s" \
+ "${PUSHOVER_STARR_INSTANCE_NAME}"
+fi
+
+notification=$(jq -n \
+ --arg token "${PUSHOVER_TOKEN}" \
+ --arg user "${PUSHOVER_USER_KEY}" \
+ --arg title "${PUSHOVER_TITLE}" \
+ --arg message "${PUSHOVER_MESSAGE:-"Unable to obtain plot summary"}" \
+ --arg url "${PUSHOVER_URL}" \
+ --arg url_title "${PUSHOVER_URL_TITLE}" \
+ --arg priority "${PUSHOVER_PRIORITY}" \
+ --arg sound "${PUSHOVER_SOUND}" \
+ --arg device "${PUSHOVER_DEVICE}" \
+ '{token: $token, user: $user, title: $title, message: $message, url: $url, url_title: $url_title, priority: $priority, sound: $sound, device: $device}' \
+)
+
+status_code=$(curl \
+ --write-out "%{http_code}" \
+ --silent \
+ --output /dev/null \
+ --header "Content-Type: application/json" \
+ --data-binary "${notification}" \
+ --request POST "https://api.pushover.net/1/messages.json" \
+)
+
+if [[ "${status_code}" -ne 200 ]] ; then
+ printf "%s - Unable to send notification with status code %s and payload: %s\n" "$(date)" "${status_code}" "$(echo "${notification}" | jq -c)" >&2
+ exit 1
+else
+ printf "%s - Sent notification with status code %s and payload: %s\n" "$(date)" "${status_code}" "$(echo "${notification}" | jq -c)"
+fi
diff --git a/cluster/apps/media-automation/radarr/secret.sops.yaml b/cluster/apps/media-automation/radarr/secret.sops.yaml
new file mode 100644
index 000000000..b893b1005
--- /dev/null
+++ b/cluster/apps/media-automation/radarr/secret.sops.yaml
@@ -0,0 +1,31 @@
+# yamllint disable
+apiVersion: v1
+kind: Secret
+metadata:
+ name: radarr
+ namespace: default
+type: Opaque
+stringData:
+ PUSHOVER_TOKEN: ENC[AES256_GCM,data:lhRZiBDtUEYQUFh5JkbzToDGjxshew/6NCGTvLgU,iv:0p1ITxTMSSrKy63eGOsX9/cKGxAsDhg7W+pgOyTIp30=,tag:6okXUgaHq134hQAb5Vf09Q==,type:str]
+ PUSHOVER_USER_KEY: ENC[AES256_GCM,data:9GOEKsbOEP+d9XzDjanfuNehROa9tJrArdCX6uvy,iv:3IFKbkFs5X2T+HrnwFZImf123jp4nWnafJOy1RFqMtY=,tag:XmnqhAk9oSLSSHi5OYtjEw==,type:str]
+ RADARR__API_KEY: ENC[AES256_GCM,data:451DYlNmSDGoHNeiK7+MyTsI26CoICs/isxiWFcpPJo=,iv:1HGC0TgKcL6ShlMgYwx/WSvOG5SFprG/sgmi6lQOvNU=,tag:uPX3JggXwXrNp7qhetG/Mw==,type:str]
+sops:
+ kms: []
+ gcp_kms: []
+ azure_kv: []
+ hc_vault: []
+ age:
+ - recipient: age1hhurqwmfvl9m3vh3hk8urulfzcdsrep2ax2neazqt435yhpamu3qj20asg
+ enc: |
+ -----BEGIN AGE ENCRYPTED FILE-----
+ YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBJaU16anJNV2pBZmxPR3h2
+ bWREUnpjcTFvd05ZQ2E4VVBDdm1FL2k4WEYwCkdQSStTNWtpdjNkUW51WS9MekdC
+ VkpTUUFjSjY2a1JMOUtqOVh5M0JRR2sKLS0tIDRmcWpJSEVvaUp4U1lsaTZYZGNw
+ OGVKWU0zNUZJSFh4aFJxQWFsYm1VeFkKaDeI/hl7z0Qh8t5W39Kxu9ert1dt4xo+
+ LX+MjpVqxiZNcfwROD4bkWeQSN+VsxoGOOyj4L15BlggNnlg+L7Hww==
+ -----END AGE ENCRYPTED FILE-----
+ lastmodified: "2022-09-15T04:09:09Z"
+ mac: ENC[AES256_GCM,data:O3b3cHpmP2MFjNo2xN+pCm99b8QZoF0XAMVkWLwWf+vMRTnj7f7cCmvqsbfESZzNLUA7n1OUvTXPO2YtavGovy1F1iS98xYDCI/WLRUJTXwOGxqOVnXrFyqD/lE71pANJWFa0Q6GAtNjhl6k6KST1wAmZQCkYlPWQgMXmipOb6s=,iv:ejZ4wuXuUTodyl8wbetG+CcPNGfBaiAu9HNTof7cgm0=,tag:j7kv5V7GsItkjVKyK7GDuw==,type:str]
+ pgp: []
+ encrypted_regex: ^(data|stringData)$
+ version: 3.7.3
diff --git a/cluster/apps/media-automation/radarr/volume.yaml b/cluster/apps/media-automation/radarr/volume.yaml
new file mode 100644
index 000000000..b80565634
--- /dev/null
+++ b/cluster/apps/media-automation/radarr/volume.yaml
@@ -0,0 +1,17 @@
+---
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ name: radarr-config
+ namespace: default
+ labels:
+ app.kubernetes.io/name: &name radarr
+ app.kubernetes.io/instance: *name
+ kasten-io/backup: "true"
+spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 15Gi
+ storageClassName: rook-ceph-block
diff --git a/cluster/apps/media-automation/readarr/helm-release.yaml b/cluster/apps/media-automation/readarr/helm-release.yaml
new file mode 100644
index 000000000..92fe2d177
--- /dev/null
+++ b/cluster/apps/media-automation/readarr/helm-release.yaml
@@ -0,0 +1,90 @@
+---
+apiVersion: helm.toolkit.fluxcd.io/v2beta1
+kind: HelmRelease
+metadata:
+ name: &app readarr
+ namespace: default
+spec:
+ interval: 15m
+ chart:
+ spec:
+ chart: app-template
+ version: 0.1.1
+ sourceRef:
+ kind: HelmRepository
+ name: bjw-s-charts
+ namespace: flux-system
+ install:
+ createNamespace: true
+ remediation:
+ retries: 5
+ upgrade:
+ remediation:
+ retries: 5
+ values:
+ image:
+ repository: ghcr.io/onedr0p/readarr-nightly
+ tag: 0.1.1.1409@sha256:00a1098977f6d77dabdad2ba8a65937a45098cd7f41285441cf74994813d5c8f
+ env:
+ TZ: "${TIMEZONE}"
+ READARR__INSTANCE_NAME: Readarr (Audio)
+ READARR__PORT: &port 80
+ READARR__LOG_LEVEL: info
+ envFrom:
+ - secretRef:
+ name: *app
+ service:
+ main:
+ ports:
+ http:
+ port: *port
+ ingress:
+ main:
+ enabled: true
+ ingressClassName: "nginx"
+ annotations:
+ auth.home.arpa/enabled: "true"
+ nginx.ingress.kubernetes.io/configuration-snippet: |-
+ proxy_set_header Accept-Encoding "";
+ sub_filter '' '';
+ sub_filter_once on;
+ hosts:
+ - host: &host "{{ .Release.Name }}.${SECRET_CLUSTER_DOMAIN}"
+ paths:
+ - path: /
+ pathType: Prefix
+ tls:
+ - hosts:
+ - *host
+ podSecurityContext:
+ runAsUser: 568
+ runAsGroup: 568
+ fsGroup: 568
+ fsGroupChangePolicy: "OnRootMismatch"
+ supplementalGroups:
+ - 100
+ persistence:
+ config:
+ enabled: true
+ existingClaim: readarr-config
+ mountPath: /config
+ books:
+ enabled: true
+ type: nfs
+ server: "${LOCAL_LAN_TRUENAS}"
+ path: /mnt/storage/home/claude/books
+ mountPath: /mnt/storage/home/claude/books
+ downloads:
+ enabled: true
+ type: nfs
+ server: "${LOCAL_LAN_TRUENAS}"
+ path: /mnt/storage/downloads
+ mountPath: /mnt/storage/downloads
+ podAnnotations:
+ secret.reloader.stakater.com/reload: *app
+ resources:
+ requests:
+ cpu: 10m
+ memory: 250Mi
+ limits:
+ memory: 1000Mi
diff --git a/cluster/apps/media-automation/readarr/kustomization.yaml b/cluster/apps/media-automation/readarr/kustomization.yaml
new file mode 100644
index 000000000..2b83e0b01
--- /dev/null
+++ b/cluster/apps/media-automation/readarr/kustomization.yaml
@@ -0,0 +1,7 @@
+---
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+resources:
+ - volume.yaml
+ - secret.sops.yaml
+ - helm-release.yaml
diff --git a/cluster/apps/media-automation/readarr/secret.sops.yaml b/cluster/apps/media-automation/readarr/secret.sops.yaml
new file mode 100644
index 000000000..7ff543c09
--- /dev/null
+++ b/cluster/apps/media-automation/readarr/secret.sops.yaml
@@ -0,0 +1,29 @@
+# yamllint disable
+apiVersion: v1
+kind: Secret
+metadata:
+ name: readarr
+ namespace: default
+type: Opaque
+stringData:
+ READARR__API_KEY: ENC[AES256_GCM,data:Vx735p7czaTKQVxQfUkkX22QN+mza1ms/Ob/qeYqNPk=,iv:AMLS+5V6+22R7IULKEyac4eEXd8yzh+qF/TO9xpbTII=,tag:KG5OWB4SYc1evdJ8Trn2NQ==,type:str]
+sops:
+ kms: []
+ gcp_kms: []
+ azure_kv: []
+ hc_vault: []
+ age:
+ - recipient: age1hhurqwmfvl9m3vh3hk8urulfzcdsrep2ax2neazqt435yhpamu3qj20asg
+ enc: |
+ -----BEGIN AGE ENCRYPTED FILE-----
+ YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBJaHh2UDcvUnF1eHJXWXMv
+ a1JQaXJYZi9MTmx3OHZ5bmVLVjVsekFyZERNCjdjVk5wb3U1bjROeE5kM1JXRVZi
+ QTJIeTMzUDZDWnF2c0NMRm1YUS95Q28KLS0tIGJPdzJLSzJEMGpuQTIwRHYvNmR0
+ WU1mNWFQTE1uU0JiOU9CVmFsWXlHRDgKgTLlh8lIOxTDBpHT1kfCerY0KQL96UU7
+ gTqR0QIxjJ1qf+KLyKAEonHtNMb1mg/eJUBPeFfhuu3HE6T9bsAIFA==
+ -----END AGE ENCRYPTED FILE-----
+ lastmodified: "2022-09-15T04:12:05Z"
+ mac: ENC[AES256_GCM,data:T/nPAUI8PP6vq8uMCefTpbKCVr747HGmLxBhVw1sWhfb6KylYj8JIRRfT4IEoPQlEcXO9ar72nEYj0AogRJJ3pf/17x3NTd0Qg8F1Xy0ZLAS5g0EHjAYBlG9FJ+2D+7qD3Clej5uWW3oXWlCZcAVYv0vjd4efuKDvyDLNzvopIk=,iv:Uj91JlLiC6Ck+e/7afPUfetc2zyThB2Nk5bi6Oc4Skg=,tag:xvwCp/8WT5EBSTMZ643Ylg==,type:str]
+ pgp: []
+ encrypted_regex: ^(data|stringData)$
+ version: 3.7.3
diff --git a/cluster/apps/media-automation/readarr/volume.yaml b/cluster/apps/media-automation/readarr/volume.yaml
new file mode 100644
index 000000000..549ad1095
--- /dev/null
+++ b/cluster/apps/media-automation/readarr/volume.yaml
@@ -0,0 +1,17 @@
+---
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ name: readarr-config
+ namespace: default
+ labels:
+ app.kubernetes.io/name: &name readarr
+ app.kubernetes.io/instance: *name
+ kasten-io/backup: "true"
+spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 1Gi
+ storageClassName: rook-ceph-block
diff --git a/cluster/apps/media-automation/recyclarr/cron-job.yaml b/cluster/apps/media-automation/recyclarr/cron-job.yaml
new file mode 100644
index 000000000..3df0ca4bc
--- /dev/null
+++ b/cluster/apps/media-automation/recyclarr/cron-job.yaml
@@ -0,0 +1,70 @@
+---
+apiVersion: batch/v1
+kind: CronJob
+metadata:
+ name: &app recyclarr
+ namespace: default
+spec:
+ schedule: "@daily"
+ jobTemplate:
+ spec:
+ ttlSecondsAfterFinished: 86400
+ template:
+ spec:
+ automountServiceAccountToken: false
+ restartPolicy: OnFailure
+ initContainers:
+ - name: render-configs
+ image: ghcr.io/onedr0p/recyclarr:2.5.0@sha256:bd4dc562a12c31857c2e198de154d4ffa734d5e7f6fe817283c6fdf5807c5fb1
+ envFrom:
+ - secretRef:
+ name: *app
+ command:
+ - "/bin/bash"
+ - -c
+ args:
+ - "envsubst < /config/recyclarr.yaml > /shared/recyclarr.yaml"
+ volumeMounts:
+ - name: config
+ mountPath: /config
+ - name: shared
+ mountPath: /shared
+ containers:
+ - name: sonarrs
+ image: ghcr.io/onedr0p/recyclarr:2.5.0@sha256:bd4dc562a12c31857c2e198de154d4ffa734d5e7f6fe817283c6fdf5807c5fb1
+ env:
+ - name: TZ
+ value: "${TIMEZONE}"
+ command:
+ - /app/recyclarr
+ args:
+ - sonarr
+ - --config
+ - /config/recyclarr.yaml
+ volumeMounts:
+ - name: shared
+ mountPath: /config/recyclarr.yaml
+ subPath: recyclarr.yaml
+ readOnly: true
+ - name: radarrs
+ image: ghcr.io/onedr0p/recyclarr:2.5.0@sha256:bd4dc562a12c31857c2e198de154d4ffa734d5e7f6fe817283c6fdf5807c5fb1
+ env:
+ - name: TZ
+ value: "${TIMEZONE}"
+ command:
+ - /app/recyclarr
+ args:
+ - radarr
+ - --config
+ - /config/recyclarr.yaml
+ volumeMounts:
+ - name: shared
+ mountPath: /config/recyclarr.yaml
+ subPath: recyclarr.yaml
+ readOnly: true
+ volumes:
+ - name: config
+ configMap:
+ name: *app
+ - name: shared
+ emptyDir: {}
diff --git a/cluster/apps/media-automation/recyclarr/kustomization.yaml b/cluster/apps/media-automation/recyclarr/kustomization.yaml
new file mode 100644
index 000000000..be3c3361c
--- /dev/null
+++ b/cluster/apps/media-automation/recyclarr/kustomization.yaml
@@ -0,0 +1,15 @@
+---
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+resources:
+ - secret.sops.yaml
+ - cron-job.yaml
+namespace: default
+configMapGenerator:
+ - name: recyclarr
+ files:
+ - recyclarr.yaml
+generatorOptions:
+ disableNameSuffixHash: true
+ annotations:
+ kustomize.toolkit.fluxcd.io/substitute: disabled
diff --git a/cluster/apps/media-automation/recyclarr/recyclarr.yaml b/cluster/apps/media-automation/recyclarr/recyclarr.yaml
new file mode 100644
index 000000000..9e90b8f6c
--- /dev/null
+++ b/cluster/apps/media-automation/recyclarr/recyclarr.yaml
@@ -0,0 +1,113 @@
+---
+# A starter config to use with Trash Updater. Most values are set to "reasonable defaults".
+# Update the values below as needed for your instance. You will be required to update the
+# API Key and URL for each instance you want to use.
+#
+# Many optional settings have been omitted to keep this template simple.
+#
+# For more details on the configuration, see the Configuration Reference on the wiki here:
+# https://github.com/rcdailey/trash-updater/wiki/Configuration-Reference
+
+sonarr:
+ - base_url: http://sonarr
+ api_key: ${SONARR_API_KEY}
+ quality_definition: hybrid
+ release_profiles:
+ - trash_ids:
+ - EBC725268D687D588A20CBC5F97E538B # Low Quality Groups
+ - 1B018E0C53EC825085DD911102E2CA36 # Release Sources (Streaming Service)
+ - 71899E6C303A07AF0E4746EFF9873532 # P2P Groups + Repack/Proper
+ - d428eda85af1df8904b4bbe4fc2f537c # Anime - First release profile
+ - 6cd9e10bb5bb4c63d2d7cd3279924c7b # Anime - Second release profile
+
+radarr:
+ - base_url: http://radarr
+ api_key: ${RADARR_APIKEY}
+ delete_old_custom_formats: true
+ quality_definition:
+ type: movie
+ preferred_ratio: 0.5
+ custom_formats:
+ - trash_ids:
+ - ff5bc9e8ce91d46c997ca3ac6994d6f8 # UHD FraMeSToR (set to 0, 1 or 3200)
+ quality_profiles:
+ - name: Any
+ score: 1
+ - name: HD
+ score: 1
+ - name: SD
+ score: 1
+ - trash_ids:
+ - 496f355514737f7d83bf7aa4d24f8169 # TrueHD Atmos
+ - 2f22d89048b01681dde8afe203bf2e95 # DTS X
+ - 417804f7f2c4308c1f4c5d380d4c4475 # ATMOS (undefined)
+ - 1af239278386be2919e1bcee0bde047e # DD+ Atmos
+ - 3cafb66171b47f226146a0770576870f # TrueHD
+ - dcf3ec6938fa32445f590a4da84256cd # DTS-HD MA
+ - a570d4a0e56a2874b64e5bfa55202a1b # FLAC
+ - e7c2fcae07cbada050a0af3357491d7b # PCM
+ - 8e109e50e0a0b83a5098b056e13bf6db # DTS-HD HRA
+ - 185f1dd7264c4562b9022d963ac37424 # DD+
+ - f9f847ac70a0af62ea4a08280b859636 # DTS-ES
+ - 1c1a4c5e823891c75bc50380a6866f73 # DTS
+ - 240770601cc226190c367ef59aba7463 # ACC
+ - c2998bd0d90ed5621d8df281e839436e # DD
+ - e23edd2482476e595fb990b12e7c609c # DV HDR10 HDR/DV Custom Formats
+ - 58d6a88f13e2db7f5059c41047876f00 # DV
+ - 55d53828b9d81cbe20b02efd00aa0efd # DV HLG HDR/DV Custom Formats
+ - a3e19f8f627608af0211acd02bf89735 # DV SDR HDR/DV Custom Formats
+ - b974a6cd08c1066250f1f177d7aa1225 # HDR10Plus
+ - dfb86d5941bc9075d6af23b09c2aeecd # HDR10
+ - e61e28db95d22bedcadf030b8f156d96 # HDR
+ - 2a4d9069cc1fe3242ff9bdaebed239bb # HDR (Undefined)
+ - 08d6d8834ad9ec87b1dc7ec8148e7a1f # PQ several HDR/DV Custom Formats
+ - 9364dd386c9b4a1100dde8264690add7 # HLG
+ - 0f12c086e289cf966fa5948eac571f44 # Hybrid
+ - 570bc9ebecd92723d2d21500f4be314c # Remaster
+ - eca37840c13c6ef2dd0262b141a5482f # 4K Remaster
+ - e0c07d59beb37348e975a930d5e50319 # Criterion Collection
+ - 957d0f44b592285f26449575e8b1167e # Special Edition
+ - eecf3a857724171f968a66cb5719e152 # IMAX
+ - 9f6cbff8cfe4ebbc1bde14c7b7bec0de # IMAX Enhanced
+ - 403f3f6266b90439cacc1e07cae4dc2d # HQ-Remux
+ - 26fa26253af4001701fedb56cec376dc # HQ-Webdl
+ - 66aaa8c2c03c0191a95f0d655b75ab10 # UHD CtrlHD
+ - 4da96773192a51cf96178212642ca3bb # UHD LEGi0N
+ - 96848626e1570c122aba8642fe2714a2 # UHD HQMUX
+ - ffebc267e9c98d3d383f37b238550079 # UHD W4NK3R
+ - ac49fdbf6a662d380556f40ff4856f29 # UHD WEBDV
+ - afeb99e5db09290546f742503ce1cdb6 # UHD DON
+ - e7718d7a3ce595f289bfee26adc178f5 # Repack
+ - ed38b889b31be83fda192888e2286d83 # BR-DISK -10000
+ - 90cedc1fea7ea5d11298bebd3d1d3223 # EVO (no WEBDL) -1000
+ - 90a6f9a284dff5103f6346090e6280c8 # LQ -10000
+ - b8cd450cbfa689c0259a01d9e29ba3d6 # 3D -10000
+ - 7357cf5161efbf8c4d5d0c30b4815ee2 # Obfuscated
+ - ae9b7c9ebde1f3bd336a8cbd1ec4c5e5 # No-RlsGroup removed do avoid multiple downloads
+ - dc98083864ea246d05a42df0d05f81cc # x265 (720/1080p)
+ quality_profiles:
+ - name: Any
+ reset_unmatched_scores: true
+ - name: HD
+ reset_unmatched_scores: true
+ - name: SD
+ reset_unmatched_scores: true
+ - trash_ids:
+ - 1c7d7b04b15cc53ea61204bebbcc1ee2 # HQ
+ quality_profiles:
+ - name: Any
+ score: 0
+ - name: HD
+ score: 0
+ - name: SD
+ score: 0
+ - trash_ids:
+ - 4b900e171accbfb172729b63323ea8ca # Optional: Multi
+ - 923b6abef9b17f937fab56cfcf89e1f1 # Optional: DV (WEBDL) without fallback to HDR, set to manual score 0 or -10000
+ quality_profiles:
+ - name: Any
+ score: 0
+ - name: HD
+ score: 0
+ - name: SD
+ score: 0
diff --git a/cluster/apps/media-automation/recyclarr/secret.sops.yaml b/cluster/apps/media-automation/recyclarr/secret.sops.yaml
new file mode 100644
index 000000000..bd97da187
--- /dev/null
+++ b/cluster/apps/media-automation/recyclarr/secret.sops.yaml
@@ -0,0 +1,30 @@
+# yamllint disable
+apiVersion: v1
+kind: Secret
+metadata:
+ name: recyclarr
+ namespace: default
+type: Opaque
+stringData:
+ RADARR_APIKEY: ENC[AES256_GCM,data:1QbSAMl0/rSOq3wPx8lkAkLGKlUzoSPQoYgSb5bh7kI=,iv:lhxNvMvl13E+a1PHViyhHZJ5w6ugr6YnR7to/d2m7w4=,tag:t4YYyJ9Nfsd5Ey19TyQ+4Q==,type:str]
+ SONARR_APIKEY: ENC[AES256_GCM,data:OfRJVHh/i8kp1C3DBvhVmBmu0cDMtotzVCBlqyo0Gms=,iv:2q2e/LIZvJHG3ensZSC14M06OH5rf8WF/C6dw8rLxLc=,tag:xuOIAoTOLoVdfmNZpxAUpg==,type:str]
+sops:
+ kms: []
+ gcp_kms: []
+ azure_kv: []
+ hc_vault: []
+ age:
+ - recipient: age1hhurqwmfvl9m3vh3hk8urulfzcdsrep2ax2neazqt435yhpamu3qj20asg
+ enc: |
+ -----BEGIN AGE ENCRYPTED FILE-----
+ YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBWWEg2ZW0zS2VVWVBsMTgx
+ bVdydkN3aW5GSHczd2xod2owc2VwWVBLQUFRCnBmVGFvYmttVmFMaGNSeW9kTCtM
+ cEpSWm5tYkhZRGJhRUNIM0lKWStoS28KLS0tIE5pWHp1Tk0yTXlJYXNOWFNONmhz
+ Z0MvSzFZcU4zM3JZWDlNZ01KTW94emcKVNr7SDcNgGF/HoPk/qk72DCFUQm9mfdp
+ ZFdxh8Fe3eEoUKuqNyuMq9HIJJaYxj3vyHKer8f1pfiUdmKkBFTT3Q==
+ -----END AGE ENCRYPTED FILE-----
+ lastmodified: "2022-09-15T04:13:16Z"
+ mac: ENC[AES256_GCM,data:R0HGv0eYumPHjSFF4yhqnv7MyEljF0S4LfDejz+v8gMlkffPXXdgG8JAedEVEGpbUC1tsc5e8X7QR69vZ6zt+LApyKKTOBG9i2gfhr986uexbmPuL1fMjT5eCI+Rddi8VSUWDTFPDI4YIKWowW1MSKLdV7KiSHUsPD2dwwQ8aJM=,iv:uNREYlkdZOxGZyU3LX0vW+GEkGPr2Uuzzx+jZrffJLw=,tag:cuT2n58cmStbLrgbwV6jOw==,type:str]
+ pgp: []
+ encrypted_regex: ^(data|stringData)$
+ version: 3.7.3
diff --git a/cluster/apps/media-automation/sonarr/helm-release.yaml b/cluster/apps/media-automation/sonarr/helm-release.yaml
new file mode 100644
index 000000000..84bcc0e85
--- /dev/null
+++ b/cluster/apps/media-automation/sonarr/helm-release.yaml
@@ -0,0 +1,102 @@
+---
+apiVersion: helm.toolkit.fluxcd.io/v2beta1
+kind: HelmRelease
+metadata:
+ name: &app sonarr
+ namespace: default
+spec:
+ interval: 15m
+ chart:
+ spec:
+ chart: app-template
+ version: 0.1.1
+ sourceRef:
+ kind: HelmRepository
+ name: bjw-s-charts
+ namespace: flux-system
+ install:
+ createNamespace: true
+ remediation:
+ retries: 5
+ upgrade:
+ remediation:
+ retries: 5
+ values:
+ image:
+ repository: ghcr.io/onedr0p/sonarr-develop
+ tag: 3.0.9.1555@sha256:63e06362f8c14829086c908e6e92768bc22568b70095bc21124cdf21f235e785
+ env:
+ TZ: "${TIMEZONE}"
+ PUSHOVER_DEBUG: "false"
+ PUSHOVER_APP_URL: &host "{{ .Release.Name }}.${SECRET_CLUSTER_DOMAIN}"
+ SONARR__INSTANCE_NAME: Sonarr
+ SONARR__PORT: &port 80
+ SONARR__APPLICATION_URL: "https://{{ .Release.Name }}.${SECRET_CLUSTER_DOMAIN}"
+ SONARR__LOG_LEVEL: info
+ envFrom:
+ - secretRef:
+ name: *app
+ service:
+ main:
+ ports:
+ http:
+ port: *port
+ ingress:
+ main:
+ enabled: true
+ ingressClassName: "nginx"
+ annotations:
+ auth.home.arpa/enabled: "true"
+ nginx.ingress.kubernetes.io/configuration-snippet: |
+ proxy_set_header Accept-Encoding "";
+ sub_filter '' '';
+ sub_filter_once on;
+ hosts:
+ - host: *host
+ paths:
+ - path: /
+ pathType: Prefix
+ tls:
+ - hosts:
+ - *host
+ podSecurityContext:
+ runAsUser: 568
+ runAsGroup: 568
+ fsGroup: 568
+ fsGroupChangePolicy: "OnRootMismatch"
+ supplementalGroups:
+ - 100
+ persistence:
+ config:
+ enabled: true
+ existingClaim: sonarr-config
+ mountPath: /config
+ downloads:
+ enabled: true
+ type: nfs
+ server: "${LOCAL_LAN_TRUENAS}"
+ path: /mnt/storage/downloads
+ mountPath: /mnt/storage/downloads
+ video:
+ enabled: true
+ type: nfs
+ server: "${LOCAL_LAN_TRUENAS}"
+ path: /mnt/storage/video
+ mountPath: /mnt/storage/video
+ scripts:
+ enabled: true
+ type: configMap
+ name: sonarr-pushover
+ subPath: pushover-notify.sh
+ mountPath: /scripts/pushover-notify.sh
+ defaultMode: 0775
+ readOnly: true
+ podAnnotations:
+ configmap.reloader.stakater.com/reload: sonarr-pushover
+ secret.reloader.stakater.com/reload: *app
+ resources:
+ requests:
+ cpu: 500m
+ memory: 500Mi
+ limits:
+ memory: 2000Mi
diff --git a/cluster/apps/media-automation/sonarr/kustomization.yaml b/cluster/apps/media-automation/sonarr/kustomization.yaml
new file mode 100644
index 000000000..8e66b93f1
--- /dev/null
+++ b/cluster/apps/media-automation/sonarr/kustomization.yaml
@@ -0,0 +1,16 @@
+---
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+namespace: default
+resources:
+ - secret.sops.yaml
+ - config-pvc.yaml
+ - helm-release.yaml
+configMapGenerator:
+ - name: sonarr-pushover
+ files:
+ - ./scripts/pushover-notify.sh
+generatorOptions:
+ disableNameSuffixHash: true
+ annotations:
+ kustomize.toolkit.fluxcd.io/substitute: disabled
diff --git a/cluster/apps/media-automation/sonarr/scripts/pushover-notify.sh b/cluster/apps/media-automation/sonarr/scripts/pushover-notify.sh
new file mode 100755
index 000000000..256ef5eba
--- /dev/null
+++ b/cluster/apps/media-automation/sonarr/scripts/pushover-notify.sh
@@ -0,0 +1,107 @@
+#!/usr/bin/env bash
+
+PUSHOVER_DEBUG="${PUSHOVER_DEBUG:-"true"}"
+# kubectl port-forward service/sonarr -n default 8989:8989
+# export PUSHOVER_APP_URL="";
+# export PUSHOVER_TOKEN="";
+# export PUSHOVER_USER_KEY="";
+# export sonarr_eventtype=Download;
+# ./notify.sh
+
+CONFIG_FILE="/config/config.xml" && [[ "${PUSHOVER_DEBUG}" == "true" ]] && CONFIG_FILE="config.xml"
+ERRORS=()
+
+#
+# Discoverable variables
+#
+# shellcheck disable=SC2086
+PUSHOVER_STARR_PORT="$(xmlstarlet sel -t -v "//Port" -nl ${CONFIG_FILE})" && [[ -z "${PUSHOVER_STARR_PORT}" ]] && ERRORS+=("PUSHOVER_STARR_PORT not defined")
+PUSHOVER_STARR_APIKEY="$(xmlstarlet sel -t -v "//ApiKey" -nl ${CONFIG_FILE})" && [[ -z "${PUSHOVER_STARR_APIKEY}" ]] && ERRORS+=("PUSHOVER_STARR_APIKEY not defined")
+PUSHOVER_STARR_INSTANCE_NAME="$(xmlstarlet sel -t -v "//InstanceName" -nl ${CONFIG_FILE})" && [[ -z "${PUSHOVER_STARR_INSTANCE_NAME}" ]] && ERRORS+=("PUSHOVER_STARR_INSTANCE_NAME not defined")
+
+#
+# Configurable variables
+#
+# Required
+PUSHOVER_APP_URL="${PUSHOVER_APP_URL:-}" && [[ -z "${PUSHOVER_APP_URL}" ]] && ERRORS+=("PUSHOVER_APP_URL not defined")
+PUSHOVER_USER_KEY="${PUSHOVER_USER_KEY:-}" && [[ -z "${PUSHOVER_USER_KEY}" ]] && ERRORS+=("PUSHOVER_USER_KEY not defined")
+PUSHOVER_TOKEN="${PUSHOVER_TOKEN:-}" && [[ -z "${PUSHOVER_TOKEN}" ]] && ERRORS+=("PUSHOVER_TOKEN not defined")
+# Optional
+PUSHOVER_DEVICE="${PUSHOVER_DEVICE:-}"
+PUSHOVER_PRIORITY="${PUSHOVER_PRIORITY:-"-2"}"
+PUSHOVER_SOUND="${PUSHOVER_SOUND:-}"
+
+#
+# Print defined variables
+#
+for pushover_vars in ${!PUSHOVER_*}
+do
+ declare -n var="${pushover_vars}"
+ [[ -n "${var}" && "${PUSHOVER_DEBUG}" = "true" ]] && printf "%s - %s=%s\n" "$(date)" "${!var}" "${var}"
+done
+
+#
+# Validate required variables are set
+#
+if [ ${#ERRORS[@]} -gt 0 ]; then
+ for err in "${ERRORS[@]}"; do printf "%s - Undefined variable %s\n" "$(date)" "${err}" >&2; done
+ exit 1
+fi
+
+#
+# Send Notification on Test
+#
+if [[ "${sonarr_eventtype:-}" == "Test" ]]; then
+ PUSHOVER_TITLE="Test Notification"
+ PUSHOVER_MESSAGE="Howdy this is a test notification from ${PUSHOVER_STARR_INSTANCE_NAME}"
+fi
+
+#
+# Send notification on Download or Upgrade
+#
+if [[ "${sonarr_eventtype:-}" == "Download" ]]; then
+ printf -v PUSHOVER_TITLE "%s - S%02dE%02d - %s [%s]" \
+ "${sonarr_series_title:-"That '70s Show"}" \
+ "${sonarr_episodefile_seasonnumber:-"8"}" \
+ "${sonarr_episodefile_episodenumbers:-"22"}" \
+ "${sonarr_episodefile_episodetitles:-"That '70s Finale"}" \
+ "${sonarr_episodefile_quality:-"Bluray-720p"}"
+ printf -v PUSHOVER_MESSAGE "%s" \
+ "$(curl --silent --header "X-Api-Key:${PUSHOVER_STARR_APIKEY}" "http://localhost:${PUSHOVER_STARR_PORT}/api/v3/episode?seriesId=${sonarr_series_id:-"1653"}" \
+ | jq -r ".[] | select(.episodeFileId==${sonarr_episodefile_id:-"167750"}) | .overview")"
+ printf -v PUSHOVER_URL "https://%s/series/%s" \
+ "${PUSHOVER_APP_URL}" \
+ "$(curl --silent --header "X-Api-Key:${PUSHOVER_STARR_APIKEY}" "http://localhost:${PUSHOVER_STARR_PORT}/api/v3/series/${sonarr_series_id:-"1653"}" \
+ | jq -r ".titleSlug")"
+ printf -v PUSHOVER_URL_TITLE "View series in %s" \
+ "${PUSHOVER_STARR_INSTANCE_NAME}"
+fi
+
+notification=$(jq -n \
+ --arg token "${PUSHOVER_TOKEN}" \
+ --arg user "${PUSHOVER_USER_KEY}" \
+ --arg title "${PUSHOVER_TITLE}" \
+ --arg message "${PUSHOVER_MESSAGE:-"Unable to obtain plot summary"}" \
+ --arg url "${PUSHOVER_URL}" \
+ --arg url_title "${PUSHOVER_URL_TITLE}" \
+ --arg priority "${PUSHOVER_PRIORITY}" \
+ --arg sound "${PUSHOVER_SOUND}" \
+ --arg device "${PUSHOVER_DEVICE}" \
+ '{token: $token, user: $user, title: $title, message: $message, url: $url, url_title: $url_title, priority: $priority, sound: $sound, device: $device}' \
+)
+
+status_code=$(curl \
+ --write-out "%{http_code}" \
+ --silent \
+ --output /dev/null \
+ --header "Content-Type: application/json" \
+ --data-binary "${notification}" \
+ --request POST "https://api.pushover.net/1/messages.json" \
+)
+
+if [[ "${status_code}" -ne 200 ]] ; then
+ printf "%s - Unable to send notification with status code %s and payload: %s\n" "$(date)" "${status_code}" "$(echo "${notification}" | jq -c)" >&2
+ exit 1
+else
+ printf "%s - Sent notification with status code %s and payload: %s\n" "$(date)" "${status_code}" "$(echo "${notification}" | jq -c)"
+fi
diff --git a/cluster/apps/media-automation/sonarr/secret.sops.yaml b/cluster/apps/media-automation/sonarr/secret.sops.yaml
new file mode 100644
index 000000000..b47d475a7
--- /dev/null
+++ b/cluster/apps/media-automation/sonarr/secret.sops.yaml
@@ -0,0 +1,31 @@
+# yamllint disable
+apiVersion: v1
+kind: Secret
+metadata:
+ name: sonarr
+ namespace: default
+type: Opaque
+stringData:
+ PUSHOVER_TOKEN: ENC[AES256_GCM,data:k19SYCSuG2e3SZA2oOc+ORF0/Awd3pbPRMh0rZVf,iv:iNjc9LCjZ1MBEnfibTVnjisyxtm7QtjRNYUnKZn8emk=,tag:uEDCKAshQpybMY/dzR/M1Q==,type:str]
+ PUSHOVER_USER_KEY: ENC[AES256_GCM,data:VYp2lrBDk0yW4QcLbeH3p/bJ6mQ7hoA2luljU5lS,iv:8Yp48tC1N+1MdeW1lDDoMKyyE6qiZqd7D6qcY25tQRs=,tag:51G1vkr+vRJx29y9/FZ+DQ==,type:str]
+ SONARR__API_KEY: ENC[AES256_GCM,data:KheRN0LzO3Fb5P78lIt8mVZBydQH+xD+uQ8lBVEGieI=,iv:jG4RqKbprdfyqXmBlbXM8BVtwc3xdHof7p2NeP+dGss=,tag:z1nW7D5X+OCXIVcSEDbLog==,type:str]
+sops:
+ kms: []
+ gcp_kms: []
+ azure_kv: []
+ hc_vault: []
+ age:
+ - recipient: age1hhurqwmfvl9m3vh3hk8urulfzcdsrep2ax2neazqt435yhpamu3qj20asg
+ enc: |
+ -----BEGIN AGE ENCRYPTED FILE-----
+ YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBwWTJrS2pINFd3d2pRK0Z2
+ K3RUOWZwdXlUa2R2S2tVcldjUkJISTJDa2hFCnA0eThHNUhocisxVGZ1Z21PUno2
+ NXo4UjN6cXI1UWZVdjNmUzA5MHdUSDgKLS0tIEx5aFZydDRjTEhnUC94cC9kUlpn
+ LzZ0MXorcXRtVFRFNGhEUVAvTEs0UUkKo3F84muItufqs61yKmUVOVg/EORHYRHL
+ VNOHwINciH7lSknIZYPP+epMVDYCAe4AFmn2CPmtW6uRDScJAnBidw==
+ -----END AGE ENCRYPTED FILE-----
+ lastmodified: "2022-09-15T04:29:06Z"
+ mac: ENC[AES256_GCM,data:2uaAEPBB/v3k5WnUrGvp4fWW/SmrA306b4fru18NdEcLi8e070DJeThxF+/eHRYWIBDHBOhGDBe5Yv3U3tOnNjrQR8aqL9wWoatHqulGrwm/HiSbJZlDXRqO9DSItisBtTs2Tp5PhxBqsXlG5oEvQiV6/w+N44I2IrDnDW0P0C0=,iv:dAh6cKA3SqdZGBLPBTHkztO2wcgO1xUUbcE2d39eNXA=,tag:S5gtSNWzp/X3X+74y/vycQ==,type:str]
+ pgp: []
+ encrypted_regex: ^(data|stringData)$
+ version: 3.7.3
diff --git a/cluster/apps/media-automation/sonarr/volume.yaml b/cluster/apps/media-automation/sonarr/volume.yaml
new file mode 100644
index 000000000..6cbf2b8d3
--- /dev/null
+++ b/cluster/apps/media-automation/sonarr/volume.yaml
@@ -0,0 +1,17 @@
+---
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ name: sonarr-config
+ namespace: default
+ labels:
+ app.kubernetes.io/name: &name sonarr
+ app.kubernetes.io/instance: *name
+ kasten-io/backup: "true"
+spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 10Gi
+ storageClassName: rook-ceph-block
diff --git a/cluster/apps/media/kustomization.yaml b/cluster/apps/media/kustomization.yaml
index 5060b59a7..7930b97be 100644
--- a/cluster/apps/media/kustomization.yaml
+++ b/cluster/apps/media/kustomization.yaml
@@ -2,23 +2,15 @@ apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- - bazarr
- calibre
- calibre-web
- flood
- jellyfin
- jobs
- komga
- - lidarr
- lychee
- music_transcode
- navidrome
- - prowlarr
- pyload
- - radarr
- - readarr
- - recyclarr
- - sonarr
- - tdarr
- theme-park
# - travelstories