Преглед изворни кода

NAS-121003 / 23.10 / Adapt charts CI and improve/fix common (#1011)

* Adapt charts CI and improve/fix common

* add check on permissions contaienr

* add postgres template

* update comments

* Update create_app.sh

* add check

* update script

* auto gen item.yaml from Chart,yaml

* rename readme on dest

* duplicate readme from the same source

* correct comment

* reoder

* remove extra space

* keep both README and app-readme

* update regex, to also allow 2 letter names, which is also valid

* No need to check host network if there aren't any pod values

* use same pattern as the pod.name label (not prepending release-name

* update deps

* add chart dirs to ci

* Add a validation to check if there is any yaml errors after merging files

* update charts path on ci

* common/1.0.0/ -> common/

* update common-test dep path

* temp update create_app script

* make permissions container name configurable, incase we want to change order of execution

* update naming convention

* fix typo and a missed name change

* do not allow `--` in names
Stavros Kois пре 2 година
родитељ
комит
929e60d801
100 измењених фајлова са 795 додато и 211 уклоњено
  1. 2 2
      .github/ct-install-config/chart_schema.yaml
  2. 15 0
      .github/ct-install-config/charts-ct-install.yaml
  3. 14 0
      .github/ct-install-config/charts-ct-lint.yaml
  4. 4 1
      .github/ct-install-config/common-ct-install.yaml
  5. 6 0
      .github/ct-install-config/common-ct-lint.yaml
  6. 124 0
      .github/workflows/charts_tests.yaml
  7. 13 29
      .github/workflows/common_library_tests.yaml
  8. 59 0
      create_app.sh
  9. 3 2
      library/common-test/Chart.yaml
  10. 1 0
      library/common-test/ci/cron-values.yaml
  11. 1 0
      library/common-test/ci/job-values.yaml
  12. 57 3
      library/common-test/tests/container/envFixed_test.yaml
  13. 26 5
      library/common-test/tests/container/image_test.yaml
  14. 34 41
      library/common-test/tests/container/resources_test.yaml
  15. 5 0
      library/common-test/tests/container/volumeMounts_test.yaml
  16. 1 0
      library/common-test/tests/cronjob/metadata_test.yaml
  17. 4 2
      library/common-test/tests/cronjob/spec_test.yaml
  18. 14 0
      library/common-test/tests/cronjob/validation_test.yaml
  19. 2 0
      library/common-test/tests/externalInterface/metadata_test.yaml
  20. 1 0
      library/common-test/tests/job/metadata_test.yaml
  21. 4 2
      library/common-test/tests/job/spec_test.yaml
  22. 15 4
      library/common-test/tests/job/validation_test.yaml
  23. 2 1
      library/common-test/tests/pod/image_pull_secret_test.yaml
  24. 4 1
      library/common-test/tests/pod/runtime_class_name_test.yaml
  25. 2 1
      library/common-test/tests/pod/service_account_name_test.yaml
  26. 47 8
      library/common-test/tests/pod/volume_ixVolume_test.yaml
  27. 2 2
      library/common-test/tests/service/metadata_test.yaml
  28. 50 0
      library/common-test/tests/service/node_port_test.yaml
  29. 4 2
      library/common-test/tests/workload/names_test.yaml
  30. 2 1
      library/common/Chart.yaml
  31. 0 0
      library/common/README.md
  32. 59 61
      library/common/docs/README.md
  33. 0 0
      library/common/docs/configmap.md
  34. 10 8
      library/common/docs/container/README.md
  35. 0 0
      library/common/docs/container/args.md
  36. 0 0
      library/common/docs/container/command.md
  37. 0 0
      library/common/docs/container/env.md
  38. 0 0
      library/common/docs/container/envFrom.md
  39. 0 0
      library/common/docs/container/envList.md
  40. 12 12
      library/common/docs/container/fixedEnv.md
  41. 0 0
      library/common/docs/container/lifecycle.md
  42. 0 0
      library/common/docs/container/probes.md
  43. 9 9
      library/common/docs/container/resources.md
  44. 7 0
      library/common/docs/container/securityContext.md
  45. 0 0
      library/common/docs/container/termination.md
  46. 0 0
      library/common/docs/imagePullSecret.md
  47. 0 0
      library/common/docs/notes.md
  48. 0 0
      library/common/docs/persistence/README.md
  49. 0 0
      library/common/docs/persistence/configmap.md
  50. 0 0
      library/common/docs/persistence/device.md
  51. 0 0
      library/common/docs/persistence/emptyDir.md
  52. 0 0
      library/common/docs/persistence/hostPath.md
  53. 0 0
      library/common/docs/persistence/ixVolume.md
  54. 0 0
      library/common/docs/persistence/secret.md
  55. 0 0
      library/common/docs/rbac.md
  56. 0 0
      library/common/docs/scaleCertificate.md
  57. 0 0
      library/common/docs/scaleExternalInterface.md
  58. 0 0
      library/common/docs/scaleGPU.md
  59. 0 0
      library/common/docs/secret.md
  60. 0 0
      library/common/docs/service/ClusterIP.md
  61. 0 0
      library/common/docs/service/NodePort.md
  62. 0 0
      library/common/docs/service/README.md
  63. 0 0
      library/common/docs/serviceAccount.md
  64. 0 0
      library/common/docs/workload/README.md
  65. 0 0
      library/common/docs/workload/cronjob.md
  66. 0 0
      library/common/docs/workload/deployment.md
  67. 0 0
      library/common/docs/workload/job.md
  68. 54 0
      library/common/templates/app_functions/_permissions.tpl
  69. 102 0
      library/common/templates/app_functions/_postgres.tpl
  70. 0 0
      library/common/templates/class/_configmap.tpl
  71. 0 0
      library/common/templates/class/_cronjob.tpl
  72. 0 0
      library/common/templates/class/_deployment.tpl
  73. 0 0
      library/common/templates/class/_job.tpl
  74. 0 0
      library/common/templates/class/_networkAttachmentDefinition.tpl
  75. 0 0
      library/common/templates/class/_rbac.tpl
  76. 0 0
      library/common/templates/class/_secret.tpl
  77. 10 9
      library/common/templates/class/_service.tpl
  78. 0 0
      library/common/templates/class/_serviceAccount.tpl
  79. 0 0
      library/common/templates/helpers/_envDupeCheck.tpl
  80. 0 0
      library/common/templates/helpers/_getPortRange.tpl
  81. 0 0
      library/common/templates/helpers/_getSelectedPod.tpl
  82. 0 0
      library/common/templates/lib/certificate/_getData.tpl
  83. 0 0
      library/common/templates/lib/certificate/_validation.tpl
  84. 1 1
      library/common/templates/lib/chart/_names.tpl
  85. 0 0
      library/common/templates/lib/chart/_notes.tpl
  86. 0 0
      library/common/templates/lib/configmap/_validation.tpl
  87. 0 0
      library/common/templates/lib/container/_args.tpl
  88. 0 0
      library/common/templates/lib/container/_command.tpl
  89. 0 0
      library/common/templates/lib/container/_env.tpl
  90. 0 0
      library/common/templates/lib/container/_envFrom.tpl
  91. 0 0
      library/common/templates/lib/container/_envList.tpl
  92. 8 3
      library/common/templates/lib/container/_fixedEnv.tpl
  93. 4 0
      library/common/templates/lib/container/_imageSelector.tpl
  94. 0 0
      library/common/templates/lib/container/_lifecycle.tpl
  95. 0 0
      library/common/templates/lib/container/_ports.tpl
  96. 0 0
      library/common/templates/lib/container/_primaryValidation.tpl
  97. 0 0
      library/common/templates/lib/container/_probes.tpl
  98. 1 1
      library/common/templates/lib/container/_resources.tpl
  99. 0 0
      library/common/templates/lib/container/_securityContext.tpl
  100. 0 0
      library/common/templates/lib/container/_termination.tpl

+ 2 - 2
.github/ct-install-config/chart_schema.yaml

@@ -1,5 +1,4 @@
 name: str(required=True)
-title: str(required=True)
 description: str(required=True)
 version: str(required=True)
 type: str(required=True)
@@ -17,7 +16,8 @@ condition: str(required=False)
 keywords: list(str(), required=False)
 tags: str(required=False)
 maintainers: list(include('maintainer'))
-annotations: map(str(), str(), required=False)
+annotations:
+  title: str(required=True)
 ---
 maintainer:
   name: str()

+ 15 - 0
.github/ct-install-config/charts-ct-install.yaml

@@ -0,0 +1,15 @@
+remote: origin
+target-branch: master
+helm-extra-args: --timeout 600s
+# This is too verbose, contains the rendered k8s objects
+# helm-extra-args: --timeout 600s --debug
+chart-yaml-schema: .github/ct-install-config/chart_schema.yaml
+debug: false
+# Also test upgrade on each app/ci-values
+upgrade: true
+chart-dirs:
+  - library/ix-dev/enterprise
+  - library/ix-dev/community
+excluded-charts:
+  - library/common-test
+  - library/common

+ 14 - 0
.github/ct-install-config/charts-ct-lint.yaml

@@ -0,0 +1,14 @@
+remote: origin
+target-branch: master
+helm-extra-args: --timeout 600s --debug
+lint-conf: .github/ct-install-config/lint-conf.yaml
+chart-yaml-schema: .github/ct-install-config/chart_schema.yaml
+# Check that the version in Chart.yaml is incremented
+check-version-increment: true
+debug: true
+chart-dirs:
+  - library/ix-dev/enterprise
+  - library/ix-dev/community
+excluded-charts:
+  - library/common-test
+  - library/common

+ 4 - 1
.github/ct-install-config/ct-install.yaml → .github/ct-install-config/common-ct-install.yaml

@@ -1,8 +1,11 @@
 remote: origin
 target-branch: master
+# Print helm debug output, contains the rendered k8s objects
 helm-extra-args: --timeout 600s --debug
 chart-yaml-schema: .github/ct-install-config/chart_schema.yaml
+debug: true
 chart-dirs:
   - library
-  - charts
+charts:
+  - library/common-test
 excluded-charts: []

+ 6 - 0
.github/ct-install-config/ct-lint.yaml → .github/ct-install-config/common-ct-lint.yaml

@@ -1,7 +1,13 @@
 remote: origin
 target-branch: master
 helm-extra-args: --timeout 600s --debug
+lint-conf: .github/ct-install-config/lint-conf.yaml
 chart-yaml-schema: .github/ct-install-config/chart_schema.yaml
+# Check that the version in Chart.yaml is incremented
+check-version-increment: true
+debug: true
 chart-dirs:
   - library
+charts:
+  - library/common-test
 excluded-charts: []

+ 124 - 0
.github/workflows/charts_tests.yaml

@@ -0,0 +1,124 @@
+name: Charts Tests
+
+on:
+  pull_request:
+    paths:
+      - library/**
+      - '!library/common'
+      - '!library/common-test'
+      - .github/ct-install-config/**
+      - '!.github/ct-install-config/common*'
+      - .github/workflows/charts_test.yaml
+
+jobs:
+  lint:
+    name: Lint Charts
+    runs-on: ubuntu-22.04
+    strategy:
+      fail-fast: false
+      matrix:
+        helm-version:
+          - v3.9.4
+          - v3.10.3
+          - v3.11.1
+    steps:
+      - name: Checkout
+        uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3
+        with:
+          # Depth 0 is required for chart-testing to work properly
+          fetch-depth: 0
+
+      - name: Install Helm
+        uses: azure/setup-helm@5119fcb9089d432beecbf79bb2c7915207344b78 # tag=v3
+        with:
+          version: ${{ matrix.helm-version }}
+
+      - uses: actions/setup-python@2c3dd9e7e29afd70cc0950079bde6c979d1f69f9 # tag=v4
+        with:
+          python-version: "3.10"
+
+      - name: Set up chart-testing
+        uses: helm/chart-testing-action@afea100a513515fbd68b0e72a7bb0ae34cb62aec # tag=v2.3.1
+
+      - name: Run chart-testing (lint)
+        id: lint
+        run: |
+          ct lint --config .github/ct-install-config/charts-ct-lint.yaml
+
+  install:
+    needs:
+      - lint
+    name: Install Charts
+    runs-on: ubuntu-22.04
+    strategy:
+      fail-fast: false
+      matrix:
+        # We run tests on k3s version of latest SCALE release, SCALE nightly and manually defined "latest"
+        k3s-version:
+          - v1.25.3+k3s1
+        # We run tests on Helm version of latest SCALE release, SCALE nightly and manually defined "latest"
+        helm-version:
+          - v3.9.4
+          - v3.11.1
+
+    steps:
+      - name: Checkout
+        uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3
+        with:
+          # Depth 0 is required for chart-testing to work properly
+          fetch-depth: 0
+
+      - name: Install Helm
+        uses: azure/setup-helm@f382f75448129b3be48f8121b9857be18d815a82 # tag=v3
+        with:
+          version: ${{ matrix.helm-version }}
+
+      - uses: actions/setup-python@2c3dd9e7e29afd70cc0950079bde6c979d1f69f9 # tag=v4
+        with:
+          python-version: "3.10"
+
+      - name: Set up chart-testing
+        uses: helm/chart-testing-action@afea100a513515fbd68b0e72a7bb0ae34cb62aec # tag=v2.3.1
+
+      - name: Create k3d cluster - Attempt 1/3
+        continue-on-error: true
+        id: createc1
+        uses: nolar/setup-k3d-k3s@293b8e5822a20bc0d5bcdd4826f1a665e72aba96 # tag=v1.0.9
+        with:
+          github-token: ${{ secrets.GITHUB_TOKEN }}
+          version: ${{ matrix.k3s-version }}
+          # Flags found here https://github.com/k3d-io/k3d
+          k3d-args: --k3s-arg --disable=metrics-server@server:*
+
+      - name: Wait 10 second to retry
+        if: steps.createc1.outcome=='failure'
+        run: |
+          sleep 10
+      - name: Create k3d cluster - Attempt 2/3
+        continue-on-error: true
+        if: steps.createc1.outcome=='failure'
+        id: createc2
+        uses: nolar/setup-k3d-k3s@293b8e5822a20bc0d5bcdd4826f1a665e72aba96 # tag=v1.0.9
+        with:
+          github-token: ${{ secrets.GITHUB_TOKEN }}
+          version: ${{ matrix.k3s-version }}
+          # Flags found here https://github.com/k3d-io/k3d
+          k3d-args: --k3s-arg --disable=metrics-server@server:*
+
+      - name: Wait 10 second to retry
+        if: steps.createc2.outcome=='failure'
+        run: |
+          sleep 10
+      - name: Create k3d cluster - Attempt 3/3
+        id: createc3
+        if: steps.createc2.outcome=='failure'
+        uses: nolar/setup-k3d-k3s@293b8e5822a20bc0d5bcdd4826f1a665e72aba96 # tag=v1.0.9
+        with:
+          github-token: ${{ secrets.GITHUB_TOKEN }}
+          version: ${{ matrix.k3s-version }}
+          # Flags found here https://github.com/k3d-io/k3d
+          k3d-args: --k3s-arg --disable=metrics-server@server:*
+
+      - name: Run chart-testing (install)
+        run: |
+          ct install --config .github/ct-install-config/charts-ct-install.yaml

+ 13 - 29
.github/workflows/common_library_tests.yaml

@@ -3,7 +3,10 @@ name: Common Library Tests
 on:
   pull_request:
     paths:
-      - library/**
+      - library/common/
+      - library/common-test/
+      - .github/ct-install-config/common*.yaml
+      - '!.github/ct-install-config/charts*'
       - .github/workflows/common_library_tests.yaml
 
 jobs:
@@ -21,7 +24,8 @@ jobs:
       - name: Checkout
         uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3
         with:
-          fetch-depth: 1
+          # Depth 0 is required for chart-testing to work properly
+          fetch-depth: 0
 
       - name: Install Helm
         uses: azure/setup-helm@5119fcb9089d432beecbf79bb2c7915207344b78 # tag=v3
@@ -38,10 +42,7 @@ jobs:
       - name: Run chart-testing (lint)
         id: lint
         run: |
-          ct lint --config .github/ct-install-config/ct-lint.yaml \
-                  --lint-conf .github/ct-install-config/lint-conf.yaml \
-                  --charts library/common-test \
-                  --debug
+          ct lint --config .github/ct-install-config/common-ct-lint.yaml
 
   unittest:
     needs:
@@ -61,7 +62,8 @@ jobs:
       - name: Checkout
         uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3
         with:
-          fetch-depth: 1
+          # Depth 0 is required for chart-testing to work properly
+          fetch-depth: 0
 
       - name: Install Helm
         uses: azure/setup-helm@f382f75448129b3be48f8121b9857be18d815a82 # tag=v3
@@ -111,7 +113,8 @@ jobs:
       - name: Checkout
         uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3
         with:
-          fetch-depth: 1
+          # Depth 0 is required for chart-testing to work properly
+          fetch-depth: 0
 
       - name: Install Helm
         uses: azure/setup-helm@f382f75448129b3be48f8121b9857be18d815a82 # tag=v3
@@ -164,33 +167,14 @@ jobs:
           # Flags found here https://github.com/k3d-io/k3d
           k3d-args: --k3s-arg --disable=metrics-server@server:*
 
-        # Install Kail to grab logs from tests, as there are cases ct-install fail to output logs
-      - name: Install Kail
-        run: |
-          export KAIL_VERSION=v0.16.1
-          wget https://github.com/boz/kail/releases/download/${KAIL_VERSION}/kail_${KAIL_VERSION}_linux_amd64.tar.gz
-          tar -xvzf kail_${KAIL_VERSION}_linux_amd64.tar.gz
-          chmod +x kail
-
       - name: Run chart-testing (install)
         run: |
+          # This is done to improve speed of the tests, so we can run tests in parallel
           # Move all ci values on a temp location (or skip if already moved from another matrix job)
           mv library/common-test/ci library/common-test/runtests || echo "Nothing to move"
 
           # Move one values.yaml to the correct location to run the test
           mv -f library/common-test/runtests/${{ matrix.values }} library/common-test/values.yaml
 
-          # Stat kail on the background to grab logs from tests
-          ./kail --ignore-ns kube-system >> /tmp/output.log &
-
           # Actually run the test
-          ct install  --config .github/ct-install-config/ct-install.yaml \
-                      --charts library/common-test \
-                      --debug || (echo -e "\n\n--===PODLOGS===--\n\n" && \
-                                  cat /tmp/output.log && \
-                                  rm -f /tmp/output.log && exit 1)
-
-          kill $!
-          echo -e "\n\n--===PODLOGS===--\n\n"
-          cat  /tmp/output.log
-          rm -f /tmp/output.log
+          ct install --config .github/ct-install-config/common-ct-install.yaml

+ 59 - 0
create_app.sh

@@ -0,0 +1,59 @@
+#!/bin/bash
+
+VERSION="v4.31.1"
+BINARY="yq_linux_amd64"
+YQ_PATH="/tmp/yq"
+BASE_PATH="library/ix-dev"
+
+if [[ ! -f "$YQ_PATH" ]]; then
+  wget "https://github.com/mikefarah/yq/releases/download/${VERSION}/${BINARY}" -O "$YQ_PATH" && \
+  chmod +x "$YQ_PATH"
+fi
+
+function check_args(){
+    local arg=$1
+    if [[ -z "$arg" ]]; then
+        echo "Error: $2 not specified"
+        exit 1
+    fi
+}
+
+function copy_app() {
+    local train=$1
+    local app=$2
+
+    # Check arguments have values
+    check_args "$train"
+    check_args "$app"
+
+    # Grab version from Chart.yaml
+    version=$("$YQ_PATH" '.version' "$BASE_PATH/$train/$app/Chart.yaml")
+    check_args "$version"
+
+    # Make sure directories exist
+    mkdir -p "$train/$app/$version"
+
+    helm dependency update "$BASE_PATH/$train/$app"
+    # Copy files over
+    rsync --archive --delete "$BASE_PATH/$train/$app/" "$train/$app/$version"
+    # Rename values.yaml to ix_values.yaml
+    mv "$train/$app/$version/values.yaml" "$train/$app/$version/ix_values.yaml"
+
+    # Remove CI directory from the versioned app
+    rm -r "$train/$app/$version/ci"
+
+    # Grab icon and categories from Chart.yaml
+    icon=$("$YQ_PATH" '.icon' "$BASE_PATH/$train/$app/Chart.yaml")
+    check_args "$icon"
+    categories=$("$YQ_PATH" '.keywords' "$BASE_PATH/$train/$app/Chart.yaml")
+    check_args "$categories"
+
+    # Create item.yaml
+    echo "" > "$train/$app/item.yaml"
+    ICON="$icon" "$YQ_PATH" '.icon_url = env(ICON)' --inplace "$train/$app/item.yaml"
+    CATEGORIES="$categories" "$YQ_PATH" '.categories = env(CATEGORIES)' --inplace "$train/$app/item.yaml"
+
+}
+
+# TODO: Call this function for each changed app
+copy_app "$1" "$2"

+ 3 - 2
library/common-test/Chart.yaml

@@ -1,5 +1,6 @@
 name: common-test
-title: Common Library Chart Testing
+annotations:
+  title: Common Library Chart Testing
 version: 1.0.0
 apiVersion: v2
 appVersion: v1.0.0
@@ -10,7 +11,7 @@ type: application
 icon: https://localhost/icon
 dependencies:
   - name: common
-    repository: file://../common/1.0.0
+    repository: file://../common
     version: ~1.0.0
 maintainers:
   - name: truenas

+ 1 - 0
library/common-test/ci/cron-values.yaml

@@ -20,6 +20,7 @@ workload:
     primary: true
     type: CronJob
     schedule: "*/1 * * * *"
+    ttlSecondsAfterFinished: 0
     podSpec:
       restartPolicy: OnFailure
       containers:

+ 1 - 0
library/common-test/ci/job-values.yaml

@@ -19,6 +19,7 @@ workload:
     enabled: true
     primary: true
     type: Job
+    ttlSecondsAfterFinished: 0
     podSpec:
       restartPolicy: Never
       containers:

+ 57 - 3
library/common-test/tests/container/envFixed_test .yaml → library/common-test/tests/container/envFixed_test.yaml

@@ -221,7 +221,7 @@ tests:
               - container-name1
       image: *image
       TZ: Europe/London
-      containerOptions:
+      resources:
         NVIDIA_CAPS:
           - compute
           - video
@@ -260,7 +260,7 @@ tests:
               - name: S6_READ_ONLY_ROOT
                 value: "1"
 
-  - it: should create the correct fixed envs with GPU and overrided on container level
+  - it: should create the correct fixed envs with GPU and overridden on container level
     set:
       scaleGPU:
         - gpu:
@@ -270,7 +270,7 @@ tests:
               - container-name1
       image: *image
       TZ: Europe/London
-      containerOptions:
+      resources:
         NVIDIA_CAPS:
           - compute
           - video
@@ -312,6 +312,60 @@ tests:
               - name: S6_READ_ONLY_ROOT
                 value: "1"
 
+  - it: should create the correct fixed envs with PUID set to 0 on container level
+    set:
+      image: *image
+      workload:
+        workload-name:
+          enabled: true
+          primary: true
+          type: Deployment
+          podSpec:
+            containers:
+              container-name1:
+                enabled: true
+                primary: true
+                imageSelector: image
+                probes: *probes
+                fixedEnv:
+                  PUID: 0
+                securityContext:
+                  runAsUser: 0
+                  runAsGroup: 0
+                  runAsNonRoot: false
+    asserts:
+      - documentIndex: &deploymentDoc 0
+        isKind:
+          of: Deployment
+      - documentIndex: *deploymentDoc
+        isAPIVersion:
+          of: apps/v1
+      - documentIndex: *deploymentDoc
+        isSubset:
+          path: spec.template.spec.containers[0]
+          content:
+            env:
+              - name: TZ
+                value: UTC
+              - name: UMASK
+                value: "002"
+              - name: UMASK_SET
+                value: "002"
+              - name: PUID
+                value: "0"
+              - name: USER_ID
+                value: "0"
+              - name: UID
+                value: "0"
+              - name: PGID
+                value: "568"
+              - name: GROUP_ID
+                value: "568"
+              - name: GID
+                value: "568"
+              - name: S6_READ_ONLY_ROOT
+                value: "1"
+
   # Failures
   - it: it should fail with NVIDIA_CAPS having invalid values
     set:

+ 26 - 5
library/common-test/tests/container/image_test.yaml

@@ -7,11 +7,11 @@ tests:
       imageDictToUse: image
       image: &image
         repository: nginx
-        tag: 1.19.0
+        tag: "1.19.0"
         pullPolicy: IfNotPresent
       imageGPU:
         repository: some-gpu-image
-        tag: 5.20.0
+        tag: "5.20"
         pullPolicy: Always
       workload:
         workload-name:
@@ -53,7 +53,7 @@ tests:
         isSubset:
           path: spec.template.spec.containers[1]
           content:
-            image: some-gpu-image:5.20.0
+            image: some-gpu-image:5.20
             imagePullPolicy: Always
 
   # Failures
@@ -121,7 +121,28 @@ tests:
     set:
       image:
         repository: nginx
-        tag: 1.19.0
+        tag: "1.19.0"
+        pullPolicy: invalid
+      workload:
+        workload-name:
+          enabled: true
+          primary: true
+          type: Deployment
+          podSpec:
+            containers:
+              container-name1:
+                enabled: true
+                primary: true
+                imageSelector: image
+    asserts:
+      - failedTemplate:
+          errorMessage: Container - Expected <.Values.image.pullPolicy> to be one of [IfNotPresent, Always, Never], but got [invalid]
+
+  - it: should fail with tag not string on selected image
+    set:
+      image:
+        repository: nginx
+        tag: 1.19
         pullPolicy: invalid
       workload:
         workload-name:
@@ -136,4 +157,4 @@ tests:
                 imageSelector: image
     asserts:
       - failedTemplate:
-          errorMessage:  Container - Expected <.Values.image.pullPolicy> to be one of [IfNotPresent, Always, Never], but got [invalid]
+          errorMessage: Container - Expected <.Values.image.tag> to be string, but got [float64]

+ 34 - 41
library/common-test/tests/container/resources_test.yaml

@@ -632,9 +632,8 @@ tests:
   - it: should fail with empty requests
     set:
       image: *image
-      containerOptions:
-        resources:
-          requests:
+      resources:
+        requests:
       workload:
         workload-name1:
           enabled: true
@@ -654,10 +653,9 @@ tests:
   - it: should fail with empty requests.cpu
     set:
       image: *image
-      containerOptions:
-        resources:
-          requests:
-            cpu: ""
+      resources:
+        requests:
+          cpu: ""
       workload:
         workload-name1:
           enabled: true
@@ -677,11 +675,10 @@ tests:
   - it: should fail with empty requests.memory
     set:
       image: *image
-      containerOptions:
-        resources:
-          requests:
-            cpu: 10m
-            memory: ""
+      resources:
+        requests:
+          cpu: 10m
+          memory: ""
       workload:
         workload-name1:
           enabled: true
@@ -701,11 +698,10 @@ tests:
   - it: should fail with invalid format in requests.cpu
     set:
       image: *image
-      containerOptions:
-        resources:
-          requests:
-            cpu: 10MB
-            memory: 50Mi
+      resources:
+        requests:
+          cpu: 10MB
+          memory: 50Mi
       workload:
         workload-name1:
           enabled: true
@@ -725,14 +721,13 @@ tests:
   - it: should fail with invalid format in limits.cpu
     set:
       image: *image
-      containerOptions:
-        resources:
-          requests:
-            cpu: 10m
-            memory: 50Mi
-          limits:
-            cpu: 10MB
-            memory: 8Gi
+      resources:
+        requests:
+          cpu: 10m
+          memory: 50Mi
+        limits:
+          cpu: 10MB
+          memory: 8Gi
       workload:
         workload-name1:
           enabled: true
@@ -752,14 +747,13 @@ tests:
   - it: should fail with invalid format in requests.memory
     set:
       image: *image
-      containerOptions:
-        resources:
-          requests:
-            cpu: 10m
-            memory: 50MB
-          limits:
-            cpu: 4000m
-            memory: 8Gi
+      resources:
+        requests:
+          cpu: 10m
+          memory: 50MB
+        limits:
+          cpu: 4000m
+          memory: 8Gi
       workload:
         workload-name1:
           enabled: true
@@ -779,14 +773,13 @@ tests:
   - it: should fail with invalid format in limits.memory
     set:
       image: *image
-      containerOptions:
-        resources:
-          requests:
-            cpu: 10m
-            memory: 50Mi
-          limits:
-            cpu: 4000m
-            memory: 8GB
+      resources:
+        requests:
+          cpu: 10m
+          memory: 50Mi
+        limits:
+          cpu: 4000m
+          memory: 8GB
       workload:
         workload-name1:
           enabled: true

+ 5 - 0
library/common-test/tests/container/volumeMounts_test.yaml

@@ -37,6 +37,7 @@ tests:
           primary: false
           type: Job
           podSpec:
+            restartPolicy: Never
             containers:
               container-name1:
                 enabled: true
@@ -121,6 +122,7 @@ tests:
           primary: false
           type: Job
           podSpec:
+            restartPolicy: Never
             containers:
               container-name1:
                 enabled: true
@@ -193,6 +195,7 @@ tests:
           primary: false
           type: Job
           podSpec:
+            restartPolicy: Never
             containers:
               container-name1:
                 enabled: true
@@ -274,6 +277,7 @@ tests:
           primary: false
           type: Job
           podSpec:
+            restartPolicy: Never
             containers:
               container-name1:
                 enabled: true
@@ -354,6 +358,7 @@ tests:
           primary: false
           type: Job
           podSpec:
+            restartPolicy: Never
             containers:
               container-name1:
                 enabled: true

+ 1 - 0
library/common-test/tests/cronjob/metadata_test.yaml

@@ -30,6 +30,7 @@ tests:
             annotation1: "{{ .Values.annotation1 }}"
             annotation2: annotation2
           podSpec:
+            restartPolicy: Never
             labels:
               pod-label1: pod-label1
               pod-label2: "{{ .Values.label2 }}"

+ 4 - 2
library/common-test/tests/cronjob/spec_test.yaml

@@ -10,7 +10,8 @@ tests:
           primary: true
           type: CronJob
           schedule: "* * * * *"
-          podSpec: {}
+          podSpec:
+            restartPolicy: Never
     asserts:
       - documentIndex: &cronJobDoc 0
         isKind:
@@ -59,7 +60,8 @@ tests:
           parallelism: 5
           ttlSecondsAfterFinished: 100
           activeDeadlineSeconds: 100
-          podSpec: {}
+          podSpec:
+            restartPolicy: Never
     asserts:
       - documentIndex: *cronJobDoc
         isSubset:

+ 14 - 0
library/common-test/tests/cronjob/validation_test.yaml

@@ -28,6 +28,20 @@ tests:
       - failedTemplate:
           errorMessage: CronJob - Expected non-empty <schedule>
 
+  - it: should fail with restartPolicy set to Always
+    set:
+      workload:
+        workload-name:
+          enabled: true
+          primary: true
+          type: CronJob
+          schedule: "* * * * *"
+          restartPolicy: Always
+          podSpec: {}
+    asserts:
+      - failedTemplate:
+          errorMessage: Expected <restartPolicy to be [OnFailure, Never] for [CronJob] but got [Always]
+
   - it: should fail with invalid completionMode (make sure job validation kicks in)
     set:
       workload:

+ 2 - 0
library/common-test/tests/externalInterface/metadata_test.yaml

@@ -121,6 +121,7 @@ tests:
           primary: false
           type: Job
           podSpec:
+            restartPolicy: Never
             containers:
               container-name1:
                 enabled: true
@@ -199,6 +200,7 @@ tests:
           type: CronJob
           schedule: "*/1 * * * *"
           podSpec:
+            restartPolicy: Never
             containers:
               container-name1:
                 enabled: true

+ 1 - 0
library/common-test/tests/job/metadata_test.yaml

@@ -29,6 +29,7 @@ tests:
             annotation1: "{{ .Values.annotation1 }}"
             annotation2: annotation2
           podSpec:
+            restartPolicy: Never
             labels:
               pod-label1: pod-label1
               pod-label2: "{{ .Values.label2 }}"

+ 4 - 2
library/common-test/tests/job/spec_test.yaml

@@ -9,7 +9,8 @@ tests:
           enabled: true
           primary: true
           type: Job
-          podSpec: {}
+          podSpec:
+            restartPolicy: Never
     asserts:
       - documentIndex: &jobDoc 0
         isKind:
@@ -40,7 +41,8 @@ tests:
           parallelism: 5
           ttlSecondsAfterFinished: 100
           activeDeadlineSeconds: 100
-          podSpec: {}
+          podSpec:
+            restartPolicy: Never
     asserts:
       - documentIndex: *jobDoc
         isSubset:

+ 15 - 4
library/common-test/tests/job/validation_test.yaml

@@ -14,20 +14,31 @@ tests:
     asserts:
       - failedTemplate:
           errorMessage: Job - Expected <completionMode> to be one of [Indexed, NonIndexed], but got [not-a-mode]
+  - it: should fail with invalid completionMode
+    set:
+      workload:
+        workload-name:
+          enabled: true
+          primary: true
+          type: Job
+          completionMode: not-a-mode
+          podSpec: {}
+    asserts:
+      - failedTemplate:
+          errorMessage: Job - Expected <completionMode> to be one of [Indexed, NonIndexed], but got [not-a-mode]
 
-  - it: should fail with completionMode to Indexed and no completions
+  - it: should fail with restartPolicy set to Always
     set:
       workload:
         workload-name:
           enabled: true
           primary: true
           type: Job
-          completionMode: Indexed
-          completions:
+          restartPolicy: Always
           podSpec: {}
     asserts:
       - failedTemplate:
-          errorMessage: Job - Expected <completions> to be set when <completionMode> is set to [Indexed]
+          errorMessage: Expected <restartPolicy to be [OnFailure, Never] for [Job] but got [Always]
 
   - it: should fail with completionMode to Indexed and no parallelism
     set:

+ 2 - 1
library/common-test/tests/pod/image_pull_secret_test.yaml

@@ -10,7 +10,8 @@ tests:
           primary: true
           type: CronJob
           schedule: "* * * * *"
-          podSpec: {}
+          podSpec:
+            restartPolicy: Never
         workload-name2:
           enabled: true
           primary: false

+ 4 - 1
library/common-test/tests/pod/runtime_class_name_test.yaml

@@ -141,13 +141,15 @@ tests:
           primary: true
           type: Job
           podSpec:
+            restartPolicy: Never
             runtimeClassName: some-other-class
         workload-name2:
           enabled: true
           primary: false
           type: CronJob
           schedule: "* * * * *"
-          podSpec: {}
+          podSpec:
+            restartPolicy: Never
     asserts:
       - documentIndex: &jobDoc 0
         isKind:
@@ -180,6 +182,7 @@ tests:
           primary: true
           type: Job
           podSpec:
+            restartPolicy: Never
             runtimeClassName: some-other-class
     asserts:
       - documentIndex: *jobDoc

+ 2 - 1
library/common-test/tests/pod/service_account_name_test.yaml

@@ -10,7 +10,8 @@ tests:
           primary: true
           type: CronJob
           schedule: "* * * * *"
-          podSpec: {}
+          podSpec:
+            restartPolicy: Never
         workload-name2:
           enabled: true
           primary: false

+ 47 - 8
library/common-test/tests/pod/volume_ixVolume_test.yaml

@@ -11,7 +11,7 @@ tests:
           type: Deployment
           podSpec: {}
       ixVolumes:
-        - /mnt/pool/ix-applications/ix-app
+        - hostPath: /mnt/pool/ix-applications/ix-app
       persistence:
         ix-vol:
           enabled: true
@@ -29,7 +29,46 @@ tests:
             hostPath:
               path: /mnt/pool/ix-applications/ix-app
 
-  - it: should pass with hostPath volume and type
+  - it: should pass with multiple ixVolume volumes
+    set:
+      workload:
+        workload-name1:
+          enabled: true
+          primary: true
+          type: Deployment
+          podSpec: {}
+      ixVolumes:
+        - hostPath: /mnt/pool/ix-applications/ix-app1
+        - hostPath: /mnt/pool/ix-applications/ix-app2
+      persistence:
+        ix-vol1:
+          enabled: true
+          type: ixVolume
+          datasetName: ix-app1
+        ix-vol2:
+          enabled: true
+          type: ixVolume
+          datasetName: ix-app2
+    asserts:
+      - documentIndex: &deploymentDoc 0
+        isKind:
+          of: Deployment
+      - documentIndex: *deploymentDoc
+        contains:
+          path: spec.template.spec.volumes
+          content:
+            name: ix-vol1
+            hostPath:
+              path: /mnt/pool/ix-applications/ix-app1
+      - documentIndex: *deploymentDoc
+        contains:
+          path: spec.template.spec.volumes
+          content:
+            name: ix-vol2
+            hostPath:
+              path: /mnt/pool/ix-applications/ix-app2
+
+  - it: should pass with ixVolume and hostPathType
     set:
       some_dataset: ix-app
       some_type: DirectoryOrCreate
@@ -40,7 +79,7 @@ tests:
           type: Deployment
           podSpec: {}
       ixVolumes:
-        - /mnt/pool/ix-applications/ix-app
+        - hostPath: /mnt/pool/ix-applications/ix-app
       persistence:
         ix-vol:
           enabled: true
@@ -96,7 +135,7 @@ tests:
       - failedTemplate:
           errorMessage: Persistence - Expected non-empty <ixVolumes> in values on <ixVolume> type
 
-  - it: should fail with empty ixVolumes
+  - it: should fail with wrong ixVolumes
     set:
       workload:
         some-workload:
@@ -105,8 +144,8 @@ tests:
           type: Deployment
           podSpec: {}
       ixVolumes:
-        - /mnt/pool/ix-applications/ix-wrong-app
-        - /mnt/pool/ix-applications/ix-other-app
+        - hostPath: /mnt/pool/ix-applications/ix-wrong-app
+        - hostPath: /mnt/pool/ix-applications/ix-other-app
       persistence:
         volume1:
           enabled: true
@@ -114,7 +153,7 @@ tests:
           datasetName: ix-app
     asserts:
       - failedTemplate:
-          errorMessage: Persistence - Expected <datasetName> [ix-app] to exist on <ixVolumes> list, but list contained [/mnt/pool/ix-applications/ix-wrong-app, /mnt/pool/ix-applications/ix-other-app] on <ixVolume> type
+          errorMessage: Persistence - Expected <datasetName> [ix-app] to exist on <ixVolumes> list, but list contained [ix-wrong-app, ix-other-app] on <ixVolume> type
 
   - it: should fail with invalid hostPathType
     set:
@@ -125,7 +164,7 @@ tests:
           type: Deployment
           podSpec: {}
       ixVolumes:
-        - /mnt/pool/ix-applications/ix-app
+        - hostPath: /mnt/pool/ix-applications/ix-app
       persistence:
         volume1:
           enabled: true

+ 2 - 2
library/common-test/tests/service/metadata_test.yaml

@@ -70,7 +70,7 @@ tests:
             app.kubernetes.io/version: *appVer
             app.kubernetes.io/instance: RELEASE-NAME
             app.kubernetes.io/name: common-test
-            service.name: release-name-common-test
+            service.name: my-service1
             g_label1: global_label1
             g_label2: global_label2
             label1: label1
@@ -82,7 +82,7 @@ tests:
         equal:
           path: metadata.labels
           value:
-            service.name: release-name-common-test-my-service2
+            service.name: my-service2
             app: common-test-1.0.0
             app.kubernetes.io/instance: RELEASE-NAME
             app.kubernetes.io/managed-by: Helm

+ 50 - 0
library/common-test/tests/service/node_port_test.yaml

@@ -49,6 +49,56 @@ tests:
               app.kubernetes.io/name: common-test
               pod.name: my-workload
 
+  - it: should pass with type NodePort and hostnetwork enabled
+    set:
+      service:
+        my-service:
+          enabled: true
+          primary: true
+          type: NodePort
+          ports:
+            port-name:
+              enabled: true
+              primary: true
+              port: 12345
+              nodePort: 30000
+      workload:
+        my-workload:
+          enabled: true
+          primary: true
+          type: Deployment
+          podSpec:
+            hostNetwork: true
+    asserts:
+      - documentIndex: &serviceDoc 1
+        isKind:
+          of: Service
+      - documentIndex: *serviceDoc
+        isAPIVersion:
+          of: v1
+      - documentIndex: *serviceDoc
+        equal:
+          path: metadata.name
+          value: release-name-common-test
+      - documentIndex: *serviceDoc
+        equal:
+          path: spec
+          value:
+            type: ClusterIP
+            publishNotReadyAddresses: false
+            ports:
+            - name: port-name
+              port: 12345
+              protocol: TCP
+              targetPort: 12345
+            selector:
+              app.kubernetes.io/instance: RELEASE-NAME
+              app.kubernetes.io/name: common-test
+              pod.name: my-workload
+      - documentIndex: *serviceDoc
+        isNull:
+          path: spec.ports[0].nodePort
+
   - it: should pass with type NodePort and available options set
     set:
       some_ip: 172.16.20.35

+ 4 - 2
library/common-test/tests/workload/names_test.yaml

@@ -15,12 +15,14 @@ tests:
           primary: false
           type: CronJob
           schedule: "*/1 * * * *"
-          podSpec: {}
+          podSpec:
+            restartPolicy: Never
         job-workload-name:
           enabled: true
           primary: false
           type: Job
-          podSpec: {}
+          podSpec:
+            restartPolicy: Never
     asserts:
       - documentIndex: &cronJobDoc 0
         isKind:

+ 2 - 1
library/common/1.0.0/Chart.yaml → library/common/Chart.yaml

@@ -1,10 +1,11 @@
 apiVersion: v2
-title: Common Library Chart
 name: common
 description: A library chart for iX Official Catalog
 type: library
 version: 1.0.0
 appVersion: v1
+annotations:
+  title: Common Library Chart
 maintainers:
   - name: truenas
     url: https://www.truenas.com/

+ 0 - 0
library/common/1.0.0/README.md → library/common/README.md


+ 59 - 61
library/common/1.0.0/docs/README.md → library/common/docs/README.md

@@ -95,31 +95,28 @@ All of the below values are applied on all pods/containers, but can be overridde
 This is so, you can have a single point to define the values from the scale UI,
 but still have the ability to override them on the pod/container level, in case you need to.
 
-| Key                                                |   Type    | Required | Helm Template |  Default  | Description                                                            |
-| :------------------------------------------------- | :-------: | :------: | :-----------: | :-------: | :--------------------------------------------------------------------- |
-| .Values.TZ                                         | `string`  |    ✅    |      ❌       | See below | Timezone that is used everywhere applicable                            |
-| .Values.PUID                                       |   `int`   |    ✅    |      ❌       | See below | PUID (Only applied when running as root)                               |
-| .Values.UMASK                                      | `string`  |    ✅    |      ❌       | See below | UMASK                                                                  |
-| .Values.NVIDIA_CAPS                                |  `list`   |    ✅    |      ❌       | See below | NVIDIA_CAPS (Only applied when scaleGPU is passed)                     |
-| .Values.containerOptions                           |  `dict`   |    ✅    |      ❌       | See below | Options that apply to all containers                                   |
-| .Values.containerOptions.resources                 |  `dict`   |    ✅    |      ❌       | See below | Resources                                                              |
-| .Values.containerOptions.resources.limits          |  `dict`   |    ✅    |      ❌       | See below | Resources                                                              |
-| .Values.containerOptions.resources.limits.cpu      | `string`  |    ✅    |      ❌       | See below | Resources                                                              |
-| .Values.containerOptions.resources.limits.memory   | `string`  |    ✅    |      ❌       | See below | Resources                                                              |
-| .Values.containerOptions.resources.requests        |  `dict`   |    ✅    |      ❌       | See below | Resources                                                              |
-| .Values.containerOptions.resources.requests.cpu    | `string`  |    ✅    |      ❌       | See below | Resources                                                              |
-| .Values.containerOptions.resources.requests.memory | `string`  |    ✅    |      ❌       | See below | Resources                                                              |
-| .Values.podOptions                                 |  `dict`   |    ✅    |      ❌       | See below | Options that apply to all pods                                         |
-| .Values.podOptions.enableServiceLinks              | `boolean` |    ✅    |      ❌       | See below | enableServiceLinks                                                     |
-| .Values.podOptions.hostNetwork                     | `boolean` |    ✅    |      ❌       | See below | hostNetwork                                                            |
-| .Values.podOptions.restartPolicy                   | `string`  |    ✅    |      ❌       | See below | restartPolicy                                                          |
-| .Values.podOptions.dnsPolicy                       | `string`  |    ✅    |      ❌       | See below | dnsPolicy                                                              |
-| .Values.podOptions.dnsConfig                       |  `list`   |    ✅    |      ❌       | See below | dnsConfig                                                              |
-| .Values.podOptions.hostAliases                     |  `list`   |    ✅    |      ❌       | See below | hostAliases                                                            |
-| .Values.podOptions.tolerations                     |  `list`   |    ✅    |      ❌       | See below | tolerations                                                            |
-| .Values.podOptions.runtimeClassName                | `string`  |    ✅    |      ❌       | See below | runtimeClassName (value in ixChartContext will always take precedence) |
-| .Values.podOptions.automountServiceAccountToken    | `boolean` |    ✅    |      ❌       | See below | automountServiceAccountToken                                           |
-| .Values.podOptions.terminationGracePeriodSeconds   |   `int`   |    ✅    |      ❌       | See below | terminationGracePeriodSeconds                                          |
+| Key                                              |   Type    | Required | Helm Template |  Default  | Description                                                            |
+| :----------------------------------------------- | :-------: | :------: | :-----------: | :-------: | :--------------------------------------------------------------------- |
+| .Values.TZ                                       | `string`  |    ✅    |      ❌       | See below | Timezone that is used everywhere applicable                            |
+| .Values.resources                                |  `dict`   |    ✅    |      ❌       | See below | Resources                                                              |
+| .Values.resources.limits                         |  `dict`   |    ✅    |      ❌       | See below | Resources                                                              |
+| .Values.resources.limits.cpu                     | `string`  |    ✅    |      ❌       | See below | Resources                                                              |
+| .Values.resources.limits.memory                  | `string`  |    ✅    |      ❌       | See below | Resources                                                              |
+| .Values.resources.requests                       |  `dict`   |    ✅    |      ❌       | See below | Resources                                                              |
+| .Values.resources.requests.cpu                   | `string`  |    ✅    |      ❌       | See below | Resources                                                              |
+| .Values.resources.requests.memory                | `string`  |    ✅    |      ❌       | See below | Resources                                                              |
+| .Values.resources.NVIDIA_CAPS                    |  `list`   |    ✅    |      ❌       | See below | NVIDIA_CAPS (Only applied when scaleGPU is passed)                     |
+| .Values.podOptions                               |  `dict`   |    ✅    |      ❌       | See below | Options that apply to all pods                                         |
+| .Values.podOptions.enableServiceLinks            | `boolean` |    ✅    |      ❌       | See below | enableServiceLinks                                                     |
+| .Values.podOptions.hostNetwork                   | `boolean` |    ✅    |      ❌       | See below | hostNetwork                                                            |
+| .Values.podOptions.restartPolicy                 | `string`  |    ✅    |      ❌       | See below | restartPolicy                                                          |
+| .Values.podOptions.dnsPolicy                     | `string`  |    ✅    |      ❌       | See below | dnsPolicy                                                              |
+| .Values.podOptions.dnsConfig                     |  `list`   |    ✅    |      ❌       | See below | dnsConfig                                                              |
+| .Values.podOptions.hostAliases                   |  `list`   |    ✅    |      ❌       | See below | hostAliases                                                            |
+| .Values.podOptions.tolerations                   |  `list`   |    ✅    |      ❌       | See below | tolerations                                                            |
+| .Values.podOptions.runtimeClassName              | `string`  |    ✅    |      ❌       | See below | runtimeClassName (value in ixChartContext will always take precedence) |
+| .Values.podOptions.automountServiceAccountToken  | `boolean` |    ✅    |      ❌       | See below | automountServiceAccountToken                                           |
+| .Values.podOptions.terminationGracePeriodSeconds |   `int`   |    ✅    |      ❌       | See below | terminationGracePeriodSeconds                                          |
 
 <!-- TODO: Improve descriptions -->
 
@@ -129,18 +126,15 @@ Defaults:
 
 ```yaml
 TZ: UTC
-PUID: 568
-UMASK: "002"
-NVIDIA_CAPS:
-  - all
-containerOptions:
-  resources:
-    limits:
-      cpu: 4000m
-      memory: 8Gi
-    requests:
-      cpu: 10m
-      memory: 50Mi
+resources:
+  limits:
+    cpu: 4000m
+    memory: 8Gi
+  requests:
+    cpu: 10m
+    memory: 50Mi
+  NVIDIA_CAPS:
+    - all
 podOptions:
   enableServiceLinks: false
   hostNetwork: false
@@ -165,27 +159,29 @@ All of the below values are applied on all pods/containers, but can be overridde
 This is so, you can have a single point to define the values from the scale UI,
 but still have the ability to override them on the pod/container level, in case you need to.
 
-| Key                                                        |   Type    | Required | Helm Template |  Default  | Description                     |
-| :--------------------------------------------------------- | :-------: | :------: | :-----------: | :-------: | :------------------------------ |
-| .Values.securityContext                                    |  `dict`   |    ✅    |      ❌       | See below | Security Context                |
-| .Values.securityContext.container                          |  `dict`   |    ✅    |      ❌       | See below | Security Context for containers |
-| .Values.securityContext.container.runAsNonRoot             | `boolean` |    ✅    |      ❌       | See below |                                 |
-| .Values.securityContext.container.runAsUser                |   `int`   |    ✅    |      ❌       | See below |                                 |
-| .Values.securityContext.container.runAsGroup               |   `int`   |    ✅    |      ❌       | See below |                                 |
-| .Values.securityContext.container.readOnlyRootFilesystem   | `boolean` |    ✅    |      ❌       | See below |                                 |
-| .Values.securityContext.container.allowPrivilegeEscalation | `boolean` |    ✅    |      ❌       | See below |                                 |
-| .Values.securityContext.container.privileged               | `boolean` |    ✅    |      ❌       | See below |                                 |
-| .Values.securityContext.container.seccompProfile           |  `dict`   |    ✅    |      ❌       | See below |                                 |
-| .Values.securityContext.container.seccompProfile.type      | `string`  |    ✅    |      ❌       | See below |                                 |
-| .Values.securityContext.container.seccompProfile.profile   | `string`  |    ✅    |      ❌       | See below |                                 |
-| .Values.securityContext.container.capabilities             |  `dict`   |    ✅    |      ❌       | See below |                                 |
-| .Values.securityContext.container.capabilities.add         |  `list`   |    ✅    |      ❌       | See below |                                 |
-| .Values.securityContext.container.capabilities.drop        |  `list`   |    ✅    |      ❌       | See below |                                 |
-| .Values.securityContext.pod                                |  `dict`   |    ✅    |      ❌       | See below | Security Context for pods       |
-| .Values.securityContext.pod.fsGroup                        |   `int`   |    ✅    |      ❌       | See below |                                 |
-| .Values.securityContext.pod.fsGroupChangePolicy            | `string`  |    ✅    |      ❌       | See below |                                 |
-| .Values.securityContext.pod.supplementalGroup              |  `list`   |    ✅    |      ❌       | See below |                                 |
-| .Values.securityContext.pod.sysctls                        |  `list`   |    ✅    |      ❌       | See below |                                 |
+| Key                                                        |   Type    | Required | Helm Template |  Default  | Description                              |
+| :--------------------------------------------------------- | :-------: | :------: | :-----------: | :-------: | :--------------------------------------- |
+| .Values.securityContext                                    |  `dict`   |    ✅    |      ❌       | See below | Security Context                         |
+| .Values.securityContext.container                          |  `dict`   |    ✅    |      ❌       | See below | Security Context for containers          |
+| .Values.securityContext.container.PUID                     |   `int`   |    ✅    |      ❌       | See below | PUID (Only applied when running as root) |
+| .Values.securityContext.container.UMASK                    | `string`  |    ✅    |      ❌       | See below | UMASK                                    |
+| .Values.securityContext.container.runAsNonRoot             | `boolean` |    ✅    |      ❌       | See below |                                          |
+| .Values.securityContext.container.runAsUser                |   `int`   |    ✅    |      ❌       | See below |                                          |
+| .Values.securityContext.container.runAsGroup               |   `int`   |    ✅    |      ❌       | See below |                                          |
+| .Values.securityContext.container.readOnlyRootFilesystem   | `boolean` |    ✅    |      ❌       | See below |                                          |
+| .Values.securityContext.container.allowPrivilegeEscalation | `boolean` |    ✅    |      ❌       | See below |                                          |
+| .Values.securityContext.container.privileged               | `boolean` |    ✅    |      ❌       | See below |                                          |
+| .Values.securityContext.container.seccompProfile           |  `dict`   |    ✅    |      ❌       | See below |                                          |
+| .Values.securityContext.container.seccompProfile.type      | `string`  |    ✅    |      ❌       | See below |                                          |
+| .Values.securityContext.container.seccompProfile.profile   | `string`  |    ✅    |      ❌       | See below |                                          |
+| .Values.securityContext.container.capabilities             |  `dict`   |    ✅    |      ❌       | See below |                                          |
+| .Values.securityContext.container.capabilities.add         |  `list`   |    ✅    |      ❌       | See below |                                          |
+| .Values.securityContext.container.capabilities.drop        |  `list`   |    ✅    |      ❌       | See below |                                          |
+| .Values.securityContext.pod                                |  `dict`   |    ✅    |      ❌       | See below | Security Context for pods                |
+| .Values.securityContext.pod.fsGroup                        |   `int`   |    ✅    |      ❌       | See below |                                          |
+| .Values.securityContext.pod.fsGroupChangePolicy            | `string`  |    ✅    |      ❌       | See below |                                          |
+| .Values.securityContext.pod.supplementalGroup              |  `list`   |    ✅    |      ❌       | See below |                                          |
+| .Values.securityContext.pod.sysctls                        |  `list`   |    ✅    |      ❌       | See below |                                          |
 
 <!-- TODO: Improve descriptions -->
 
@@ -196,6 +192,8 @@ securityContext:
   # -- Container security context for all containers
   # Can be overruled per container
   container:
+    PUID: 568
+    UMASK: "002"
     runAsNonRoot: true
     runAsUser: 568
     runAsGroup: 568
@@ -244,15 +242,15 @@ image:
 You can define additional images using the following convention:
 
 ```yaml
-imageWorker:
+workerImage:
   repository: ""
   tag: ""
   pullPolicy: IfNotPresent
 ```
 
-There isn't anything special in the above format, it's just a convention.
+There isn't anything special in the above format (`nameImage`), it's just a convention.
 It's also a format that some external tools can use for automatic image updates.
-For example, `Renovate`
+For example, [Renovate](https://docs.renovatebot.com/modules/manager/helm-values/#additional-information)
 
 ---
 

+ 0 - 0
library/common/1.0.0/docs/configmap.md → library/common/docs/configmap.md


+ 10 - 8
library/common/1.0.0/docs/container/README.md → library/common/docs/container/README.md

@@ -2,13 +2,14 @@
 
 Assume every key below has a prefix of `workload.[workload-name].podSpec`.
 
-| Key                                 |   Type    | Required | Helm Template | Default | Description                       |
-| :---------------------------------- | :-------: | :------: | :-----------: | :-----: | :-------------------------------- |
-| containers.[container-name]         |  `dict`   |    ✅    |      ❌       |  `{}`   | Define the container as dict      |
-| containers.[container-name].enabled | `boolean` |    ✅    |      ❌       | `false` | Enables or Disables the container |
-| containers.[container-name].primary | `boolean` |    ✅    |      ❌       | `false` | Sets the container as primary     |
-| containers.[container-name].stdin   | `boolean` |    ❌    |      ❌       | `false` | whether to enable stdin or not    |
-| containers.[container-name].tty     | `boolean` |    ❌    |      ❌       | `false` | whether to enable tty or not      |
+| Key                                       |   Type    | Required | Helm Template | Default | Description                       |
+| :---------------------------------------- | :-------: | :------: | :-----------: | :-----: | :-------------------------------- |
+| containers.[container-name]               |  `dict`   |    ✅    |      ❌       |  `{}`   | Define the container as dict      |
+| containers.[container-name].enabled       | `boolean` |    ✅    |      ❌       | `false` | Enables or Disables the container |
+| containers.[container-name].imageSelector | `string`  |    ✅    |      ✅       | `image` | Defines the image dict to use     |
+| containers.[container-name].primary       | `boolean` |    ✅    |      ❌       | `false` | Sets the container as primary     |
+| containers.[container-name].stdin         | `boolean` |    ❌    |      ❌       | `false` | whether to enable stdin or not    |
+| containers.[container-name].tty           | `boolean` |    ❌    |      ❌       | `false` | whether to enable tty or not      |
 
 ---
 
@@ -53,6 +54,7 @@ workload:
         container-name:
           enabled: true
           primary: true
+          imageSelector: image
           stdin: true
           tty: true
 ```
@@ -62,7 +64,7 @@ workload:
 | Key                                     |   Type    | Required | Helm Template | Default | Description                                            |
 | :-------------------------------------- | :-------: | :------: | :-----------: | :-----: | :----------------------------------------------------- |
 | initContainers.[container-name]         |  `dict`   |    ✅    |      ❌       |  `{}`   | Define the initContainer as dict                       |
-| initContainers.[container-name].enabled | `boolean` |    ✅    |      ✅       | `false` | Enables or Disables the initContainer                      |
+| initContainers.[container-name].enabled | `boolean` |    ✅    |      ✅       | `false` | Enables or Disables the initContainer                  |
 | initContainers.[container-name].type    | `string`  |    ✅    |      ✅       |  `{}`   | Define the type initContainer (init, install, upgrade) |
 
 > Supports all keys from [container](container.md)

+ 0 - 0
library/common/1.0.0/docs/container/args.md → library/common/docs/container/args.md


+ 0 - 0
library/common/1.0.0/docs/container/command.md → library/common/docs/container/command.md


+ 0 - 0
library/common/1.0.0/docs/container/env.md → library/common/docs/container/env.md


+ 0 - 0
library/common/1.0.0/docs/container/envFrom.md → library/common/docs/container/envFrom.md


+ 0 - 0
library/common/1.0.0/docs/container/envList.md → library/common/docs/container/envList.md


+ 12 - 12
library/common/1.0.0/docs/container/fixedEnv.md → library/common/docs/container/fixedEnv.md

@@ -2,13 +2,13 @@
 
 Assume every key below has a prefix of `workload.[workload-name].podSpec.containers.[container-name]`.
 
-| Key                  |   Type   | Required | Helm Template |                   Default                    | Description                                                                   |
-| :------------------- | :------: | :------: | :-----------: | :------------------------------------------: | :---------------------------------------------------------------------------- |
-| fixedEnv             |  `dict`  |    ❌    |      ❌       |                     `{}`                     | Override fixed Envs for the container                                         |
-| fixedEnv.TZ          | `string` |    ❌    |      ❌       |              `{{ .Values.TZ }}`              | Override default TZ for the container                                         |
-| fixedEnv.UMASK       | `string` |    ❌    |      ❌       |    `{{ .Values.containerOptions.UMASK }}`    | Override the default UMASK for the container (Applies to UMASK and UMASK_SET) |
-| fixedEnv.PUID        | `string` |    ❌    |      ❌       |    `{{ .Values.containerOptions.PUID }}`     | Override the default PUID for the container (Applies to PUID. USER_ID, UID)   |
-| fixedEnv.NVIDIA_CAPS |  `list`  |    ❌    |      ❌       | `{{ .Values.containerOptions.NVIDIA_CAPS }}` | Override the default NVIDIA_CAPS for the container, each entry is a string    |
+| Key                  |   Type   | Required | Helm Template |                     Default                     | Description                                                                   |
+| :------------------- | :------: | :------: | :-----------: | :---------------------------------------------: | :---------------------------------------------------------------------------- |
+| fixedEnv             |  `dict`  |    ❌    |      ❌       |                      `{}`                       | Override fixed Envs for the container                                         |
+| fixedEnv.TZ          | `string` |    ❌    |      ❌       |               `{{ .Values.TZ }}`                | Override default TZ for the container                                         |
+| fixedEnv.UMASK       | `string` |    ❌    |      ❌       | `{{ .Values.securityContext.container.UMASK }}` | Override the default UMASK for the container (Applies to UMASK and UMASK_SET) |
+| fixedEnv.PUID        | `string` |    ❌    |      ❌       | `{{ .Values.securityContext.container.PUID }}`  | Override the default PUID for the container (Applies to PUID. USER_ID, UID)   |
+| fixedEnv.NVIDIA_CAPS |  `list`  |    ❌    |      ❌       |      `{{ .Values.resources.NVIDIA_CAPS }}`      | Override the default NVIDIA_CAPS for the container, each entry is a string    |
 
 > Environment variables in `fixedEnv` will be scanned for duplicate keys
 > between other secrets/configmaps/env/envList and will throw an error if it finds any.
@@ -20,14 +20,14 @@ Notes:
 By default it will set the following environment variables:
 
 - TZ: `{{ .Values.TZ }}` (or the value set in the container level under `fixedEnv`)
-- UMASK: `{{ .Values.containerOptions.UMASK }}` (or the value set in the container level under `fixedEnv`)
-- UMASK_SET: `{{ .Values.containerOptions.UMASK }}` (or the value set in the container level under `fixedEnv`)
+- UMASK: `{{ .Values.securityContext.container.UMASK }}` (or the value set in the container level under `fixedEnv`)
+- UMASK_SET: `{{ .Values.securityContext.container.UMASK }}` (or the value set in the container level under `fixedEnv`)
 - S6_READ_ONLY_ROOT: `1` (Only when `readOnlyRootFilesystem` or `runAsNonRoot` is `true`)
-- PUID, USER_ID, UID: `{{ .Values.containerOptions.PUID }}` (or the value set in the container level under `fixedEnv`)
+- PUID, USER_ID, UID: `{{ .Values.securityContext.container.PUID }}` (or the value set in the container level under `fixedEnv`)
   - Only when `runAsUser` or `runAsGroup` is `0`
-- PGID, GROUP_ID, GID: To the `fsGroup` set for the pod (Either the default or the overrided value)
+- PGID, GROUP_ID, GID: To the `fsGroup` set for the pod (Either the default or the overridden value)
   - Only when `runAsUser` or `runAsGroup` is `0`
-- NVIDIA_DRIVER_CAPABILITIES: `{{ .Values.containerOptions.NVIDIA_CAPS }}` (or the value set in the container level under `fixedEnv`)
+- NVIDIA_DRIVER_CAPABILITIES: `{{ .Values.resources.NVIDIA_CAPS }}` (or the value set in the container level under `fixedEnv`)
   - Only when `scaleGPU` is assigned to the container
 
 ---

+ 0 - 0
library/common/1.0.0/docs/container/lifecycle.md → library/common/docs/container/lifecycle.md


+ 0 - 0
library/common/1.0.0/docs/container/probes.md → library/common/docs/container/probes.md


+ 9 - 9
library/common/1.0.0/docs/container/resources.md → library/common/docs/container/resources.md

@@ -4,15 +4,15 @@ Assume every key below has a prefix of `workload.[workload-name].podSpec.contain
 
 | Key                       |   Type   | Required | Helm Template |                          Default                           | Description                                  |
 | :------------------------ | :------: | :------: | :-----------: | :--------------------------------------------------------: | :------------------------------------------- |
-| resources                 |  `dict`  |    ✅    |      ❌       |         `{{ .Values.containerOptions.resources }}`         | Define resources for the container           |
-| resources.requests        |  `dict`  |    ✅    |      ❌       |    `{{ .Values.containerOptions.resources.requests }}`     | Define the requests for the container        |
-| resources.requests.cpu    | `string` |    ✅    |      ❌       |  `{{ .Values.containerOptions.resources.requests.cpu }}`   | Define the requests.cpu for the container    |
-| resources.requests.memory | `string` |    ✅    |      ❌       | `{{ .Values.containerOptions.resources.requests.memory }}` | Define the requests.memory for the container |
-| resources.limits          |  `dict`  |    ❌    |      ❌       |     `{{ .Values.containerOptions.resources.limits }}`      | Define the limits for the container          |
-| resources.limits.cpu      | `string` |    ❌    |      ❌       |   `{{ .Values.containerOptions.resources.limits.cpu }}`    | Define the limits.cpu for the container      |
-| resources.limits.memory   | `string` |    ❌    |      ❌       |  `{{ .Values.containerOptions.resources.limits.memory }}`  | Define the limits.memory for the container   |
-
-> Each value that is not defined in the `resources` under the container level, it will get replaced with the value defined `.Values.containerOptions.resources`.
+| resources                 |  `dict`  |    ✅    |      ❌       |         `{{ .Values.resources }}`         | Define resources for the container           |
+| resources.requests        |  `dict`  |    ✅    |      ❌       |    `{{ .Values.resources.requests }}`     | Define the requests for the container        |
+| resources.requests.cpu    | `string` |    ✅    |      ❌       |  `{{ .Values.resources.requests.cpu }}`   | Define the requests.cpu for the container    |
+| resources.requests.memory | `string` |    ✅    |      ❌       | `{{ .Values.resources.requests.memory }}` | Define the requests.memory for the container |
+| resources.limits          |  `dict`  |    ❌    |      ❌       |     `{{ .Values.resources.limits }}`      | Define the limits for the container          |
+| resources.limits.cpu      | `string` |    ❌    |      ❌       |   `{{ .Values.resources.limits.cpu }}`    | Define the limits.cpu for the container      |
+| resources.limits.memory   | `string` |    ❌    |      ❌       |  `{{ .Values.resources.limits.memory }}`  | Define the limits.memory for the container   |
+
+> Each value that is not defined in the `resources` under the container level, it will get replaced with the value defined `.Values.resources`.
 > `requests` is **required**, because without it, kubernetes uses the `limits` as the `requests`. Which can lead pods to be evicted when they reach their `limits` or not even scheduled.
 > `limits` is **optional**, can be set to "unlimited" by setting it's values (`cpu` and `memory`) to `0`.
 

+ 7 - 0
library/common/1.0.0/docs/container/securityContext.md → library/common/docs/container/securityContext.md

@@ -57,3 +57,10 @@ workload:
               drop:
                 - ALL
 ```
+
+---
+
+Notes:
+
+When setting capabilities for containers, remember to **NOT** include `CAP_` prefix.
+For example, `CAP_NET_ADMIN` should be `NET_ADMIN`.

+ 0 - 0
library/common/1.0.0/docs/container/termination.md → library/common/docs/container/termination.md


+ 0 - 0
library/common/1.0.0/docs/imagePullSecret.md → library/common/docs/imagePullSecret.md


+ 0 - 0
library/common/1.0.0/docs/notes.md → library/common/docs/notes.md


+ 0 - 0
library/common/1.0.0/docs/persistence/README.md → library/common/docs/persistence/README.md


+ 0 - 0
library/common/1.0.0/docs/persistence/configmap.md → library/common/docs/persistence/configmap.md


+ 0 - 0
library/common/1.0.0/docs/persistence/device.md → library/common/docs/persistence/device.md


+ 0 - 0
library/common/1.0.0/docs/persistence/emptyDir.md → library/common/docs/persistence/emptyDir.md


+ 0 - 0
library/common/1.0.0/docs/persistence/hostPath.md → library/common/docs/persistence/hostPath.md


+ 0 - 0
library/common/1.0.0/docs/persistence/ixVolume.md → library/common/docs/persistence/ixVolume.md


+ 0 - 0
library/common/1.0.0/docs/persistence/secret.md → library/common/docs/persistence/secret.md


+ 0 - 0
library/common/1.0.0/docs/rbac.md → library/common/docs/rbac.md


+ 0 - 0
library/common/1.0.0/docs/scaleCertificate.md → library/common/docs/scaleCertificate.md


+ 0 - 0
library/common/1.0.0/docs/scaleExternalInterface.md → library/common/docs/scaleExternalInterface.md


+ 0 - 0
library/common/1.0.0/docs/scaleGPU.md → library/common/docs/scaleGPU.md


+ 0 - 0
library/common/1.0.0/docs/secret.md → library/common/docs/secret.md


+ 0 - 0
library/common/1.0.0/docs/service/ClusterIP.md → library/common/docs/service/ClusterIP.md


+ 0 - 0
library/common/1.0.0/docs/service/NodePort.md → library/common/docs/service/NodePort.md


+ 0 - 0
library/common/1.0.0/docs/service/README.md → library/common/docs/service/README.md


+ 0 - 0
library/common/1.0.0/docs/serviceAccount.md → library/common/docs/serviceAccount.md


+ 0 - 0
library/common/1.0.0/docs/workload/README.md → library/common/docs/workload/README.md


+ 0 - 0
library/common/1.0.0/docs/workload/cronjob.md → library/common/docs/workload/cronjob.md


+ 0 - 0
library/common/1.0.0/docs/workload/deployment.md → library/common/docs/workload/deployment.md


+ 0 - 0
library/common/1.0.0/docs/workload/job.md → library/common/docs/workload/job.md


+ 54 - 0
library/common/templates/app_functions/_permissions.tpl

@@ -0,0 +1,54 @@
+{{/* Returns an init container that fixes permissions */}}
+{{/* Call this template:
+{{ include "ix.v1.common.app.permissions" (dict "UID" 568 "GID" 568 "type" "init") }}
+
+type (optional): init or install (default: install)
+UID: UID to change permissions to
+GID: GID to change permissions to
+*/}}
+{{- define "ix.v1.common.app.permissions" -}}
+  {{- $type := .type | default "install" -}}
+  {{- $containerName := .containerName | default "permissions" -}}
+  {{- $UID := .UID -}}
+  {{- $GID := .GID -}}
+
+  {{- if (kindIs "invalid" $type) -}}
+    {{- fail "Permissions Container - [type] cannot be empty" -}}
+  {{- end -}}
+  {{- if (kindIs "invalid" $containerName) -}}
+    {{- fail "Permissions Container - [containerName] cannot be empty" -}}
+  {{- end -}}
+  {{- if (kindIs "invalid" $GID) -}}
+    {{- fail "Permissions Container - [GID] cannot be empty" -}}
+  {{- end -}}
+  {{- if (kindIs "invalid" $UID) -}}
+    {{- fail "Permissions Container - [UID] cannot be empty" -}}
+  {{- end }}
+
+{{ $containerName }}:
+  enabled: true
+  type: {{ $type }}
+  imageSelector: bashImage
+  resources:
+    limits:
+      cpu: 1000m
+      memory: 512Mi
+  securityContext:
+    runAsUser: 0
+    runAsGroup: 0
+    runAsNonRoot: false
+    readOnlyRootFilesystem: false
+    capabilities:
+      add:
+        - CHOWN
+  command: bash
+  args:
+    - -c
+    - |
+      echo "Changing ownership to {{ $UID }}:{{ $GID }} on the following directories:"
+      ls -la /mnt/directories
+      chown -R {{ $UID }}:{{ $GID }} /mnt/directories
+      echo "Finished changing ownership"
+      echo "Permissions after changing ownership:"
+      ls -la /mnt/directories
+{{- end -}}

+ 102 - 0
library/common/templates/app_functions/_postgres.tpl

@@ -0,0 +1,102 @@
+{{/* Returns a postgres pod with init container for fixing permissions
+and a pre-upgrade job to backup the database */}}
+{{/* Call this template:
+{{ include "ix.v1.common.app.postgres" (dict "name" "postgres" "secretName" "postgres-creds" "backupPath" "/postgres_backup" "resources" .Values.resources) }}
+
+name (optional): Name of the postgres pod/container (default: postgres)
+secretName (required): Name of the secret containing the postgres credentials
+backupPath (optional): Path to store the backup, it's the container's path (default: /postgres_backup)
+resources (required): Resources for the postgres container
+*/}}
+{{- define "ix.v1.common.app.postgres" -}}
+  {{- $name := .name | default "postgres" -}}
+  {{- $secretName := (required "Postgres - Secret Name is required" .secretName) -}}
+  {{- $backupPath := .backupPath | default "/postgres_backup" -}}
+  {{- $resources := (required "Postgres - Resources are required" .resources) }}
+{{ $name }}:
+  enabled: true
+  type: Deployment
+  podSpec:
+    containers:
+      {{ $name }}:
+        enabled: true
+        primary: true
+        imageSelector: postgresImage
+        securityContext:
+          runAsUser: 999
+          runAsGroup: 999
+          readOnlyRootFilesystem: false
+        resources:
+          limits:
+            cpu: {{ $resources.limits.cpu }}
+            memory: {{ $resources.limits.memory }}
+        envFrom:
+          - secretRef:
+              name: {{ $secretName }}
+        probes:
+          liveness:
+            enabled: true
+            type: exec
+            command:
+              - sh
+              - -c
+              - "until pg_isready -U ${POSTGRES_USER} -h localhost; do sleep 2; done"
+          readiness:
+            enabled: true
+            type: exec
+            command:
+              - sh
+              - -c
+              - "until pg_isready -U ${POSTGRES_USER} -h localhost; do sleep 2; done"
+          startup:
+            enabled: true
+            type: exec
+            command:
+              - sh
+              - -c
+              - "until pg_isready -U ${POSTGRES_USER} -h localhost; do sleep 2; done"
+    initContainers:
+    {{- include "ix.v1.common.app.permissions" (dict "UID" 999 "GID" 999) | nindent 6 }}
+postgresbackup:
+  enabled: true
+  type: Job
+  annotations:
+    "helm.sh/hook": pre-upgrade
+    "helm.sh/hook-weight": "1"
+    "helm.sh/hook-delete-policy": hook-succeeded
+  podSpec:
+    restartPolicy: Never
+    containers:
+      postgresbackup:
+        enabled: true
+        primary: true
+        imageSelector: postgresImage
+        securityContext:
+          runAsUser: 999
+          runAsGroup: 999
+          readOnlyRootFilesystem: false
+        probes:
+          liveness:
+            enabled: false
+          readiness:
+            enabled: false
+          startup:
+            enabled: false
+        resources:
+          limits:
+            cpu: 2000m
+            memory: 2Gi
+        envFrom:
+          - secretRef:
+              name: {{ $secretName }}
+        command:
+          - sh
+          - -c
+          - |
+            until pg_isready -U ${POSTGRES_USER} -h ${POSTGRES_HOST}; do sleep 2; done
+            echo "Creating backup of ${POSTGRES_DB} database"
+            pg_dump --dbname=${POSTGRES_URL} --file {{ $backupPath }}/${POSTGRES_DB}_$(date +%Y-%m-%d_%H-%M-%S).sql || echo "Failed to create backup"
+            echo "Backup finished"
+    initContainers:
+    {{- include "ix.v1.common.app.permissions" (dict "UID" 999 "GID" 999 "type" "init") | nindent 6 }}
+{{- end -}}

+ 0 - 0
library/common/1.0.0/templates/class/_configmap.tpl → library/common/templates/class/_configmap.tpl


+ 0 - 0
library/common/1.0.0/templates/class/_cronjob.tpl → library/common/templates/class/_cronjob.tpl


+ 0 - 0
library/common/1.0.0/templates/class/_deployment.tpl → library/common/templates/class/_deployment.tpl


+ 0 - 0
library/common/1.0.0/templates/class/_job.tpl → library/common/templates/class/_job.tpl


+ 0 - 0
library/common/1.0.0/templates/class/_networkAttachmentDefinition.tpl → library/common/templates/class/_networkAttachmentDefinition.tpl


+ 0 - 0
library/common/1.0.0/templates/class/_rbac.tpl → library/common/templates/class/_rbac.tpl


+ 0 - 0
library/common/1.0.0/templates/class/_secret.tpl → library/common/templates/class/_secret.tpl


+ 10 - 9
library/common/1.0.0/templates/class/_service.tpl → library/common/templates/class/_service.tpl

@@ -24,6 +24,11 @@ objectData: The service data, that will be used to render the Service object.
   {{- if $podValues -}}
     {{/* Get Pod hostNetwork configuration */}}
     {{- $hostNetwork = include "ix.v1.common.lib.pod.hostNetwork" (dict "rootCtx" $rootCtx "objectData" $podValues) -}}
+
+    {{/* When hostNetwork is set on the pod, force ClusterIP, so services wont try to bind the same ports on the host */}}
+    {{- if or (and (kindIs "bool" $hostNetwork) $hostNetwork) (and (kindIs "string" $hostNetwork) (eq $hostNetwork "true")) -}}
+      {{- $svcType = "ClusterIP" -}}
+    {{- end -}}
   {{- end -}}
 
   {{- range $portName, $port := $objectData.ports -}}
@@ -34,15 +39,11 @@ objectData: The service data, that will be used to render the Service object.
     {{- end -}}
   {{- end -}}
 
-  {{/* When hostNetwork is set on the pod, force ClusterIP, so services wont try to bind the same ports on the host */}}
-  {{- if or (and (kindIs "bool" $hostNetwork) $hostNetwork) (and (kindIs "string" $hostNetwork) (eq $hostNetwork "true")) -}}
-    {{- $svcType = "ClusterIP" -}}
-  {{- end -}}
-
   {{/* When hostPort is defined, force ClusterIP aswell */}}
   {{- if $hasHostPort -}}
     {{- $svcType = "ClusterIP" -}}
-  {{- end }}
+  {{- end -}}
+  {{- $_ := set $objectData "type" $svcType }}
 
 ---
 apiVersion: v1
@@ -50,7 +51,7 @@ kind: Service
 metadata:
   name: {{ $objectData.name }}
   {{- $labels := (mustMerge ($objectData.labels | default dict) (include "ix.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)
-                            (include "ix.v1.common.lib.metadata.selectorLabels" (dict "rootCtx" $rootCtx "objectType" "service" "objectName" $objectData.name) | fromYaml)) -}}
+                            (include "ix.v1.common.lib.metadata.selectorLabels" (dict "rootCtx" $rootCtx "objectType" "service" "objectName" $objectData.shortName) | fromYaml)) -}}
   {{- with (include "ix.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
   labels:
     {{- . | nindent 4 }}
@@ -61,9 +62,9 @@ metadata:
     {{- . | nindent 4 }}
   {{- end }}
 spec:
-  {{- if eq $svcType "ClusterIP" -}}
+  {{- if eq $objectData.type "ClusterIP" -}}
     {{- include "ix.v1.common.lib.service.spec.clusterIP" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 2 -}}
-  {{- else if eq $svcType "NodePort" -}}
+  {{- else if eq $objectData.type "NodePort" -}}
     {{- include "ix.v1.common.lib.service.spec.nodePort" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 2 -}}
   {{- end -}}
   {{- with (include "ix.v1.common.lib.service.ports" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim) }}

+ 0 - 0
library/common/1.0.0/templates/class/_serviceAccount.tpl → library/common/templates/class/_serviceAccount.tpl


+ 0 - 0
library/common/1.0.0/templates/helpers/_envDupeCheck.tpl → library/common/templates/helpers/_envDupeCheck.tpl


+ 0 - 0
library/common/1.0.0/templates/helpers/_getPortRange.tpl → library/common/templates/helpers/_getPortRange.tpl


+ 0 - 0
library/common/1.0.0/templates/helpers/_getSelectedPod.tpl → library/common/templates/helpers/_getSelectedPod.tpl


+ 0 - 0
library/common/1.0.0/templates/lib/certificate/_getData.tpl → library/common/templates/lib/certificate/_getData.tpl


+ 0 - 0
library/common/1.0.0/templates/lib/certificate/_validation.tpl → library/common/templates/lib/certificate/_validation.tpl


+ 1 - 1
library/common/1.0.0/templates/lib/chart/_names.tpl → library/common/templates/lib/chart/_names.tpl

@@ -27,7 +27,7 @@
 
   {{- $name := .name -}}
 
-  {{- if not (mustRegexMatch "^[a-z0-9]([a-z0-9-]){1,61}[a-z0-9]$" $name) -}}
+  {{- if not (mustRegexMatch "^[a-z0-9]([a-z0-9]-?|-?[a-z0-9]){0,61}[a-z0-9]$" $name) -}}
     {{- fail (printf "Name [%s] is not valid. Must start and end with an alphanumeric lowercase character. It can contain '-'. And must be at most 63 characters." $name) -}}
   {{- end -}}
 

+ 0 - 0
library/common/1.0.0/templates/lib/chart/_notes.tpl → library/common/templates/lib/chart/_notes.tpl


+ 0 - 0
library/common/1.0.0/templates/lib/configmap/_validation.tpl → library/common/templates/lib/configmap/_validation.tpl


+ 0 - 0
library/common/1.0.0/templates/lib/container/_args.tpl → library/common/templates/lib/container/_args.tpl


+ 0 - 0
library/common/1.0.0/templates/lib/container/_command.tpl → library/common/templates/lib/container/_command.tpl


+ 0 - 0
library/common/1.0.0/templates/lib/container/_env.tpl → library/common/templates/lib/container/_env.tpl


+ 0 - 0
library/common/1.0.0/templates/lib/container/_envFrom.tpl → library/common/templates/lib/container/_envFrom.tpl


+ 0 - 0
library/common/1.0.0/templates/lib/container/_envList.tpl → library/common/templates/lib/container/_envList.tpl


+ 8 - 3
library/common/1.0.0/templates/lib/container/_fixedEnv.tpl → library/common/templates/lib/container/_fixedEnv.tpl

@@ -13,7 +13,7 @@ objectData: The object data to be used to render the container.
     {{- $_ := set $objectData "fixedEnv" dict -}}
   {{- end -}}
 
-  {{- $nvidiaCaps := $rootCtx.Values.containerOptions.NVIDIA_CAPS -}}
+  {{- $nvidiaCaps := $rootCtx.Values.resources.NVIDIA_CAPS -}}
 
   {{- if $objectData.fixedEnv.NVIDIA_CAPS -}}
     {{- $nvidiaCaps = $objectData.fixedEnv.NVIDIA_CAPS -}}
@@ -34,8 +34,13 @@ objectData: The object data to be used to render the container.
 
   {{- $fixed := list -}}
   {{- $TZ := $objectData.fixedEnv.TZ | default $rootCtx.Values.TZ -}}
-  {{- $UMASK := $objectData.fixedEnv.UMASK | default $rootCtx.Values.containerOptions.UMASK -}}
-  {{- $PUID := $objectData.fixedEnv.PUID | default $rootCtx.Values.containerOptions.PUID -}}
+  {{- $UMASK := $objectData.fixedEnv.UMASK | default $rootCtx.Values.securityContext.container.UMASK -}}
+
+  {{- $PUID := $objectData.fixedEnv.PUID | default $rootCtx.Values.securityContext.container.PUID -}}
+  {{- if and (not (kindIs "invalid" $objectData.fixedEnv.PUID)) (eq (int $objectData.fixedEnv.PUID) 0) -}}
+    {{- $PUID = $objectData.fixedEnv.PUID -}}
+  {{- end -}}
+
   {{/* calculatedFSGroup is passed from the pod */}}
   {{- $PGID := $objectData.calculatedFSGroup -}}
 

+ 4 - 0
library/common/1.0.0/templates/lib/container/_imageSelector.tpl → library/common/templates/lib/container/_imageSelector.tpl

@@ -29,6 +29,10 @@ objectData: The object data to be used to render the container.
     {{- fail (printf "Container - Expected non-empty <.Values.%s.tag>" $selector) -}}
   {{- end -}}
 
+  {{- if not (kindIs "string" $imageObj.tag) -}}
+    {{- fail (printf "Container - Expected <.Values.%s.tag> to be string, but got [%s]" $selector (kindOf $imageObj.tag)) -}}
+  {{- end -}}
+
   {{- if not $imageObj.pullPolicy -}}
     {{- $_ := set $imageObj "pullPolicy" "IfNotPresent" -}}
   {{- end -}}

+ 0 - 0
library/common/1.0.0/templates/lib/container/_lifecycle.tpl → library/common/templates/lib/container/_lifecycle.tpl


+ 0 - 0
library/common/1.0.0/templates/lib/container/_ports.tpl → library/common/templates/lib/container/_ports.tpl


+ 0 - 0
library/common/1.0.0/templates/lib/container/_primaryValidation.tpl → library/common/templates/lib/container/_primaryValidation.tpl


+ 0 - 0
library/common/1.0.0/templates/lib/container/_probes.tpl → library/common/templates/lib/container/_probes.tpl


+ 1 - 1
library/common/1.0.0/templates/lib/container/_resources.tpl → library/common/templates/lib/container/_resources.tpl

@@ -8,7 +8,7 @@ objectData: The object data to be used to render the container.
   {{- $rootCtx := .rootCtx -}}
   {{- $objectData := .objectData -}}
 
-  {{- $resources := $rootCtx.Values.containerOptions.resources -}}
+  {{- $resources := $rootCtx.Values.resources -}}
 
   {{- if $objectData.resources -}}
     {{- $resources = mustMergeOverwrite $resources $objectData.resources -}}

+ 0 - 0
library/common/1.0.0/templates/lib/container/_securityContext.tpl → library/common/templates/lib/container/_securityContext.tpl


+ 0 - 0
library/common/1.0.0/templates/lib/container/_termination.tpl → library/common/templates/lib/container/_termination.tpl


Неке датотеке нису приказане због велике количине промена