diff --git a/.github/workflows/kubernetes-charts-build.yaml b/.github/workflows/kubernetes-charts-build.yaml index 5888cba..bd34fd2 100644 --- a/.github/workflows/kubernetes-charts-build.yaml +++ b/.github/workflows/kubernetes-charts-build.yaml @@ -47,6 +47,20 @@ jobs: echo "changed=true" >> "$GITHUB_OUTPUT" fi + - name: Recursive dependency update + if: steps.list-changed.outputs.changed == 'true' + working-directory: . + run: | + # Run twice so subcharts get their deps first, then umbrella gets updated copies (with nested deps) + for _ in 1 2; do + for chart in deployment/kubernetes/charts/*/; do + if [[ -f "${chart}Chart.yaml" ]] && grep -q "^dependencies:" "${chart}Chart.yaml" 2>/dev/null; then + echo "Updating dependencies for $chart" + helm dependency update "$chart" + fi + done + done + - name: Run chart-testing (lint) if: steps.list-changed.outputs.changed == 'true' working-directory: . diff --git a/deployment/kubernetes/charts/cogstack-helm-ce/Chart.lock b/deployment/kubernetes/charts/cogstack-helm-ce/Chart.lock index c968dc0..d201f3d 100644 --- a/deployment/kubernetes/charts/cogstack-helm-ce/Chart.lock +++ b/deployment/kubernetes/charts/cogstack-helm-ce/Chart.lock @@ -8,5 +8,5 @@ dependencies: - name: medcat-trainer-helm repository: file://../medcat-trainer-helm version: 0.0.1 -digest: sha256:ed3f7c95117421145affc912bbec79151b7dd55062c7358b837074f0e0bf4641 -generated: "2026-02-26T12:55:11.318221565Z" +digest: sha256:08371a768a9f330606777903fab163ca84918222bbe3f516fab2772f5563d390 +generated: "2026-02-26T15:00:09.073243923Z" diff --git a/deployment/kubernetes/charts/cogstack-helm-ce/Chart.yaml b/deployment/kubernetes/charts/cogstack-helm-ce/Chart.yaml index d526459..83f76da 100644 --- a/deployment/kubernetes/charts/cogstack-helm-ce/Chart.yaml +++ b/deployment/kubernetes/charts/cogstack-helm-ce/Chart.yaml @@ -27,6 +27,8 @@ maintainers: - name: alhendrickson email: alistair@cogstack.org +icon: "https://avatars.githubusercontent.com/u/28688163" + dependencies: - name: medcat-service-helm alias: medcat-service @@ -37,5 +39,6 @@ dependencies: version: "0.0.1" repository: "file://../medcat-service-helm" - name: medcat-trainer-helm + alias: medcat-trainer version: "0.0.1" repository: "file://../medcat-trainer-helm" diff --git a/deployment/kubernetes/charts/cogstack-helm-ce/README.md b/deployment/kubernetes/charts/cogstack-helm-ce/README.md index 207b334..53712fb 100644 --- a/deployment/kubernetes/charts/cogstack-helm-ce/README.md +++ b/deployment/kubernetes/charts/cogstack-helm-ce/README.md @@ -15,23 +15,12 @@ This chart is an umbrella chart that deploys: ## Prerequisites - Kubernetes cluster -- Helm 3 +- Helm 3+ ## Installation -From the chart directory (or repo root), update dependencies and install: - -```bash -cd deployment/kubernetes/charts/cogstack-helm-ce -helm dependency update -helm install cogstack-ce . --namespace cogstack --create-namespace -``` - -Or from the repo root: - -```bash -helm dependency update deployment/kubernetes/charts/cogstack-helm-ce -helm install cogstack-ce deployment/kubernetes/charts/cogstack-helm-ce --namespace cogstack --create-namespace +```sh +helm install cogstack oci://registry-1.docker.io/cogstacksystems/cogstack-helm-ce ``` ## Configuration @@ -67,7 +56,7 @@ anoncat-service: Install with overrides: ```bash -helm install cogstack-ce . -f my-values.yaml --namespace cogstack --create-namespace +helm install cogstack . -f my-values.yaml --namespace cogstack --create-namespace ``` ## Dependencies diff --git a/deployment/kubernetes/charts/cogstack-helm-ce/templates/NOTES.txt b/deployment/kubernetes/charts/cogstack-helm-ce/templates/NOTES.txt index e69de29..c089821 100644 --- a/deployment/kubernetes/charts/cogstack-helm-ce/templates/NOTES.txt +++ b/deployment/kubernetes/charts/cogstack-helm-ce/templates/NOTES.txt @@ -0,0 +1,21 @@ +# CogStack Community Edition is installed + +# 1. AnonCAT Service port forward +export ANONCAT_POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name=anoncat-service,app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") +export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $ANONCAT_POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") +kubectl --namespace {{ .Release.Namespace }} port-forward $ANONCAT_POD_NAME 5001:$CONTAINER_PORT --pod-running-timeout=5m0s & + +# 2.Medcat service port forward +export MEDCAT_POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name=anoncat-service,app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") +export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $MEDCAT_POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") +kubectl --namespace {{ .Release.Namespace }} port-forward $MEDCAT_POD_NAME 5000:$CONTAINER_PORT --pod-running-timeout=5m0s & + +# 3. MedCAT Trainer Port forward +export TRAINER_POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name=medcat-trainer,app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") +export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $TRAINER_POD_NAME -o jsonpath="{.spec.containers[?(@.name==\"nginx\")].ports[0].containerPort}") +export CONTAINER_PORT_API=$(kubectl get pod --namespace {{ .Release.Namespace }} $TRAINER_POD_NAME -o jsonpath="{.spec.containers[?(@.name==\"medcat-trainer\")].ports[0].containerPort}") +kubectl --namespace {{ .Release.Namespace }} port-forward $TRAINER_POD_NAME 8000:$CONTAINER_PORT 8001:$CONTAINER_PORT_API & + +echo "Visit http://127.0.0.1:5000 to use MedCAT Service" +echo "Visit http://127.0.0.1:5001 to use AnonCAT" +echo "Visit http://127.0.0.1:8000 to use MedCAT Trainer" \ No newline at end of file diff --git a/deployment/kubernetes/charts/medcat-service-helm/templates/tests/test-acceptance.yaml b/deployment/kubernetes/charts/medcat-service-helm/templates/tests/test-acceptance.yaml index f8048c4..fb8efaa 100644 --- a/deployment/kubernetes/charts/medcat-service-helm/templates/tests/test-acceptance.yaml +++ b/deployment/kubernetes/charts/medcat-service-helm/templates/tests/test-acceptance.yaml @@ -14,6 +14,17 @@ spec: securityContext: runAsUser: 0 command: ["/bin/sh", "-c"] + env: + # Only assert the payload if we are using the default model packs. This is to avoid testing a model that doesnt have the concepts set. + - name: SHOULD_ASSERT_PAYLOAD + value: {{- if and (not .Values.model.downloadUrl) + (or + (eq .Values.env.APP_MEDCAT_MODEL_PACK "/cat/models/examples/example-medcat-v2-model-pack.zip") + (eq .Values.env.APP_MEDCAT_MODEL_PACK "/cat/models/examples/example-deid-model-pack.zip") + ) + }} "true"{{- else }} "false"{{- end }} + - name: EXPECTED_ANNOTATION + value: "{{- if .Values.env.DEID_MODE -}}PATIENT{{- else -}}Kidney Failure{{- end -}}" args: - | set -e @@ -23,24 +34,35 @@ spec: api="{{ include "medcat-service.fullname" . }}:{{ .Values.service.port }}/api/process" input_text="The patient was diagnosed with Kidney Failure" input_payload="{\"content\":{\"text\":\"${input_text}\"}}" - expected_annotation="Kidney Failure" echo "Calling POST $api with payload '$input_payload'" - actual=$(curl -s -X POST "$api" \ + http_code=$(curl -s -w "%{http_code}" -o /tmp/response_body -X POST "$api" \ -H 'Content-Type: application/json' \ --user-agent 'helm-test {{ .Chart.Name }}-v{{ .Chart.Version }}' \ -d "$input_payload") + actual=$(cat /tmp/response_body) + + if [ "$http_code" != "200" ]; then + echo "Expected HTTP 200 OK, got $http_code" + echo "Response body: $actual" + exit 1 + fi + echo "Response status: $http_code OK" echo "Received result '$actual'" actual_annotation=$(echo "$actual" | jq -r '.result.annotations[0]["0"].pretty_name') - echo "Expected Annotation is '${expected_annotation}'. Actual Annotation is '${actual_annotation}'" - - if [ "$actual_annotation" = "$expected_annotation" ]; then - echo "Service working and extracting annotations" - else - echo "Expected: $expected_annotation, Got: $actual_annotation" - echo -e "Actual response was:\n${actual}" - exit 1 + + if [ "$SHOULD_ASSERT_PAYLOAD" = "true" ]; then + echo "Expected Annotation is '${EXPECTED_ANNOTATION}'" + + if [ "$actual_annotation" = "$EXPECTED_ANNOTATION" ]; then + echo "Service working and extracting annotations" + else + echo "Expected: $EXPECTED_ANNOTATION, Got: $actual_annotation" + echo -e "Actual response was:\n${actual}" + exit 1 + fi fi + echo "Passed acceptance test for medcat service" restartPolicy: Never \ No newline at end of file diff --git a/deployment/kubernetes/charts/medcat-service-helm/values.yaml b/deployment/kubernetes/charts/medcat-service-helm/values.yaml index 683e4bb..1deb070 100644 --- a/deployment/kubernetes/charts/medcat-service-helm/values.yaml +++ b/deployment/kubernetes/charts/medcat-service-helm/values.yaml @@ -60,7 +60,7 @@ env: OTEL_EXPERIMENTAL_RESOURCE_DETECTORS: "containerid,os" OTEL_RESOURCE_ATTRIBUTES: "k8s.pod.uid=$(K8S_POD_UID),k8s.pod.name=$(K8S_POD_NAME),k8s.namespace.name=$(K8S_POD_NAMESPACE),k8s.node.name=$(K8S_NODE_NAME)" OTEL_METRICS_EXPORTER: "none" - OTEL_LOGS_EXPORTER: "none" + OTEL_LOGS_EXPORTER: "none" OTEL_PYTHON_FASTAPI_EXCLUDED_URLS: "/api/health,/metrics" # Enable downloading of public models using wget on startup. Model will be downloaded to /models/ and used for APP_MEDCAT_MODEL_PACK @@ -70,7 +70,6 @@ model: {} # Name of the model pack to save to. Will be stored at /models/ # name: my-model.zip - # Allow setting env values from field/configmap/secret references. Defaults to include k8s details f envValueFrom: K8S_NODE_NAME: @@ -86,7 +85,6 @@ envValueFrom: fieldRef: fieldPath: metadata.namespace - # This is for the secrets for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ imagePullSecrets: [] # This is to override the chart name. @@ -150,7 +148,7 @@ ingress: paths: - path: / pathType: ImplementationSpecific - # - Optional alternative to hosts: allows for global ingress without hostname. Overrides hosts if both are set. + # - Optional alternative to hosts: allows for global ingress without hostname. Overrides hosts if both are set. # http: # - paths: # - path: /medcat-service diff --git a/deployment/kubernetes/charts/medcat-trainer-helm/Chart.yaml b/deployment/kubernetes/charts/medcat-trainer-helm/Chart.yaml index 1f75d14..4604112 100644 --- a/deployment/kubernetes/charts/medcat-trainer-helm/Chart.yaml +++ b/deployment/kubernetes/charts/medcat-trainer-helm/Chart.yaml @@ -27,6 +27,8 @@ maintainers: - name: alhendrickson email: alistair@cogstack.org +icon: "https://avatars.githubusercontent.com/u/28688163" + # Chart.yaml dependencies: - name: solr diff --git a/deployment/kubernetes/charts/medcat-trainer-helm/templates/ingress.yaml b/deployment/kubernetes/charts/medcat-trainer-helm/templates/ingress.yaml index e2fc0dd..08b71eb 100644 --- a/deployment/kubernetes/charts/medcat-trainer-helm/templates/ingress.yaml +++ b/deployment/kubernetes/charts/medcat-trainer-helm/templates/ingress.yaml @@ -35,7 +35,7 @@ spec: {{- end }} backend: service: - name: {{ include "medcat-trainer-helm.fullname" $ }}-medcat-trainer + name: {{ include "medcat-trainer-helm.fullname" $ }} port: number: {{ $.Values.service.port }} {{- end }} diff --git a/deployment/kubernetes/charts/medcat-trainer-helm/templates/medcat-trainer-configmap.yaml b/deployment/kubernetes/charts/medcat-trainer-helm/templates/medcat-trainer-configmap.yaml index 96eb40b..8d2cc29 100644 --- a/deployment/kubernetes/charts/medcat-trainer-helm/templates/medcat-trainer-configmap.yaml +++ b/deployment/kubernetes/charts/medcat-trainer-helm/templates/medcat-trainer-configmap.yaml @@ -1,7 +1,7 @@ apiVersion: v1 kind: ConfigMap metadata: - name: {{ include "medcat-trainer-helm.fullname" . }}-medcat-trainer-config + name: {{ include "medcat-trainer-helm.fullname" . }}-config labels: {{- include "medcat-trainer-helm.labels" . | nindent 4 }} app.kubernetes.io/component: medcat-trainer diff --git a/deployment/kubernetes/charts/medcat-trainer-helm/templates/medcat-trainer-deployment.yaml b/deployment/kubernetes/charts/medcat-trainer-helm/templates/medcat-trainer-deployment.yaml index 3fe54b7..a2ec2bd 100644 --- a/deployment/kubernetes/charts/medcat-trainer-helm/templates/medcat-trainer-deployment.yaml +++ b/deployment/kubernetes/charts/medcat-trainer-helm/templates/medcat-trainer-deployment.yaml @@ -1,7 +1,7 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: {{ include "medcat-trainer-helm.fullname" . }}-medcat-trainer + name: {{ include "medcat-trainer-helm.fullname" . }} labels: {{- include "medcat-trainer-helm.labels" . | nindent 4 }} spec: @@ -55,7 +55,7 @@ spec: - /etc/supervisord.conf envFrom: - configMapRef: - name: {{ include "medcat-trainer-helm.fullname" . }}-medcat-trainer-env + name: {{ include "medcat-trainer-helm.fullname" . }}-env - secretRef: name: {{ include "medcat-trainer-helm.fullname" . }}-secret {{- with .Values.livenessProbe }} @@ -134,7 +134,7 @@ spec: volumes: - name: medcat-trainer-config configMap: - name: {{ include "medcat-trainer-helm.fullname" . }}-medcat-trainer-config + name: {{ include "medcat-trainer-helm.fullname" . }}-config - name: api-media persistentVolumeClaim: claimName: {{ include "medcat-trainer-helm.fullname" . }}-api-media diff --git a/deployment/kubernetes/charts/medcat-trainer-helm/templates/medcat-trainer-env-configmap.yaml b/deployment/kubernetes/charts/medcat-trainer-helm/templates/medcat-trainer-env-configmap.yaml index 5c41e57..c6cda56 100644 --- a/deployment/kubernetes/charts/medcat-trainer-helm/templates/medcat-trainer-env-configmap.yaml +++ b/deployment/kubernetes/charts/medcat-trainer-helm/templates/medcat-trainer-env-configmap.yaml @@ -1,7 +1,7 @@ apiVersion: v1 kind: ConfigMap metadata: - name: {{ include "medcat-trainer-helm.fullname" . }}-medcat-trainer-env + name: {{ include "medcat-trainer-helm.fullname" . }}-env labels: {{- include "medcat-trainer-helm.labels" . | nindent 4 }} app.kubernetes.io/component: medcat-trainer diff --git a/deployment/kubernetes/charts/medcat-trainer-helm/templates/service.yaml b/deployment/kubernetes/charts/medcat-trainer-helm/templates/service.yaml index 7859d82..8fa7ede 100644 --- a/deployment/kubernetes/charts/medcat-trainer-helm/templates/service.yaml +++ b/deployment/kubernetes/charts/medcat-trainer-helm/templates/service.yaml @@ -1,7 +1,7 @@ apiVersion: v1 kind: Service metadata: - name: {{ include "medcat-trainer-helm.fullname" . }}-medcat-trainer + name: {{ include "medcat-trainer-helm.fullname" . }} labels: {{- include "medcat-trainer-helm.labels" . | nindent 4 }} spec: diff --git a/deployment/kubernetes/charts/medcat-trainer-helm/templates/tests/test-connection.yaml b/deployment/kubernetes/charts/medcat-trainer-helm/templates/tests/test-connection.yaml index d03f3b1..44cee28 100644 --- a/deployment/kubernetes/charts/medcat-trainer-helm/templates/tests/test-connection.yaml +++ b/deployment/kubernetes/charts/medcat-trainer-helm/templates/tests/test-connection.yaml @@ -11,5 +11,5 @@ spec: - name: wget image: busybox command: ['wget'] - args: ['{{ include "medcat-trainer-helm.fullname" . }}-medcat-trainer:{{ .Values.service.port }}/nginx/health/live', '-U helm-test {{ .Chart.Name }}-v{{ .Chart.Version }}'] + args: ['{{ include "medcat-trainer-helm.fullname" . }}:{{ .Values.service.port }}/nginx/health/live', '-U helm-test {{ .Chart.Name }}-v{{ .Chart.Version }}'] restartPolicy: Never