From 85bd199bb2a0c6cf8e97ec8c6caccf21f9c46f97 Mon Sep 17 00:00:00 2001 From: Jennings Zhang Date: Mon, 3 Jun 2024 04:47:45 -0400 Subject: [PATCH 1/2] Remove automatic creation of "the chris user" --- charts/chris/Chart.yaml | 2 +- charts/chris/templates/heart.yml | 29 ------------------- .../templates/pfdcm/oxidicom-deployment.yml | 3 -- charts/chris/templates/the-chris-user.yml | 24 --------------- 4 files changed, 1 insertion(+), 57 deletions(-) delete mode 100644 charts/chris/templates/the-chris-user.yml diff --git a/charts/chris/Chart.yaml b/charts/chris/Chart.yaml index b436ace..6d38589 100644 --- a/charts/chris/Chart.yaml +++ b/charts/chris/Chart.yaml @@ -17,7 +17,7 @@ keywords: icon: ./logo_chris.png type: application -version: "0.13.0" +version: "0.14.0" appVersion: "5.0.0" maintainers: diff --git a/charts/chris/templates/heart.yml b/charts/chris/templates/heart.yml index 8777d96..e319ae8 100644 --- a/charts/chris/templates/heart.yml +++ b/charts/chris/templates/heart.yml @@ -106,20 +106,6 @@ spec: else: created_user = User.objects.create_superuser(**superuser_config) print(f'Created superuser "{created_user.username}"') - - the_chris_user_config = { - 'username': os.environ['CHRIS_USERNAME'], - 'password': os.environ['CHRIS_PASSWORD'], - 'email': os.environ['CHRIS_EMAIL'] - } - if (existing_user := User.objects.filter(username=the_chris_user_config['username']).first()) is not None: - existing_user.set_password(the_chris_user_config['password']) - existing_user.save() - print(f'Updated password for user "{existing_user.username}"') - else: - created_user = User.objects.create_user(**the_chris_user_config) - print(f'Created user "{created_user.username}"') - {{- include "cube.container" . | nindent 10 }} - name: CHRIS_SUPERUSER_USERNAME valueFrom: @@ -136,21 +122,6 @@ spec: secretKeyRef: name: {{ .Release.Name }}-chris-superuser key: email - - name: CHRIS_USERNAME - valueFrom: - secretKeyRef: - name: {{ .Release.Name }}-the-chris-user - key: CHRIS_USERNAME - - name: CHRIS_EMAIL - valueFrom: - secretKeyRef: - name: {{ .Release.Name }}-the-chris-user - key: CHRIS_EMAIL - - name: CHRIS_PASSWORD - valueFrom: - secretKeyRef: - name: {{ .Release.Name }}-the-chris-user - key: CHRIS_PASSWORD - name: wait-rabbitmq command: diff --git a/charts/chris/templates/pfdcm/oxidicom-deployment.yml b/charts/chris/templates/pfdcm/oxidicom-deployment.yml index 4e313c9..853d68f 100644 --- a/charts/chris/templates/pfdcm/oxidicom-deployment.yml +++ b/charts/chris/templates/pfdcm/oxidicom-deployment.yml @@ -96,9 +96,6 @@ spec: {{- if .Values.pfdcm.listener.env }} {{- .Values.pfdcm.listener.env | toYaml | nindent 12 }} {{- end }} - envFrom: - - secretRef: - name: {{ .Release.Name }}-the-chris-user volumeMounts: - mountPath: /data name: file-storage diff --git a/charts/chris/templates/the-chris-user.yml b/charts/chris/templates/the-chris-user.yml deleted file mode 100644 index 7612e9f..0000000 --- a/charts/chris/templates/the-chris-user.yml +++ /dev/null @@ -1,24 +0,0 @@ -# The "chris" user is a special user who is hard-coded to be able to see all feeds. -# They are also hard-coded to be able to register PACSFiles. -# The oxidicom (pfdcm listener) application needs the "chris" user. - -apiVersion: v1 -kind: Secret -type: Opaque -metadata: - name: {{ .Release.Name }}-the-chris-user - namespace: {{ .Release.Namespace }} - labels: - app.kubernetes.io/name: "the-chris-user" - {{- include "cube.labels" . | nindent 4 }} - annotations: - kubernetes.io/description: "Automatically created system ChRIS special user \"chris\"" -stringData: - CHRIS_USERNAME: "chris" - CHRIS_EMAIL: "chris+noreply@babymri.org" -data: - {{- with (lookup "v1" "Secret" .Release.Namespace ( print .Release.Name "-the-chris-user")) }} - CHRIS_PASSWORD: {{ index .data "CHRIS_PASSWORD" }} - {{- else }} - CHRIS_PASSWORD: {{ randAlphaNum 32 | b64enc | quote }} - {{- end }} From f39c2a05fd352c44ded7f6594259522bb6feff8a Mon Sep 17 00:00:00 2001 From: Jennings Zhang Date: Mon, 3 Jun 2024 12:33:22 -0400 Subject: [PATCH 2/2] Upgrade oxidicom to v2.0.0 --- .../templates/pfdcm/oxidicom-deployment.yml | 76 +++++++++++++------ charts/chris/values.yaml | 51 ++++++++----- testing/default-values.yaml | 5 +- testing/observe/opentelemetry-collector.yaml | 15 ++-- 4 files changed, 97 insertions(+), 50 deletions(-) diff --git a/charts/chris/templates/pfdcm/oxidicom-deployment.yml b/charts/chris/templates/pfdcm/oxidicom-deployment.yml index 853d68f..6392132 100644 --- a/charts/chris/templates/pfdcm/oxidicom-deployment.yml +++ b/charts/chris/templates/pfdcm/oxidicom-deployment.yml @@ -1,12 +1,25 @@ +{{- define "orthanc.dicomService" -}} +{{ .Release.Name }}-orthanc-dicom:{{ .Values.orthanc.dicomService.port }} +{{- end -}} + {{- define "oxidicom.pacsAddress" -}} +{{- if (and .Values.orthanc.enabled (not .Values.orthanc.dicomService.enabled)) -}} +{{- fail ".orthanc.dicomService.enabled must be true" -}} +{{- end -}} {{- if .Values.pfdcm.listener.config.pacsAddress -}} -{{- .Values.pfdcm.listener.config.pacsAddress -}}, +{{- if (and .Values.orthanc.enabled (not (contains (include "orthanc.dicomService" .) .Values.pfdcm.listener.config.pacsAddress))) -}} +{{- fail (printf "pfdcm.listener.config.pacsAddress must be configured with %s=\"%s\"" .Values.orthanc.config.dicomAet (include "orthanc.dicomService" .)) -}} +{{- end -}} +{{- .Values.pfdcm.listener.config.pacsAddress -}} +{{- else -}} +{{ "{" }}{{ .Values.orthanc.config.dicomAet }}={{ include "orthanc.dicomService" . | quote }}{{ "}" }} +{{- end -}} {{- end -}} -{{- if .Values.orthanc.enabled -}} - {{- if not .Values.orthanc.dicomService.enabled -}} - {{- fail "Orthanc's .dicomService must be enabled" -}} - {{- end -}} -{{ .Values.orthanc.config.dicomAet }}={{ .Release.Name }}-orthanc-dicom:{{ .Values.orthanc.dicomService.port }}, +{{- define "oxidicom.databasePoolSize" -}} +{{- if .Values.pfdcm.listener.config.databasePool -}} +{{- .Values.pfdcm.listener.config.databasePool -}} +{{- else if .Values.postgresql.primary.resources.requests.cpu -}} +{{- .Values.postgresql.primary.resources.requests.cpu -}} {{- end -}} {{- end -}} {{- if .Values.pfdcm.enabled -}} @@ -53,42 +66,59 @@ spec: resources: {{- toYaml .Values.pfdcm.listener.resources | nindent 12 }} env: - - name: PORT + - name: OXIDICOM_DB_CONNECTION + valueFrom: + secretKeyRef: + {{- if not .Values.postgresql.serviceBindings.enabled }} + {{- fail "Oxidicom requires the value .postgresql.serviceBindings.enabled: true" }} + {{- end }} + name: {{ .Release.Name }}-postgresql-svcbind-custom-user + key: uri + - name: OXIDICOM_LISTENER_PORT value: {{ .Values.pfdcm.listener.service.port | quote }} - - name: CHRIS_FILES_ROOT + - name: OXIDICOM_FILES_ROOT value: /data - - name: CHRIS_URL - value: "http://{{ .Release.Name }}-server:{{ .Values.cube.server.service.port }}/api/v1/" - - name: CHRIS_SCP_AET + - name: OXIDICOM_SCP_AET value: {{ .Values.pfdcm.aet | quote }} - - name: CHRIS_LISTENER_THREADS + {{- if (include "oxidicom.databasePoolSize" .) }} + - name: OXIDICOM_DB_POOL + value: {{ include "oxidicom.databasePoolSize" . | quote }} + {{- end }} + {{- if .Values.pfdcm.listener.config.batchSize }} + - name: OXIDICOM_DB_BATCH_SIZE + value: {{ .Values.pfdcm.listener.config.batchSize | quote }} + {{- end }} + {{- if .Values.pfdcm.listener.config.listenerThreads }} + - name: OXIDICOM_LISTENER_THREADS value: {{ .Values.pfdcm.listener.config.listenerThreads | quote }} - - name: CHRIS_PUSHER_THREADS - value: {{ .Values.pfdcm.listener.config.pusherThreads | quote }} - + {{- end }} {{- if .Values.pfdcm.listener.config.verbose }} - - name: CHRIS_VERBOSE + - name: OXIDICOM_VERBOSE value: {{ .Values.pfdcm.listener.config.verbose | quote }} {{- end }} - {{- if .Values.pfdcm.listener.config.httpRetries }} - - name: CHRIS_HTTP_RETRIES - value: {{ .Values.pfdcm.listener.config.httpRetries | quote }} + {{- if .Values.pfdcm.listener.config.tokioThreads }} + - name: TOKIO_WORKER_THREADS + value: {{ .Values.pfdcm.listener.config.tokioThreads | quote }} {{- end }} {{- /* DICOM SCP Options */}} {{- if .Values.pfdcm.listener.config.strictPduLength }} - - name: CHRIS_SCP_STRICT + - name: OXIDICOM_SCP_STRICT value: {{ .Values.pfdcm.listener.config.strictPduLength | quote }} {{- end }} {{- if .Values.pfdcm.listener.config.maxPduLength }} - - name: CHRIS_SCP_MAX_PDU_LENGTH + - name: OXIDICOM_SCP_MAX_PDU_LENGTH value: {{ .Values.pfdcm.listener.config.maxPduLength | quote }} {{- end }} {{- if .Values.pfdcm.listener.config.uncompressedOnly }} - - name: CHRIS_SCP_UNCOMPRESSED_ONLY + - name: OXIDICOM_SCP_UNCOMPRESSED_ONLY value: {{ .Values.pfdcm.listener.config.uncompressedOnly | quote }} {{- end }} + {{- if .Values.pfdcm.listener.config.promiscuous }} + - name: OXIDICOM_SCP_PROMISCUOUS + value: {{ .Values.pfdcm.listener.config.promiscuous | quote }} + {{- end }} {{- if (include "oxidicom.pacsAddress" .) }} - - name: CHRIS_PACS_ADDRESS + - name: OXIDICOM_PACS_ADDRESS value: {{ include "oxidicom.pacsAddress" . | quote }} {{- end }} diff --git a/charts/chris/values.yaml b/charts/chris/values.yaml index c712016..8850ae0 100644 --- a/charts/chris/values.yaml +++ b/charts/chris/values.yaml @@ -186,6 +186,12 @@ postgresql: database: "chris" username: "chris" + # Create secret for service binding (Experimental) + # Ref: https://servicebinding.io/service-provider/ + serviceBindings: + # required if pfdcm.listener.enabled: true + enabled: true + # one of: [standalone, replication] # Replication is supported, see upstream README.md for configuration. architecture: standalone @@ -336,14 +342,14 @@ pfdcm: insecureEdgeTerminationPolicy: Redirect destinationCACertificate: '' replicas: 1 - maxWorkers: 1 + maxWorkers: 8 resources: limits: cpu: 1 - memory: 1Gi + memory: 4Gi requests: cpu: 1 - memory: 1Gi + memory: 4Gi # DICOM application entity title aet: "ChRIS" @@ -377,7 +383,7 @@ pfdcm: image: repository: ghcr.io/fnndsc/oxidicom pullPolicy: IfNotPresent - tag: "1.0.2" + tag: "2.0.0" podAnnotations: {} # The PACS server must be configured to push to this service. # If using Orthanc, the Helm chart will help you validate your @@ -393,16 +399,22 @@ pfdcm: # - name: OTEL_RESOURCE_ATTRIBUTES # value: service.name=oxidicom # - name: OTEL_EXPORTER_OTLP_ENDPOINT - # value: http://tempo:4318 + # value: http://tempo:4317 + + # Optional configurations of oxidicom. config: - ## number of times - # httpRetries: 3 - ## number of DICOM listener threads - listenerThreads: 4 + # listenerThreads: 8 + + ## number of Tokio runtime threads + ## ref: https://github.com/FNNDSC/oxidicom/tree/v2.0.0?tab=readme-ov-file#performance-tuning + # tokioThreads: 8 + + ## size of database connection pool + # databasePool: 10 - ## number of threads to use for pushing files to CUBE - pusherThreads: 2 + ## maximum number of PACS files to register per database command + # batchSize: 20 ## verbose logging # verbose: true @@ -412,19 +424,22 @@ pfdcm: # strictPduLength: true # uncompressedOnly: true # maxPduLength: 16384 + ## Whether to accept unknown DICOM transfer syntaxes. + # promiscuous: true ## Addresses of the PACS pushing to us. Used for looking up the NumberOfSeriesRelatedInstances. - ## Do not specify a value for pacsAddress if you are using the Orthanc sub-chart. - # pacsAddress: pacs.server.local:4242 + ## Do not specify a value for pacsAddress if you are using only the Orthanc sub-chart. + ## Value must be a string in the form `{AET="5.6.7.8:11111", MGH="9.10.11.12:33333"}` + # pacsAddress: '{HOSPITAL="pacs:4242"}' resources: # It's written in Rust! - # with 16 threads, CPU usage peaks at 120m and memory usage peaks at 1.3 GiB + # Memory usage typically stays under 20MiB, unless there is backpressure from slow disk or database write speed. limits: - cpu: 500m - memory: 1907Mi + cpu: 1 + memory: 2Gi requests: - cpu: 500m - memory: 1907Mi + cpu: 1 + memory: 2Gi # PACS server orthanc: diff --git a/testing/default-values.yaml b/testing/default-values.yaml index ef17e28..c5eac2e 100644 --- a/testing/default-values.yaml +++ b/testing/default-values.yaml @@ -44,14 +44,13 @@ pfdcm: type: NodePort nodePort: 32004 config: - listenerThreads: 4 - pusherThreads: 4 verbose: true + promiscuous: true env: - name: OTEL_RESOURCE_ATTRIBUTES value: service.name=oxidicom - name: OTEL_EXPORTER_OTLP_ENDPOINT - value: http://otel-collector-opentelemetry-collector.observe.svc.cluster.local:4318 + value: http://otel-collector-opentelemetry-collector.observe.svc.cluster.local:4317 resources: limits: cpu: 500m diff --git a/testing/observe/opentelemetry-collector.yaml b/testing/observe/opentelemetry-collector.yaml index 105239a..71caa05 100644 --- a/testing/observe/opentelemetry-collector.yaml +++ b/testing/observe/opentelemetry-collector.yaml @@ -1,3 +1,6 @@ +image: + repository: "otel/opentelemetry-collector-contrib" + # Valid values are "daemonset", "deployment", and "statefulset". mode: "daemonset" @@ -58,8 +61,8 @@ config: receivers: otlp: protocols: - http: - endpoint: ${env:MY_POD_IP}:4318 + grpc: + endpoint: ${env:MY_POD_IP}:4317 kubeletstats: insecure_skip_verify: true # prometheus: @@ -105,11 +108,11 @@ config: ports: otlp: enabled: false - otlp-http: + otlp-grpc: enabled: true - containerPort: 4318 - servicePort: 4318 - hostPort: 4318 + containerPort: 4317 + servicePort: 4317 + hostPort: 4317 protocol: TCP jaeger-compact: enabled: false