Przeglądaj źródła

photoprism - migrate library (#2163)

* photoprism - migrate library

* update templates

* perms

* remove old deploy

* update ui

* add migration

* run as root and drop privs post start to keep backwards comp

* no need to fix perms now it runs as root

* update migration

* fix typo
Stavros Kois 1 rok temu
rodzic
commit
2719c2d6b1
25 zmienionych plików z 876 dodań i 443 usunięć
  1. 4 4
      library/ix-dev/charts/photoprism/Chart.lock
  2. 3 3
      library/ix-dev/charts/photoprism/Chart.yaml
  3. 2 2
      library/ix-dev/charts/photoprism/README.md
  4. 2 2
      library/ix-dev/charts/photoprism/app-readme.md
  5. BIN
      library/ix-dev/charts/photoprism/charts/common-1.2.9.tgz
  6. BIN
      library/ix-dev/charts/photoprism/charts/common-2304.0.1.tgz
  7. 17 0
      library/ix-dev/charts/photoprism/ci/basic-values.yaml
  8. 13 0
      library/ix-dev/charts/photoprism/ci/pass-values.yaml
  9. 0 21
      library/ix-dev/charts/photoprism/ci/test-values.yaml
  10. 5 21
      library/ix-dev/charts/photoprism/metadata.yaml
  11. 98 0
      library/ix-dev/charts/photoprism/migrations/migrate
  12. 503 225
      library/ix-dev/charts/photoprism/questions.yaml
  13. 1 0
      library/ix-dev/charts/photoprism/templates/NOTES.txt
  14. 35 0
      library/ix-dev/charts/photoprism/templates/_migration.tpl
  15. 40 0
      library/ix-dev/charts/photoprism/templates/_persistance.tpl
  16. 74 0
      library/ix-dev/charts/photoprism/templates/_photoprism.tpl
  17. 12 0
      library/ix-dev/charts/photoprism/templates/_portal.tpl
  18. 15 0
      library/ix-dev/charts/photoprism/templates/_service.tpl
  19. 13 0
      library/ix-dev/charts/photoprism/templates/common.yaml
  20. 0 93
      library/ix-dev/charts/photoprism/templates/deployment.yaml
  21. 0 34
      library/ix-dev/charts/photoprism/templates/pre-install-job.yaml
  22. 0 8
      library/ix-dev/charts/photoprism/templates/secret.yaml
  23. 0 9
      library/ix-dev/charts/photoprism/templates/service.yaml
  24. 0 21
      library/ix-dev/charts/photoprism/templates/tests/deployment-check.yaml
  25. 39 0
      library/ix-dev/charts/photoprism/values.yaml

+ 4 - 4
library/ix-dev/charts/photoprism/Chart.lock

@@ -1,6 +1,6 @@
 dependencies:
 - name: common
-  repository: file://../../../common/2304.0.1
-  version: 2304.0.1
-digest: sha256:1ed155c6760e1166e2cb75b52bc5e81c6bdf0252c16ff5ede001157077c41670
-generated: "2023-04-24T13:40:53.604174144+03:00"
+  repository: file://../../../common
+  version: 1.2.9
+digest: sha256:af1a9a1f87e3e48453c9f25f909f5ebcd7fa6e25162b7b425448ba752bcdbc5c
+generated: "2024-02-12T15:40:23.281898434+02:00"

+ 3 - 3
library/ix-dev/charts/photoprism/Chart.yaml

@@ -3,7 +3,7 @@ description: AI-powered app for browsing, organizing & sharing your photo collec
 annotations:
   title: PhotoPrism
 type: application
-version: 1.1.2
+version: 2.0.0
 apiVersion: v2
 appVersion: '231128'
 kubeVersion: '>=1.16.0-0'
@@ -13,8 +13,8 @@ maintainers:
     email: dev@ixsystems.com
 dependencies:
   - name: common
-    repository: file://../../../common/2304.0.1
-    version: 2304.0.1
+    repository: file://../../../common
+    version: 1.2.9
 home: https://photoprism.app/
 icon: https://media.sys.truenas.net/apps/photoprism/icons/icon.svg
 sources:

+ 2 - 2
library/ix-dev/charts/photoprism/README.md

@@ -1,3 +1,3 @@
-# Photo Prism
+# PhotoPrism
 
-PhotoPrism is a server-based application for browsing, organizing and sharing your personal photo collection.
+[PhotoPrism](https://photoprism.app/) is a server-based application for browsing, organizing and sharing your personal photo collection.

+ 2 - 2
library/ix-dev/charts/photoprism/app-readme.md

@@ -1,3 +1,3 @@
-# Photo Prism
+# PhotoPrism
 
-PhotoPrism is a server-based application for browsing, organizing and sharing your personal photo collection.
+[PhotoPrism](https://photoprism.app/) is a server-based application for browsing, organizing and sharing your personal photo collection.

BIN
library/ix-dev/charts/photoprism/charts/common-1.2.9.tgz


BIN
library/ix-dev/charts/photoprism/charts/common-2304.0.1.tgz


+ 17 - 0
library/ix-dev/charts/photoprism/ci/basic-values.yaml

@@ -0,0 +1,17 @@
+photoprismNetwork:
+  webPort: 30489
+
+photoprismConfig:
+  public: true
+
+photoprismID:
+  user: 1000
+  group: 1000
+
+photoprismStorage:
+  import:
+    type: pvc
+  originals:
+    type: pvc
+  storage:
+    type: pvc

+ 13 - 0
library/ix-dev/charts/photoprism/ci/pass-values.yaml

@@ -0,0 +1,13 @@
+photoprismNetwork:
+  webPort: 30489
+
+photoprismConfig:
+  password: secret
+
+photoprismStorage:
+  import:
+    type: pvc
+  originals:
+    type: pvc
+  storage:
+    type: pvc

+ 0 - 21
library/ix-dev/charts/photoprism/ci/test-values.yaml

@@ -1,21 +0,0 @@
-appVolumeMounts:
-  import:
-    emptyDir: true
-    mountPath: /photoprism/import
-  original:
-    emptyDir: true
-    mountPath: /photoprism/originals
-  storage:
-    emptyDir: true
-    mountPath: /photoprism/storage
-dnsConfig:
-  options: []
-emptyDirVolumes: true
-environmentVariables: []
-extraAppVolumeMounts: []
-ownerGID: 568
-ownerUID: 568
-password: admin123
-public: false
-web_port: 32000
-global: {}

+ 5 - 21
library/ix-dev/charts/photoprism/metadata.yaml

@@ -1,36 +1,20 @@
 runAsContext:
-  - userName: root
-    groupName: root
+  - userName: photoprism
+    groupName: photoprism
     gid: 0
     uid: 0
-    description: Photoprism runs as root user.
+    description: Photoprism run as a root user.
 capabilities:
   - name: CHOWN
     description: Photoprism is able to chown files.
   - name: FOWNER
     description: Photoprism is able to bypass permission checks for it's sub-processes.
-  - name: SYS_CHROOT
-    description: Photoprism is able to use chroot.
-  - name: MKNOD
-    description: Photoprism is able to create device nodes.
   - name: DAC_OVERRIDE
     description: Photoprism is able to bypass permission checks.
-  - name: FSETID
-    description: Photoprism is able to set file capabilities.
-  - name: KILL
-    description: Photoprism is able to kill processes.
   - name: SETGID
     description: Photoprism is able to set group ID for it's sub-processes.
   - name: SETUID
     description: Photoprism is able to set user ID for it's sub-processes.
-  - name: SETPCAP
-    description: Photoprism is able to set process capabilities.
-  - name: NET_BIND_SERVICE
-    description: Photoprism is able to bind to privileged ports.
-  - name: SETFCAP
-    description: Photoprism is able to set file capabilities.
-  - name: NET_RAW
-    description: Photoprism is able to use raw sockets.
-  - name: AUDIT_WRITE
-    description: Photoprism is able to write to audit log.
+  - name: KILL
+    description: Photoprism is able to kill processes.
 hostMounts: []

+ 98 - 0
library/ix-dev/charts/photoprism/migrations/migrate

@@ -0,0 +1,98 @@
+#!/usr/bin/python3
+import json
+import os
+import sys
+
+def migrate_volume(volume):
+    return {
+        'type': 'hostPath',
+        'readOnly': volume.get('readOnly', False),
+        'hostPathConfig': {
+            'hostPath': volume['hostPath']
+        },
+    } if volume.get('hostPathEnabled', False) else {
+        'type': 'ixVolume',
+        'readOnly': volume.get('readOnly', False),
+        'ixVolumeConfig': {
+            'datasetName': volume['datasetName'],
+        },
+    }
+
+def migrate_common_lib(values):
+    delete_keys = [
+        'memLimit', 'cpuLimit', 'enableResourceLimits', 'extraAppVolumeMounts',
+        'password', 'public', 'ownerUID', 'ownerGID', 'dnsConfig', 'environmentVariables',
+        'web_port', 'host_network', 'appVolumeMounts', 'gpuConfiguration'
+    ]
+
+    values.update({
+        # Migrate Network
+        'photoprismNetwork': {
+            'webPort': values['web_port'],
+            'hostNetwork': values['host_network'],
+        },
+        # Migrate Resources
+        'resources': {
+            'limits': {
+                'cpu': values.get('cpuLimit', '4000m'),
+                'memory': values.get('memLimit', '8Gi'),
+            }
+        },
+        'photoprismGPU': values.get('gpuConfiguration', {}),
+        # Migrate DNS
+        'podOptions': {
+            'dnsConfig': {
+                'options': [
+                    {'name': opt['name'], 'value': opt['value']}
+                    for opt in values.get('dnsConfig', {}).get('options', [])
+                ]
+            }
+        },
+        # Migrate run context
+        'photoprismID': {
+            'user': values['ownerUID'],
+            'group': values['ownerGID'],
+        },
+        # Migrate Config
+        'photoprismConfig': {
+            'public': values['public'],
+            'password': values.get('password', ''),
+            'additionalEnvs': values.get('environmentVariables', []),
+        },
+        # Migrate Storage
+        'photoprismStorage': {
+            'import': migrate_volume(values['appVolumeMounts']['import']),
+            'storage': migrate_volume(values['appVolumeMounts']['storage']),
+            'originals': migrate_volume(values['appVolumeMounts']['original']),
+            'additionalStorages': [
+                {
+                    'type': 'hostPath',
+                    'hostPathConfig': {'hostPath': e['hostPath']},
+                    'mountPath': e['mountPath'],
+                    'readOnly': e.get('readOnly', False),
+                }
+                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()))))

+ 503 - 225
library/ix-dev/charts/photoprism/questions.yaml

@@ -1,315 +1,593 @@
 groups:
-  - name: "Configuration"
-    description: "Photo Prism application configuration"
-  - name: "Storage"
-    description: "Configure storage for photo prism"
-  - name: "Networking"
-    description: "Networking Configuration for photo prism"
-  - name: "Advanced DNS Settings"
-    description: "Configure DNS settings"
-  - name: "Resource Reservation"
-    description: "Specify resources to be allocated to workload"
-  - name: "Resource Limits"
-    description: "Set CPU/memory limits for Kubernetes Pod"
+  - name: Photoprism Configuration
+    description: Configure Photoprism
+  - name: User and Group Configuration
+    description: Configure User and Group for Photoprism
+  - name: Advanced Pod Configuration
+    description: Configure Advanced Pod Options for Photoprism
+  - name: Network Configuration
+    description: Configure Network for Photoprism
+  - name: Storage Configuration
+    description: Configure Storage for Photoprism
+  - name: Resources Configuration
+    description: Configure Resources for Photoprism
 
 portals:
   web_portal:
     protocols:
-      - "http"
+      - "$kubernetes-resource_configmap_portal_protocol"
     host:
-      - "$node_ip"
+      - "$kubernetes-resource_configmap_portal_host"
     ports:
-      - "$variable-web_port"
-    path: "/"
+      - "$kubernetes-resource_configmap_portal_port"
+    path: "$kubernetes-resource_configmap_portal_path"
 
 questions:
-  - variable: host_network
-    group: Networking
-    label: Host Network
-    description: |
-      Bind to the host network. It's recommended to keep this disabled but may be needed for photoprism to be reachable from a hostNetworked VPN.</br>
-    schema:
-      type: boolean
-      default: false
-
-  - variable: web_port
-    label: "Web Port for photo prism"
-    group: Networking
-    schema:
-      type: int
-      min: 8000
-      max: 65535
-      default: 20800
-      required: true
-
-  - variable: dnsConfig
-    label: "DNS Configuration"
-    group: "Advanced DNS Settings"
+  - variable: photoprismConfig
+    label: ""
+    group: Photoprism Configuration
     schema:
       type: dict
       attrs:
-        - variable: options
-          label: "DNS Options"
+        - variable: public
+          label: Public
+          description: |
+            Enable public access to Photoprism.</br>
+            If enabled, Photoprism will be accessible without authentication.
+          schema:
+            type: boolean
+            default: false
+        - variable: password
+          label: Password
+          description: |
+            Set a password for Photoprism.</br>
+            If public access is enabled, a password is required.
+          schema:
+            type: string
+            default: ""
+            required: true
+            show_if: [["public", "=", false]]
+            private: true
+        - variable: additionalEnvs
+          label: Additional Environment Variables
+          description: Configure additional environment variables for Photoprism.
           schema:
             type: list
+            default: []
             items:
-              - variable: optionsEntry
-                label: "Option Entry Configuration"
+              - variable: env
+                label: Environment Variable
                 schema:
                   type: dict
                   attrs:
                     - variable: name
-                      label: "Option Name"
+                      label: Name
                       schema:
                         type: string
                         required: true
                     - variable: value
-                      label: "Option Value"
+                      label: Value
                       schema:
                         type: string
                         required: true
 
-  - variable: ownerUID
-    label: "Storage User ID"
-    description: "User ID of the storage volume being used (application will chown the storage volume path with specified UID)"
-    group: Configuration
-    schema:
-      type: int
-      default: 568
-      min: 1
-      max: 65535
-
-  - variable: ownerGID
-    label: "Storage Group ID"
-    description: "Group ID of the storage volume being used (application will chown the storage volume path with specified GID)"
-    group: Configuration
+  - variable: photoprismID
+    label: ""
+    group: User and Group Configuration
     schema:
-      type: int
-      default: 568
-      min: 1
-      max: 65535
-
-  - variable: password
-    label: "Password"
-    group: "Configuration"
-    schema:
-      type: string
-      private: true
-      required: true
-      empty: false
-      immutable: true
-      default: "admin123"
-      show_if: [["public", "=", false]]
-
-  - variable: public
-    label: "Enable Public Access"
-    description: "Disable password authentication, WebDAV, and the advanced settings page"
-    group: "Configuration"
-    schema:
-      type: boolean
-      default: false
+      type: dict
+      attrs:
+        - variable: user
+          label: User ID
+          description: The user id that Photoprism files will be owned by.
+          schema:
+            type: int
+            min: 568
+            default: 568
+            required: true
+        - variable: group
+          label: Group ID
+          description: The group id that Photoprism files will be owned by.
+          schema:
+            type: int
+            min: 568
+            default: 568
+            required: true
 
-  - variable: environmentVariables
-    label: "Photo Prism environment"
-    group: "Configuration"
+  - variable: podOptions
+    label: ""
+    group: Advanced Pod Configuration
     schema:
-      type: list
-      default: []
-      items:
-        - variable: environmentVariable
-          label: "Environment Variable"
+      type: dict
+      attrs:
+        - variable: dnsConfig
+          label: Advanced DNS Configuration
           schema:
             type: dict
             attrs:
-              - variable: name
-                label: "Name"
+              - variable: options
+                label: DNS Options
                 schema:
-                  type: string
-              - variable: value
-                label: "Value"
-                schema:
-                  type: string
+                  type: list
+                  items:
+                    - variable: optionsEntry
+                      label: DNS Option Entry
+                      schema:
+                        type: dict
+                        attrs:
+                          - variable: name
+                            label: Option Name
+                            schema:
+                              type: string
+                              required: true
+                          - variable: value
+                            label: Option Value
+                            schema:
+                              type: string
+                              required: true
 
-  - variable: appVolumeMounts
-    label: "Photo Prism Storage"
-    group: "Storage"
+  - variable: photoprismNetwork
+    label: ""
+    group: Network Configuration
     schema:
       type: dict
       attrs:
-        - variable: original
-          label: "Storage Volume for Original Media"
+        - variable: webPort
+          label: WebUI Port
+          description: The port for Photoprism WebUI
+          schema:
+            type: int
+            default: 20800
+            min: 9000
+            max: 65535
+            required: true
+        - variable: hostNetwork
+          label: Host Network
+          description: |
+            Bind to the host network. It's recommended to keep this disabled.
+          schema:
+            type: boolean
+            default: false
+
+  - variable: photoprismStorage
+    label: ""
+    group: Storage Configuration
+    schema:
+      type: dict
+      attrs:
+        - variable: import
+          label: Photoprism Import Storage
+          description: The path to store Photoprism Import.
           schema:
             type: dict
             attrs:
-              - variable: datasetName
-                label: "Original Storage Volume Dataset Name"
+              - variable: type
+                label: Type
+                description: |
+                  ixVolume: Is dataset created automatically by the system.</br>
+                  Host Path: Is a path that already exists on the system.
                 schema:
                   type: string
-                  hidden: true
+                  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"
-                  show_if: [["hostPathEnabled", "=", false]]
-                  default: "ix-photoprism_original"
-                  editable: false
-              - variable: mountPath
-                label: "Original Storage Mount Path"
-                description: "Path where the volume will be mounted inside the pod"
-                schema:
-                  type: path
-                  hidden: true
-                  editable: true
-                  default: "/photoprism/originals"
-              - variable: readOnly
-                label: "Read Only"
-                description: "Mount volume as read only"
-                schema:
-                  type: boolean
-                  default: false
-              - variable: hostPathEnabled
-                label: "Enable Custom Host Path for Photo Prism Original Storage Volume"
+                  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: "import"
+                    - variable: aclEntries
+                      label: ACL Configuration
+                      schema:
+                        type: dict
+                        show_if: [["aclEnable", "=", true]]
+                        attrs: []
+              - variable: hostPathConfig
+                label: Host Path Configuration
                 schema:
-                  type: boolean
-                  default: false
-                  show_subquestions_if: true
-                  subquestions:
+                  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 for Photo Prism Original Storage Volume"
+                      label: Host Path
+                      description: The host path to use for storage.
                       schema:
                         type: hostpath
+                        show_if: [["aclEnable", "=", false]]
                         required: true
         - variable: storage
-          label: "Storage Volume for sidecar/cache/database"
+          label: Photoprism Storage
+          description: The path to store Photoprism Storage.
           schema:
             type: dict
             attrs:
-              - variable: datasetName
-                label: "Storage Volume Dataset Name"
+              - variable: type
+                label: Type
+                description: |
+                  ixVolume: Is dataset created automatically by the system.</br>
+                  Host Path: Is a path that already exists on the system.
                 schema:
                   type: string
-                  hidden: true
+                  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"
-                  show_if: [["hostPathEnabled", "=", false]]
-                  default: "ix-photoprism_storage"
-                  editable: false
-              - variable: mountPath
-                label: "Storage Mount Path"
-                description: "Path where the volume will be mounted inside the pod"
-                schema:
-                  type: path
-                  hidden: true
-                  editable: true
-                  default: "/photoprism/storage"
-              - variable: hostPathEnabled
-                label: "Enable Custom Host Path for Photo Prism Storage Volume"
+                  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: "storage"
+                    - variable: aclEntries
+                      label: ACL Configuration
+                      schema:
+                        type: dict
+                        show_if: [["aclEnable", "=", true]]
+                        attrs: []
+              - variable: hostPathConfig
+                label: Host Path Configuration
                 schema:
-                  type: boolean
-                  default: false
-                  show_subquestions_if: true
-                  subquestions:
+                  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 for Photo Prism Storage Volume"
+                      label: Host Path
+                      description: The host path to use for storage.
                       schema:
                         type: hostpath
+                        show_if: [["aclEnable", "=", false]]
                         required: true
-        - variable: import
-          label: "Storage Volume for imports"
+        - variable: originals
+          label: Photoprism Originals Storage
+          description: The path to store Photoprism Originals.
           schema:
             type: dict
             attrs:
-              - variable: datasetName
-                label: "Import Storage Volume Dataset Name"
+              - variable: type
+                label: Type
+                description: |
+                  ixVolume: Is dataset created automatically by the system.</br>
+                  Host Path: Is a path that already exists on the system.</br>
                 schema:
                   type: string
-                  hidden: true
-                  $ref:
-                    - "normalize/ixVolume"
-                  show_if: [["hostPathEnabled", "=", false]]
-                  default: "ix-photoprism_import"
-                  editable: false
-              - variable: mountPath
-                label: "Storage Mount Path"
-                description: "Path where the volume will be mounted inside the pod"
-                schema:
-                  type: path
-                  hidden: true
-                  editable: true
-                  default: "/photoprism/import"
-              - variable: hostPathEnabled
-                label: "Enable Custom Host Path for Photo Prism Import Storage Volume"
+                  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)
+                    - value: "emptyDir"
+                      description: emptyDir (Temporary directory created on the disk or in memory)
+              - variable: readOnly
+                label: Read Only
+                description: Mount the volume as read only.
                 schema:
                   type: boolean
                   default: false
-                  show_subquestions_if: true
-                  subquestions:
+              - 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: "originals"
+                    - 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 for Photo Prism Import Storage Volume"
+                      label: Host Path
+                      description: The host path to use for storage.
                       schema:
                         type: hostpath
+                        show_if: [["aclEnable", "=", false]]
                         required: true
 
-  - variable: extraAppVolumeMounts
-    label: "Extra Host Path Volumes"
-    group: "Storage"
+        - variable: additionalStorages
+          label: Additional Storage
+          description: Additional storage for Photoprism.
+          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.</br>
+                        Host Path: Is a path that already exists on the system.</br>
+                        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
+    label: Resources Configuration
+    group: Resources Configuration
     schema:
-      type: list
-      items:
-        - variable: extraAppVolume
-          label: "Host Path Volume"
-          description: "Add an extra host path volume for Photo Prism application"
+      type: dict
+      attrs:
+        - variable: limits
+          label: Limits
           schema:
             type: dict
             attrs:
-              - variable: mountPath
-                label: "Mount Path in Pod"
-                description: "Path where the volume will be mounted inside the pod"
+              - variable: cpu
+                label: CPU
+                description: CPU limit for Photoprism.
                 schema:
-                  type: path
+                  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</br>
+                    - Plain Integer - eg. 1</br>
+                    - Float - eg. 0.5</br>
+                    - Milicpu - eg. 500m
+                  default: "4000m"
                   required: true
-              - variable: readOnly
-                label: "Read Only"
-                description: "Mount volume as read only"
-                schema:
-                  type: boolean
-                  default: false
-              - variable: hostPath
-                label: "Host Path"
-                description: "Host path"
+              - variable: memory
+                label: Memory
+                description: Memory limit for Photoprism.
                 schema:
-                  type: hostpath
+                  type: string
+                  max_length: 12
+                  valid_chars: '^[1-9][0-9]*([EPTGMK]i?|e[0-9]+)?$'
+                  valid_chars_error: |
+                    Valid Memory limit formats are</br>
+                    - Suffixed with E/P/T/G/M/K - eg. 1G</br>
+                    - Suffixed with Ei/Pi/Ti/Gi/Mi/Ki - eg. 1Gi</br>
+                    - Plain Integer in bytes - eg. 1024</br>
+                    - Exponent - eg. 134e6
+                  default: "8Gi"
                   required: true
 
-  # Specify GPU configuration
-  - variable: gpuConfiguration
-    label: "GPU Configuration"
-    group: "Resource Reservation"
+  - variable: photoprismGPU
+    group: Resources Configuration
+    label: GPU Configuration
     schema:
       type: dict
       $ref:
         - "definitions/gpuConfiguration"
       attrs: []
-
-  - variable: enableResourceLimits
-    label: "Enable Pod resource limits"
-    group: "Resource Limits"
-    schema:
-      type: boolean
-      default: false
-  - variable: cpuLimit
-    label: "CPU Limit"
-    description: "CPU resource limit allow  plain integer values with suffix m(milli) e.g 1000m, 100."
-    group: "Resource Limits"
-    schema:
-      type: string
-      show_if: [["enableResourceLimits", "=", true]]
-      valid_chars: "^\\d+(?:\\.\\d+(?!.*m$)|m?$)"
-      default: "4000m"
-  - variable: memLimit
-    label: "Memory Limit"
-    group: "Resource Limits"
-    description: "Memory limits is specified by number of bytes. Followed by quantity suffix like E,P,T,G,M,k and Ei,Pi,Ti,Mi,Gi,Ki can also be used. e.g 129e6, 129M,  128974848000m, 123Mi"
-    schema:
-      type: string
-      show_if: [["enableResourceLimits", "=", true]]
-      valid_chars: "^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$"
-      default: "8Gi"

+ 1 - 0
library/ix-dev/charts/photoprism/templates/NOTES.txt

@@ -0,0 +1 @@
+{{ include "ix.v1.common.lib.chart.notes" $ }}

+ 35 - 0
library/ix-dev/charts/photoprism/templates/_migration.tpl

@@ -0,0 +1,35 @@
+{{- define "photoprism.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 "photoprism.migration" -}}
+  {{- $versions := (fromYaml (include "photoprism.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 .1.3 */}}
+      {{- if and (eq $oldV.Major 1) (or (ne $oldV.Minor 1) (lt ($oldV.Patch | int) 3)) -}}
+        {{/* Block the upgrade */}}
+        {{- fail "Migration to 2.x.x is only allowed from 1.1.3 or higher" -}}
+      {{- end -}}
+    {{- end -}}
+  {{- end -}}
+{{- end -}}

+ 40 - 0
library/ix-dev/charts/photoprism/templates/_persistance.tpl

@@ -0,0 +1,40 @@
+{{- define "photoprism.persistence" -}}
+persistence:
+  import:
+    enabled: true
+    {{- include "ix.v1.common.app.storageOptions" (dict "storage" .Values.photoprismStorage.import) | nindent 4 }}
+    targetSelector:
+      photoprism:
+        photoprism:
+          mountPath: /photoprism/import
+  storage:
+    enabled: true
+    {{- include "ix.v1.common.app.storageOptions" (dict "storage" .Values.photoprismStorage.storage) | nindent 4 }}
+    targetSelector:
+      photoprism:
+        photoprism:
+          mountPath: /photoprism/storage
+  originals:
+    enabled: true
+    {{- include "ix.v1.common.app.storageOptions" (dict "storage" .Values.photoprismStorage.originals) | nindent 4 }}
+    targetSelector:
+      photoprism:
+        photoprism:
+          mountPath: /photoprism/originals
+  tmp:
+    enabled: true
+    type: emptyDir
+    targetSelector:
+      photoprism:
+        photoprism:
+          mountPath: /tmp
+  {{- range $idx, $storage := .Values.photoprismStorage.additionalStorages }}
+  {{ printf "ha-%v:" (int $idx) }}
+    enabled: true
+    {{- include "ix.v1.common.app.storageOptions" (dict "storage" $storage) | nindent 4 }}
+    targetSelector:
+      photoprism:
+        photoprism:
+          mountPath: {{ $storage.mountPath }}
+  {{- end }}
+{{- end -}}

+ 74 - 0
library/ix-dev/charts/photoprism/templates/_photoprism.tpl

@@ -0,0 +1,74 @@
+{{- define "photoprism.workload" -}}
+workload:
+  photoprism:
+    enabled: true
+    primary: true
+    type: Deployment
+    podSpec:
+      hostNetwork: {{ .Values.photoprismNetwork.hostNetwork }}
+      securityContext:
+        fsGroup: {{ .Values.photoprismID.group }}
+      containers:
+        photoprism:
+          enabled: true
+          primary: true
+          imageSelector: image
+          securityContext:
+            runAsUser: 0
+            runAsGroup: 0
+            runAsNonRoot: false
+            readOnlyRootFilesystem: false
+            capabilities:
+              add:
+                - CHOWN
+                - FOWNER
+                - DAC_OVERRIDE
+                - SETGID
+                - SETUID
+                - KILL
+          env:
+            PHOTOPRISM_HTTP_PORT: {{ .Values.photoprismNetwork.webPort }}
+            PHOTOPRISM_ADMIN_PASSWORD: {{ .Values.photoprismConfig.password }}
+            PHOTOPRISM_PUBLIC: {{ .Values.photoprismConfig.public }}
+            PHOTOPRISM_UID: {{ .Values.photoprismID.user }}
+            PHOTOPRISM_GID: {{ .Values.photoprismID.group }}
+            PHOTOPRISM_STORAGE_PATH: /photoprism/storage
+            PHOTOPRISM_ORIGINALS_PATH: /photoprism/originals
+            PHOTOPRISM_IMPORT_PATH: /photoprism/import
+          fixedEnv:
+            PUID: {{ .Values.photoprismID.user }}
+          {{ with .Values.photoprismConfig.additionalEnvs }}
+          envList:
+            {{ range $env := . }}
+            - name: {{ $env.name }}
+              value: {{ $env.value }}
+            {{ end }}
+          {{ end }}
+          probes:
+            liveness:
+              enabled: true
+              type: http
+              path: /
+              port: {{ .Values.photoprismNetwork.webPort }}
+            readiness:
+              enabled: true
+              type: http
+              path: /
+              port: {{ .Values.photoprismNetwork.webPort }}
+            startup:
+              enabled: true
+              type: http
+              path: /
+              port: {{ .Values.photoprismNetwork.webPort }}
+
+{{ with .Values.photoprismGPU }}
+scaleGPU:
+  {{ range $key, $value := . }}
+  - gpu:
+      {{ $key }}: {{ $value }}
+    targetSelector:
+      photoprism:
+        - photoprism
+  {{ end }}
+{{ end }}
+{{- end -}}

+ 12 - 0
library/ix-dev/charts/photoprism/templates/_portal.tpl

@@ -0,0 +1,12 @@
+{{- define "photoprism.portal" -}}
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: portal
+data:
+  port: {{ .Values.photoprismNetwork.webPort | quote }}
+  path: "/"
+  protocol: "http"
+  host: $node_ip
+{{- end -}}

+ 15 - 0
library/ix-dev/charts/photoprism/templates/_service.tpl

@@ -0,0 +1,15 @@
+{{- define "photoprism.service" -}}
+service:
+  photoprism:
+    enabled: true
+    primary: true
+    type: NodePort
+    targetSelector: photoprism
+    ports:
+      webui:
+        enabled: true
+        primary: true
+        port: {{ .Values.photoprismNetwork.webPort }}
+        nodePort: {{ .Values.photoprismNetwork.webPort }}
+        targetSelector: photoprism
+{{- end -}}

+ 13 - 0
library/ix-dev/charts/photoprism/templates/common.yaml

@@ -0,0 +1,13 @@
+{{- include "ix.v1.common.loader.init" . -}}
+
+{{- include "photoprism.migration" $ -}}
+
+{{/* Merge the templates with Values */}}
+{{- $_ := mustMergeOverwrite .Values (include "photoprism.workload" $ | fromYaml) -}}
+{{- $_ := mustMergeOverwrite .Values (include "photoprism.service" $ | fromYaml) -}}
+{{- $_ := mustMergeOverwrite .Values (include "photoprism.persistence" $ | fromYaml) -}}
+
+{{/* Create the configmap for portal manually*/}}
+{{- include "photoprism.portal" $ -}}
+
+{{- include "ix.v1.common.loader.apply" . -}}

+ 0 - 93
library/ix-dev/charts/photoprism/templates/deployment.yaml

@@ -1,93 +0,0 @@
-{{ include "common.storage.hostPathValidate" .Values }}
-apiVersion: {{ template "common.capabilities.deployment.apiVersion" . }}
-kind: Deployment
-metadata:
-  name: {{ template "common.names.fullname" . }}
-  labels:
-    app: {{ template "common.names.name" . }}
-    chart: {{ template "common.names.chart" . }}
-    release: {{ .Release.Name }}
-    heritage: {{ .Release.Service }}
-  annotations:
-    rollme: {{ randAlphaNum 5 | quote }}
-spec:
-  replicas: {{ (default 1 .Values.replicas) }}
-  strategy:
-    type: "Recreate"
-  selector:
-    matchLabels:
-      app: {{ template "common.names.name" . }}
-      release: {{ .Release.Name }}
-  template:
-    metadata:
-      name: {{ template "common.names.fullname" . }}
-      labels:
-        app: {{ template "common.names.name" . }}
-        release: {{ .Release.Name }}
-        {{- include "common.labels.selectorLabels" . | nindent 8 }}
-      annotations: {{ include "common.annotations" . | nindent 8 }}
-    spec:
-      hostNetwork: {{ .Values.host_network }}
-      {{- if hasKey .Values "global" }}
-        {{- if hasKey .Values.global "ixChartContext" }}
-          {{- if .Values.global.ixChartContext.addNvidiaRuntimeClass }}
-      runtimeClassName: {{ .Values.global.ixChartContext.nvidiaRuntimeClassName }}
-          {{- end }}
-        {{- end }}
-      {{- end }}
-      containers:
-        - name: {{ .Chart.Name }}
-          {{ include "common.resources.limitation" . | nindent 10 }}
-          {{ include "common.containers.imageConfig" .Values.image | nindent 10 }}
-          volumeMounts: {{ include "common.storage.configureAppVolumeMountsInContainer" .Values | nindent 12 }}
-          {{ range $index, $hostPathConfiguration := .Values.extraAppVolumeMounts }}
-            - name: extrappvolume-{{ $index }}
-              mountPath: {{ $hostPathConfiguration.mountPath }}
-              readOnly: {{ $hostPathConfiguration.readOnly | default false }}
-          {{ end }}
-          ports:
-            - name: web
-              containerPort: {{ .Values.web_port }}
-          readinessProbe:
-            httpGet:
-              path: /
-              port: {{ .Values.web_port }}
-            initialDelaySeconds: 10
-            periodSeconds: 10
-            timeoutSeconds: 5
-            failureThreshold: 5
-            successThreshold: 2
-          livenessProbe:
-            httpGet:
-              path: /
-              port: {{ .Values.web_port }}
-            initialDelaySeconds: 10
-            periodSeconds: 10
-            timeoutSeconds: 5
-            failureThreshold: 5
-            successThreshold: 1
-          startupProbe:
-            httpGet:
-              path: /
-              port: {{ .Values.web_port }}
-            initialDelaySeconds: 10
-            periodSeconds: 5
-            timeoutSeconds: 2
-            failureThreshold: 60
-            successThreshold: 1
-          env:
-            {{ $secretName := (include "common.names.fullname" .) }}
-            {{ $envList := (default list .Values.environmentVariables) }}
-            {{ $envList = mustAppend $envList (dict "name" "PHOTOPRISM_HTTP_PORT" "value" .Values.web_port) }}
-            {{ $envList = mustAppend $envList (dict "name" "PHOTOPRISM_ADMIN_PASSWORD" "valueFromSecret" true "secretName" $secretName "secretKey" "password") }}
-            {{ if .Values.public }}
-            {{ $envList = mustAppend $envList (dict "name" "PHOTOPRISM_PUBLIC" "value" "true") }}
-            {{ end }}
-            {{ include "common.containers.environmentVariables" (dict "environmentVariables" $envList) | nindent 12 }}
-{{ include "common.networking.dnsConfiguration" .Values | nindent 6 }}
-      volumes: {{ include "common.storage.configureAppVolumes" .Values | nindent 8 }}
-      {{ range $index, $hostPathConfiguration := .Values.extraAppVolumeMounts }}
-        - name: extrappvolume-{{ $index }}
-          hostPath:
-            path: {{ $hostPathConfiguration.hostPath }}
-      {{ end }}

+ 0 - 34
library/ix-dev/charts/photoprism/templates/pre-install-job.yaml

@@ -1,34 +0,0 @@
-apiVersion: batch/v1
-kind: Job
-metadata:
-  name: "{{ template "common.names.fullname" . }}-preinstall-job"
-  labels:
-    app.kubernetes.io/managed-by: {{ .Release.Service | quote }}
-    app.kubernetes.io/instance: {{ .Release.Name | quote }}
-    app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
-    helm.sh/chart: {{ template "common.names.chart" . }}
-  annotations:
-    "helm.sh/hook": pre-install
-    "helm.sh/hook-delete-policy": hook-succeeded
-spec:
-  template:
-    metadata:
-      name: "{{ template "common.names.fullname" . }}-preinstall-hook"
-      labels:
-        app.kubernetes.io/managed-by: {{ .Release.Service | quote }}
-        app.kubernetes.io/instance: {{ .Release.Name | quote }}
-        helm.sh/chart: {{ template "common.names.chart" . }}
-    spec:
-      restartPolicy: Never
-      containers:
-      - name: pre-install-job
-        image: "alpine:latest"
-        command:
-          - "chown"
-          - "-R"
-          - "{{ .Values.ownerUID }}:{{ .Values.ownerGID }}"
-          - "{{ .Values.appVolumeMounts.storage.mountPath }}"
-          - "{{ .Values.appVolumeMounts.original.mountPath }}"
-          - "{{ .Values.appVolumeMounts.import.mountPath }}"
-        volumeMounts: {{ include "common.storage.configureAppVolumeMountsInContainer" .Values | nindent 12 }}
-      volumes: {{ include "common.storage.configureAppVolumes" .Values | nindent 8 }}

+ 0 - 8
library/ix-dev/charts/photoprism/templates/secret.yaml

@@ -1,8 +0,0 @@
-apiVersion: v1
-kind: Secret
-metadata:
-  name: {{ template "common.names.fullname" . }}
-  labels: {{ include "common.labels" . | nindent 4 }}
-type: Opaque
-data:
-  password: {{ .Values.password | b64enc | quote }}

+ 0 - 9
library/ix-dev/charts/photoprism/templates/service.yaml

@@ -1,9 +0,0 @@
-{{ $selectors := list }}
-{{ $selectors = mustAppend $selectors (dict "key" "app" "value" (include "common.names.name" .) ) }}
-{{ $selectors = mustAppend $selectors (dict "key" "release" "value" .Release.Name ) }}
-{{ $ports := list }}
-{{ $ports = mustAppend $ports (dict "name" "web" "port" .Values.web_port "nodePort" .Values.web_port "targetPort" .Values.web_port) }}
-{{ $params := . }}
-{{ $_ := set $params "commonService" (dict "type" "NodePort" "ports" $ports ) }}
-{{ $_1 := set .Values "extraSelectorLabels" $selectors }}
-{{ include "common.classes.service" $params }}

+ 0 - 21
library/ix-dev/charts/photoprism/templates/tests/deployment-check.yaml

@@ -1,21 +0,0 @@
-{{- $serviceName := (include "common.names.fullname" .) -}}
-apiVersion: v1
-kind: Pod
-metadata:
-  name: {{ .Release.Name }}-photoprism
-  labels:
-    app: {{ .Release.Name }}
-    release: {{ .Release.Name }}
-  annotations:
-    "helm.sh/hook": test
-spec:
-    containers:
-      - name: test-curl
-        image: alpine/curl
-        imagePullPolicy: "IfNotPresent"
-        command:
-          - /bin/sh
-          - -ec
-          - |
-            curl --connect-timeout 5 --max-time 10 --retry 5 --retry-delay 15 --retry-max-time 90 --retry-all-errors -ksf http://{{ $serviceName }}:{{.Values.web_port}}/
-    restartPolicy: Never

+ 39 - 0
library/ix-dev/charts/photoprism/values.yaml

@@ -2,3 +2,42 @@ image:
   pullPolicy: IfNotPresent
   repository: photoprism/photoprism
   tag: '231128'
+
+resources:
+  limits:
+    cpu: 4000m
+    memory: 8Gi
+
+podOptions:
+  dnsConfig:
+    options: []
+
+photoprismConfig:
+  public: false
+  password: ''
+  additionalEnvs: []
+
+photoprismNetwork:
+  webPort: 20800
+  hostNetwork: false
+
+photoprismID:
+  user: 568
+  group: 568
+
+photoprismStorage:
+  import:
+    type: ixVolume
+    ixVolumeConfig:
+      datasetName: import
+  storage:
+    type: ixVolume
+    ixVolumeConfig:
+      datasetName: storage
+  originals:
+    type: ixVolume
+    ixVolumeConfig:
+      datasetName: originals
+  additionalStorages: []
+
+photoprismGPU: {}