diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 9a6d6be2d1c9ff60634516efdfe771b0ee64c9f9..6bfb7f540852a5ea28560d2a94c341852e62a51c 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -516,6 +516,25 @@ build_tango-panic-gui:
       - images/ska-tango-images-pytango-runtime/*
       - images/ska-tango-images-tango-pytango/*
 
+test-chart-templates:
+  stage: test
+  variables:
+    MINIKUBE: "false"
+  tags:
+  - k8srunner
+  image: $SKA_K8S_TOOLS_DEPLOY_IMAGE
+  script:
+    - helm plugin install https://github.com/quintush/helm-unittest
+    - make chart_test
+    - mkdir -p ./build/reports
+    - mv charts/build/chart_template_tests.xml ./build/reports/chart_template_tests.xml
+  artifacts:
+    name: "$CI_PROJECT_NAME-$CI_JOB_ID"
+    paths:
+      - "build/"
+    reports:
+      junit: build/reports/chart_template_tests.xml
+
 test-chart:
   stage: test
   variables:
diff --git a/.make b/.make
index 9ced8540d41df0f5c68cc503b93be5bdd1518997..3147e518066888b16adebc8126f20ccabdf3b42c 160000
--- a/.make
+++ b/.make
@@ -1 +1 @@
-Subproject commit 9ced8540d41df0f5c68cc503b93be5bdd1518997
+Subproject commit 3147e518066888b16adebc8126f20ccabdf3b42c
diff --git a/Makefile b/Makefile
index bbca64ba5c60a9c80eed87742fc0a5ce8cd65184..427dfed5b5dec260ce095aa1db6ed1af318afba3 100644
--- a/Makefile
+++ b/Makefile
@@ -41,6 +41,9 @@ include .make/release.mk
 # include raw support
 include .make/raw.mk
 
+# include docs support
+include .make/docs.mk
+
 # include your own private variables for custom deployment configuration
 -include PrivateRules.mak
 
@@ -281,6 +284,10 @@ test: helm-pre-publish ## test the application on K8s
 		echo "Status set at \"$$status\" in ./Makefile test target"; \
 		exit $$status
 
+chart_test: helm-pre-publish #clean dep-up
+	helm package charts/ska-tango-util/ -d charts/ska-tango-base/charts/; \
+	mkdir -p charts/build; helm unittest charts/ska-tango-base/ --helm3 --with-subchart --output-type JUnit --output-file charts/build/chart_template_tests.xml; \
+
 show:
 	echo $$TANGO_HOST
 
diff --git a/charts/ska-tango-base/templates/databaseds.yaml b/charts/ska-tango-base/templates/databaseds.yaml
index 755bde13291cec16a8167f22532bf82ce906f650..ad3230ac11e96197d400cda806b1e319a5c55f2a 100644
--- a/charts/ska-tango-base/templates/databaseds.yaml
+++ b/charts/ska-tango-base/templates/databaseds.yaml
@@ -14,8 +14,10 @@ metadata:
     domain: {{ .Values.databaseds.domain }}
     intent: {{ .Values.databaseds.intent }}
 {{ toYaml (coalesce .Values.global.labels .Values.labels "label:none") | indent 4 }}
+{{ if or (.Values.global.annotations) (.Values.annotations) }}
   annotations:
-{{ toYaml (coalesce .Values.global.annotations .Values.annotations "annotations:none") | indent 4 }}
+{{ toYaml (coalesce .Values.global.annotations .Values.annotations) | indent 4 }}
+{{ end }}
 spec:
   ports:
   - name: ds
@@ -41,8 +43,10 @@ metadata:
     domain: {{ .Values.databaseds.domain }}
     intent: {{ .Values.databaseds.intent }}
 {{ toYaml (coalesce .Values.global.labels .Values.labels "label:none") | indent 4 }}
+{{ if or (.Values.global.annotations) (.Values.annotations) }}
   annotations:
-{{ toYaml (coalesce .Values.global.annotations .Values.annotations "annotations:none") | indent 4 }}
+{{ toYaml (coalesce .Values.global.annotations .Values.annotations) | indent 4 }}
+{{ end }}
 spec:
   selector:
     matchLabels:
diff --git a/charts/ska-tango-base/templates/ingress.yaml b/charts/ska-tango-base/templates/ingress.yaml
index 87456e04b51b2cee4c6ab61d633a554fb8d812ed..2dcdfaadfedff6e37fa87622e151e6d845ae1fb1 100644
--- a/charts/ska-tango-base/templates/ingress.yaml
+++ b/charts/ska-tango-base/templates/ingress.yaml
@@ -15,7 +15,9 @@ metadata:
   annotations:
     kubernetes.io/ingress.class: nginx
     nginx.ingress.kubernetes.io/rewrite-target: /$1
-{{ toYaml (coalesce .Values.global.annotations .Values.annotations "annotations:none") | indent 4 }}
+{{ if or (.Values.global.annotations) (.Values.annotations) }}
+{{ toYaml (coalesce .Values.global.annotations .Values.annotations) | indent 4 }}
+{{ end }}
 spec:
   rules:
     - http:
@@ -43,7 +45,9 @@ metadata:
   annotations:
     kubernetes.io/ingress.class: traefik
     traefik.ingress.kubernetes.io/request-modifier: "ReplacePathRegex: /{{ .Release.Namespace }}/(.*) /$1"
-{{ toYaml (coalesce .Values.global.annotations .Values.annotations "annotations:none") | indent 4 }}
+{{ if or (.Values.global.annotations) (.Values.annotations) }}
+{{ toYaml (coalesce .Values.global.annotations .Values.annotations) | indent 4 }}
+{{ end }}
 spec:
   rules:
     - http:
diff --git a/charts/ska-tango-base/templates/itango.yaml b/charts/ska-tango-base/templates/itango.yaml
index 731c59be18c4128b2796f09a1878be8a86d1cf7b..2a56b4fe70670374bd1a95c850a4d86e5e20dd8f 100644
--- a/charts/ska-tango-base/templates/itango.yaml
+++ b/charts/ska-tango-base/templates/itango.yaml
@@ -16,8 +16,10 @@ metadata:
     function: {{ .Values.itango.function }}
     domain: {{ .Values.itango.domain }}
     intent: {{ .Values.itango.intent }}
+{{ if or (.Values.global.annotations) (.Values.annotations) }}
   annotations:
-{{ toYaml (coalesce .Values.global.annotations .Values.annotations "annotations:none") | indent 4 }}
+{{ toYaml (coalesce .Values.global.annotations .Values.annotations) | indent 4 }}
+{{ end }}
 spec:
   initContainers:
   - name: check-dependencies-0
diff --git a/charts/ska-tango-base/templates/jive.yaml b/charts/ska-tango-base/templates/jive.yaml
index 1b49dee49959d9edb05dd6cd6aece4938cedd747..72508fb4249db2f1ab96b245b2c0e5a33a135264 100644
--- a/charts/ska-tango-base/templates/jive.yaml
+++ b/charts/ska-tango-base/templates/jive.yaml
@@ -12,8 +12,10 @@ metadata:
     function: {{ .Values.jive.function }}
     domain: {{ .Values.jive.domain }}
     intent: {{ .Values.jive.intent }}
+{{ if or (.Values.global.annotations) (.Values.annotations) }}
   annotations:
-{{ toYaml (coalesce .Values.global.annotations .Values.annotations "annotations:none") | indent 4 }}
+{{ toYaml (coalesce .Values.global.annotations .Values.annotations) | indent 4 }}
+{{ end }}
 spec:
   containers:
   - name: jive
diff --git a/charts/ska-tango-base/templates/logviewer.yaml b/charts/ska-tango-base/templates/logviewer.yaml
index 890df9f090227b2f2d68e2c44ab5dfd5f9f9bcd1..295e7c3f7237e617b273f8f69b40468fbebc8e9a 100644
--- a/charts/ska-tango-base/templates/logviewer.yaml
+++ b/charts/ska-tango-base/templates/logviewer.yaml
@@ -12,8 +12,10 @@ metadata:
     function: {{ .Values.logviewer.function }}
     domain: {{ .Values.logviewer.domain }}
     intent: {{ .Values.logviewer.intent }}
+{{ if or (.Values.global.annotations) (.Values.annotations) }}
   annotations:
-{{ toYaml (coalesce .Values.global.annotations .Values.annotations "annotations:none") | indent 4 }}
+{{ toYaml (coalesce .Values.global.annotations .Values.annotations) | indent 4 }}
+{{ end }}
 spec:
   containers:
   - name: logviewer
diff --git a/charts/ska-tango-base/templates/tango-rest.yaml b/charts/ska-tango-base/templates/tango-rest.yaml
index ef8f87345a7f5b89c55e6b9e44c487a234ef024d..c4fa9a56c9669f86c1bd2c757c61ece4191e4f0a 100644
--- a/charts/ska-tango-base/templates/tango-rest.yaml
+++ b/charts/ska-tango-base/templates/tango-rest.yaml
@@ -40,8 +40,10 @@ metadata:
     function: {{ .Values.tangorest.function }}
     domain: {{ .Values.tangorest.domain }}
     intent: {{ .Values.tangorest.intent }}
+{{ if or (.Values.global.annotations) (.Values.annotations) }}
   annotations:
-{{ toYaml (coalesce .Values.global.annotations .Values.annotations "annotations:none") | indent 4 }}
+{{ toYaml (coalesce .Values.global.annotations .Values.annotations) | indent 4 }}
+{{ end }}
 spec:
   selector:
     matchLabels:
@@ -59,8 +61,10 @@ spec:
         function: {{ .Values.tangorest.function }}
         domain: {{ .Values.tangorest.domain }}
         intent: {{ .Values.tangorest.intent }}
+{{ if or (.Values.global.annotations) (.Values.annotations) }}
       annotations:
-{{ toYaml (coalesce .Values.global.annotations .Values.annotations "annotations:none") | indent 8 }}
+{{ toYaml (coalesce .Values.global.annotations .Values.annotations) | indent 8 }}
+{{ end }}
     spec:
       {{- if .Values.pullSecrets }}
       imagePullSecrets:
diff --git a/charts/ska-tango-base/templates/tangodb-pv.yaml b/charts/ska-tango-base/templates/tangodb-pv.yaml
index 2b485d04cd8bd8cf730f01784222bdff736cf2d4..89f0ef891025dce6bc6c330c331cf8279d50cbeb 100644
--- a/charts/ska-tango-base/templates/tangodb-pv.yaml
+++ b/charts/ska-tango-base/templates/tangodb-pv.yaml
@@ -10,8 +10,10 @@ metadata:
   namespace: {{ .Release.Namespace }}
   labels:
 {{ toYaml (coalesce .Values.global.labels .Values.labels "label:none") | indent 4 }}
+{{ if or (.Values.global.annotations) (.Values.annotations) }}
   annotations:
-{{ toYaml (coalesce .Values.global.annotations .Values.annotations "annotations:none") | indent 4 }}
+{{ toYaml (coalesce .Values.global.annotations .Values.annotations) | indent 4 }}
+{{ end }}
 spec:
   storageClassName: standard
   persistentVolumeReclaimPolicy: Recycle
@@ -31,8 +33,10 @@ metadata:
   namespace: {{ .Release.Namespace }}
   labels:
 {{ toYaml (coalesce .Values.global.labels .Values.labels "label:none") | indent 4 }}
+{{ if or (.Values.global.annotations) (.Values.annotations) }}
   annotations:
-{{ toYaml (coalesce .Values.global.annotations .Values.annotations "annotations:none") | indent 4 }}
+{{ toYaml (coalesce .Values.global.annotations .Values.annotations) | indent 4 }}
+{{ end }}
 spec:
 {{ if (coalesce .Values.global.minikube .Values.minikube false)  }}
   storageClassName: standard
diff --git a/charts/ska-tango-base/templates/tangodb.yaml b/charts/ska-tango-base/templates/tangodb.yaml
index 40be53f88e9d047cb56465fc0d3e574e54ae3534..b6441331864805ca10ad3a293f542be61dde1253 100644
--- a/charts/ska-tango-base/templates/tangodb.yaml
+++ b/charts/ska-tango-base/templates/tangodb.yaml
@@ -12,8 +12,10 @@ metadata:
     domain: {{ .Values.tangodb.domain }}
     intent: {{ .Values.tangodb.intent }}
 {{ toYaml (coalesce .Values.global.labels .Values.labels "label:none") | indent 4 }}
+{{ if or (.Values.global.annotations) (.Values.annotations) }}
   annotations:
-{{ toYaml (coalesce .Values.global.annotations .Values.annotations "annotations:none") | indent 4 }}
+{{ toYaml (coalesce .Values.global.annotations .Values.annotations) | indent 4 }}
+{{ end }}
 spec:
   ports:
   - name: mysql
@@ -39,8 +41,10 @@ metadata:
     domain: {{ .Values.tangodb.domain }}
     intent: {{ .Values.tangodb.intent }}
 {{ toYaml (coalesce .Values.global.labels .Values.labels "label:none") | indent 4 }}
+{{ if or (.Values.global.annotations) (.Values.annotations) }}
   annotations:
-{{ toYaml (coalesce .Values.global.annotations .Values.annotations "annotations:none") | indent 4 }}
+{{ toYaml (coalesce .Values.global.annotations .Values.annotations) | indent 4 }}
+{{ end }}
 spec:
   selector:
     matchLabels:
@@ -59,8 +63,10 @@ spec:
         domain: {{ .Values.tangodb.domain }}
         intent: {{ .Values.tangodb.intent }}
 {{ toYaml (coalesce .Values.global.labels .Values.labels "label:none") | indent 8 }}
+{{ if or (.Values.global.annotations) (.Values.annotations) }}
       annotations:
-{{ toYaml (coalesce .Values.global.annotations .Values.annotations "annotations:none") | indent 8 }}
+{{ toYaml (coalesce .Values.global.annotations .Values.annotations) | indent 8 }}
+{{ end }}
     spec:
       containers:
       - name: tangodb
diff --git a/charts/ska-tango-base/templates/vnc.yaml b/charts/ska-tango-base/templates/vnc.yaml
index c1dde00f58b564951a6a659ba82d55a6f8e599a9..3405f0069ea3e44f77cee47d91323d41567309cf 100644
--- a/charts/ska-tango-base/templates/vnc.yaml
+++ b/charts/ska-tango-base/templates/vnc.yaml
@@ -12,8 +12,10 @@ metadata:
     domain: {{ .Values.vnc.domain }}
     intent: {{ .Values.vnc.intent }}
 {{ toYaml (coalesce .Values.global.labels .Values.labels "label:none") | indent 4 }}
+{{ if or (.Values.global.annotations) (.Values.annotations) }}
   annotations:
-{{ toYaml (coalesce .Values.global.annotations .Values.annotations "annotations:none") | indent 4 }}
+{{ toYaml (coalesce .Values.global.annotations .Values.annotations) | indent 4 }}
+{{ end }}
 spec:
   type: NodePort
   ports:
@@ -48,8 +50,10 @@ metadata:
     domain: {{ .Values.vnc.domain }}
     intent: {{ .Values.vnc.intent }}
 {{ toYaml (coalesce .Values.global.labels .Values.labels "label:none") | indent 4 }}
+{{ if or (.Values.global.annotations) (.Values.annotations) }}
   annotations:
-{{ toYaml (coalesce .Values.global.annotations .Values.annotations "annotations:none") | indent 4 }}
+{{ toYaml (coalesce .Values.global.annotations .Values.annotations) | indent 4 }}
+{{ end }}
 spec:
   selector:
     matchLabels:
@@ -68,8 +72,10 @@ spec:
         domain: {{ .Values.vnc.domain }}
         intent: {{ .Values.vnc.intent }}
 {{ toYaml (coalesce .Values.global.labels .Values.labels "label:none") | indent 8 }}
+{{ if or (.Values.global.annotations) (.Values.annotations) }}
       annotations:
-{{ toYaml (coalesce .Values.global.annotations .Values.annotations "annotations:none") | indent 8 }}
+{{ toYaml (coalesce .Values.global.annotations .Values.annotations) | indent 8 }}
+{{ end }}
     spec:
       containers:
       - name: vnc
diff --git a/charts/ska-tango-base/tests/deviceservers_test.yaml b/charts/ska-tango-base/tests/deviceservers_test.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e1e7d4fa433071853d564060bc74ee6dea0ef26d
--- /dev/null
+++ b/charts/ska-tango-base/tests/deviceservers_test.yaml
@@ -0,0 +1,299 @@
+---
+suite: deviceservers
+templates:
+  - deviceservers.yaml
+tests:
+  - it: should have the readiness probes setup using the parameters in the values.yaml file.
+    documentIndex: 6
+    asserts:
+      - isNotEmpty:
+          path: spec.template.spec.containers[0].readinessProbe
+      - equal:
+          path: spec.template.spec.containers[0].readinessProbe
+          value:
+            exec:
+              command:
+              - sh
+              - -c
+              - tango_admin
+              - --ping-device
+              - sys/tg_test/1
+            failureThreshold: 3
+            initialDelaySeconds: 0
+            periodSeconds: 10
+            successThreshold: 1
+            timeoutSeconds: 1
+  - it: should have the liveness probes setup using the parameters in the values.yaml file.
+    documentIndex: 6
+    asserts:
+      - isNotEmpty:
+          path: spec.template.spec.containers[0].livenessProbe
+      - equal:
+          path: spec.template.spec.containers[0].livenessProbe
+          value:
+            exec:
+              command:
+              - sh
+              - -c
+              - tango_admin
+              - --ping-device
+              - sys/tg_test/1
+            failureThreshold: 3
+            initialDelaySeconds: 0
+            periodSeconds: 10
+            successThreshold: 1
+            timeoutSeconds: 1
+  - it: should generate readiness and liveness probes for a TANGO server instance with one Tango class and multiple devices.
+    documentIndex: 6
+    set:
+      deviceServers:
+        tangotest:
+          server:
+            name: "TangoTest"
+            instances:
+            - name: "test"
+              classes:
+              - name: "TangoTest"
+                devices:
+                - name: "sys/tg_test/1"
+                - name: "sys/tg_test/2"
+                - name: "sys/tg_test/3"
+    asserts:
+      - isNotEmpty:
+          path: spec.template.spec.containers[0].livenessProbe
+      - isNotEmpty:
+          path: spec.template.spec.containers[0].readinessProbe
+      - equal:
+          path: spec.template.spec.containers[0].livenessProbe.exec.command
+          value:
+            - sh
+            - -c
+            - tango_admin 
+            - --ping-device
+            - sys/tg_test/1
+            - "&&"
+            - tango_admin
+            - --ping-device
+            - sys/tg_test/2
+            - "&&"
+            - tango_admin
+            - --ping-device
+            - sys/tg_test/3
+      - equal:
+          path: spec.template.spec.containers[0].readinessProbe.exec.command
+          value:
+            - sh
+            - -c
+            - tango_admin 
+            - --ping-device
+            - sys/tg_test/1
+            - "&&"
+            - tango_admin
+            - --ping-device
+            - sys/tg_test/2
+            - "&&"
+            - tango_admin
+            - --ping-device
+            - sys/tg_test/3
+  - it: should use the appropriate values to generate the liveness and readiness probes from both the values.yaml and the _multidevice-svc.yaml files, respectively.
+    documentIndex: 6
+    set:
+      deviceServers:
+        tangotest:
+          livenessProbe:
+            failureThreshold: null
+            periodSeconds: null
+          readinessProbe:
+            timeoutSeconds: null
+            successThreshold: null
+    asserts:
+      - equal:
+          path: spec.template.spec.containers[0].livenessProbe
+          value:
+            exec:
+              command:
+              - sh
+              - -c
+              - tango_admin
+              - --ping-device
+              - sys/tg_test/1
+            failureThreshold: 3
+            initialDelaySeconds: 0
+            periodSeconds: 5
+            successThreshold: 1
+            timeoutSeconds: 1
+      - equal:
+          path: spec.template.spec.containers[0].readinessProbe
+          value:
+            exec:
+              command:
+              - sh
+              - -c
+              - tango_admin
+              - --ping-device
+              - sys/tg_test/1
+            failureThreshold: 3
+            initialDelaySeconds: 0
+            periodSeconds: 10
+            successThreshold: 1
+            timeoutSeconds: 1
+  - it: should use default values (from the _multidevice-svc.yaml) to generate the liveness and readiness probes if the readinessProbe/livenessProbe tags are not present in the values.yaml file.
+    documentIndex: 6
+    set:
+      deviceServers:
+        tangotest:
+          livenessProbe: null
+          readinessProbe: null
+    asserts:
+      - isNotEmpty:
+          path: spec.template.spec.containers[0].livenessProbe
+      - equal:
+          path: spec.template.spec.containers[0].livenessProbe
+          value:
+            exec:
+              command:
+              - sh
+              - -c
+              - tango_admin
+              - --ping-device
+              - sys/tg_test/1
+            failureThreshold: 3
+            initialDelaySeconds: 0
+            periodSeconds: 5
+            successThreshold: 1
+            timeoutSeconds: 1
+      - equal:
+          path: spec.template.spec.containers[0].readinessProbe
+          value:
+            exec:
+              command:
+              - sh
+              - -c
+              - tango_admin
+              - --ping-device
+              - sys/tg_test/1
+            failureThreshold: 3
+            initialDelaySeconds: 0
+            periodSeconds: 5
+            successThreshold: 1
+            timeoutSeconds: 1
+  - it: should generate liveness and readiness probes for a TANGO server instance with multiple TANGO classes.
+    documentIndex: 6
+    set:
+      deviceServers:
+        tangotest:
+          server:
+            name: "TangoTest"
+            instances:
+            - name: "test"
+              classes:
+              - name: "TangoTest1"
+                devices:
+                - name: "sys/tg_test/11"
+              - name: "TangoTest2"
+                devices:
+                - name: "sys/tg_test/12"
+              - name: "TangoTest3"
+                devices:
+                - name: "sys/tg_test/13"
+    asserts:
+      - equal:
+          path: spec.template.spec.containers[0].command
+          value:
+            - retry
+            - --sleep=1
+            - --tries=100
+            - --
+            - /usr/local/bin/TangoTest
+            - "test"
+      - equal:
+          path: spec.template.spec.containers[0].readinessProbe
+          value:
+            exec:
+              command:
+              - sh
+              - -c
+              - tango_admin
+              - --ping-device
+              - sys/tg_test/11
+              - "&&"
+              - tango_admin
+              - --ping-device
+              - sys/tg_test/12
+              - "&&"
+              - tango_admin
+              - --ping-device
+              - sys/tg_test/13
+            failureThreshold: 3
+            initialDelaySeconds: 0
+            periodSeconds: 10
+            successThreshold: 1
+            timeoutSeconds: 1
+      - equal:
+          path: spec.template.spec.containers[0].livenessProbe
+          value:
+            exec:
+              command:
+              - sh
+              - -c
+              - tango_admin
+              - --ping-device
+              - sys/tg_test/11
+              - "&&"
+              - tango_admin
+              - --ping-device
+              - sys/tg_test/12
+              - "&&"
+              - tango_admin
+              - --ping-device
+              - sys/tg_test/13
+            failureThreshold: 3
+            initialDelaySeconds: 0
+            periodSeconds: 10
+            successThreshold: 1
+            timeoutSeconds: 1
+  - it: should generate multiple StatefulSet resources for a TANGO server with multiple server instances.
+    set:
+      deviceServers:
+        tangotest:
+          instances: ["test", "test2"]
+          server:
+            instances:
+            - name: "test"
+              classes:
+              - name: "TangoTest1"
+                devices:
+                - name: "sys/tg_test/1"
+            - name: "test2"
+              classes:
+              - name: "TangoTest2"
+                devices:
+                - name: "sys/tg_test/2"
+    asserts:
+      - isKind:
+          of: StatefulSet
+        documentIndex: 6
+      - equal:
+          path: spec.template.spec.containers[0].command
+          value:
+            - retry
+            - --sleep=1
+            - --tries=100
+            - --
+            - /usr/local/bin/TangoTest
+            - "test"
+        documentIndex: 6
+      - isKind:
+          of: StatefulSet
+        documentIndex: 8
+      - equal:
+          path: spec.template.spec.containers[0].command
+          value:
+            - retry
+            - --sleep=1
+            - --tries=100
+            - --
+            - /usr/local/bin/TangoTest
+            - "test2"
+        documentIndex: 8
+
diff --git a/charts/ska-tango-base/values.yaml.sh b/charts/ska-tango-base/values.yaml.sh
index 6a4874d2ba711bf3b782693ff0ae18cb5e59577b..c7142f1fd47cb0c8bfea7dd878cb1aacc8533df4 100644
--- a/charts/ska-tango-base/values.yaml.sh
+++ b/charts/ska-tango-base/values.yaml.sh
@@ -17,10 +17,10 @@ cat <<EOF > ${VALUES_YAML}
 # This is a YAML-formatted file.
 # Declare variables to be passed into your templates.
 
-global:
-  annotations:
-    app.gitlab.com/app: CI_PROJECT_PATH_SLUG
-    app.gitlab.com/env: CI_ENVIRONMENT_SLUG
+# global:
+#   annotations:
+#     app.gitlab.com/app: CI_PROJECT_PATH_SLUG
+#     app.gitlab.com/env: CI_ENVIRONMENT_SLUG
   # by setting this parameter we can disable the lower level sub-system tango-base, archiver and webjive
   # sub-system:
   #   tango-base:
@@ -122,7 +122,8 @@ databaseds:
     failureThreshold: 3
 
 deviceServers:
-  - name: tangotest
+  tangotest:
+    name: tangotest
     function: tango-test
     domain: tango-base
     command: "/usr/local/bin/TangoTest"
@@ -152,6 +153,18 @@ deviceServers:
         cpu: 500m     # 500m = 0.5 CPU
         memory: 512Mi # 512Mi = 0.5 GB mem
         ephemeral-storage: 1Gi
+    livenessProbe:
+      initialDelaySeconds: 0
+      periodSeconds: 10
+      timeoutSeconds: 1
+      successThreshold: 1
+      failureThreshold: 3
+    readinessProbe:
+      initialDelaySeconds: 0
+      periodSeconds: 10
+      timeoutSeconds: 1
+      successThreshold: 1
+      failureThreshold: 3
 
 tangodb:
   enabled: true
diff --git a/charts/ska-tango-util/templates/_multidevice-svc.yaml b/charts/ska-tango-util/templates/_multidevice-svc.yaml
index cfe3aa66262bebea1b11b60da95111f6e0d13cd3..39cc847693215bf913e881a8d08d751ab897a986 100644
--- a/charts/ska-tango-util/templates/_multidevice-svc.yaml
+++ b/charts/ska-tango-util/templates/_multidevice-svc.yaml
@@ -9,7 +9,7 @@ Parameters:
 {{ define "ska-tango-util.multidevice-svc.tpl" }}
 ---
 {{ $labels := coalesce .local.Values.global.labels .local.Values.labels "label:none" }}
-{{ $annotations := coalesce .local.Values.global.annotations .local.Values.annotations "annotations:none" }}
+{{ $annotations := coalesce .local.Values.global.annotations .local.Values.annotations }}
 {{ $default_tango_host := printf "%s-%s:10000" "databaseds-tango-base-" .local.Release.Name }}
 {{ $tango_host := tpl (coalesce .local.Values.global.tango_host .local.Values.tango_host $default_tango_host | toString) .local }}
 {{ $dsconfig := coalesce .local.Values.global.dsconfig .local.Values.dsconfig}}
@@ -18,6 +18,31 @@ Parameters:
 {{ $deviceserver_name := tpl (coalesce .name .deviceserver.name | toString) .local }}
 {{ $kubectl_wait_timeout := coalesce $dsconfig.timeout "120s" }}
 
+{{ $lprobe_initial_delay_seconds := 0 }}
+{{ $lprobe_period_seconds := 5 }}
+{{ $lprobe_timeout_seconds := 1 }}
+{{ $lprobe_success_threshold := 1 }}
+{{ $lprobe_failure_threshold := 3 }}
+{{ if $deviceserver.livenessProbe }}
+{{ $lprobe_initial_delay_seconds = coalesce $deviceserver.livenessProbe.initialDelaySeconds $lprobe_initial_delay_seconds }}
+{{ $lprobe_period_seconds = coalesce $deviceserver.livenessProbe.periodSeconds $lprobe_period_seconds }}
+{{ $lprobe_timeout_seconds = coalesce $deviceserver.livenessProbe.timeoutSeconds $lprobe_timeout_seconds }}
+{{ $lprobe_success_threshold = coalesce $deviceserver.livenessProbe.successThreshold $lprobe_success_threshold }}
+{{ $lprobe_failure_threshold = coalesce $deviceserver.livenessProbe.failureThreshold $lprobe_failure_threshold }}
+{{ end }}
+
+{{ $rprobe_initial_delay_seconds := 0 }}
+{{ $rprobe_period_seconds := 5 }}
+{{ $rprobe_timeout_seconds := 1 }}
+{{ $rprobe_success_threshold := 1 }}
+{{ $rprobe_failure_threshold := 3 }}
+{{ if $deviceserver.readinessProbe }}
+{{ $rprobe_initial_delay_seconds = coalesce $deviceserver.readinessProbe.initialDelaySeconds $rprobe_initial_delay_seconds }}
+{{ $rprobe_period_seconds = coalesce $deviceserver.readinessProbe.periodSeconds $rprobe_period_seconds }}
+{{ $rprobe_timeout_seconds = coalesce $deviceserver.readinessProbe.timeoutSeconds $rprobe_timeout_seconds }}
+{{ $rprobe_success_threshold = coalesce $deviceserver.readinessProbe.successThreshold $rprobe_success_threshold }}
+{{ $rprobe_failure_threshold = coalesce $deviceserver.readinessProbe.failureThreshold $rprobe_failure_threshold }}
+{{ end }}
 ---
 {{ range $instance := $deviceserver.server.instances }}
 {{ $safe_instance := $instance.name | toString | replace "_" "-" }}
@@ -36,8 +61,10 @@ metadata:
     function: {{ $deviceserver.function }}
     domain: {{ $deviceserver.domain }}
     subsystem: {{ $chart.Values.subsystem }}
+{{ if $annotations }}
   annotations:
 {{ toYaml $annotations | indent 4 }}
+{{ end }}
 spec:
   selector:
     subsystem: {{ $chart.Values.subsystem }}
@@ -55,8 +82,10 @@ metadata:
     function: {{ $deviceserver.function }}
     domain: {{ $deviceserver.domain }}
     subsystem: {{ $chart.Values.subsystem }}
+{{ if $annotations }}
   annotations:
 {{ toYaml $annotations | indent 4 }}
+{{ end }}
 spec:
   selector:
     matchLabels:
@@ -72,8 +101,10 @@ spec:
         domain: {{ $deviceserver.domain }}
         subsystem: {{ $chart.Values.subsystem }}
 {{ toYaml $labels | indent 8 }}
+    {{ if $annotations }}
       annotations:
 {{ toYaml $annotations | indent 8 }}
+    {{ end }}
     spec:
       volumes:
         - name: configuration
@@ -175,6 +206,58 @@ spec:
           - name: configuration
             mountPath: data
             readOnly: true
+        livenessProbe:
+          exec:
+            command:
+            - "sh"
+            - "-c"
+          {{- range $index_class, $class := $instance.classes }}
+          {{ $num_of_classes := len $instance.classes }}
+          {{ $num_of_classes = sub $num_of_classes 1 }}
+          {{ $num_of_devices := len $class.devices }}
+          {{ $num_of_devices = sub $num_of_devices 1 }}
+          {{- range $index_device, $device := $class.devices }}
+            - tango_admin
+            - --ping-device
+          {{ if or (lt $index_class $num_of_classes) (lt $index_device  $num_of_devices)  }}
+            - {{ $device.name }}
+            - "&&"
+          {{ else }}
+            - {{ $device.name }}
+          {{ end }}
+          {{ end }}
+          {{ end }}
+          initialDelaySeconds: {{ default 0 $lprobe_initial_delay_seconds }}
+          periodSeconds: {{ $lprobe_period_seconds }}
+          timeoutSeconds: {{ $lprobe_timeout_seconds }}
+          successThreshold: {{ $lprobe_success_threshold }}
+          failureThreshold: {{ $lprobe_failure_threshold }}
+        readinessProbe:
+          exec:
+            command:
+            - "sh"
+            - "-c"
+          {{- range $index_class, $class := $instance.classes }}
+          {{ $num_of_classes := len $instance.classes }}
+          {{ $num_of_classes = sub $num_of_classes 1 }}
+          {{ $num_of_devices := len $class.devices }}
+          {{ $num_of_devices = sub $num_of_devices 1 }}
+          {{- range $index_device, $device := $class.devices }}
+            - tango_admin
+            - --ping-device
+          {{ if or (lt $index_class $num_of_classes) (lt $index_device  $num_of_devices)  }}
+            - {{ $device.name }}
+            - "&&"
+          {{ else }}
+            - {{ $device.name }}
+          {{ end }}
+          {{ end }}
+          {{ end }}
+          initialDelaySeconds: {{ default 0 $rprobe_initial_delay_seconds }}
+          periodSeconds: {{ $rprobe_period_seconds }}
+          timeoutSeconds: {{ $rprobe_timeout_seconds }}
+          successThreshold: {{ $rprobe_success_threshold }}
+          failureThreshold: {{ $rprobe_failure_threshold }}
         env:
         - name: TANGO_HOST
           value: {{ $tango_host }}