diff --git a/charts/emby/2.0.0/.helmignore b/charts/emby/2.0.0/.helmignore new file mode 100644 index 0000000000..e559de0a01 --- /dev/null +++ b/charts/emby/2.0.0/.helmignore @@ -0,0 +1,24 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +# OWNERS file for Kubernetes +OWNERS diff --git a/charts/emby/2.0.0/Chart.lock b/charts/emby/2.0.0/Chart.lock new file mode 100644 index 0000000000..85a4574775 --- /dev/null +++ b/charts/emby/2.0.0/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common + repository: file://../../../common + version: 1.2.9 +digest: sha256:af1a9a1f87e3e48453c9f25f909f5ebcd7fa6e25162b7b425448ba752bcdbc5c +generated: "2024-01-22T16:49:24.448208256+02:00" diff --git a/charts/emby/2.0.0/Chart.yaml b/charts/emby/2.0.0/Chart.yaml new file mode 100644 index 0000000000..afef4294b8 --- /dev/null +++ b/charts/emby/2.0.0/Chart.yaml @@ -0,0 +1,24 @@ +name: emby +description: Emby is designed to help you manage your personal media library, such as home videos and photos +annotations: + title: Emby Server +type: application +version: 2.0.0 +apiVersion: v2 +appVersion: 4.7.14.0 +kubeVersion: '>=1.16.0-0' +maintainers: + - name: truenas + url: https://www.truenas.com/ + email: dev@ixsystems.com +dependencies: + - name: common + repository: file://../../../common + version: 1.2.9 +home: https://emby.media/ +icon: https://media.sys.truenas.net/apps/emby/icons/icon.png +sources: + - https://hub.docker.com/r/emby/embyserver +keywords: + - emby + - media diff --git a/charts/emby/2.0.0/README.md b/charts/emby/2.0.0/README.md new file mode 100644 index 0000000000..680e4bdd23 --- /dev/null +++ b/charts/emby/2.0.0/README.md @@ -0,0 +1,3 @@ +# Emby + +[Emby](https://emby.media/) is designed to help you manage your personal media library, such as home videos and photos diff --git a/charts/emby/2.0.0/app-readme.md b/charts/emby/2.0.0/app-readme.md new file mode 100644 index 0000000000..680e4bdd23 --- /dev/null +++ b/charts/emby/2.0.0/app-readme.md @@ -0,0 +1,3 @@ +# Emby + +[Emby](https://emby.media/) is designed to help you manage your personal media library, such as home videos and photos diff --git a/charts/emby/2.0.0/charts/common-1.2.9.tgz b/charts/emby/2.0.0/charts/common-1.2.9.tgz new file mode 100644 index 0000000000..cf131132de Binary files /dev/null and b/charts/emby/2.0.0/charts/common-1.2.9.tgz differ diff --git a/charts/emby/2.0.0/ci/basic-values.yaml b/charts/emby/2.0.0/ci/basic-values.yaml new file mode 100644 index 0000000000..2eb3654848 --- /dev/null +++ b/charts/emby/2.0.0/ci/basic-values.yaml @@ -0,0 +1,10 @@ +embyNetwork: + webPort: 31000 + +embyID: + user: 1000 + group: 1000 + +embyStorage: + config: + type: pvc diff --git a/charts/emby/2.0.0/ci/extra-values.yaml b/charts/emby/2.0.0/ci/extra-values.yaml new file mode 100644 index 0000000000..8fd4060a87 --- /dev/null +++ b/charts/emby/2.0.0/ci/extra-values.yaml @@ -0,0 +1,11 @@ +embyNetwork: + webPort: 31000 + +embyStorage: + config: + type: pvc + additionalStorages: + - type: pvc + mountPath: /action_movies + - type: pvc + mountPath: /adventure_movies diff --git a/charts/emby/2.0.0/ci/hostNet-values.yaml b/charts/emby/2.0.0/ci/hostNet-values.yaml new file mode 100644 index 0000000000..05c8b76fc0 --- /dev/null +++ b/charts/emby/2.0.0/ci/hostNet-values.yaml @@ -0,0 +1,7 @@ +embyNetwork: + webPort: 31000 + hostNetwork: true + +embyStorage: + config: + type: pvc diff --git a/charts/emby/2.0.0/ix_values.yaml b/charts/emby/2.0.0/ix_values.yaml new file mode 100644 index 0000000000..9d5e197283 --- /dev/null +++ b/charts/emby/2.0.0/ix_values.yaml @@ -0,0 +1,30 @@ +image: + pullPolicy: IfNotPresent + repository: emby/embyserver + tag: 4.7.14.0 + +resources: + limits: + cpu: 4000m + memory: 8Gi + +embyConfig: + additionalEnvs: [] + +# On migration the default is 2 +embyID: + user: 568 + group: 568 + +embyNetwork: + webPort: 9096 + hostNetwork: false + +embyStorage: + config: + type: ixVolume + ixVolumeConfig: + datasetName: config + additionalStorages: [] + +embyGPU: {} diff --git a/charts/emby/2.0.0/metadata.yaml b/charts/emby/2.0.0/metadata.yaml new file mode 100644 index 0000000000..61276c0fdc --- /dev/null +++ b/charts/emby/2.0.0/metadata.yaml @@ -0,0 +1,18 @@ +runAsContext: + - userName: root + groupName: root + gid: 0 + uid: 0 + description: Emby runs as root user. +capabilities: + - name: CHOWN + description: Emby is able to chown files. + - name: DAC_OVERRIDE + description: Emby is able to bypass permission checks. + - name: FOWNER + description: Emby is able to bypass permission checks for it's sub-processes. + - name: SETGID + description: Emby is able to set group ID for it's sub-processes. + - name: SETUID + description: Emby is able to set user ID for it's sub-processes. +hostMounts: [] diff --git a/charts/emby/2.0.0/migrations/migrate b/charts/emby/2.0.0/migrations/migrate new file mode 100755 index 0000000000..9b0d6843d7 --- /dev/null +++ b/charts/emby/2.0.0/migrations/migrate @@ -0,0 +1,82 @@ +#!/usr/bin/python3 +import json +import os +import sys + +def migrate_volume(volume): + return { + 'type': 'hostPath', + 'hostPathConfig': { + 'hostPath': volume['hostPath'] + }, + } if volume.get('hostPathEnabled', False) else { + 'type': 'ixVolume', + 'ixVolumeConfig': { + 'datasetName': volume['datasetName'], + }, + } + +def migrate_common_lib(values): + delete_keys = [ + 'hostNetwork', 'environmentVariables', 'updateStrategy', 'embyServerHttp', 'gpuConfiguration', + 'appVolumeMounts', 'extraAppVolumeMounts', 'enableResourceLimits', 'cpuLimit', 'memLimit' + ] + + values.update({ + # Migrate Network + 'embyNetwork': { + 'webPort': values['embyServerHttp'], + 'hostNetwork': values['hostNetwork'], + }, + # Migrate Resources + 'resources': { + 'limits': { + 'cpu': values.get('cpuLimit', '4000m'), + 'memory': values.get('memLimit', '8Gi'), + } + }, + 'embyID': { + # We didn't have exposed this on UI the default + # set by the container is 2, so we will use that + 'user': 2, + 'group': 2, + }, + # Migrate Config + 'embyConfig': { + 'additionalEnvs': values.get('environmentVariables', []), + }, + # Migrate Storage + 'embyStorage': { + 'config': migrate_volume(values['appVolumeMounts']['config']), + 'additionalStorages': [ + { + 'type': 'hostPath', + 'hostPathConfig': {'hostPath': e['hostPath']}, + 'mountPath': e['mountPath'], + 'readOnly': e['readOnly'], + } + for e in values.get('extraAppVolumeMounts', []) + ], + }, + }) + + for k in delete_keys: + values.pop(k, None) + + return values + +def migrate(values): + # If this missing, we have already migrated + if not 'appVolumeMounts' in values.keys(): + return values + + return migrate_common_lib(values) + + +if __name__ == '__main__': + if len(sys.argv) != 2: + exit(1) + + if os.path.exists(sys.argv[1]): + with open(sys.argv[1], 'r') as f: + print(json.dumps(migrate(json.loads(f.read())))) diff --git a/charts/emby/2.0.0/questions.yaml b/charts/emby/2.0.0/questions.yaml new file mode 100644 index 0000000000..afacdb7239 --- /dev/null +++ b/charts/emby/2.0.0/questions.yaml @@ -0,0 +1,378 @@ +groups: + - name: Emby Configuration + description: Configure Emby + - name: User and Group Configuration + description: Configure User and Group for Emby + - name: Network Configuration + description: Configure Network for Emby + - name: Storage Configuration + description: Configure Storage for Emby + - name: Resources Configuration + description: Configure Resources for Emby + +portals: + web_portal: + protocols: + - "$kubernetes-resource_configmap_portal_protocol" + host: + - "$kubernetes-resource_configmap_portal_host" + ports: + - "$kubernetes-resource_configmap_portal_port" + path: "$kubernetes-resource_configmap_portal_path" + +questions: + - variable: embyConfig + label: "" + group: Emby Configuration + schema: + type: dict + attrs: + - variable: additionalEnvs + label: Additional Environment Variables + description: Configure additional environment variables for Emby. + schema: + type: list + default: [] + items: + - variable: env + label: Environment Variable + schema: + type: dict + attrs: + - variable: name + label: Name + schema: + type: string + required: true + - variable: value + label: Value + schema: + type: string + required: true + + - variable: embyID + label: "" + group: User and Group Configuration + schema: + type: dict + attrs: + - variable: user + label: User ID + description: The user id that Emby files will be owned by. + schema: + type: int + min: 2 + default: 568 + required: true + - variable: group + label: Group ID + description: The group id that Emby files will be owned by. + schema: + type: int + min: 2 + default: 568 + required: true + + - variable: embyNetwork + label: "" + group: Network Configuration + schema: + type: dict + attrs: + - variable: hostNetwork + label: Host Network + description: | + Bind to the host network. While it's recommended to keep this disabled.
+ It's required for autodiscovery to work. + schema: + type: boolean + default: false + - variable: webPort + label: Web Port + description: The port for the Emby Web UI. + schema: + type: int + show_if: [["hostNetwork", "=", false]] + min: 9000 + max: 65535 + default: 9096 + required: true + + - variable: embyStorage + label: "" + group: Storage Configuration + schema: + type: dict + attrs: + - variable: config + label: Emby Config Storage + description: The path to store Emby Configuration. + schema: + type: dict + attrs: + - variable: type + label: Type + description: | + ixVolume: Is dataset created automatically by the system.
+ Host Path: Is a path that already exists on the system. + schema: + type: string + required: true + immutable: true + default: "ixVolume" + enum: + - value: "hostPath" + description: Host Path (Path that already exists on the system) + - value: "ixVolume" + description: ixVolume (Dataset created automatically by the system) + - variable: ixVolumeConfig + label: ixVolume Configuration + description: The configuration for the ixVolume dataset. + schema: + type: dict + show_if: [["type", "=", "ixVolume"]] + $ref: + - "normalize/ixVolume" + attrs: + - variable: aclEnable + label: Enable ACL + description: Enable ACL for the dataset. + schema: + type: boolean + default: false + - variable: datasetName + label: Dataset Name + description: The name of the dataset to use for storage. + schema: + type: string + required: true + immutable: true + hidden: true + default: "config" + - variable: aclEntries + label: ACL Configuration + schema: + type: dict + show_if: [["aclEnable", "=", true]] + attrs: [] + - variable: hostPathConfig + label: Host Path Configuration + schema: + type: dict + show_if: [["type", "=", "hostPath"]] + attrs: + - variable: aclEnable + label: Enable ACL + description: Enable ACL for the dataset. + schema: + type: boolean + default: false + - variable: acl + label: ACL Configuration + schema: + type: dict + show_if: [["aclEnable", "=", true]] + attrs: [] + $ref: + - "normalize/acl" + - variable: hostPath + label: Host Path + description: The host path to use for storage. + schema: + type: hostpath + show_if: [["aclEnable", "=", false]] + required: true + + - variable: additionalStorages + label: Additional Storage + description: Additional storage for Emby. + schema: + type: list + default: [] + items: + - variable: storageEntry + label: Storage Entry + schema: + type: dict + attrs: + - variable: type + label: Type + description: | + ixVolume: Is dataset created automatically by the system.
+ Host Path: Is a path that already exists on the system.
+ SMB Share: Is a SMB share that is mounted to a persistent volume claim. + schema: + type: string + required: true + default: "ixVolume" + immutable: true + enum: + - value: "hostPath" + description: Host Path (Path that already exists on the system) + - value: "ixVolume" + description: ixVolume (Dataset created automatically by the system) + - value: "smb-pv-pvc" + description: SMB Share (Mounts a persistent volume claim to a SMB share) + - variable: readOnly + label: Read Only + description: Mount the volume as read only. + schema: + type: boolean + default: false + - variable: mountPath + label: Mount Path + description: The path inside the container to mount the storage. + schema: + type: path + required: true + - variable: hostPathConfig + label: Host Path Configuration + schema: + type: dict + show_if: [["type", "=", "hostPath"]] + attrs: + - variable: aclEnable + label: Enable ACL + description: Enable ACL for the dataset. + schema: + type: boolean + default: false + - variable: acl + label: ACL Configuration + schema: + type: dict + show_if: [["aclEnable", "=", true]] + attrs: [] + $ref: + - "normalize/acl" + - variable: hostPath + label: Host Path + description: The host path to use for storage. + schema: + type: hostpath + show_if: [["aclEnable", "=", false]] + required: true + - variable: ixVolumeConfig + label: ixVolume Configuration + description: The configuration for the ixVolume dataset. + schema: + type: dict + show_if: [["type", "=", "ixVolume"]] + $ref: + - "normalize/ixVolume" + attrs: + - variable: aclEnable + label: Enable ACL + description: Enable ACL for the dataset. + schema: + type: boolean + default: false + - variable: datasetName + label: Dataset Name + description: The name of the dataset to use for storage. + schema: + type: string + required: true + immutable: true + default: "storage_entry" + - variable: aclEntries + label: ACL Configuration + schema: + type: dict + show_if: [["aclEnable", "=", true]] + attrs: [] + - variable: smbConfig + label: SMB Share Configuration + description: The configuration for the SMB Share. + schema: + type: dict + show_if: [["type", "=", "smb-pv-pvc"]] + attrs: + - variable: server + label: Server + description: The server for the SMB share. + schema: + type: string + required: true + - variable: share + label: Share + description: The share name for the SMB share. + schema: + type: string + required: true + - variable: domain + label: Domain (Optional) + description: The domain for the SMB share. + schema: + type: string + - variable: username + label: Username + description: The username for the SMB share. + schema: + type: string + required: true + - variable: password + label: Password + description: The password for the SMB share. + schema: + type: string + required: true + private: true + - variable: size + label: Size (in Gi) + description: The size of the volume quota. + schema: + type: int + required: true + min: 1 + default: 1 + + - variable: resources + group: Resources Configuration + label: "" + schema: + type: dict + attrs: + - variable: limits + label: Limits + schema: + type: dict + attrs: + - variable: cpu + label: CPU + description: CPU limit for Emby. + schema: + type: string + max_length: 6 + valid_chars: '^(0\.[1-9]|[1-9][0-9]*)(\.[0-9]|m?)$' + valid_chars_error: | + Valid CPU limit formats are
+ - Plain Integer - eg. 1
+ - Float - eg. 0.5
+ - Milicpu - eg. 500m + default: "4000m" + required: true + - variable: memory + label: Memory + description: Memory limit for Emby. + schema: + type: string + max_length: 12 + valid_chars: '^[1-9][0-9]*([EPTGMK]i?|e[0-9]+)?$' + valid_chars_error: | + Valid Memory limit formats are
+ - Suffixed with E/P/T/G/M/K - eg. 1G
+ - Suffixed with Ei/Pi/Ti/Gi/Mi/Ki - eg. 1Gi
+ - Plain Integer in bytes - eg. 1024
+ - Exponent - eg. 134e6 + default: "8Gi" + required: true + + - variable: embyGPU + group: Resources Configuration + label: GPU Configuration + schema: + type: dict + $ref: + - "definitions/gpuConfiguration" + attrs: [] diff --git a/charts/emby/2.0.0/templates/NOTES.txt b/charts/emby/2.0.0/templates/NOTES.txt new file mode 100644 index 0000000000..ba4e01146c --- /dev/null +++ b/charts/emby/2.0.0/templates/NOTES.txt @@ -0,0 +1 @@ +{{ include "ix.v1.common.lib.chart.notes" $ }} diff --git a/charts/emby/2.0.0/templates/_emby.tpl b/charts/emby/2.0.0/templates/_emby.tpl new file mode 100644 index 0000000000..96a37f9800 --- /dev/null +++ b/charts/emby/2.0.0/templates/_emby.tpl @@ -0,0 +1,64 @@ +{{- define "emby.workload" -}} +workload: + emby: + enabled: true + primary: true + type: Deployment + podSpec: + hostNetwork: {{ .Values.embyNetwork.hostNetwork }} + securityContext: + fsGroup: {{ .Values.embyID.group }} + containers: + emby: + enabled: true + primary: true + imageSelector: image + securityContext: + runAsUser: 0 + runAsGroup: 0 + runAsNonRoot: false + readOnlyRootFilesystem: false + capabilities: + add: + - CHOWN + - DAC_OVERRIDE + - FOWNER + - SETGID + - SETUID + fixedEnv: + PUID: {{ .Values.embyID.user }} + {{ with .Values.embyConfig.additionalEnvs }} + envList: + {{ range $env := . }} + - name: {{ $env.name }} + value: {{ $env.value }} + {{ end }} + {{ end }} + probes: + liveness: + enabled: true + type: http + path: /emby/System/Ping + port: 8096 + readiness: + enabled: true + type: http + path: /emby/System/Ping + port: 8096 + startup: + enabled: true + type: http + path: /emby/System/Ping + port: 8096 + +{{ with .Values.embyGPU }} +scaleGPU: + {{ range $key, $value := . }} + - gpu: + {{ $key }}: {{ $value }} + targetSelector: + emby: + - emby + {{ end }} +{{ end }} +{{- end -}} diff --git a/charts/emby/2.0.0/templates/_migration.tpl b/charts/emby/2.0.0/templates/_migration.tpl new file mode 100644 index 0000000000..d3300a3e83 --- /dev/null +++ b/charts/emby/2.0.0/templates/_migration.tpl @@ -0,0 +1,35 @@ +{{- define "emby.get-versions" -}} + {{- $oldChartVersion := "" -}} + {{- $newChartVersion := "" -}} + + {{/* Safely access the context, so it wont block CI */}} + {{- if hasKey .Values.global "ixChartContext" -}} + {{- if .Values.global.ixChartContext.upgradeMetadata -}} + + {{- $oldChartVersion = .Values.global.ixChartContext.upgradeMetadata.oldChartVersion -}} + {{- $newChartVersion = .Values.global.ixChartContext.upgradeMetadata.newChartVersion -}} + {{- if and (not $oldChartVersion) (not $newChartVersion) -}} + {{- fail "Upgrade Metadata is missing. Cannot proceed" -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- toYaml (dict "old" $oldChartVersion "new" $newChartVersion) -}} +{{- end -}} + +{{- define "emby.migration" -}} + {{- $versions := (fromYaml (include "emby.get-versions" $)) -}} + {{- if and $versions.old $versions.new -}} + {{- $oldV := semver $versions.old -}} + {{- $newV := semver $versions.new -}} + + {{/* If new is v2.x.x */}} + {{- if eq ($newV.Major | int) 2 -}} + {{/* And old is v1.x.x, but lower than .30 */}} + {{- if and (eq $oldV.Major 1) (lt ($oldV.Patch | int) 30) -}} + {{/* Block the upgrade */}} + {{- fail "Migration to 2.x.x is only allowed from 1.0.30 or higher" -}} + {{- end -}} + {{- end -}} + {{- end -}} +{{- end -}} diff --git a/charts/emby/2.0.0/templates/_persistance.tpl b/charts/emby/2.0.0/templates/_persistance.tpl new file mode 100644 index 0000000000..3e2ecfe0e6 --- /dev/null +++ b/charts/emby/2.0.0/templates/_persistance.tpl @@ -0,0 +1,26 @@ +{{- define "emby.persistence" -}} +persistence: + config: + enabled: true + {{- include "ix.v1.common.app.storageOptions" (dict "storage" .Values.embyStorage.config) | nindent 4 }} + targetSelector: + emby: + emby: + mountPath: /config + tmp: + enabled: true + type: emptyDir + targetSelector: + emby: + emby: + mountPath: /tmp + {{- range $idx, $storage := .Values.embyStorage.additionalStorages }} + {{ printf "emby-%v:" (int $idx) }} + enabled: true + {{- include "ix.v1.common.app.storageOptions" (dict "storage" $storage) | nindent 4 }} + targetSelector: + emby: + emby: + mountPath: {{ $storage.mountPath }} + {{- end }} +{{- end -}} diff --git a/charts/emby/2.0.0/templates/_portal.tpl b/charts/emby/2.0.0/templates/_portal.tpl new file mode 100644 index 0000000000..edaad0a5fc --- /dev/null +++ b/charts/emby/2.0.0/templates/_portal.tpl @@ -0,0 +1,16 @@ +{{- define "emby.portal" -}} +{{- $port := .Values.embyNetwork.webPort -}} +{{- if .Values.embyNetwork.hostNetwork -}} + {{- $port = 8096 -}} +{{- end }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: portal +data: + port: {{ $port | quote }} + path: "/" + protocol: "http" + host: $node_ip +{{- end -}} diff --git a/charts/emby/2.0.0/templates/_service.tpl b/charts/emby/2.0.0/templates/_service.tpl new file mode 100644 index 0000000000..f6972e0f43 --- /dev/null +++ b/charts/emby/2.0.0/templates/_service.tpl @@ -0,0 +1,35 @@ +{{- define "emby.service" -}} +service: + emby: + enabled: true + primary: true + type: NodePort + targetSelector: emby + ports: + webui: + enabled: true + primary: true + port: {{ .Values.embyNetwork.webPort }} + nodePort: {{ .Values.embyNetwork.webPort }} + targetPort: 8096 + targetSelector: emby + discovery: + enabled: true + # This service is added only to provide + # a way for in-cluster apps to discovery emby + # For LAN discovery, host networking is required + type: ClusterIP + targetSelector: emby + ports: + dlna: + enabled: true + primary: true + port: 1900 + targetPort: 1900 + targetSelector: emby + local-discovery: + enabled: true + port: 7359 + targetPort: 7359 + targetSelector: emby +{{- end -}} diff --git a/charts/emby/2.0.0/templates/common.yaml b/charts/emby/2.0.0/templates/common.yaml new file mode 100644 index 0000000000..bf5fc4eccd --- /dev/null +++ b/charts/emby/2.0.0/templates/common.yaml @@ -0,0 +1,13 @@ +{{- include "ix.v1.common.loader.init" . -}} + +{{- include "emby.migration" $ -}} + +{{/* Merge the templates with Values */}} +{{- $_ := mustMergeOverwrite .Values (include "emby.workload" $ | fromYaml) -}} +{{- $_ := mustMergeOverwrite .Values (include "emby.service" $ | fromYaml) -}} +{{- $_ := mustMergeOverwrite .Values (include "emby.persistence" $ | fromYaml) -}} + +{{/* Create the configmap for portal manually*/}} +{{- include "emby.portal" $ -}} + +{{- include "ix.v1.common.loader.apply" . -}} diff --git a/charts/emby/2.0.0/to_keep_versions.md b/charts/emby/2.0.0/to_keep_versions.md new file mode 100644 index 0000000000..1f40b08e8b --- /dev/null +++ b/charts/emby/2.0.0/to_keep_versions.md @@ -0,0 +1,4 @@ +# 1.0.30 + +This version is kept because it contains a fix that is needed for migration to v2.x.x +It should be safe to remove few months after v2.x.x is released.