diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2a2fe30..8ee398e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,7 +19,8 @@ jobs: if: always() uses: ./.github/workflows/_container.yml with: - publish: ${{ needs.test.result == 'success' }} + # publish is always true as there is no tests for dev-c7 at present + publish: true permissions: contents: read packages: write diff --git a/Charts/dev-c7/Chart.yaml b/Charts/dev-c7/Chart.yaml index 268df46..c7a1a4d 100644 --- a/Charts/dev-c7/Chart.yaml +++ b/Charts/dev-c7/Chart.yaml @@ -11,4 +11,4 @@ version: 0.1.0 # This is the version number of the application being deployed. It implies the # the version tag of the container image. -appVersion: 2025.5.1 +appVersion: 2025.9.1-beta.2 diff --git a/Charts/dev-c7/templates/deployment.yaml b/Charts/dev-c7/templates/deployment.yaml deleted file mode 100644 index 9da5ff5..0000000 --- a/Charts/dev-c7/templates/deployment.yaml +++ /dev/null @@ -1,83 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ include "dls-k8s-c7.fullname" . }} - labels: - {{- include "dls-k8s-c7.labels" . | nindent 4 }} -spec: - replicas: {{ .Values.replicaCount }} - selector: - matchLabels: - {{- include "dls-k8s-c7.selectorLabels" . | nindent 6 }} - template: - metadata: - {{- with .Values.podAnnotations }} - annotations: - {{- toYaml . | nindent 8 }} - {{- end }} - labels: - {{- include "dls-k8s-c7.labels" . | nindent 8 }} - {{- with .Values.podLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - spec: - hostNetwork: {{ .Values.hostNetwork }} - {{- with .Values.imagePullSecrets }} - imagePullSecrets: - {{- toYaml . | nindent 8 }} - {{- end }} - securityContext: - runAsNonRoot: true - runAsUser: {{ .Values.userId }} - runAsGroup: {{ .Values.groupId | default .Values.userId }} - containers: - - name: {{ .Chart.Name }} - image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" - command: - - bash - args: - - "-c" - - "sleep infinity" - workingDir: /dls_sw/prod/R3.14.12.7/ioc/BL16I/BL16I-MO-IOC-12/21-2 - {{- with .Values.securityContext }} - securityContext: - {{- toYaml . | nindent 12 }} - {{- end }} - env: - - name: HOME - value: /home/{{ .Values.userName }} - - name: USER - value: {{ .Values.userName }} - imagePullPolicy: {{ .Values.image.pullPolicy }} - {{- with .Values.livenessProbe }} - livenessProbe: - {{- toYaml . | nindent 12 }} - {{- end }} - {{- with .Values.readinessProbe }} - readinessProbe: - {{- toYaml . | nindent 12 }} - {{- end }} - {{- with .Values.resources }} - resources: - {{- toYaml . | nindent 12 }} - {{- end }} - {{- with .Values.volumeMounts }} - volumeMounts: - {{- toYaml . | nindent 12 }} - {{- end }} - {{- with .Values.volumes }} - volumes: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.nodeSelector }} - nodeSelector: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.affinity }} - affinity: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.tolerations }} - tolerations: - {{- toYaml . | nindent 8 }} - {{- end }} diff --git a/Charts/dev-c7/templates/statefulset.yaml b/Charts/dev-c7/templates/statefulset.yaml new file mode 100644 index 0000000..2b375d7 --- /dev/null +++ b/Charts/dev-c7/templates/statefulset.yaml @@ -0,0 +1,106 @@ +{{- /* +Default the derivable substitution values. + +This keeps the length of the values.txt file for each individual IOC +to a minimum +*/ -}} +{{- $location := default .Values.global.location .Values.location | required "ERROR - You must supply location or global.location" -}} +{{- $ioc_group := default .Values.global.ioc_group .Values.ioc_group | required "ERROR - You must supply ioc_group or global.ioc_group" -}} +{{- $image := .Values.image | required "ERROR - You must supply image." -}} + +{{- $enabled := eq .Values.global.enabled false | ternary false true -}} + +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ .Release.Name }} + labels: + app: {{ .Release.Name }} + location: {{ $location }} + ioc_group: {{ $ioc_group }} + enabled: {{ $enabled | quote }} + is_ioc: "true" +spec: + replicas: {{ $enabled | ternary 1 0 }} + selector: + matchLabels: + app: {{ .Release.Name }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + app: {{ .Release.Name }} + location: {{ $location }} + ioc_group: {{ $ioc_group }} + is_ioc: "true" + spec: + hostNetwork: {{ .Values.hostNetwork }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + terminationGracePeriodSeconds: 2 + {{- with .Values.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + command: + {{- .Values.command | toYaml | nindent 12 }} + stdin: true + tty: true + {{- $domain := (.Values.ioc_domain | default $location) | upper }} + {{- $ioc_name := (.Values.ioc_name | default .Release.Name) | upper }} + {{ $workingDir := "" }} {{- /* create the variable in global scope before setting in if/else!!! */ -}} + {{- if .Values.ioc_path }} + {{- $workingDir = printf "%s/%s" .Values.ioc_path $ioc_name }} + {{- else }} + {{- $workingDir = printf "/dls_sw/prod/%s/ioc/%s/%s/%s" .Values.epics_version $domain $ioc_name .Values.ioc_version }} + {{- end }} + workingDir: {{ $workingDir }} + {{- with .Values.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + env: + # psuedo home sets up epics module etc. + - name: HOME + value: /epics_home + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- with .Values.livenessProbe }} + livenessProbe: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.readinessProbe }} + readinessProbe: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.volumeMounts }} + volumeMounts: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.volumes }} + volumes: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/Charts/dev-c7/values.schema.json b/Charts/dev-c7/values.schema.json index bb86fa3..1b4561e 100644 --- a/Charts/dev-c7/values.schema.json +++ b/Charts/dev-c7/values.schema.json @@ -8,6 +8,17 @@ "$ref": "https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master/v1.33.3/affinity.json", "type": "object" }, + "command": { + "description": "container entry point command", + "type": "array", + "items": { + "type": "string" + } + }, + "epics_version": { + "description": "the EPICS version, used to generate the /dls_sw/prod path to ioc_name", + "type": "string" + }, "fullnameOverride": { "type": "string" }, @@ -38,6 +49,22 @@ "imagePullSecrets": { "type": "array" }, + "ioc_domain": { + "description": "the IOC domain (e.g. BL16I FE02J SR03C)", + "type": "string" + }, + "ioc_name": { + "description": "the folder name for the compiled IOC, defaults to ucase of the services folder name", + "type": "string" + }, + "ioc_path": { + "description": "overrides the parent folder for ioc_name to any path in /dls_sw/work or /dls_sw/prod", + "type": "string" + }, + "ioc_version": { + "description": "the IOC release, used to generate the /dls_sw/prod path to ioc_name", + "type": "string" + }, "nameOverride": { "type": "string" }, @@ -57,10 +84,6 @@ "$ref": "https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master/v1.33.3/podspec.json#/properties/securityContext", "type": "object" }, - "replicaCount": { - "description": "Set to 0 to stop the IOC, 1 to run the IOC", - "type": "integer" - }, "resources": { "$ref": "https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master/v1.33.3/container.json#/properties/resources", "type": "object" @@ -73,12 +96,6 @@ "$ref": "https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master/v1.33.3/podspec.json#/properties/tolerations", "type": "array" }, - "userId": { - "type": "integer" - }, - "userName": { - "type": "string" - }, "volumeMounts": { "$ref": "https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master/v1.33.3/container.json#/properties/volumeMounts", "type": "array", diff --git a/Charts/dev-c7/values.yaml b/Charts/dev-c7/values.yaml index 9fe6ed5..45cff6f 100644 --- a/Charts/dev-c7/values.yaml +++ b/Charts/dev-c7/values.yaml @@ -8,13 +8,22 @@ # With annotations for building the schema using: # https://github.com/losisin/helm-values-schema-json.git +# @schema description: the folder name for the compiled IOC, defaults to ucase of the services folder name +ioc_name: "" +# @schema description: the IOC release, used to generate the /dls_sw/prod path to ioc_name +ioc_version: "" +# @schema description: the IOC domain (e.g. BL16I FE02J SR03C) +ioc_domain: "" +# @schema description: the EPICS version, used to generate the /dls_sw/prod path to ioc_name +epics_version: R3.14.12.7 + +# @schema description: overrides the parent folder for ioc_name to any path in /dls_sw/work or /dls_sw/prod +ioc_path: "" + # @schema description: shared values for all services # @schema additionalProperties: true global: {} -# @schema description: Set to 0 to stop the IOC, 1 to run the IOC -replicaCount: 1 - # @schema description: container image URI image: repository: ghcr.io/diamondlightsource/dev-c7 @@ -23,9 +32,11 @@ image: # Overrides the image tag whose default is the chart appVersion. tag: "" -# these must be filled -userId: 1200288 -userName: hgv27681 +# @schema description: container entry point command +command: + - bash + - -lc + - stdio-expose ./bin/linux-x86_64/st*.sh # @schema description: enable host networking for the pod hostNetwork: false @@ -72,9 +83,6 @@ volumes: - name: etc hostPath: path: /dls_sw/etc - - name: home - hostPath: - path: /home/hgv27681 # volumeMounts for the Deployment. # @schema $ref: $k8s/container.json#/properties/volumeMounts @@ -97,8 +105,6 @@ volumeMounts: - name: etc mountPath: /dls_sw/etc readOnly: true - - name: home - mountPath: /home/hgv27681 # @schema $ref: $k8s/podspec.json#/properties/tolerations tolerations: [] diff --git a/Dockerfile b/Dockerfile index 27bc402..6576e39 100644 --- a/Dockerfile +++ b/Dockerfile @@ -74,3 +74,20 @@ RUN yum remove -y git git-core && \ # change the nobody account and group IDs to match RedHat RUN sed -i 's/99:99/65534:65534/' /etc/passwd && \ sed -i 's/:99:/:65534:/' /etc/group + +# Install uv using the official image +# See https://docs.astral.sh/uv/guides/integration/docker/#installing-uv +COPY --from=ghcr.io/astral-sh/uv:0.8 /uv /uvx /bin/ +WORKDIR /opt + +ENV UV_PYTHON_INSTALL_DIR=/python +ENV PATH="${PATH}:/opt/.venv/bin" + +# Add in stdio socket for sharing the epics console +RUN uv venv --managed-python --python 3.12 && \ + uv pip install stdio-socket && \ + chmod -R a+rwX /opt/.venv + +# Make a psuedo home directory for running in cluster +COPY epics_home /epics_home +RUN chmod a+rws /epics_home diff --git a/epics_home/.bashrc b/epics_home/.bashrc new file mode 100644 index 0000000..a8d5270 --- /dev/null +++ b/epics_home/.bashrc @@ -0,0 +1,15 @@ +#! /bin/bash + +# Source global definitions +if [ -f /etc/bashrc ]; then + . /etc/bashrc +fi + +# Source global definitions +if [ -f ~/bashrc_local ]; then + . ~/.bashrc_local +fi + +module load epics/3.14.12.7 + +alias console=/opt/.venv/bin/console diff --git a/epics_home/README.md b/epics_home/README.md new file mode 100644 index 0000000..a84a263 --- /dev/null +++ b/epics_home/README.md @@ -0,0 +1,5 @@ +# epics_home + +This is a psuedo home directory for launching EPICS IOCs in-cluster using dev-c7. + +It allows us to have a writeable home directory and also to set up the module system with .bashrc. This in turn lets us load the epics module and gives access to caRepeater amoungst other things. diff --git a/schemas/dev-c7.service.schema.json b/schemas/dev-c7.service.schema.json new file mode 100644 index 0000000..dfbeecf --- /dev/null +++ b/schemas/dev-c7.service.schema.json @@ -0,0 +1,12 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "properties": { + "dev-c7": { + "$ref": "dev-c7.values.schema.json", + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false +}