diff --git a/.github/workflows/workflows.yml b/.github/workflows/helm-chart.yml similarity index 66% rename from .github/workflows/workflows.yml rename to .github/workflows/helm-chart.yml index 62af795..bdfdca1 100644 --- a/.github/workflows/workflows.yml +++ b/.github/workflows/helm-chart.yml @@ -1,8 +1,9 @@ -name: Release Artifacts +# Copyright 2024 The MathWorks, Inc. +name: Release Helm Chart -on: +on: release: - types: [created, edited] + types: [created] jobs: release-controller-image: @@ -16,19 +17,18 @@ jobs: uses: actions/checkout@v4 - name: Log in to GitHub Container Registry - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push Docker image - uses: docker/build-push-action@v3 + uses: docker/build-push-action@v5 with: push: true tags: ghcr.io/mathworks-ref-arch/matlab-parallel-server-k8s/mjs-controller-image:${{ github.event.release.tag_name }} context: ./controller - file: ./controller/Dockerfile release-helm-chart: runs-on: ubuntu-latest @@ -38,23 +38,22 @@ jobs: steps: - name: Check out the repo - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install Helm uses: azure/setup-helm@v4 - - name: Lint the chart + - name: Lint chart run: helm lint mjs --set maxWorkers=4,matlabPVC=test,checkpointPVC=test,logPVC=test,workerLogPVC=test - name: Check chart versions run: grep "version. ${{ github.event.release.tag_name }}" mjs/Chart.yaml && grep "appVersion. ${{ github.event.release.tag_name }}" mjs/Chart.yaml # Use "." (any character) rather than ":", since ":" breaks YAML parser - - name: Package the chart - run: echo ${{ github.event.release.tag_name }} && helm package mjs --version ${{ github.event.release.tag_name }} --app-version ${{ github.event.release.tag_name }} + - name: Package chart + run: helm package mjs --version ${{ github.event.release.tag_name }} --app-version ${{ github.event.release.tag_name }} - name: Login to GitHub Container Registry - run: echo ${{ secrets.HELM_TOKEN }} | helm registry login ghcr.io/hannahpullen --username hannahpullen --password-stdin - - - name: Deploy the chart - run: helm push mjs-${GITHUB_REF#refs/tags/}.tgz oci://ghcr.io/mathworks-ref-arch/matlab-parallel-server-k8s + run: echo ${{ secrets.HELM_TOKEN }} | helm registry login ghcr.io/mathworks-ref-arch --username hannahpullen --password-stdin + - name: Upload chart + run: helm push mjs-${{ github.event.release.tag_name }}.tgz oci://ghcr.io/mathworks-ref-arch/matlab-parallel-server-k8s diff --git a/.github/workflows/parallel-server-images.yml b/.github/workflows/parallel-server-images.yml new file mode 100644 index 0000000..cbdc877 --- /dev/null +++ b/.github/workflows/parallel-server-images.yml @@ -0,0 +1,118 @@ +# Copyright 2024 The MathWorks, Inc. +name: Build and push MATLAB Parallel Server images + +on: + workflow_dispatch: + push: + # Trigger the workflow if image files or this workflow file are changed + branches: + - main + paths: + - "images/job-manager/**" + - "images/worker/**" + - ".github/workflows/parallel-server-images.yml" + schedule: + # Run at 00:00 on every Tuesday (2nd Day of the Week) + # This captures updates to matlab-deps, which is rebuilt every Monday + - cron: "0 0 * * 2" + +env: + LICENSE_FILE_PATH: ${{ github.workspace }}/license.lic + JM_IMAGE: ghcr.io/mathworks-ref-arch/matlab-parallel-server-k8s/mjs-job-manager-image + +jobs: + # Build the job manager image and push to GHCR. + build-push-job-manager-image: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + strategy: + fail-fast: false + matrix: + matlab-release: [r2024a] + + steps: + - name: Checkout repo + uses: actions/checkout@v4 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build local image + uses: docker/build-push-action@v5 + with: + platforms: linux/amd64 + context: ./images/job-manager + build-args: MATLAB_RELEASE=${{ matrix.matlab-release }} + tags: ${{ env.JM_IMAGE }}:${{ matrix.matlab-release }} + + - name: Test MJS on container + env: + BIN_DIR: /opt/matlab/toolbox/parallel/bin + run: docker run ${JM_IMAGE}:${{ matrix.matlab-release }} bash -c "${BIN_DIR}/mjs start && ${BIN_DIR}/startjobmanager && ${BIN_DIR}/glnxa64/mjshealthcheck -matlabroot /opt/matlab" + + - name: Push to GHCR + uses: docker/build-push-action@v5 + with: + platforms: linux/amd64 + context: ./images/job-manager + tags: ${{ env.JM_IMAGE }}:${{ matrix.matlab-release }} + push: true + + # Build the worker image on top of the job manager image. This requires a large runner so we have enough storage for the local image. + build-push-worker-image: + runs-on: ubuntu-latest-m + needs: [build-push-job-manager-image] + permissions: + contents: read + packages: write + + strategy: + fail-fast: false + matrix: + matlab-release: [r2024a] + + env: + WORKER_IMAGE: ghcr.io/mathworks-ref-arch/matlab-parallel-server-k8s/mjs-worker-image + + steps: + - name: Checkout repo + uses: actions/checkout@v4 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build local image + uses: docker/build-push-action@v5 + with: + platforms: linux/amd64 + context: ./images/worker + build-args: MATLAB_RELEASE=${{ matrix.matlab-release }} + tags: ${{ env.WORKER_IMAGE }}:${{ matrix.matlab-release }} + + - name: Generate MATLAB license file + run: echo '${{ secrets.MATLAB_LICENSE_FILE_R2024A }}' > ${{ env.LICENSE_FILE_PATH }} + + - name: Test MATLAB on container + env: + MLM_LICENSE_FILE: /tmp/license.lic # License file path on container + run: docker run -v ${LICENSE_FILE_PATH}:${MLM_LICENSE_FILE} ${WORKER_IMAGE}:${{ matrix.matlab-release }} bash -c "MLM_LICENSE_FILE=${MLM_LICENSE_FILE} /opt/matlab/bin/matlab -batch 'version'" + + - name: Push to GHCR + uses: docker/build-push-action@v5 + with: + platforms: linux/amd64 + context: ./images/worker + tags: ${{ env.WORKER_IMAGE }}:${{ matrix.matlab-release }} + build-args: MATLAB_RELEASE=${{ matrix.matlab-release }} + push: true diff --git a/README.md b/README.md index dc2aa3b..e4c545c 100644 --- a/README.md +++ b/README.md @@ -2,14 +2,14 @@ [![View MATLAB Parallel Server in Kubernetes on File Exchange](https://www.mathworks.com/matlabcentral/images/matlab-file-exchange.svg)](https://www.mathworks.com/matlabcentral/fileexchange/167676-matlab-parallel-server-in-kubernetes) -This repository contains utilities for using MATLAB® Parallel Server in a Kubernetes® cluster. +This repository contains utilities for using MATLAB® Parallel Server™ in a Kubernetes® cluster. ## Introduction This guide explains how to deploy MATLAB Job Scheduler onto your Kubernetes cluster. You can then connect to the MATLAB Job Scheduler and use it to run MATLAB Parallel Server jobs on the Kubernetes cluster. -For more information on MATLAB Job Scheduler and MATLAB Parallel Server, see the MathWorks documentation on [MATLAB Parallel Server](https://www.mathworks.com/help/matlab-parallel-server/index.html). +For more information on MATLAB Job Scheduler and MATLAB Parallel Server, see the MathWorks® documentation on [MATLAB Parallel Server](https://www.mathworks.com/help/matlab-parallel-server/index.html). ## Requirements @@ -20,7 +20,6 @@ Before you start, you need the following: - Uses Kubernetes version 1.21.1 or later. - Meets the system requirements for running MATLAB Job Scheduler. For details, see the MathWorks documentation for [MATLAB Parallel Server Product Requirements](https://www.mathworks.com/support/requirements/matlab-parallel-server.html). - Configured to create external load balancers that allow traffic into the cluster. -- Docker® installed on your computer. For help with installing Docker, see [Get Docker](https://docs.docker.com/get-docker/). - Kubectl installed on your computer and configured to access your Kubernetes cluster. For help with installing Kubectl, see [Install Tools](https://kubernetes.io/docs/tasks/tools/) on the Kubernetes website. - Helm® version 3.8.0 or later installed on your computer. For help with installing Helm, see [Quickstart Guide](https://helm.sh/docs/intro/quickstart/). - Network access to the MathWorks Container Registry, `containers.mathworks.com`, and the GitHub® Container registry, `ghcr.io`. @@ -51,14 +50,11 @@ Create these volumes using your preferred storage medium. For instructions, see the [Kubernetes PersistentVolume documentation](https://kubernetes.io/docs/concepts/storage/persistent-volumes/). The software requires three PersistentVolumes to retain job data and logs. -You can also use a PersistentVolume to mount your own MATLAB Parallel Server installation onto the MATLAB Job Scheduler pods. -If you do not create a PersistentVolume containing a MATLAB Parallel Server installation, you must use a Docker image that has MATLAB Parallel Server installed. Create a PersistentVolume for each of the following applications: - An empty PersistentVolume with access mode `ReadWriteOnce` for MATLAB Job Scheduler's checkpoint folder, which retains job data after exiting the session - An empty PersistentVolume with access mode `ReadWriteOnce` to retain logs from the MATLAB Job Scheduler job manager - An empty PersistentVolume with access mode `ReadWriteMany` to retain logs from the MATLAB Job Scheduler workers -- A PersistentVolume with access mode `ReadOnlyMany` containing a MATLAB Parallel Server installation Now create a *PersistentVolumeClaim* for each PersistentVolume. You can create a PersistentVolumeClaim by using the following example configuration file. @@ -82,25 +78,6 @@ spec: storage: ``` -### Build MATLAB Parallel Server Docker Image (Optional) - -The MATLAB Job Scheduler pods require a MATLAB Parallel Server installation. -By default, you mount this from a PersistentVolume, as described in the previous step. -If you do not have a MATLAB Parallel Server installation to mount, you can build a Docker image containing a MATLAB Parallel Server installation instead. - -Build a Docker image that contains a MATLAB Parallel Server installation. -- Specify `` as a MATLAB release number with a lowercase `r`. For example, to install MATLAB R2024a, specify `` as `r2024a`. The MATLAB release must be version R2024a or later. -- Specify `` as a space-separated list of MATLAB toolboxes you want to install. The toolbox names must match the product names listed on the MathWorks® product page with any spaces replaced by underscores. For example, to install Parallel Computing Toolbox and Deep Learning Toolbox, specify `` as `Parallel_Computing_Toolbox Deep_Learning_Toolbox`. For a complete list of product names, see [MathWorks Products](https://www.mathworks.com/products.html). -- Specify `` as the Docker tag to use for the image. -``` -docker build https://raw.githubusercontent.com/mathworks-ref-arch/matlab-dockerfile/main/Dockerfile --build-arg MATLAB_INSTALL_LOCATION=/opt/matlab --build-arg MATLAB_RELEASE= --build-arg MATLAB_PRODUCT_LIST="MATLAB MATLAB_Parallel_Server " -t -``` - -Push the image to a repository that is visible to your Kubernetes cluster. - -For more information on building a MATLAB Docker image, see [Create a MATLAB Container Image](https://github.com/mathworks-ref-arch/matlab-dockerfile) in the GitHub repository. - - ### Create Administrator Password Secret By default, MATLAB Job Scheduler in Kubernetes runs at security level 2. @@ -123,24 +100,30 @@ Copy the following lines into a YAML file, `values.yaml`, and modify the values ```yaml matlabRelease: r2024a maxWorkers: 100 -matlabPVC: "matlab-pvc" + +# Licensing settings +useOnlineLicensing: true +networkLicenseManager: "" + +# PersistentVolumeClaim settings checkpointPVC: "checkpoint-pvc" logPVC: "log-pvc" workerLogPVC: "worker-log-pvc" + +# Security settings jobManagerUserID: 0 jobManagerGroupID: 0 -matlabImage: "" ``` Modify the following values: - `matlabRelease` — Specify the release number of the MATLAB Parallel Server installation. - `maxWorkers` — Specify the maximum number of MATLAB Parallel Server workers to run in the cluster. The cluster starts with zero workers and automatically scales up to this number as the cluster becomes busy. -- `matlabPVC` — Specify the name of a PersistentVolumeClaim that is bound to the PersistentVolume with a MATLAB Parallel Server installation. +- `useOnlineLicensing` — Option to use MathWorks online licensing. Set this parameter to true to use online licensing to manage licensing for your cluster users. When enabled, users must log in to their MathWorks account to connect to the cluster, and their account must be linked to a MATLAB Parallel Server license that is managed online. For more information about online licensing, see [Use Online Licensing for MATLAB Parallel Server](https://www.mathworks.com/products/matlab-parallel-server/online-licensing.html) on the MathWorks website. To learn how to set up online licensing, see the MathWorks documentation [Configure MATLAB Parallel Server Licensing for Cloud Platforms](https://www.mathworks.com/help/matlab-parallel-server/configure-matlab-parallel-server-licensing-for-cloud-platforms.html). +- `networkLicenseManager` — To use a network license manager to manage licensing for your cluster users, specify the address of your network license manager in the format `port@host`. The license manager must be accessible from the Kubernetes cluster. You can install or use an existing network license manager running on-premises or on AWS®. To install a network license manager on-premises, see the MathWorks documentation [Install License Manager on License Server](https://www.mathworks.com/help/install/ug/install-license-manager-on-license-server.html). To deploy a network license manager reference architecture on AWS, select a MATLAB release from [Network License Manager for MATLAB on AWS](https://github.com/mathworks-ref-arch/license-manager-for-matlab-on-aws). - `checkpointPVC` — Specify the name of a PersistentVolumeClaim that is bound to a PersistentVolume used to retain job data. - `logPVC` — Specify the name of a PersistentVolumeClaim that is bound to a PersistentVolume used to retain job manager logs. - `workerLogPVC` — Specify the name of a PersistentVolumeClaim that is bound to a PersistentVolume used to retain worker logs. - `jobManagerUserID` — Specify the user ID of the user account that MATLAB Job Scheduler should use to run the job manager pod. The user must have write permission for the checkpoint and log PersistentVolumes. To find the user ID, on a Linux machine, run `id -u`. - `jobManagerGroupID` — Specify the group ID of the user account that MATLAB Job Scheduler should use to run the job manager pod. The user must have write permission for the checkpoint and log PersistentVolumes. To find the group ID, on a Linux machine, run `id -g`. -- `matlabImage` — Specify the URI of a Docker image that contains a MATLAB Parallel Server installation. Specify a URI only if you built a Docker image instead of mounting a MATLAB Parallel Server installation from a PersistentVolume. If you specify this parameter, set the `matlabPVC` parameter to an empty string (`""`). For a full list of the configurable Helm values that you can set in this file, see the [Helm Values](helm_values.md) page. @@ -228,6 +211,13 @@ If you created a custom load balancer service, delete the service: kubectl delete service mjs-ingress-proxy --namespace mjs ``` +If you want to reinstall MATLAB Job Scheduler, you must ensure that the load balancer service is deleted first. +To check the status of the load balancer service, run: +``` +kubectl get service mjs-ingress-proxy --namespace mjs +``` +If the load balancer service appears, wait for some time, then run the command again to confirm that the load balancer service is not found before proceeding with the MATLAB Job Scheduler reinstallation. + ## Examples Create a cluster object using your cluster profile ``: @@ -311,6 +301,29 @@ end ## Advanced Setup Steps +### Customize Worker Image + +The MATLAB Parallel Server workers run on an image that contains MATLAB, Simulink, all MathWorks toolboxes, and the Deep Learning Support Packages by default. +If you want to increase the performance of creating worker pods or customise the toolboxes or support packages used, you have two options: +1. Build a custom Docker image with only the toolboxes you need +2. Mount the MATLAB installation from a PersistentVolume + +#### Build Custom Docker Image + +To build a custom Docker image, see [Create a MATLAB Parallel Server Container Image](images/worker/README.md). +Push the image to a repository that is visible to your Kubernetes cluster. + +Modify your `values.yaml` file to set the `workerImage` and `workerImageTag` parameters to the URI and tag of your image before installating the Helm chart. + +#### Mount MATLAB from a PersistentVolume + +To mount MATLAB from a PersistentVolume, create a PersistentVolume and PersistentVolumeClaim with access mode `ReadOnlyMany` containing a MATLAB Parallel Server installation. +For example, if your Kubernetes cluster runs on-premise, you could create a PersistentVolume from an NFS server containing the MATLAB Parallel Server installation. +For details on creating the PersistentVolumeClaim, see the [Create Persistent Volumes](#create-persistent-volumes) section. + +Modify your `values.yaml` file to set the `matlabPVC` parameter to the name of your PersistentVolumeClaim before installating the Helm chart. +The worker pods will now use the image URI specified in the `matlabDepsImage` parameter instead of the `workerImage` parameter. + ### Customize Load Balancer MATLAB Job Scheduler in Kubernetes uses a Kubernetes load balancer service to expose MATLAB Job Scheduler to MATLAB clients running outside of the Kubernetes cluster. diff --git a/mjs/Chart.yaml b/chart/mjs/Chart.yaml similarity index 81% rename from mjs/Chart.yaml rename to chart/mjs/Chart.yaml index cdccb10..65b71d6 100644 --- a/mjs/Chart.yaml +++ b/chart/mjs/Chart.yaml @@ -3,5 +3,5 @@ apiVersion: v2 name: mjs description: A Helm chart for MATLAB (R) Job Scheduler in Kubernetes type: application -version: 1.0.0 -appVersion: 1.0.0 +version: 1.1.0 +appVersion: 1.1.0 diff --git a/chart/mjs/templates/_derived.tpl b/chart/mjs/templates/_derived.tpl new file mode 100644 index 0000000..a8ac089 --- /dev/null +++ b/chart/mjs/templates/_derived.tpl @@ -0,0 +1,22 @@ +# Define derived settings for use in multiple template files. +# Copyright 2024 The MathWorks, Inc. + +# Maximum number of pool proxies needed by this chart +{{- define "derived.numProxies" -}} +{{ divf .Values.maxWorkers .Values.workersPerPoolProxy | ceil }} +{{- end -}} + +# MJS lookup port +{{- define "derived.lookupPort" -}} +{{ add .Values.basePort 6 | int }} +{{- end -}} + +# Job manager port +{{- define "derived.jobManagerPort" -}} +{{ add .Values.basePort 9 | int }} +{{- end -}} + +# Whether to create environment variables for each service in the namespace (default false to prevent creation of too many environment variables) +{{- define "derived.enableServiceLinks" -}} +{{ .Values.enableServiceLinks | default false }} +{{- end -}} diff --git a/chart/mjs/templates/_paths.tpl b/chart/mjs/templates/_paths.tpl new file mode 100644 index 0000000..14259ad --- /dev/null +++ b/chart/mjs/templates/_paths.tpl @@ -0,0 +1,78 @@ +# Define paths of files and directories for use in multiple template files. +# Copyright 2024 The MathWorks, Inc. + +# MATLAB root on containers +{{- define "paths.matlabroot" -}} +/opt/matlab +{{- end -}} + +# Checkpoint base on containers +# If running as non-root user and not mounting checkpointbase, use a directory that a non-root user can create +{{- define "paths.checkpointbase" -}} +{{- $isNonRoot := ne (int $.Values.jobManagerUserID) 0 -}} +{{- if and $isNonRoot (empty $.Values.checkpointPVC) -}} +/tmp/checkpoint +{{- else -}} +/mjs/checkpoint +{{- end -}} +{{- end -}} + +# Log base on containers +# If running as non-root user and not mounting log directory, use a directory that a non-root user can create +{{- define "paths.logbase" -}} +{{- $isNonRoot := ne (int $.Values.jobManagerUserID) 0 -}} +{{- if and $isNonRoot (empty $.Values.logPVC) -}} +/tmp/log +{{- else -}} +/mjs/log +{{- end -}} +{{- end -}} + +# MJS config file directory +{{- define "paths.configDir" -}} +/mjs/config +{{- end -}} + +# Shared secret directory +{{- define "paths.secretDir" -}} +/mjs/secret +{{- end -}} + +# Name of the shared secret file +{{- define "paths.secretFile" -}} +secret.json +{{- end -}} + +# Name of the certificate file +{{- define "paths.certFile" -}} +certificate.json +{{- end -}} + +# Full path of the shared secret file +{{- define "paths.secretPath" -}} +{{- printf "%s/%s" (include "paths.secretDir" .) (include "paths.secretFile" .) -}} +{{- end -}} + +# Full path of the certificate file +{{- define "paths.certPath" -}} +{{- printf "%s/%s" (include "paths.secretDir" .) (include "paths.certFile" .) -}} +{{- end -}} + +# Name of controller config file +{{- define "paths.controllerConfig" -}} +config.json +{{- end -}} + +# Controller log file +# If not mounting logs, do not write controller logs to a file +{{- define "paths.controllerLog" -}} +{{- if .Values.logPVC -}} +{{- printf "%s/%s" (include "paths.logbase" .) "controller.log" -}} +{{- else -}} +{{- end -}} +{{- end -}} + +# Ingress proxy config file +{{- define "paths.ingressProxyConfig" -}} +haproxy.cfg +{{- end -}} \ No newline at end of file diff --git a/chart/mjs/templates/_resources.tpl b/chart/mjs/templates/_resources.tpl new file mode 100644 index 0000000..c2bd470 --- /dev/null +++ b/chart/mjs/templates/_resources.tpl @@ -0,0 +1,47 @@ +# Define Kubernetes resource names for use in multiple template files. +# Copyright 2024 The MathWorks, Inc. + +# Job manager +{{- define "resources.jobManager" -}} +mjs-job-manager +{{- end -}} + +# Ingress proxy +{{- define "resources.ingressProxy" -}} +mjs-ingress-proxy +{{- end -}} + +# Controller +{{- define "resources.controller" -}} +mjs-controller +{{- end -}} + +# Pool proxy +{{- define "resources.poolProxy" -}} +mjs-pool-proxy +{{- end -}} + +# MJS config map +{{- define "resources.mjsConfigMap" -}} +mjs-config +{{- end -}} + +# Controller config map +{{- define "resources.controllerConfigMap" -}} +mjs-controller-config +{{- end -}} + +# Ingress proxy config map +{{- define "resources.ingressConfigMap" -}} +mjs-ingress-proxy-config +{{- end -}} + +# Controller service account +{{- define "resources.controllerServiceAccount" -}} +{{ printf "%s-serviceaccount" (include "resources.controller" .) }} +{{- end -}} + +# Controller role +{{- define "resources.controllerRole" -}} +{{ printf "%s-role" (include "resources.controller" .) }} +{{- end -}} \ No newline at end of file diff --git a/chart/mjs/templates/controller-configmap.yaml b/chart/mjs/templates/controller-configmap.yaml new file mode 100644 index 0000000..2cdbba6 --- /dev/null +++ b/chart/mjs/templates/controller-configmap.yaml @@ -0,0 +1,94 @@ +# Config file for the MJS controller. +# Copyright 2024 The MathWorks, Inc. +{{- $workerImageTag := .Values.matlabImageTag | default .Values.matlabRelease }} +{{- $jobManagerImageTag := .Values.jobManagerImageTag | default .Values.matlabRelease }} +{{- $workerImage := .Values.matlabImage }} +{{- $jobManagerImage := .Values.jobManagerImage }} +{{- if not (empty .Values.matlabPVC) }} + {{- $workerImage = .Values.matlabDepsImage }} + {{- if .Values.jobManagerUsesPVC }} + {{- $jobManagerImage = .Values.matlabDepsImage }} + {{- end -}} +{{- end -}} +{{- $poolProxyImageTag := .Values.poolProxyImageTag | default .Values.matlabRelease }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "resources.controllerConfigMap" . }} +data: + {{ include "paths.controllerConfig" . }}: | + { + "BasePort": {{ .Values.basePort | int }}, + "CertFileName": {{ include "paths.certFile" . | quote }}, + "CheckpointBase": {{ include "paths.checkpointbase" . | quote }}, + "CheckpointPVC": {{ .Values.checkpointPVC | quote }}, + "ClusterHost": {{ .Values.clusterHost | quote }}, + "ControllerLogfile": {{ include "paths.controllerLog" . | quote }}, + "DeploymentName": {{ include "resources.controller" . | quote}}, + "EnableServiceLinks": {{ include "derived.enableServiceLinks" . }}, + "ExtraWorkerEnvironment": { + {{- $comma := "" }} + {{- range $key, $value := .Values.extraWorkerEnv }} + {{ $comma }}{{ $key | quote }}: {{ $value | quote }} + {{- $comma = "," }} + {{- end }} + }, + "IdleStop": {{ .Values.idleStop }}, + "InternalClientsOnly": {{ .Values.internalClientsOnly }}, + "JobManagerImage": {{ printf "%s:%s" $jobManagerImage $jobManagerImageTag | quote }}, + "JobManagerImagePullPolicy": {{ .Values.jobManagerImagePullPolicy | quote }}, + "JobManagerName": {{ .Values.jobManagerName | quote }}, + "JobManagerCPULimit": {{ .Values.jobManagerCPULimit | quote }}, + "JobManagerCPURequest": {{ .Values.jobManagerCPURequest | quote }}, + "JobManagerMemoryLimit": {{ .Values.jobManagerMemoryLimit | quote }}, + "JobManagerMemoryRequest": {{ .Values.jobManagerMemoryRequest | quote }}, + "JobManagerGroupID": {{ .Values.jobManagerGroupID }}, + "JobManagerUserID": {{ .Values.jobManagerUserID }}, + "JobManagerUID": {{ uuidv4 | quote }}, + "LivenessProbeFailureThreshold": {{ .Values.livenessProbeFailureThreshold | default 3 }}, + "LivenessProbePeriod": {{ .Values.livenessProbePeriod | default 300 }}, + "LivenessProbeTimeout": {{ .Values.livenessProbeTimeout | default 30 }}, + "LoadBalancerName": {{ (include "resources.ingressProxy" .) | quote }}, + "LogBase": {{ include "paths.logbase" . | quote }}, + "LogLevel": {{ .Values.logLevel }}, + "LogPVC": {{ .Values.logPVC | quote }}, + "MatlabPVC": {{ .Values.matlabPVC | default "" | quote }}, + "MatlabRoot": {{ include "paths.matlabroot" . | quote }}, + "MaxWorkers": {{ .Values.maxWorkers }}, + "MinWorkers": {{ .Values.minWorkers }}, + "MJSDefConfigMap": {{ include "resources.mjsConfigMap" . | quote }}, + "MJSDefDir" : {{ include "paths.configDir" . | quote }}, + "Namespace": {{ .Release.Namespace | quote }}, + "NetworkLicenseManager": {{ .Values.networkLicenseManager | quote }}, + "Period": {{ .Values.autoScalingPeriod }}, + "PortsPerWorker": {{ .Values.portsPerWorker | default 2 }}, + "PoolProxyBasePort": {{ .Values.poolProxyBasePort }}, + "PoolProxyCPULimit": {{ .Values.poolProxyCPULimit | quote }}, + "PoolProxyCPURequest": {{ .Values.poolProxyCPURequest | quote }}, + "PoolProxyImage": {{ printf "%s:%s" .Values.poolProxyImage $poolProxyImageTag | quote }}, + "PoolProxyImagePullPolicy": {{ .Values.poolProxyImagePullPolicy | quote }}, + "PoolProxyMemoryLimit": {{ .Values.poolProxyMemoryLimit | quote }}, + "PoolProxyMemoryRequest": {{ .Values.poolProxyMemoryRequest | quote }}, + "ResizePath": {{ printf "%s/toolbox/parallel/bin/resize" (include "paths.matlabroot" .) | quote }}, + "RequireClientCertificate": {{ .Values.requireClientCertificate }}, + "RequireScriptVerification": {{ .Values.requireScriptVerification }}, + "SecretDir": {{ include "paths.secretDir" . | quote }}, + "SecretFileName": {{ include "paths.secretFile" . | quote }}, + "SecurityLevel": {{ .Values.securityLevel }}, + "StartupProbeFailureThreshold": {{ .Values.startupProbeFailureThreshold | default 60 }}, + "StartupProbeInitialDelay": {{ .Values.startupProbeInitialDelay | default 5 }}, + "StartupProbePeriod": {{ .Values.startupProbePeriod | default 1 }}, + "StopWorkerGracePeriod": {{ .Values.stopWorkerGracePeriod }}, + "WorkerCPULimit": {{ .Values.workerCPULimit | quote }}, + "WorkerCPURequest": {{ .Values.workerCPURequest | quote }}, + "WorkerImage": {{ printf "%s:%s" $workerImage $workerImageTag | quote }}, + "WorkerImagePullPolicy": {{ .Values.matlabImagePullPolicy | quote }}, + "WorkerMemoryLimit": {{ .Values.workerMemoryLimit | quote }}, + "WorkerMemoryRequest": {{ .Values.workerMemoryRequest | quote }}, + "WorkerLogPVC": {{ .Values.workerLogPVC | quote }}, + "WorkerPassword": {{ .Values.workerPassword | quote }}, + "WorkersPerPoolProxy": {{ .Values.workersPerPoolProxy }}, + "WorkerUsername": {{ .Values.workerUsername | quote }}, + "UsePoolProxy": {{ .Values.usePoolProxy | default true }}, + "UseSecureCommunication": {{ .Values.useSecureCommunication }} + } diff --git a/chart/mjs/templates/controller-deployment.yaml b/chart/mjs/templates/controller-deployment.yaml new file mode 100644 index 0000000..1ed8935 --- /dev/null +++ b/chart/mjs/templates/controller-deployment.yaml @@ -0,0 +1,57 @@ +# Deployment for the MJS controller. +# Copyright 2024 The MathWorks, Inc. +{{- $controllerImageTag := .Values.controllerImageTag | default .Chart.AppVersion }} +{{- $name := include "resources.controller" . }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ $name }} +spec: + selector: + matchLabels: + app: {{ $name }} + replicas: 1 + template: + metadata: + labels: + app: {{ $name }} + spec: + # Controller requires elevated Kubernetes permissions + serviceAccountName: {{ include "resources.controllerServiceAccount" . }} + + # If set to false, disable creation of environment variables for services + enableServiceLinks: {{ include "derived.enableServiceLinks" . }} + + containers: + - name: {{ $name }} + image: {{ printf "%s:%s" .Values.controllerImage $controllerImageTag }} + imagePullPolicy: {{ .Values.controllerImagePullPolicy }} + + # The controller process requires the path to a config file as an input argument + # This file is mounted from a ConfigMap (defined in mjs.yaml) + {{- $configMapDir := "/config" }} + args: + - {{ printf "-config=%s/%s" $configMapDir (include "paths.controllerConfig" .) }} + + # Mount the config file from the ConfigMap + {{- $configVolName := "config-vol" }} + volumeMounts: + - name: {{ $configVolName }} + mountPath: {{ $configMapDir }} + + # Store controller logs in the same directory as the job manager logs + {{- $logVolName := "log-vol" }} + {{- if .Values.logPVC }} + - name: {{ $logVolName }} + mountPath: {{ include "paths.logbase" . }} + {{- end }} + + volumes: + - name: {{ $configVolName }} + configMap: + name: {{ include "resources.controllerConfigMap" . }} + {{- if .Values.logPVC }} + - name: {{ $logVolName }} + persistentVolumeClaim: + claimName: {{ .Values.logPVC }} + {{- end }} \ No newline at end of file diff --git a/chart/mjs/templates/controller-role.yaml b/chart/mjs/templates/controller-role.yaml new file mode 100644 index 0000000..b6fecb2 --- /dev/null +++ b/chart/mjs/templates/controller-role.yaml @@ -0,0 +1,16 @@ +# Role for the MJS controller with permissions to interact with the Kubernetes cluster. +# Copyright 2024 The MathWorks, Inc. +kind: Role +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "resources.controllerRole" . }} +rules: +- apiGroups: [""] + resources: ["pods", "services", "secrets"] + verbs: ["create", "get", "list", "delete", "update"] +- apiGroups: [""] + resources: ["pods/exec"] + verbs: ["create"] +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["create", "get", "list", "delete", "update"] \ No newline at end of file diff --git a/chart/mjs/templates/controller-rolebinding.yaml b/chart/mjs/templates/controller-rolebinding.yaml new file mode 100644 index 0000000..339753a --- /dev/null +++ b/chart/mjs/templates/controller-rolebinding.yaml @@ -0,0 +1,13 @@ +# Bind the MJS controller role to the service account. +# Copyright 2024 The MathWorks, Inc. +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ printf "%s-rolebinding" (include "resources.controller" .) }} +subjects: +- kind: ServiceAccount + name: {{ include "resources.controllerServiceAccount" . }} +roleRef: + kind: Role + name: {{ include "resources.controllerRole" . }} + apiGroup: rbac.authorization.k8s.io \ No newline at end of file diff --git a/chart/mjs/templates/controller-serviceaccount.yaml b/chart/mjs/templates/controller-serviceaccount.yaml new file mode 100644 index 0000000..bae605c --- /dev/null +++ b/chart/mjs/templates/controller-serviceaccount.yaml @@ -0,0 +1,6 @@ +# Service account for the MJS controller pod. +# Copyright 2024 The MathWorks, Inc. +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "resources.controllerServiceAccount" . }} \ No newline at end of file diff --git a/chart/mjs/templates/ingress-proxy-configmap.yaml b/chart/mjs/templates/ingress-proxy-configmap.yaml new file mode 100644 index 0000000..a6f8915 --- /dev/null +++ b/chart/mjs/templates/ingress-proxy-configmap.yaml @@ -0,0 +1,43 @@ +{{- if not .Values.internalClientsOnly }} +# HAproxy config file with rules for mapping to the job manager or pool proxies based on TCP port. +# Copyright 2024 The MathWorks, Inc. +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "resources.ingressConfigMap" . }} +data: + {{ include "paths.ingressProxyConfig" . }}: | + global + log stdout local0 + defaults + default-server init-addr last,libc,none + log global + option tcplog + mode tcp + timeout connect 30s + timeout client 300s + timeout server 300s + + # Rules for proxying traffic to the job manager pod. + frontend front-lookup + bind {{ printf "*:%d" (include "derived.lookupPort" . | int) }} + default_backend back-mjs-job-manager + frontend front-jobmanager + bind {{ printf "*:%d" (include "derived.jobManagerPort" . | int) }} + default_backend back-mjs-job-manager + backend back-mjs-job-manager + server mjs-job-manager mjs-job-manager + + # Rules for proxying traffic to the parallel pool proxies. + # Each parallel pool proxy has a unique port, which should be mapped to the + # corresponding Kubernetes service for that proxy. + {{- range untilStep 0 (include "derived.numProxies" . | int) 1 }} + {{- $portNum := add $.Values.poolProxyBasePort . | int }} + {{- $poolProxyName := printf "%s-%d" (include "resources.poolProxy" .) (add . 1) }} + frontend front-{{ $poolProxyName }} + bind {{ printf "*:%d" $portNum }} + default_backend back-{{ $poolProxyName }} + backend back-{{ $poolProxyName }} + server {{ $poolProxyName }} {{ $poolProxyName }} + {{ end -}} +{{ end -}} \ No newline at end of file diff --git a/chart/mjs/templates/ingress-proxy-deployment.yaml b/chart/mjs/templates/ingress-proxy-deployment.yaml new file mode 100644 index 0000000..1efd7d3 --- /dev/null +++ b/chart/mjs/templates/ingress-proxy-deployment.yaml @@ -0,0 +1,44 @@ +{{- if not .Values.internalClientsOnly }} +# Deployment running HAproxy; this proxies incoming connections to the job manager +# or workers via a single external load balancer. +# Copyright 2024 The MathWorks, Inc. +{{- $name := include "resources.ingressProxy" . }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ $name }} +spec: + selector: + matchLabels: + app: {{ $name }} + replicas: 1 + template: + metadata: + labels: + app: {{ $name }} + spec: + # If set to false, disable creation of environment variables for services + enableServiceLinks: {{ include "derived.enableServiceLinks" . }} + + containers: + - name: haproxy + image: {{ $.Values.haproxyImage }} + imagePullPolicy: {{ $.Values.haproxyImagePullPolicy }} + + # Pass the config file path as an input argument + {{- $configDir := "/usr/local/etc/haproxy/" }} + args: + - "-f" + - {{ printf "%s/%s" $configDir (include "paths.ingressProxyConfig" .) }} + + # Mount the config file from the ConfigMap + {{- $configVolName := "config-volume" }} + volumeMounts: + - name: {{ $configVolName }} + mountPath: {{ $configDir }} + + volumes: + - name: {{ $configVolName }} + configMap: + name: {{ include "resources.ingressConfigMap" . }} +{{ end -}} diff --git a/chart/mjs/templates/ingress-proxy-service.yaml b/chart/mjs/templates/ingress-proxy-service.yaml new file mode 100644 index 0000000..8e89ccd --- /dev/null +++ b/chart/mjs/templates/ingress-proxy-service.yaml @@ -0,0 +1,37 @@ +{{- if and .Values.autoCreateLoadBalancer (not .Values.internalClientsOnly) }} +# LoadBalancer Service for routing traffic from outside the Kubernetes cluster. +# Copyright 2024 The MathWorks, Inc. +{{- $name := include "resources.ingressProxy" . }} +apiVersion: v1 +kind: Service +metadata: + name: {{ $name }} + labels: + app: {{ $name }} +spec: + type: LoadBalancer + selector: + app: {{ $name }} + ports: + # Job manager ports + - name: "tcp-lookup" + protocol: TCP + appProtocol: TCP + port: {{ include "derived.lookupPort" . }} + targetPort: {{ include "derived.lookupPort" . }} + - name: "tcp-jobmanager" + protocol: TCP + appProtocol: TCP + port: {{ include "derived.jobManagerPort" . }} + targetPort: {{ include "derived.jobManagerPort" . }} + + # Pool proxy ports + {{- range untilStep 0 (include "derived.numProxies" . | int) 1 }} + {{- $poolProxyPort := add $.Values.poolProxyBasePort . }} + - name: {{ printf "tcp-pool-proxy-%d" (add . 1) }} + protocol: TCP + appProtocol: TCP + port: {{ $poolProxyPort }} + targetPort: {{ $poolProxyPort }} + {{ end -}} +{{ end -}} \ No newline at end of file diff --git a/chart/mjs/templates/job-manager-service.yaml b/chart/mjs/templates/job-manager-service.yaml new file mode 100644 index 0000000..afd1a13 --- /dev/null +++ b/chart/mjs/templates/job-manager-service.yaml @@ -0,0 +1,25 @@ +# Internal Service for workers to use to communicate with the job manager +# Copyright 2024 The MathWorks, Inc. +apiVersion: v1 +kind: Service +metadata: + name: {{ include "resources.jobManager" . }} + labels: + app: {{ include "resources.jobManager" . }} +spec: + type: ClusterIP + + # Match the job manager pod + selector: + app: {{ include "resources.jobManager" . }} + + ports: + {{- $minPort := .Values.basePort | int }} + {{- $maxPort := add $minPort 10 | int }} + {{- range untilStep $minPort $maxPort 1 }} + - name: {{ printf "tcp-%d" . }} + protocol: TCP + appProtocol: TCP + port: {{ . }} + targetPort: {{ . }} + {{- end }} \ No newline at end of file diff --git a/chart/mjs/templates/mjs-configmap.yaml b/chart/mjs/templates/mjs-configmap.yaml new file mode 100644 index 0000000..78ec033 --- /dev/null +++ b/chart/mjs/templates/mjs-configmap.yaml @@ -0,0 +1,99 @@ +# ConfigMap containing scripts for the job manager and worker pods. +# Copyright 2024 The MathWorks, Inc. +{{- $localMJSDef := "/tmp/mjs_def.sh" }} +{{- $binDir := printf "%s/toolbox/parallel/bin/" (include "paths.matlabroot" .) }} +{{- $basePort := .Values.basePort | int }} +{{- $workerStartedFile := "/tmp/worker-started" }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "resources.mjsConfigMap" . }} +data: + mjs_def.sh: | + # Common mjs_def.sh file for the job manager and workers + BASE_PORT={{ .Values.basePort }} + MAX_LINUX_WORKERS={{ .Values.maxWorkers }} + CHECKPOINTBASE={{ include "paths.checkpointbase" . }} + PIDBASE=/tmp/pid + USE_SECURE_COMMUNICATION={{ .Values.useSecureCommunication }} + REQUIRE_CLIENT_CERTIFICATE={{ .Values.requireClientCertificate }} + REQUIRE_SCRIPT_VERIFICATION={{ .Values.requireScriptVerification }} + SECURITY_LEVEL={{ .Values.securityLevel }} + SHARED_SECRET_FILE={{ include "paths.secretPath" . }} + USE_ONLINE_LICENSING={{ .Values.useOnlineLicensing }} + + jobManager.sh: | + # Script to run on the MATLAB Job Scheduler job manager pod + set -o errexit + + # Set up the mjs_def file + cp {{ printf "%s/mjs_def.sh" (include "paths.configDir" .) }} {{ $localMJSDef }} + echo "HOSTNAME={{ include "resources.jobManager" . }}" >> {{ $localMJSDef }} + echo "LOGBASE={{ include "paths.logbase" . }}" >> {{ $localMJSDef }} + + # Start the MJS service + {{ printf "%s/mjs" $binDir }} start -mjsdef {{ $localMJSDef }} -loglevel {{ .Values.logLevel }} -disablereliableconnections + + # Start the job manager + {{- $jmCommand := printf "%s/startjobmanager -name \"%s\" -baseport %d" $binDir .Values.jobManagerName $basePort }} + {{- if .Values.requireClientCertificate }} + {{- $jmCommand = printf "%s -certificate \"%s\"" $jmCommand (include "paths.certPath" .) }} + {{- end }} + {{- if .Values.requireScriptVerification }} + {{- $jmCommand = printf "%s -secretfile \"%s\"" $jmCommand (include "paths.secretPath" .) }} + {{- end }} + {{ $jmCommand }} || echo "startjobmanager failed; there may already be a job manager running" + + # Keep the container running + sleep infinity + + worker.sh: | + # Script to run on worker pods + set -o errexit + + # Set up the mjs_def file + cp {{ printf "%s/mjs_def.sh" (include "paths.configDir" .) }} {{ $localMJSDef }} + LOGBASE={{ include "paths.logbase" . }}/${WORKER_NAME} + echo "LOGBASE=${LOGBASE}" >> {{ $localMJSDef }} + echo "HOSTNAME=${HOSTNAME}" >> {{ $localMJSDef }} + + # Ensure log directory exists and is writeable by workers + if [ ! -d "${LOGBASE}" ]; then + mkdir -p "${LOGBASE}" + fi + chmod o+w "${LOGBASE}" + + # Create a user to run MATLAB as + useradd --create-home {{ .Values.workerUsername }} + echo {{ printf "%s:%s" .Values.workerUsername .Values.workerPassword }} | chpasswd + + # Start the MJS service + {{ printf "%s/mjs" $binDir }} start -mjsdef {{ $localMJSDef }} -loglevel {{ .Values.logLevel }} -disablereliableconnections + + # Start the worker + {{- $workerCmd := printf "%s/startworker -jobmanager \"%s\" -jobmanagerhost \"%s\" -name \"${WORKER_NAME}\" -baseport %d" $binDir .Values.jobManagerName (include "resources.jobManager" .) $basePort }} + {{- if .Values.requireScriptVerification }} + {{- $workerCmd = printf "%s -secretfile \"%s\"" $workerCmd (include "paths.secretPath" .) }} + {{- end }} + {{ $workerCmd }} + + # Add a file to indicate that startworker is complete + touch {{ $workerStartedFile }} + + # Keep the container running + sleep infinity + + stopWorker.sh: | + # Script to gracefully shut down a worker + # First, wait for startworker to have finished successfully + while [ ! -f {{ $workerStartedFile | quote }} ]]; do + echo "Waiting for startworker to finish" + sleep 1 + done + + # Stop the worker + {{- $stopCmd := printf "%s/stopworker -clean -name ${WORKER_NAME}" $binDir }} + {{- if .Values.requireScriptVerification }} + {{- $stopCmd = printf "%s -secretfile \"%s\"" $stopCmd (include "paths.secretPath" .) }} + {{- end }} + {{ $stopCmd }} diff --git a/mjs/templates/no_upgrade.yaml b/chart/mjs/templates/no_upgrade.yaml similarity index 89% rename from mjs/templates/no_upgrade.yaml rename to chart/mjs/templates/no_upgrade.yaml index 8f9f8b8..ce945de 100644 --- a/mjs/templates/no_upgrade.yaml +++ b/chart/mjs/templates/no_upgrade.yaml @@ -1,3 +1,4 @@ +{{- /* Copyright 2024 The MathWorks, Inc. */}} {{- if .Release.IsUpgrade }} {{- fail (printf "Helm upgrade is not supported for this chart. To change the configuration or chart version of MATLAB Job Scheduler in Kubernetes, run 'helm uninstall %s --namespace %s' to remove the existing Helm release, then install a new Helm release with the values and chart version of your choice." .Release.Name .Release.Namespace) }} {{- end }} diff --git a/chart/mjs/templates/pool-proxy-services.yaml b/chart/mjs/templates/pool-proxy-services.yaml new file mode 100644 index 0000000..ee4f2df --- /dev/null +++ b/chart/mjs/templates/pool-proxy-services.yaml @@ -0,0 +1,26 @@ +# Create a service for each pool proxy so that the ingress proxy always has a backend to route to. +# Note that the pool proxy pods themselves are created later by the controller. +# Copyright 2024 The MathWorks, Inc. +{{- range untilStep 0 (include "derived.numProxies" . | int) 1 }} +{{- $portNum := add $.Values.poolProxyBasePort . | int }} +{{- $proxyNum := add . 1 }} +{{- $name := printf "%s-%d" (include "resources.poolProxy" .) $proxyNum }} +apiVersion: v1 +kind: Service +metadata: + name: {{ $name }} + labels: + app: {{ include "resources.poolProxy" . }} + proxyName: {{ $name }} + port: {{ $portNum | quote }} + proxyID: {{ $proxyNum | quote }} +spec: + type: ClusterIP + selector: + proxyName: {{ $name }} + ports: + - protocol: TCP + port: {{ $portNum }} + targetPort: {{ $portNum }} +--- +{{ end -}} \ No newline at end of file diff --git a/mjs/templates/requirements.yaml b/chart/mjs/templates/requirements.yaml similarity index 78% rename from mjs/templates/requirements.yaml rename to chart/mjs/templates/requirements.yaml index 774bbde..1ec47ab 100644 --- a/mjs/templates/requirements.yaml +++ b/chart/mjs/templates/requirements.yaml @@ -2,10 +2,6 @@ {{- required "Specify a value for the maximum number of MATLAB Job Scheduler workers to start using the maxWorkers parameter." .Values.maxWorkers }} -{{- if not .Values.matlabImage }} -{{- required "Specify either the URI of a Docker image containing a MATLAB Parallel Server installation using the matlabImage parameter or the name of a Persistent Volume Claim that contains a MATLAB Parallel Server installation using the matlabPVC parameter." .Values.matlabPVC }} -{{- end }} - {{- if not (hasKey .Values "checkpointPVC") }} {{- required "Specify the name of a Persistent Volume Claim to store persistent job data using the checkpointPVC parameter. Set this parameter to an empty string if you do not want to persist job data, but be aware that you may lose job and task data unexpectedly between job manager restarts." .Values.checkpointPVC }} {{- end }} diff --git a/mjs/values.yaml b/chart/mjs/values.yaml similarity index 77% rename from mjs/values.yaml rename to chart/mjs/values.yaml index ff1323d..5194d6f 100644 --- a/mjs/values.yaml +++ b/chart/mjs/values.yaml @@ -1,10 +1,18 @@ # Default values for MATLAB Job Scheduler (MJS) in Kubernetes. # Copyright 2024 The MathWorks, Inc. -# Image containing MATLAB Parallel Server -matlabImage: "" # If this field is unset, the mathworks/matlab-deps image is used by default +# Release number of the MATLAB version to use +matlabRelease: "r2024a" + +# Image for the MATLAB workers +matlabImage: "ghcr.io/mathworks-ref-arch/matlab-parallel-server-k8s/mjs-worker-image" matlabImagePullPolicy: "IfNotPresent" -matlabRelease: "r2024a" # Release number of the MATLAB version to use +matlabImageTag: "" # If this field is unset, the matlabRelease parameter is used as the tag + +# Image for the MJS job manager +jobManagerImage: "ghcr.io/mathworks-ref-arch/matlab-parallel-server-k8s/mjs-job-manager-image" +jobManagerImagePullPolicy: "IfNotPresent" +jobManagerImageTag: "" # If this field is unset, the matlabRelease parameter is used as the tag # Image containing the MJS in Kubernetes controller controllerImage: "ghcr.io/mathworks-ref-arch/matlab-parallel-server-k8s/mjs-controller-image" @@ -68,11 +76,15 @@ internalClientsOnly: false # Flag to allow only MATLAB clients running inside th networkLicenseManager: "" # Address of a network license manager with format port@host useOnlineLicensing: false # Set to true to use Online Licensing +# Options to mount a MATLAB Parallel Server installation from a PersistentVolumeClaim (PVC) +matlabDepsImage: "mathworks/matlab-deps" +matlabPVC: "" # Name of a PVC that contains a MATLAB Parallel Server installation to use. If this is set, the matlabDepsImage parameter is used for the worker containers instead of the matlabImage parameter +jobManagerUsesPVC: false # If true, the job manager container mounts the MATLAB Parallel Server installation from the PVC rather than using the jobManagerImage parameter + # Specify the maximum number of workers that the cluster can automatically resize to in your custom values.yaml file. # maxWorkers: 32 -# Specify the names of the Persistent Volume Claims (PVCs) for these parameters in your custom values.yaml file. -# matlabPVC: "matlab-pvc" # Name of a PVC that contains a MATLAB Parallel Server installation +# Specify the names of the PVCs for these parameters in your custom values.yaml file. # checkpointPVC: "checkpoint-pvc" # Name of a PVC where MATLAB Parallel Server stores persistent data related to the job manager # logPVC: "log-pvc" # Name of a PVC where MATLAB Parallel Server stores job manager logs # workerLogPVC: "worker-log-pvc" # Name of a PVC where MATLAB Parallel Server stores worker logs diff --git a/helm_values.md b/helm_values.md index e6d571b..33fb229 100644 --- a/helm_values.md +++ b/helm_values.md @@ -21,14 +21,20 @@ If you do not include a parameter in your YAML file, your configuration uses the `jobManagerCPULimit` | CPU limit for the job manager pod. | — `jobManagerCPURequest` | CPU request for the job manager pod. | `1` `jobManagerGroupID` | Group ID of the user account that MATLAB Job Scheduler uses to run the job manager pod. The user must have write permission for the checkpoint and log PersistentVolumes. To find the group ID, on a Linux machine, run the command `id -g` in the terminal. | `0` +`jobManagerImage` | URI of the MATLAB Parallel Server image to use for the MATLAB Job Scheduler job manager. | `ghcr.io/mathworks-ref-arch/matlab-parallel-server-k8s/mjs-job-manager-image` +`jobManagerImagePullPolicy` | Pull policy for the job manager image. | `IfNotPresent` +`jobManagerImageTag` | Tag of the image to use for the job manager image. If you do not set this value, the Helm chart uses the `matlabRelease` parameter as the tag. | — `jobManagerMemoryLimit` | Memory limit for the job manager pod. | — `jobManagerMemoryRequest` | Memory request for the job manager pod. | `4Gi` `jobManagerName` | Name of the MATLAB Job Scheduler job manager. | `MJS_Kubernetes` `jobManagerUserID` | User ID of the user account that MATLAB Job Scheduler uses to run the job manager pod. The user must have write permission for the checkpoint and log PersistentVolumes. To find the user ID, on a Linux machine, run `id -u` in the terminal. | `0` +`jobManagerUsesPVC` | Flag to mount a MATLAB Parallel Server installation from a PersistentVolume onto the job manager pod if the `matlabPVC` parameter is set. If this flag is set to true, the job manager pod uses the image specified in the `matlabDepsImage` parameter. | `false` `logLevel` | Verbosity level of MATLAB Job Scheduler logging. | `0` `logPVC` | Name of the PersistentVolumeClaim that is bound to the PersistentVolume used to retain job manager logs. | — -`matlabImage` | URI of the image to use for the MATLAB Job Scheduler pods. If unset, your configuration uses the [`mathworks/matlab-deps`](https://hub.docker.com/r/mathworks/matlab-deps) image. Set this value if you built a custom Docker image containing a MATLAB Parallel Server installation or if you want to use a privately hosted version of the `mathworks/matlab-deps` image. | — -`matlabImagePullPolicy` | Pull policy for the MATLAB image. | `IfNotPresent` +`matlabDepsImage` | URI of the MATLAB dependencies image to use for the MATLAB Job Scheduler worker pods if the MATLAB Parallel Server installation is mounted from a PersistentVolume. The worker pods only use this image if the `matlabPVC` parameter is set. The worker pods use the `matlabImageTag` parameter as the image tag. | `mathworks/matlab-deps` +`matlabImage` | URI of the image to use for the MATLAB Job Scheduler workers. This image should contain a MATLAB Parallel Server installation, plus any MathWorks toolboxes you want to use in your MATLAB Parallel Server jobs. | `ghcr.io/mathworks-ref-arch/matlab-parallel-server-k8s/mjs-worker-image` +`matlabImagePullPolicy` | Pull policy for the worker image. | `IfNotPresent` +`matlabImageTag` | Tag of the image to use for the worker image. If you do not set this value, the Helm chart uses the `matlabRelease` parameter as the tag. | — `matlabPVC` | Name of the PersistentVolumeClaim that is bound to the PersistentVolume with a MATLAB Parallel Server installation. Set this option only if you did not build a Docker image containing a MATLAB Parallel Server installation. | — `matlabRelease` | Release number of the MATLAB version to use. | `r2024a` `maxWorkers` | Maximum number of workers that the cluster can automatically resize to. | — diff --git a/controller/Dockerfile b/images/controller/Dockerfile similarity index 92% rename from controller/Dockerfile rename to images/controller/Dockerfile index 81e3fe8..f69b6fd 100644 --- a/controller/Dockerfile +++ b/images/controller/Dockerfile @@ -1,7 +1,7 @@ # Copyright 2024 The MathWorks, Inc. # Stage 1: Build the controller executable -FROM golang:1.21.6 as builder +FROM golang:1.22.2 as builder WORKDIR /app COPY src/ /app RUN go version diff --git a/controller/src/cmd/main.go b/images/controller/src/cmd/main.go similarity index 96% rename from controller/src/cmd/main.go rename to images/controller/src/cmd/main.go index 83c66db..fc39824 100644 --- a/controller/src/cmd/main.go +++ b/images/controller/src/cmd/main.go @@ -1,4 +1,4 @@ -// Package main runs the MJS in Kubernetes controller +// Package main runs the MJS in Kubernetes controller. // Copyright 2024 The MathWorks, Inc. package main diff --git a/controller/src/go.mod b/images/controller/src/go.mod similarity index 99% rename from controller/src/go.mod rename to images/controller/src/go.mod index 2138a94..9721fa6 100644 --- a/controller/src/go.mod +++ b/images/controller/src/go.mod @@ -1,6 +1,6 @@ module controller -go 1.21.6 +go 1.22.2 require ( github.com/google/uuid v1.3.0 diff --git a/controller/src/go.sum b/images/controller/src/go.sum similarity index 100% rename from controller/src/go.sum rename to images/controller/src/go.sum diff --git a/controller/src/internal/config/config.go b/images/controller/src/internal/config/config.go similarity index 94% rename from controller/src/internal/config/config.go rename to images/controller/src/internal/config/config.go index 9e207fc..48008de 100644 --- a/controller/src/internal/config/config.go +++ b/images/controller/src/internal/config/config.go @@ -19,12 +19,15 @@ type Config struct { ClusterHost string DeploymentName string EnableServiceLinks bool + ExtraWorkerEnvironment map[string]string JobManagerUID string IdleStop int InternalClientsOnly bool JobManagerName string JobManagerCPULimit string JobManagerCPURequest string + JobManagerImage string + JobManagerImagePullPolicy string JobManagerMemoryLimit string JobManagerMemoryRequest string JobManagerGroupID int64 @@ -38,8 +41,6 @@ type Config struct { LogBase string LogLevel int LogPVC string - MatlabImagePullPolicy string - MatlabImage string MatlabRoot string MatlabPVC string MaxWorkers int @@ -48,7 +49,6 @@ type Config struct { MJSDefDir string Namespace string NetworkLicenseManager string - OverrideWrapperPhoenix bool Period int PortsPerWorker int PoolProxyBasePort int @@ -71,6 +71,8 @@ type Config struct { StopWorkerGracePeriod int64 WorkerCPURequest string WorkerCPULimit string + WorkerImage string + WorkerImagePullPolicy string WorkerLogPVC string WorkerMemoryRequest string WorkerMemoryLimit string diff --git a/controller/src/internal/controller/controller.go b/images/controller/src/internal/controller/controller.go similarity index 99% rename from controller/src/internal/controller/controller.go rename to images/controller/src/internal/controller/controller.go index e0b64d0..d1d32dd 100644 --- a/controller/src/internal/controller/controller.go +++ b/images/controller/src/internal/controller/controller.go @@ -288,7 +288,10 @@ func (c *Controller) createJobManager() error { // Wait for the pod to be ready before returning c.logger.Info("waiting for job manager pod to be ready") - c.waitForJobManager() + err = c.waitForJobManager() + if err != nil { + return err + } c.logger.Info("found ready job manager pod") return nil } diff --git a/controller/src/internal/controller/controller_test.go b/images/controller/src/internal/controller/controller_test.go similarity index 99% rename from controller/src/internal/controller/controller_test.go rename to images/controller/src/internal/controller/controller_test.go index aad070a..8134bfb 100644 --- a/controller/src/internal/controller/controller_test.go +++ b/images/controller/src/internal/controller/controller_test.go @@ -186,7 +186,8 @@ func TestCreateProfile(t *testing.T) { secret, err = certificate.New().CreateSharedSecret() require.NoError(tt, err) } - controller.createProfile(secret) + err = controller.createProfile(secret) + require.NoError(t, err) expectedHost := fmt.Sprintf("%s:%d", lbAddress, controller.config.BasePort) verifyClusterProfileCreated(tt, controller, secret, expectedHost, tc.requireClientCertificate) }) diff --git a/controller/src/internal/k8s/k8s.go b/images/controller/src/internal/k8s/k8s.go similarity index 100% rename from controller/src/internal/k8s/k8s.go rename to images/controller/src/internal/k8s/k8s.go diff --git a/controller/src/internal/k8s/k8s_test.go b/images/controller/src/internal/k8s/k8s_test.go similarity index 100% rename from controller/src/internal/k8s/k8s_test.go rename to images/controller/src/internal/k8s/k8s_test.go diff --git a/controller/src/internal/logging/logging.go b/images/controller/src/internal/logging/logging.go similarity index 90% rename from controller/src/internal/logging/logging.go rename to images/controller/src/internal/logging/logging.go index f78f169..de54855 100644 --- a/controller/src/internal/logging/logging.go +++ b/images/controller/src/internal/logging/logging.go @@ -3,6 +3,7 @@ package logging import ( + "fmt" "os" "time" @@ -18,9 +19,15 @@ type Logger struct { // Gracefully close a logger func (l *Logger) Close() { - l.Logger.Sync() + err := l.Logger.Sync() + if err != nil { + fmt.Fprintf(os.Stderr, "error syncing logger: %v\n", err) + } if l.logFile != nil { - l.logFile.Sync() + err := l.logFile.Sync() + if err != nil { + fmt.Fprintf(os.Stderr, "error syncing log file: %v\n", err) + } l.logFile.Close() } } diff --git a/controller/src/internal/logging/logging_test.go b/images/controller/src/internal/logging/logging_test.go similarity index 100% rename from controller/src/internal/logging/logging_test.go rename to images/controller/src/internal/logging/logging_test.go diff --git a/controller/src/internal/request/request.go b/images/controller/src/internal/request/request.go similarity index 100% rename from controller/src/internal/request/request.go rename to images/controller/src/internal/request/request.go diff --git a/controller/src/internal/request/request_test.go b/images/controller/src/internal/request/request_test.go similarity index 98% rename from controller/src/internal/request/request_test.go rename to images/controller/src/internal/request/request_test.go index 3fc636e..a31448d 100644 --- a/controller/src/internal/request/request_test.go +++ b/images/controller/src/internal/request/request_test.go @@ -176,7 +176,8 @@ func TestProcessJSONMultipleJobManagers(t *testing.T) { m, _ := createRequestGetterWithMockClient(t, &config.Config{}) didExit := false m.exitFunc = func() { didExit = true } - m.processRequest([]byte(rawReq)) + _, err := m.processRequest([]byte(rawReq)) + require.NoError(t, err) assert.True(t, didExit, "Process should have exited when multiple job managers were found") } diff --git a/controller/src/internal/rescaler/rescaler.go b/images/controller/src/internal/rescaler/rescaler.go similarity index 100% rename from controller/src/internal/rescaler/rescaler.go rename to images/controller/src/internal/rescaler/rescaler.go diff --git a/controller/src/internal/rescaler/rescaler_test.go b/images/controller/src/internal/rescaler/rescaler_test.go similarity index 100% rename from controller/src/internal/rescaler/rescaler_test.go rename to images/controller/src/internal/rescaler/rescaler_test.go diff --git a/controller/src/internal/resize/resize.go b/images/controller/src/internal/resize/resize.go similarity index 98% rename from controller/src/internal/resize/resize.go rename to images/controller/src/internal/resize/resize.go index 26bf7bc..f46411f 100644 --- a/controller/src/internal/resize/resize.go +++ b/images/controller/src/internal/resize/resize.go @@ -105,7 +105,7 @@ func (m *MJSResizer) DeleteWorkers(names []string) error { // Clean up resources associated with the workers we successfully deleted if m.config.UsePoolProxy() { - m.deleteProxiesIfNotNeeded(existingWorkers, deletedWorkerIDMap) + return m.deleteProxiesIfNotNeeded(existingWorkers, deletedWorkerIDMap) } return nil } @@ -147,7 +147,7 @@ func (m *MJSResizer) addWorkersAndProxies(workers []specs.WorkerInfo) error { // Clean up the proxy if none of its associated workers were successfully added if !workersWereAdded { - m.deletePoolProxy(proxy.Name) + return m.deletePoolProxy(proxy.Name) } } return nil @@ -300,7 +300,10 @@ func (m *MJSResizer) deleteProxiesIfNotNeeded(originalWorkers []Worker, deletedI for _, proxy := range existingProxies { shouldKeep := toKeep[proxy.ID] if !shouldKeep { - m.deletePoolProxy(proxy.Name) + err = m.deletePoolProxy(proxy.Name) + if err != nil { + m.logger.Warn("error deleting pool proxy", zap.Error(err)) + } } } return nil diff --git a/controller/src/internal/resize/resize_test.go b/images/controller/src/internal/resize/resize_test.go similarity index 98% rename from controller/src/internal/resize/resize_test.go rename to images/controller/src/internal/resize/resize_test.go index 6f06392..32a8b83 100644 --- a/controller/src/internal/resize/resize_test.go +++ b/images/controller/src/internal/resize/resize_test.go @@ -201,7 +201,8 @@ func TestGetProxiesNeededForWorkers(t *testing.T) { proxies := []specs.PoolProxyInfo{} for _, p := range tc.existingProxies { proxy := specs.NewPoolProxyInfo(p, resizer.config.PoolProxyBasePort) - resizer.addPoolProxy(proxy) + err := resizer.addPoolProxy(proxy) + require.NoError(t, err) proxies = append(proxies, proxy) } verifyGetProxiesResponse(t, resizer, proxies) @@ -255,7 +256,8 @@ func TestDeleteProxiesIfNotNeeded(t *testing.T) { proxies := []specs.PoolProxyInfo{} for _, p := range tc.existingProxies { proxy := specs.NewPoolProxyInfo(p, resizer.config.PoolProxyBasePort) - resizer.addPoolProxy(proxy) + err := resizer.addPoolProxy(proxy) + require.NoError(t, err) proxies = append(proxies, proxy) } verifyGetProxiesResponse(t, resizer, proxies) @@ -269,7 +271,8 @@ func TestDeleteProxiesIfNotNeeded(t *testing.T) { for _, w := range tc.deletedWorkerIDs { deletedIDsMap[w] = true } - resizer.deleteProxiesIfNotNeeded(origWorkers, deletedIDsMap) + err := resizer.deleteProxiesIfNotNeeded(origWorkers, deletedIDsMap) + require.NoError(t, err) // Check the remaining proxies are as expected finalProxies := []specs.PoolProxyInfo{} @@ -323,13 +326,15 @@ func verifyEndToEndScaling(t *testing.T, useProxy bool) { {Name: "worker4", ID: 4}, {Name: "worker5", ID: 5}, } - resizer.AddWorkers(workers2) + err = resizer.AddWorkers(workers2) + require.NoError(t, err) allWorkers := append(workers1, workers2...) verifyClusterState(t, resizer, allWorkers, useProxy) // Delete some workers toDelete := []string{"worker2", "worker4"} - resizer.DeleteWorkers(toDelete) + err = resizer.DeleteWorkers(toDelete) + require.NoError(t, err) // Check remaining workers remainingWorkers := []specs.WorkerInfo{} @@ -351,7 +356,8 @@ func verifyEndToEndScaling(t *testing.T, useProxy bool) { verifyClusterState(t, resizer, remainingWorkers, useProxy) // Clean up remaining workers - resizer.DeleteWorkers(remainingWorkerNames) + err = resizer.DeleteWorkers(remainingWorkerNames) + require.NoError(t, err) verifyClusterState(t, resizer, []specs.WorkerInfo{}, useProxy) } diff --git a/controller/src/internal/specs/specs.go b/images/controller/src/internal/specs/specs.go similarity index 93% rename from controller/src/internal/specs/specs.go rename to images/controller/src/internal/specs/specs.go index 2332d95..bc3f76b 100644 --- a/controller/src/internal/specs/specs.go +++ b/images/controller/src/internal/specs/specs.go @@ -73,8 +73,8 @@ func (s *SpecFactory) GetWorkerDeploymentSpec(w *WorkerInfo) *appsv1.Deployment workerScript := filepath.Join(s.config.MJSDefDir, "worker.sh") container := corev1.Container{ Name: "mjs-worker", - Image: s.config.MatlabImage, - ImagePullPolicy: corev1.PullPolicy(s.config.MatlabImagePullPolicy), + Image: s.config.WorkerImage, + ImagePullPolicy: corev1.PullPolicy(s.config.WorkerImagePullPolicy), Command: []string{"/bin/sh"}, Args: []string{workerScript}, } @@ -106,6 +106,12 @@ func (s *SpecFactory) GetWorkerDeploymentSpec(w *WorkerInfo) *appsv1.Deployment } else { workerEnv["MDCE_OVERRIDE_EXTERNAL_HOSTNAME"] = s.GetServiceHostname(w.HostName) // Hostname for clients inside the K8s cluster } + + // Add custom worker environment variables + for key, val := range s.config.ExtraWorkerEnvironment { + workerEnv[key] = val + } + addEnv(&container, workerEnv) // Add pre-stop hook to stop the worker cleanly @@ -252,8 +258,8 @@ func (s *SpecFactory) GetJobManagerDeploymentSpec() *appsv1.Deployment { jobManagerScript := filepath.Join(s.config.MJSDefDir, "jobManager.sh") container := corev1.Container{ Name: JobManagerHostname, - Image: s.config.MatlabImage, - ImagePullPolicy: corev1.PullPolicy(s.config.MatlabImagePullPolicy), + Image: s.config.JobManagerImage, + ImagePullPolicy: corev1.PullPolicy(s.config.JobManagerImagePullPolicy), Command: []string{"/bin/sh", jobManagerScript}, } addResourceRequests(&container, s.config.JobManagerCPURequest, s.config.JobManagerMemoryRequest) @@ -337,13 +343,6 @@ func (s *SpecFactory) GetJobManagerDeploymentSpec() *appsv1.Deployment { addVolumeFromSecret(&pod, SharedSecretName, secretVolumeName, s.config.SecretDir, true) } - // Mount custom phoenix config file - if s.config.OverrideWrapperPhoenix { - const wrapperPhoenixFile = "wrapper-phoenix.config" - configPath := filepath.Join(s.config.MatlabRoot, "toolbox", "parallel", "config", wrapperPhoenixFile) - addVolumeFromConfigMapFile(&pod, "mjs-phoenix-config", "phoenix-volume", wrapperPhoenixFile, configPath) - } - // Ensure this pod can resolve itself via its service name without having to use the Kubernetes service; this ensures it can resolve its own MJS service even if the Kubernetes service does not map to this pod pod.HostAliases = []corev1.HostAlias{{ IP: "127.0.0.1", @@ -415,33 +414,6 @@ func addVolumeFromConfigMap(pod *corev1.PodSpec, configMapName, volumeName, moun addVolume(pod, source, volumeName, mountPath, true) } -// addVolumeFromConfigMapFile adds a volume mounted from a ConfigMap file to a single file on the pod -func addVolumeFromConfigMapFile(pod *corev1.PodSpec, configMapName, volumeName, fileName, mountPath string) { - source := corev1.VolumeSource{ - ConfigMap: &corev1.ConfigMapVolumeSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: configMapName, - }, - Items: []corev1.KeyToPath{ - { - Key: fileName, - Path: fileName, - }, - }, - }, - } - pod.Containers[0].VolumeMounts = append(pod.Containers[0].VolumeMounts, corev1.VolumeMount{ - Name: volumeName, - MountPath: mountPath, - SubPath: fileName, - ReadOnly: true, - }) - pod.Volumes = append(pod.Volumes, corev1.Volume{ - Name: volumeName, - VolumeSource: source, - }) -} - // addVolumeFromSecret adds a volume mounted from a Kubernetes Secret to a pod spec func addVolumeFromSecret(pod *corev1.PodSpec, secretName, volumeName, mountPath string, restrictReadAccess bool) { source := corev1.VolumeSource{ diff --git a/controller/src/internal/specs/specs_test.go b/images/controller/src/internal/specs/specs_test.go similarity index 86% rename from controller/src/internal/specs/specs_test.go rename to images/controller/src/internal/specs/specs_test.go index 13029f7..7df4968 100644 --- a/controller/src/internal/specs/specs_test.go +++ b/images/controller/src/internal/specs/specs_test.go @@ -161,6 +161,38 @@ func TestGetJobManagerSpecs(t *testing.T) { } } +// Test the ability to add custom environment variables to the worker pod spec +func TestExtraWorkerEnv(t *testing.T) { + conf := createTestConfig() + extraEnv := map[string]string{ + "MY_VAR1": "test", + "ANOTHER_VAR": "test2", + } + conf.ExtraWorkerEnvironment = extraEnv + + specFactory := NewSpecFactory(conf, types.UID("abc")) + workerSpec := specFactory.GetWorkerDeploymentSpec(&WorkerInfo{ + Name: "worker1", + ID: 1, + HostName: "host1", + }) + workerEnv := workerSpec.Spec.Template.Spec.Containers[0].Env + + for key, value := range extraEnv { + found := false + var gotValue string + for _, item := range workerEnv { + if item.Name == key { + found = true + gotValue = item.Value + break + } + } + assert.Truef(t, found, "Custom worker environment variable %s not found", key) + assert.Equalf(t, value, gotValue, "Unexpected value for worker environment variable %s", key) + } +} + func verifyWorkerSpecs(t *testing.T, specFactory *SpecFactory, conf *config.Config, ownerUID types.UID) { assert := assert.New(t) testWorker := &WorkerInfo{ @@ -182,8 +214,8 @@ func verifyWorkerSpecs(t *testing.T, specFactory *SpecFactory, conf *config.Conf pod := deployment.Spec.Template.Spec assert.Len(pod.Containers, 1, "Worker pod should have 1 container") container := pod.Containers[0] - assert.Equal(conf.MatlabImage, container.Image, "Worker container has incorrect image") - assert.Equal(conf.MatlabImagePullPolicy, string(container.ImagePullPolicy), "Worker container has incorrect image pull policy") + assert.Equal(conf.WorkerImage, container.Image, "Worker container has incorrect image") + assert.Equal(conf.WorkerImagePullPolicy, string(container.ImagePullPolicy), "Worker container has incorrect image pull policy") assert.Equal(conf.WorkerCPULimit, container.Resources.Limits.Cpu().String(), "Worker container has incorrect CPU limit") assert.Equal(conf.WorkerCPURequest, container.Resources.Requests.Cpu().String(), "Worker container has incorrect CPU request") assert.Equal(conf.WorkerMemoryLimit, container.Resources.Limits.Memory().String(), "Worker container has incorrect memory limit") @@ -320,8 +352,8 @@ func verifyJobManagerSpec(t *testing.T, specFactory *SpecFactory, conf *config.C pod := deployment.Spec.Template.Spec assert.Len(pod.Containers, 1, "Job manager pod should have 1 container") container := pod.Containers[0] - assert.Equal(conf.MatlabImage, container.Image, "Job manager container has incorrect image") - assert.Equal(conf.MatlabImagePullPolicy, string(container.ImagePullPolicy), "Job manager container has incorrect image pull policy") + assert.Equal(conf.JobManagerImage, container.Image, "Job manager container has incorrect image") + assert.Equal(conf.JobManagerImagePullPolicy, string(container.ImagePullPolicy), "Job manager container has incorrect image pull policy") assert.Equal(conf.JobManagerCPULimit, container.Resources.Limits.Cpu().String(), "Job manager container has incorrect CPU limit") assert.Equal(conf.JobManagerCPURequest, container.Resources.Requests.Cpu().String(), "Job manager container has incorrect CPU request") assert.Equal(conf.JobManagerMemoryLimit, container.Resources.Limits.Memory().String(), "Job manager container has incorrect memory limit") @@ -385,41 +417,43 @@ func verifyEnvVar(t *testing.T, pod *corev1.PodSpec, key, value string) { // Create a Config object populated with test values func createTestConfig() *config.Config { return &config.Config{ - BasePort: 20000, - CheckpointPVC: "checkpoint-pvc", - EnableServiceLinks: false, - MatlabImagePullPolicy: "Never", - MatlabImage: "my-matlab-image", - LogBase: "/var/logs", - LogLevel: 3, - MatlabRoot: "/opt/matlab", - MatlabPVC: "matlab-pvc", - MJSDefConfigMap: "mjsdef-cm", - MJSDefDir: "/def-dir", - NetworkLicenseManager: "20000@mylicensemanager", - PortsPerWorker: 3, - PoolProxyImage: "my-proxy", - PoolProxyImagePullPolicy: "Always", - PoolProxyBasePort: 40000, - PoolProxyCPURequest: "500m", - PoolProxyCPULimit: "500m", - PoolProxyMemoryLimit: "2Gi", - PoolProxyMemoryRequest: "1Gi", - WorkerCPURequest: "3", - WorkerCPULimit: "4", - WorkerMemoryRequest: "3Gi", - WorkerMemoryLimit: "4Gi", - JobManagerCPURequest: "3", - JobManagerCPULimit: "4", - JobManagerMemoryRequest: "3Gi", - JobManagerMemoryLimit: "4Gi", - JobManagerGroupID: 1000, - JobManagerUserID: 2000, - WorkerLogPVC: "worker-pvc", - LogPVC: "log-pvc", - WorkerPassword: "workerpw", - WorkersPerPoolProxy: 10, - WorkerUsername: "myuser", + BasePort: 20000, + CheckpointPVC: "checkpoint-pvc", + EnableServiceLinks: false, + WorkerImagePullPolicy: "Never", + WorkerImage: "my-matlab-image", + JobManagerImagePullPolicy: "IfNotPresent", + JobManagerImage: "my-jm-image", + LogBase: "/var/logs", + LogLevel: 3, + MatlabRoot: "/opt/matlab", + MatlabPVC: "matlab-pvc", + MJSDefConfigMap: "mjsdef-cm", + MJSDefDir: "/def-dir", + NetworkLicenseManager: "20000@mylicensemanager", + PortsPerWorker: 3, + PoolProxyImage: "my-proxy", + PoolProxyImagePullPolicy: "Always", + PoolProxyBasePort: 40000, + PoolProxyCPURequest: "500m", + PoolProxyCPULimit: "500m", + PoolProxyMemoryLimit: "2Gi", + PoolProxyMemoryRequest: "1Gi", + WorkerCPURequest: "3", + WorkerCPULimit: "4", + WorkerMemoryRequest: "3Gi", + WorkerMemoryLimit: "4Gi", + JobManagerCPURequest: "3", + JobManagerCPULimit: "4", + JobManagerMemoryRequest: "3Gi", + JobManagerMemoryLimit: "4Gi", + JobManagerGroupID: 1000, + JobManagerUserID: 2000, + WorkerLogPVC: "worker-pvc", + LogPVC: "log-pvc", + WorkerPassword: "workerpw", + WorkersPerPoolProxy: 10, + WorkerUsername: "myuser", } } diff --git a/controller/src/mocks/k8s/Client.go b/images/controller/src/mocks/k8s/Client.go similarity index 100% rename from controller/src/mocks/k8s/Client.go rename to images/controller/src/mocks/k8s/Client.go diff --git a/controller/src/mocks/request/Getter.go b/images/controller/src/mocks/request/Getter.go similarity index 100% rename from controller/src/mocks/request/Getter.go rename to images/controller/src/mocks/request/Getter.go diff --git a/controller/src/mocks/rescaler/Rescaler.go b/images/controller/src/mocks/rescaler/Rescaler.go similarity index 100% rename from controller/src/mocks/rescaler/Rescaler.go rename to images/controller/src/mocks/rescaler/Rescaler.go diff --git a/controller/src/mocks/resize/Resizer.go b/images/controller/src/mocks/resize/Resizer.go similarity index 100% rename from controller/src/mocks/resize/Resizer.go rename to images/controller/src/mocks/resize/Resizer.go diff --git a/images/job-manager/Dockerfile b/images/job-manager/Dockerfile new file mode 100644 index 0000000..cc6f84d --- /dev/null +++ b/images/job-manager/Dockerfile @@ -0,0 +1,49 @@ +# Copyright 2024 The MathWorks, Inc. +# This Dockerfile allows you to build a Docker® image for the MATLAB® Job Scheduler job manager. +# The MATLAB Package Manager installs MATLAB and MATLAB Parallel Server on the image. +# Use the optional build argument to customize the version of MATLAB the MATLAB Package Manager installs. + +# Here is an example docker build command with the optional build argument. +# docker build --build-arg MATLAB_RELEASE=r2024a -t mjs-job-manager . + +# To specify which MATLAB release to install in the container, edit the value of the MATLAB_RELEASE argument. +# Use lowercase to specify the release, for example: ARG MATLAB_RELEASE=r2024a +ARG MATLAB_RELEASE=r2024a + +# When you start the build stage, by default this Dockerfile uses the Ubuntu-based matlab-deps image. +# To check the available matlab-deps images, see: https://hub.docker.com/r/mathworks/matlab-deps +FROM mathworks/matlab-deps:${MATLAB_RELEASE} + +# Declare build arguments to use at the current build stage. +ARG MATLAB_RELEASE + +# Install mpm dependencies. +RUN export DEBIAN_FRONTEND=noninteractive \ + && apt-get update \ + && apt-get install --no-install-recommends --yes \ + wget \ + unzip \ + ca-certificates \ + && apt-get clean \ + && apt-get autoremove \ + && rm -rf /var/lib/apt/lists/* + +# Run mpm to install MATLAB. +RUN wget -q https://www.mathworks.com/mpm/glnxa64/mpm \ + && chmod +x mpm \ + && sudo ./mpm install \ + --release=${MATLAB_RELEASE} \ + --destination=/opt/matlab \ + --products MATLAB \ + || (echo "MPM Installation Failure. See below for more information:" && cat /tmp/mathworks_root.log && false) \ + && sudo rm -rf mpm /tmp/mathworks_root.log + +# Run mpm to install MATLAB Parallel Server. +RUN wget -q https://www.mathworks.com/mpm/glnxa64/mpm \ + && chmod +x mpm \ + && sudo ./mpm install \ + --release=${MATLAB_RELEASE} \ + --destination=/opt/matlab \ + --products MATLAB_Parallel_Server \ + || (echo "MPM Installation Failure. See below for more information:" && cat /tmp/mathworks_root.log && false) \ + && sudo rm -rf mpm /tmp/mathworks_root.log diff --git a/images/worker/Dockerfile b/images/worker/Dockerfile new file mode 100644 index 0000000..414519c --- /dev/null +++ b/images/worker/Dockerfile @@ -0,0 +1,76 @@ +# Copyright 2024 The MathWorks, Inc. +# This Dockerfile allows you to build a Docker® image for MATLAB® Parallel Server workers. +# The MATLAB Package Manager installs MATLAB toolboxes on the image. +# Use the optional build argument to customize the version of MATLAB the MATLAB Package Manager installs. + +# Here is an example docker build command with the optional build arguments. +# docker build --build-arg MATLAB_RELEASE=r2024a -t matlab-parallel-server . + +# To specify which MATLAB release to install in the container, edit the value of the MATLAB_RELEASE argument. +# Use lowercase to specify the release, for example: ARG MATLAB_RELEASE=r2024a +ARG MATLAB_RELEASE=r2024a +FROM ghcr.io/mathworks-ref-arch/matlab-parallel-server-k8s/mjs-job-manager-image:${MATLAB_RELEASE} + +# Declare build arguments to use at the current build stage. +ARG MATLAB_RELEASE +ARG INCLUDE_SIMULINK=true + +# Install mpm dependencies. +RUN export DEBIAN_FRONTEND=noninteractive \ + && apt-get update \ + && apt-get install --no-install-recommends --yes \ + wget \ + unzip \ + ca-certificates \ + && apt-get clean \ + && apt-get autoremove \ + && rm -rf /var/lib/apt/lists/* + +# Add the matlab user for workers to run as +ENV USER_HOME=/home/matlab +RUN useradd matlab --shell /bin/bash --home ${USER_HOME} + +# Copy the input file onto the container +ENV INPUT_DIR=/tmp/${MATLAB_RELEASE} +COPY mpm-input-files/${MATLAB_RELEASE} ${INPUT_DIR} + +# Run mpm to install Simulink. +RUN if [ ${INCLUDE_SIMULINK} = true ]; then \ + wget -q https://www.mathworks.com/mpm/glnxa64/mpm \ + && chmod +x mpm \ + && sudo ./mpm install \ + --release=${MATLAB_RELEASE} \ + --destination=/opt/matlab \ + --products Simulink \ + || (echo "MPM Installation Failure. See below for more information:" && cat /tmp/mathworks_root.log && false) \ + && sudo rm -rf mpm /tmp/mathworks_root.log; \ + fi + +# Run mpm to install MATLAB toolboxes. +ENV MATLAB_TOOLBOX_FILE=${INPUT_DIR}/matlab-toolboxes.txt +RUN wget -q https://www.mathworks.com/mpm/glnxa64/mpm \ + && chmod +x mpm \ + && sudo ./mpm install \ + --inputfile ${MATLAB_TOOLBOX_FILE} \ + || (echo "MPM Installation Failure. See below for more information:" && cat /tmp/mathworks_root.log && false) \ + && sudo rm -rf mpm /tmp/mathworks_root.log ${MATLAB_TOOLBOX_FILE} + +# Run mpm to install Simulink toolboxes. +ENV SIMULINK_TOOLBOX_FILE=${INPUT_DIR}/simulink-toolboxes.txt +RUN if [ ${INCLUDE_SIMULINK} = true ]; then \ + wget -q https://www.mathworks.com/mpm/glnxa64/mpm \ + && chmod +x mpm \ + && sudo ./mpm install \ + --inputfile ${SIMULINK_TOOLBOX_FILE} \ + || (echo "MPM Installation Failure. See below for more information:" && cat /tmp/mathworks_root.log && false) \ + && sudo rm -rf mpm /tmp/mathworks_root.log ${SIMULINK_TOOLBOX_FILE}; \ + fi + +# Run mpm to install support packages into the matlab user's HOME folder. +ENV SUPPORT_PACKAGE_FILE=${INPUT_DIR}/support-packages.txt +RUN wget -q https://www.mathworks.com/mpm/glnxa64/mpm \ + && chmod +x mpm \ + && sudo HOME=${USER_HOME} ./mpm install \ + --inputfile ${SUPPORT_PACKAGE_FILE} \ + || (echo "MPM Installation Failure. See below for more information:" && cat /tmp/mathworks_root.log && false) \ + && sudo rm -rf mpm /tmp/mathworks_root.log ${SUPPORT_PACKAGE_FILE} diff --git a/images/worker/README.md b/images/worker/README.md new file mode 100644 index 0000000..70cf131 --- /dev/null +++ b/images/worker/README.md @@ -0,0 +1,52 @@ +# Create a MATLAB Parallel Server Container Image + +This Dockerfile in this folder builds an image for MATLAB® Parallel Server workers using [MATLAB Package Manager (*mpm*)](https://github.com/mathworks-ref-arch/matlab-dockerfile/blob/main/MPM.md). +Use the Dockerfile to build a custom image that contains the toolboxes and support packages you need. + +## Requirements +- Docker® installed on your computer. For help with installing Docker, see [Get Docker](https://docs.docker.com/get-docker/). + +## Build Instructions + +### Download Respository + +To download a zip file of this repository, at the top of this repository page, select Code > Download ZIP. +Alternatively, to clone this repository to your computer with Git installed, run the following command on your operating system's command line: + +``` +git clone https://github.com/mathworks-ref-arch/matlab-parallel-server-on-kubernetes +``` + +Navigate to this directory by running +``` +cd matlab-parallel-server-on-kubernetes/images/worker +``` + +### Modify `mpm` Input Files + +The toolboxes and support packages that `mpm` installs on your image are configured using `mpm` input files. +The `mpm-input-files/` folder contains a folder for each MATLAB release that supports MATLAB Job Scheduler in Kubernetes containing the following files: +- `matlab-toolboxes.txt`: An `mpm` input file containing a list of MATLAB toolboxes to install. By default, the input file installs all MATLAB toolboxes. +- `simulink-toolboxes.txt`: An `mpm` input file containing a list of Simulink toolboxes to install. By default, the input file installs all Simulink toolboxes. +- `support-packages.txt`: An `mpm` input file containing a list of support packages to install. By default, the input file only installs Deep Learning support packages. + +Edit the files in the directory corresponding to the release you want to build an image for. +For example, if you want to build an image for MATLAB R2024a with custom MATLAB toolboxes, edit the `mpm-input-files/r2024a/toolboxes.txt` file. + +Comment out any toolboxes or support packages you do not want to install by adding a `#` symbol before the toolbox or support package name. +Uncomment any support packages you want to install by removing the `#` symbol from the beginning of the line containing the support package name. + +### Build Image + +Build the Docker image. +- Specify `` as a MATLAB release number with a lowercase `r`. For example, to install MATLAB R2024a, specify `` as `r2024a`. +- Specify `` as `true` to install Simulink and the Simulink toolboxes, or `false` to only install MATLAB toolboxes and support packages. +- Specify `` as the Docker tag to use for the image. + +``` +docker build --build-arg MATLAB_RELEASE= --build-arg INCLUDE_SIMULINK= -t . +``` + +--- + +Copyright 2024 The MathWorks, Inc. diff --git a/images/worker/mpm-input-files/r2024a/matlab-toolboxes.txt b/images/worker/mpm-input-files/r2024a/matlab-toolboxes.txt new file mode 100644 index 0000000..00b4abd --- /dev/null +++ b/images/worker/mpm-input-files/r2024a/matlab-toolboxes.txt @@ -0,0 +1,153 @@ +######################################################################## +## Configuration File for Installing R2024a MathWorks Products +######################################################################## +## +## Use this file to configure an installation of MathWorks products +## and support packages from the command line using the +## MATLAB Package Manager (mpm). For example, you can set the +## products and support packages you want to install and the +## folder where you want to install them. +## +## To configure your MATLAB installation: +## +## 1. Set configuration parameters by uncommenting lines that +## start with a single '#' and updating the values. The +## comments above each parameter describe the valid values. +## +## 2. Run mpm from the command line, using the --inputfile option +## to specify the full path to this configuration file. +## +## mpm install --inputfile +## +## You can download template input files for all supported releases from +## https://github.com/mathworks-ref-arch/matlab-dockerfile/blob/main/MPM.md +## +######################################################################## + + +######################################################################## +## RELEASE +######################################################################## +## +## By default, mpm installs the latest versions of R2024a +## MathWorks products and support packages. +## +## To install a specific update for R2024a, set the desired update +## number (for example, 1, 2, 3, and so on) and uncomment the +## following line. An updateLevel of 0 installs the general release. + +# updateLevel=0 + + +######################################################################## +## SPECIFY INSTALLATION FOLDER +######################################################################## +## +## Specify the full path to the folder where you want to install MATLAB. +## If you are adding products or support packages to an existing MATLAB +## installation, specify the full path to the folder where MATLAB is installed. +## +## Example: +## (Windows) destinationFolder=C:\Program Files\MATLAB\RXXXX +## (Linux) destinationFolder=/usr/local/RXXXX +## (macOS) destinationFolder=/Applications/MATLAB/RXXXX +## +## Set the desired value for destinationFolder and +## uncomment the following line. + +destinationFolder=/opt/matlab + + +######################################################################## +## INSTALL PRODUCTS +######################################################################## +## +## Uncomment the lines for the products you want to install. + +product.5G_Toolbox +product.Aerospace_Toolbox +product.Antenna_Toolbox +product.Audio_Toolbox +product.Automated_Driving_Toolbox +product.Bioinformatics_Toolbox +product.Bluetooth_Toolbox +product.Communications_Toolbox +product.Computer_Vision_Toolbox +product.Control_System_Toolbox +product.Curve_Fitting_Toolbox +product.DSP_HDL_Toolbox +product.DSP_System_Toolbox +product.Database_Toolbox +product.Datafeed_Toolbox +product.Deep_Learning_HDL_Toolbox +product.Deep_Learning_Toolbox +product.Econometrics_Toolbox +product.Embedded_Coder +product.Filter_Design_HDL_Coder +product.Financial_Instruments_Toolbox +product.Financial_Toolbox +product.Fixed-Point_Designer +product.Fuzzy_Logic_Toolbox +product.GPU_Coder +product.Global_Optimization_Toolbox +product.HDL_Coder +product.HDL_Verifier +product.Image_Acquisition_Toolbox +product.Image_Processing_Toolbox +product.Industrial_Communication_Toolbox +product.Instrument_Control_Toolbox +product.LTE_Toolbox +product.Lidar_Toolbox +product.MATLAB_Coder +product.MATLAB_Compiler +product.MATLAB_Compiler_SDK +product.MATLAB_Report_Generator +product.MATLAB_Test +product.Mapping_Toolbox +product.Medical_Imaging_Toolbox +product.Model_Predictive_Control_Toolbox +product.Navigation_Toolbox +product.Optimization_Toolbox +product.Parallel_Computing_Toolbox +product.Partial_Differential_Equation_Toolbox +product.Phased_Array_System_Toolbox +product.Predictive_Maintenance_Toolbox +product.RF_PCB_Toolbox +product.RF_Toolbox +product.ROS_Toolbox +product.Radar_Toolbox +product.Reinforcement_Learning_Toolbox +product.Requirements_Toolbox +product.Risk_Management_Toolbox +product.Robotics_System_Toolbox +product.Robust_Control_Toolbox +product.Satellite_Communications_Toolbox +product.Sensor_Fusion_and_Tracking_Toolbox +product.SerDes_Toolbox +product.Signal_Integrity_Toolbox +product.Signal_Processing_Toolbox +product.SoC_Blockset +product.Statistics_and_Machine_Learning_Toolbox +product.Symbolic_Math_Toolbox +product.System_Composer +product.System_Identification_Toolbox +product.Text_Analytics_Toolbox +product.UAV_Toolbox +product.Vehicle_Dynamics_Blockset +product.Vehicle_Network_Toolbox +product.Vision_HDL_Toolbox +product.WLAN_Toolbox +product.Wavelet_Toolbox +product.Wireless_HDL_Toolbox +product.Wireless_Testbench + + +######################################################################## +## CHECKSUM +######################################################################## +## +## NOTE: DO NOT edit this field. MathWorks uses this field to +## check the integrity of the input file. Changing the value +## of the checksum field invalidates this input file. + +?checksum=UjIwMjRh diff --git a/images/worker/mpm-input-files/r2024a/simulink-toolboxes.txt b/images/worker/mpm-input-files/r2024a/simulink-toolboxes.txt new file mode 100644 index 0000000..2a1585d --- /dev/null +++ b/images/worker/mpm-input-files/r2024a/simulink-toolboxes.txt @@ -0,0 +1,108 @@ +######################################################################## +## Configuration File for Installing R2024a MathWorks Products +######################################################################## +## +## Use this file to configure an installation of MathWorks products +## and support packages from the command line using the +## MATLAB Package Manager (mpm). For example, you can set the +## products and support packages you want to install and the +## folder where you want to install them. +## +## To configure your MATLAB installation: +## +## 1. Set configuration parameters by uncommenting lines that +## start with a single '#' and updating the values. The +## comments above each parameter describe the valid values. +## +## 2. Run mpm from the command line, using the --inputfile option +## to specify the full path to this configuration file. +## +## mpm install --inputfile +## +## You can download template input files for all supported releases from +## https://github.com/mathworks-ref-arch/matlab-dockerfile/blob/main/MPM.md +## +######################################################################## + + +######################################################################## +## RELEASE +######################################################################## +## +## By default, mpm installs the latest versions of R2024a +## MathWorks products and support packages. +## +## To install a specific update for R2024a, set the desired update +## number (for example, 1, 2, 3, and so on) and uncomment the +## following line. An updateLevel of 0 installs the general release. + +# updateLevel=0 + + +######################################################################## +## SPECIFY INSTALLATION FOLDER +######################################################################## +## +## Specify the full path to the folder where you want to install MATLAB. +## If you are adding products or support packages to an existing MATLAB +## installation, specify the full path to the folder where MATLAB is installed. +## +## Example: +## (Windows) destinationFolder=C:\Program Files\MATLAB\RXXXX +## (Linux) destinationFolder=/usr/local/RXXXX +## (macOS) destinationFolder=/Applications/MATLAB/RXXXX +## +## Set the desired value for destinationFolder and +## uncomment the following line. + +destinationFolder=/opt/matlab + + +######################################################################## +## INSTALL PRODUCTS +######################################################################## +## +## Uncomment the lines for the products you want to install. + +product.AUTOSAR_Blockset +product.Aerospace_Blockset +product.C2000_Microcontroller_Blockset +product.DDS_Blockset +product.Mixed-Signal_Blockset +product.Motor_Control_Blockset +product.Powertrain_Blockset +product.RF_Blockset +product.SimBiology +product.SimEvents +product.Simscape +product.Simscape_Battery +product.Simscape_Driveline +product.Simscape_Electrical +product.Simscape_Fluids +product.Simscape_Multibody +product.Simulink_3D_Animation +product.Simulink_Check +product.Simulink_Coder +product.Simulink_Compiler +product.Simulink_Control_Design +product.Simulink_Coverage +product.Simulink_Design_Optimization +product.Simulink_Design_Verifier +product.Simulink_Desktop_Real-Time +product.Simulink_Fault_Analyzer +product.Simulink_PLC_Coder +product.Simulink_Real-Time +product.Simulink_Report_Generator +product.Simulink_Test +product.Stateflow + + +######################################################################## +## CHECKSUM +######################################################################## +## +## NOTE: DO NOT edit this field. MathWorks uses this field to +## check the integrity of the input file. Changing the value +## of the checksum field invalidates this input file. + +?checksum=UjIwMjRh diff --git a/images/worker/mpm-input-files/r2024a/support-packages.txt b/images/worker/mpm-input-files/r2024a/support-packages.txt new file mode 100644 index 0000000..43e2d5b --- /dev/null +++ b/images/worker/mpm-input-files/r2024a/support-packages.txt @@ -0,0 +1,264 @@ +######################################################################## +## Configuration File for Installing R2024a MathWorks Products +######################################################################## +## +## Use this file to configure an installation of MathWorks products +## and support packages from the command line using the +## MATLAB Package Manager (mpm). For example, you can set the +## products and support packages you want to install and the +## folder where you want to install them. +## +## To configure your MATLAB installation: +## +## 1. Set configuration parameters by uncommenting lines that +## start with a single '#' and updating the values. The +## comments above each parameter describe the valid values. +## +## 2. Run mpm from the command line, using the --inputfile option +## to specify the full path to this configuration file. +## +## mpm install --inputfile +## +## You can download template input files for all supported releases from +## https://github.com/mathworks-ref-arch/matlab-dockerfile/blob/main/MPM.md +## +######################################################################## + + +######################################################################## +## RELEASE +######################################################################## +## +## By default, mpm installs the latest versions of R2024a +## MathWorks products and support packages. +## +## To install a specific update for R2024a, set the desired update +## number (for example, 1, 2, 3, and so on) and uncomment the +## following line. An updateLevel of 0 installs the general release. + +# updateLevel=0 + + +######################################################################## +## SPECIFY INSTALLATION FOLDER +######################################################################## +## +## Specify the full path to the folder where you want to install MATLAB. +## If you are adding products or support packages to an existing MATLAB +## installation, specify the full path to the folder where MATLAB is installed. +## +## Example: +## (Windows) destinationFolder=C:\Program Files\MATLAB\RXXXX +## (Linux) destinationFolder=/usr/local/RXXXX +## (macOS) destinationFolder=/Applications/MATLAB/RXXXX +## +## Set the desired value for destinationFolder and +## uncomment the following line. + +destinationFolder=/opt/matlab + + +######################################################################## +## INSTALL SUPPORT PACKAGES +######################################################################## +## +## Uncomment the lines for the support packages you want to install. + +#product.6G_Exploration_Library_for_5G_Toolbox +#product.ASIC_Testbench_for_HDL_Verifier +#product.Aerospace_Blockset_Interface_for_Unreal_Engine_Projects +#product.Audio_Toolbox_Interface_for_SpeechBrain_and_Torchaudio_Libraries +#product.Automated_Driving_Toolbox_Importer_for_Zenrin_Japan_Map_API_3.0_(Itsumo_NAVI_API_3.0)_Service +#product.Automated_Driving_Toolbox_Interface_for_Unreal_Engine_Projects +#product.Automated_Driving_Toolbox_Model_for_Lidar_Lane_Detection +#product.CI/CD_Automation_for_Simulink_Check +#product.Communications_Toolbox_Support_Package_for_Analog_Devices_ADALM-Pluto_Radio +#product.Communications_Toolbox_Support_Package_for_RTL-SDR_Radio +#product.Communications_Toolbox_Support_Package_for_USRP_Embedded_Series_Radio +#product.Communications_Toolbox_Support_Package_for_USRP_Radio +#product.Communications_Toolbox_Wireless_Network_Simulation_Library +#product.Component_Deployment_Guideline_for_Embedded_Coder +#product.Computer_Vision_Toolbox_Automated_Visual_Inspection_Library +#product.Computer_Vision_Toolbox_Interface_for_OpenCV_in_MATLAB +#product.Computer_Vision_Toolbox_Interface_for_OpenCV_in_Simulink +#product.Computer_Vision_Toolbox_Model_for_Inflated-3D_Video_Classification +#product.Computer_Vision_Toolbox_Model_for_Mask_R-CNN_Instance_Segmentation +#product.Computer_Vision_Toolbox_Model_for_Object_Keypoint_Detection +#product.Computer_Vision_Toolbox_Model_for_Pose_Mask_R-CNN_6-DoF_Object_Pose_Estimation +#product.Computer_Vision_Toolbox_Model_for_R(2+1)D_Video_Classification +#product.Computer_Vision_Toolbox_Model_for_SOLOv2_Instance_Segmentation +#product.Computer_Vision_Toolbox_Model_for_SlowFast_Video_Classification +#product.Computer_Vision_Toolbox_Model_for_Text_Detection +#product.Computer_Vision_Toolbox_Model_for_Vision_Transformer_Network +#product.Computer_Vision_Toolbox_Model_for_YOLO_v2_Object_Detection +#product.Computer_Vision_Toolbox_Model_for_YOLO_v3_Object_Detection +#product.Computer_Vision_Toolbox_Model_for_YOLO_v4_Object_Detection +#product.Computer_Vision_Toolbox_OCR_Language_Data +#product.Data_Acquisition_Toolbox_Support_Package_for_Analog_Devices_ADALM1000_Hardware +#product.Data_Acquisition_Toolbox_Support_Package_for_Digilent_Analog_Discovery_Hardware +#product.Data_Acquisition_Toolbox_Support_Package_for_Measurement_Computing_Hardware +#product.Data_Acquisition_Toolbox_Support_Package_for_National_Instruments_NI-DAQmx_Devices +#product.Data_Acquisition_Toolbox_Support_Package_for_Windows_Sound_Cards +#product.Database_Toolbox_Interface_for_Neo4j_Bolt_Protocol +#product.Databricks_ODBC_Driver_for_Database_Toolbox +product.Deep_Learning_HDL_Toolbox_Support_Package_for_Intel_FPGA_and_SoC_Devices +product.Deep_Learning_HDL_Toolbox_Support_Package_for_Xilinx_FPGA_and_SoC_Devices +product.Deep_Learning_Toolbox_Converter_for_ONNX_Model_Format +product.Deep_Learning_Toolbox_Converter_for_PyTorch_Model_Format +product.Deep_Learning_Toolbox_Converter_for_TensorFlow_models +product.Deep_Learning_Toolbox_Importer_for_Caffe_Models +product.Deep_Learning_Toolbox_Interface_for_TensorFlow_Lite +product.Deep_Learning_Toolbox_Model_Quantization_Library +product.Deep_Learning_Toolbox_Model_for_AlexNet_Network +product.Deep_Learning_Toolbox_Model_for_DarkNet-19_Network +product.Deep_Learning_Toolbox_Model_for_DarkNet-53_Network +product.Deep_Learning_Toolbox_Model_for_DenseNet-201_Network +product.Deep_Learning_Toolbox_Model_for_EfficientNet-b0_Network +product.Deep_Learning_Toolbox_Model_for_GoogLeNet_Network +product.Deep_Learning_Toolbox_Model_for_Inception-ResNet-v2_Network +product.Deep_Learning_Toolbox_Model_for_Inception-v3_Network +product.Deep_Learning_Toolbox_Model_for_MobileNet-v2_Network +product.Deep_Learning_Toolbox_Model_for_NASNet-Large_Network +product.Deep_Learning_Toolbox_Model_for_NASNet-Mobile_Network +product.Deep_Learning_Toolbox_Model_for_Places365-GoogLeNet_Network +product.Deep_Learning_Toolbox_Model_for_ResNet-101_Network +product.Deep_Learning_Toolbox_Model_for_ResNet-18_Network +product.Deep_Learning_Toolbox_Model_for_ResNet-50_Network +product.Deep_Learning_Toolbox_Model_for_ShuffleNet_Network +product.Deep_Learning_Toolbox_Model_for_VGG-16_Network +product.Deep_Learning_Toolbox_Model_for_VGG-19_Network +product.Deep_Learning_Toolbox_Model_for_Xception_Network +product.Deep_Learning_Toolbox_Verification_Library +#product.Embedded_Coder_Interface_to_QEMU_Emulator +#product.Embedded_Coder_Support_Package_For_Linux_Applications +#product.Embedded_Coder_Support_Package_for_ARM_Cortex-A_Processors +#product.Embedded_Coder_Support_Package_for_ARM_Cortex-M_Processors +#product.Embedded_Coder_Support_Package_for_ARM_Cortex-R_Processors +#product.Embedded_Coder_Support_Package_for_BeagleBone_Black_Hardware +#product.Embedded_Coder_Support_Package_for_Infineon_AURIX_TC3x_Microcontrollers +#product.Embedded_Coder_Support_Package_for_Infineon_AURIX_TC4x_Microcontrollers +#product.Embedded_Coder_Support_Package_for_Intel_SoC_Devices +#product.Embedded_Coder_Support_Package_for_STMicroelectronics_STM32_Processors +#product.Embedded_Coder_Support_Package_for_Xilinx_Zynq_Platform +#product.Ephemeris_Data_for_Aerospace_Toolbox +#product.Extended_Tire_Features_for_Vehicle_Dynamics_Blockset +#product.FMU_Builder_For_Simulink +#product.GPU_Coder_Interface_for_Deep_Learning_Libraries +#product.GUIDE_to_App_Designer_Migration_Tool_for_MATLAB +#product.Geoid_Data_for_Aerospace_Toolbox +#product.HDL_Coder_Support_Package_for_Intel_FPGA_and_SoC_Devices +#product.HDL_Coder_Support_Package_for_Microchip_FPGA_and_SoC_Devices +#product.HDL_Coder_Support_Package_for_Xilinx_FPGA_and_SoC_Devices +#product.HDL_Verifier_Support_Package_for_Intel_FPGA_Boards +#product.HDL_Verifier_Support_Package_for_Microsemi_FPGA_Boards +#product.HDL_Verifier_Support_Package_for_Xilinx_FPGA_Boards +#product.Image_Acquisition_Toolbox_Support_Package_for_DCAM_Hardware +#product.Image_Acquisition_Toolbox_Support_Package_for_Kinect_for_Windows_Sensor +#product.Image_Acquisition_Toolbox_Support_Package_for_Matrox_Hardware +#product.Image_Acquisition_Toolbox_Support_Package_for_National_Instruments_Frame_Grabbers +#product.Image_Acquisition_Toolbox_Support_Package_for_OS_Generic_Video_Interface +#product.Image_Acquisition_Toolbox_Support_Package_for_Point_Grey_Hardware +#product.Image_Acquisition_Toolbox_Support_Package_for_Teledyne_DALSA_Sapera_Hardware +#product.Image_Processing_Toolbox_Hyperspectral_Imaging_Library +#product.Image_Processing_Toolbox_Image_Data +#product.Image_Processing_Toolbox_Model_for_Segment_Anything_Model +#product.Instrument_Control_Toolbox_Support_Package_for_IVI_and_VXIplug&play_Drivers +#product.Instrument_Control_Toolbox_Support_Package_for_Keysight_(Agilent)_IO_Libraries_and_VISA_Interface +#product.Instrument_Control_Toolbox_Support_Package_for_National_Instruments_NI-845x_I2C/SPI_Interface +#product.Instrument_Control_Toolbox_Support_Package_for_National_Instruments_NI-DCPower_Power_Supplies +#product.Instrument_Control_Toolbox_Support_Package_for_National_Instruments_NI-DMM_Digital_Multimeters +#product.Instrument_Control_Toolbox_Support_Package_for_National_Instruments_NI-FGEN_Function_Generators +#product.Instrument_Control_Toolbox_Support_Package_for_National_Instruments_NI-SCOPE_Oscilloscopes +#product.Instrument_Control_Toolbox_Support_Package_for_National_Instruments_NI-SWITCH_Hardware +#product.Instrument_Control_Toolbox_Support_Package_for_National_Instruments_VISA_and_ICP_Interfaces +#product.Instrument_Control_Toolbox_Support_Package_for_Rohde_Schwarz_VISA_Interface +#product.Instrument_Control_Toolbox_Support_Package_for_Total_Phase_Aardvark_I2C/SPI_Interface +#product.Integro-Differential_Modeling_Framework_for_MATLAB +#product.Lidar_Toolbox_Model_for_RandLA-Net_Semantic_Segmentation +#product.Lidar_Toolbox_Support_Package_for_Hokuyo_LiDAR_Sensors +#product.Lidar_Toolbox_Support_Package_for_Ouster_Lidar_Sensors +#product.Lidar_Toolbox_Support_Package_for_Velodyne_LiDAR_Sensors +#product.MATLAB_Basemap_Data_-_bluegreen +#product.MATLAB_Basemap_Data_-_colorterrain +#product.MATLAB_Basemap_Data_-_grayland +#product.MATLAB_Basemap_Data_-_grayterrain +#product.MATLAB_Basemap_Data_-_landcover +#product.MATLAB_Client_for_MATLAB_Production_Server +#product.MATLAB_Coder_Interface_for_Deep_Learning_Libraries +#product.MATLAB_Coder_Interface_for_Visual_Studio_Code_Debugging +#product.MATLAB_Coder_Support_Package_for_NVIDIA_Jetson_and_NVIDIA_DRIVE_Platforms +#product.MATLAB_Support_Package_for_Android_Sensors +#product.MATLAB_Support_Package_for_Apple_iOS_Sensors +#product.MATLAB_Support_Package_for_Arduino_Hardware +#product.MATLAB_Support_Package_for_BeagleBone_Black_Hardware +#product.MATLAB_Support_Package_for_LEGO_MINDSTORMS_EV3_Hardware +#product.MATLAB_Support_Package_for_Quantum_Computing +#product.MATLAB_Support_Package_for_Raspberry_Pi_Hardware +#product.MATLAB_Support_Package_for_USB_Webcams +#product.MATLAB_Support_for_MinGW-w64_C/C++/Fortran_Compiler +#product.MariaDB_ODBC_Driver_for_Database_Toolbox +#product.Medical_Imaging_Toolbox_Interface_for_Cellpose +#product.Medical_Imaging_Toolbox_Interface_for_MONAI_Label_Library +#product.Mixed-Signal_Blockset_Models +#product.Modelscape_for_MATLAB +#product.Multi-Version_Co-Simulation_for_Simulink +#product.PostgreSQL_ODBC_Driver_for_Database_Toolbox +#product.Powertrain_Blockset_Drive_Cycle_Data +#product.RF_Blockset_Models_for_Analog_Devices_RF_Transceivers +#product.ROS_Toolbox_Support_Package_for_TurtleBot-Based_Robots +#product.Radar_Toolbox_Support_Package_for_Texas_Instruments_mmWave_Radar_Sensors +#product.Robotics_System_Toolbox_Interface_for_Unreal_Engine_Projects +#product.Robotics_System_Toolbox_Robot_Library_Data +#product.Robotics_System_Toolbox_Support_Package_for_Kinova_Gen3_Manipulators +#product.Robotics_System_Toolbox_Support_Package_for_Universal_Robots_UR_Series_Manipulators +#product.Scenario_Builder_for_Automated_Driving_Toolbox +#product.Scenario_Variant_Generator_for_Automated_Driving_Toolbox +#product.Signal_Processing_Toolbox_Support_Package_for_Linux_IIO_Devices +#product.Simulink_Coder_Support_Package_for_ARM_Cortex-based_VEX_Microcontroller +#product.Simulink_Coder_Support_Package_for_BeagleBone_Blue_Hardware +#product.Simulink_Coder_Support_Package_for_NXP_FRDM-K64F_Board +#product.Simulink_Coder_Support_Package_for_NXP_FRDM-KL25Z_Board +#product.Simulink_Coder_Support_Package_for_STMicroelectronics_Nucleo_Boards +#product.Simulink_Coder_Support_Package_for_VEX_EDR_V5_Robot_Brain +#product.Simulink_Interface_for_Siemens_MF-Tyre/MF-Swift_Tire_Model +#product.Simulink_Real-Time_XIL_Support_Package +#product.Simulink_Support_Package_for_Android_Devices +#product.Simulink_Support_Package_for_Arduino_Hardware +#product.Simulink_Support_Package_for_LEGO_MINDSTORMS_EV3_Hardware +#product.Simulink_Support_Package_for_Parrot_Minidrones +#product.Simulink_Support_Package_for_Raspberry_Pi_Hardware +#product.Simulink_Test_Support_Package_for_ASAM_XIL +#product.SoC_Blockset_Support_Package_for_Embedded_Linux_Devices +#product.SoC_Blockset_Support_Package_for_Infineon_AURIX_Microcontrollers +#product.SoC_Blockset_Support_Package_for_Intel_Devices +#product.SoC_Blockset_Support_Package_for_Xilinx_Devices +#product.Source_control_integration_with_Microsoft(R)_Source-Code_Control_Interface_(MSSCCI)_for_MATLAB_and_Simulink +#product.Streaming_Data_Framework_for_MATLAB_Production_Server +#product.Text_Analytics_Toolbox_Model_for_BERT-Base_Multilingual_Cased_Network +#product.Text_Analytics_Toolbox_Model_for_BERT-Base_Network +#product.Text_Analytics_Toolbox_Model_for_BERT-Large_Network +#product.Text_Analytics_Toolbox_Model_for_BERT-Mini_Network +#product.Text_Analytics_Toolbox_Model_for_BERT-Small_Network +#product.Text_Analytics_Toolbox_Model_for_BERT-Tiny_Network +#product.Text_Analytics_Toolbox_Model_for_all-MiniLM-L12-v2_Network +#product.Text_Analytics_Toolbox_Model_for_all-MiniLM-L6-v2_Network +#product.Text_Analytics_Toolbox_Model_for_fastText_English_16_Billion_Token_Word_Embedding +#product.Text_Analytics_Toolbox_Model_from_UDify_Data +#product.UAV_Toolbox_Interface_for_Unreal_Engine_Projects +#product.UAV_Toolbox_Support_Package_for_PX4_Autopilots +#product.Variant_Manager_for_Simulink +#product.Vehicle_Dynamics_Blockset_Interface_for_Unreal_Engine_Projects +#product.Vehicle_Dynamics_Blockset_Maneuver_Data +#product.WINNER_II_Channel_Model_for_Communications_Toolbox +#product.Wireless_Testbench_Support_Package_for_NI_USRP_Radios + + +######################################################################## +## CHECKSUM +######################################################################## +## +## NOTE: DO NOT edit this field. MathWorks uses this field to +## check the integrity of the input file. Changing the value +## of the checksum field invalidates this input file. + +?checksum=UjIwMjRh diff --git a/mjs/templates/haproxy.yaml b/mjs/templates/haproxy.yaml deleted file mode 100644 index de9e35d..0000000 --- a/mjs/templates/haproxy.yaml +++ /dev/null @@ -1,165 +0,0 @@ -# Template for a deployment running HAproxy. -# This proxies incoming connections to the job manager -# or workers via a single external load balancer. -# Copyright 2024 The MathWorks, Inc. -{{- if (not .Values.internalClientsOnly) }} # Only need HAproxy if we support clients outside of Kubernetes - -# Create the HAproxy config file; this configures -# proxying of connections based on TCP port. -{{- $poolProxyPrefix := "mjs-pool-proxy" }} -{{- $configMapName := "haproxy-config" }} -{{- $configFileName := "haproxy.cfg" }} -{{- $numProxies := divf .Values.maxWorkers .Values.workersPerPoolProxy | ceil | int }} -{{- $minPortAllWorkers := add $.Values.basePort 10 | int }} # Minimum worker port if not using a parallel pool proxy -{{- $name := "mjs-ingress-proxy" }} -{{- $lookupPort := add .Values.basePort 6 | int }} -{{- $jobManagerPort := add .Values.basePort 9 | int }} -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ $configMapName }} -data: - {{ $configFileName }}: | - global - log stdout local0 - defaults - default-server init-addr last,libc,none - log global - option tcplog - mode tcp - timeout connect 30s - timeout client 300s - timeout server 300s - # Rules for proxying traffic to the job manager pod. - frontend front-lookup - bind {{ printf "*:%d" $lookupPort }} - default_backend back-mjs-job-manager - frontend front-jobmanager - bind {{ printf "*:%d" $jobManagerPort }} - default_backend back-mjs-job-manager - backend back-mjs-job-manager - server mjs-job-manager mjs-job-manager -{{- if .Values.usePoolProxy | default true }} - # Rules for proxying traffic to the parallel pool proxies. - # Each parallel pool proxy has a unique port, which should be mapped to the - # corresponding Kubernetes service for that proxy. - {{- range untilStep 0 $numProxies 1 }} - {{- $portNum := add $.Values.poolProxyBasePort . | int }} - {{- $poolProxyName := printf "%s-%d" $poolProxyPrefix (add . 1) }} - frontend front-{{ $poolProxyName }} - bind {{ printf "*:%d" $portNum }} - default_backend back-{{ $poolProxyName }} - backend back-{{ $poolProxyName }} - server {{ $poolProxyName }} {{ $poolProxyName }} - {{- end }} -{{- else }} - # Rules for proxying parallel pool traffic to the workers. - # Each worker has a set of unique ports, which should be mapped to the - # corresponding Kubernetes service for that worker. - {{- range untilStep 0 (.Values.maxWorkers | int) 1 }} - {{- $workerName := printf "mjs-worker-%d" (add . 1) }} - {{- $minPort := add $minPortAllWorkers (mul $.Values.portsPerWorker .) | int }} - {{- range untilStep 0 ($.Values.portsPerWorker | int) 1 }} - frontend {{ printf "front-%s-%d" $workerName . }} - bind {{ printf "*:%d" (add $minPort .) }} - default_backend back-{{ $workerName }} - {{- end }} - backend back-{{ $workerName }} - server {{ $workerName }} {{ $workerName }} - {{- end }} -{{- end }} ---- - -# Create the HAproxy deployment -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ $name }} -spec: - selector: - matchLabels: - app: {{ $name }} - replicas: 1 - template: - metadata: - labels: - app: {{ $name }} - spec: - # If set to false, disable creation of environment variables for services - enableServiceLinks: {{ .Values.enableServicelinks | default false }} - - containers: - - name: haproxy - image: {{ $.Values.haproxyImage }} - imagePullPolicy: {{ $.Values.haproxyImagePullPolicy }} - - # Pass the config file path as an input argument - {{- $configDir := "/usr/local/etc/haproxy/" }} - args: - - "-f" - - {{ printf "%s/%s" $configDir $configFileName }} - - # Mount the config file from the ConfigMap - {{- $configVolName := "config-volume" }} - volumeMounts: - - name: {{ $configVolName }} - mountPath: {{ $configDir }} - - volumes: - - name: {{ $configVolName }} - configMap: - name: {{ $configMapName }} ---- - -# Create a Kubernetes Service for each HAproxy backend -# (HAproxy will error if a backend cannot be found) -{{- if .Values.usePoolProxy | default true }} - {{- range untilStep 0 $numProxies 1 }} - {{- $portNum := add $.Values.poolProxyBasePort . | int }} - {{- $poolProxyNum := add . 1 }} - {{- $poolProxyName := printf "%s-%d" $poolProxyPrefix $poolProxyNum }} -apiVersion: v1 -kind: Service -metadata: - name: {{ $poolProxyName }} - labels: - app: {{ $poolProxyPrefix }} - proxyName: {{ $poolProxyName }} - port: {{ $portNum | quote }} - proxyID: {{ $poolProxyNum | quote }} -spec: - type: ClusterIP - selector: - proxyName: {{ $poolProxyName }} - ports: - - protocol: TCP - port: {{ $portNum }} - targetPort: {{ $portNum }} ---- - {{- end }} -{{- else }} - {{- $minPortAllWorkers := add $.Values.basePort 10 | int }} - {{- range untilStep 0 (.Values.maxWorkers | int) 1 }} - {{- $workerName := printf "mjs-worker-%d" (add . 1) }} -apiVersion: v1 -kind: Service -metadata: - name: {{ $workerName }} -spec: - # Match to the MJS worker pod - selector: - workerName: {{ $workerName }} - - # Expose unique pool ports needed by this worker - ports: - {{- $minPort := add $minPortAllWorkers (mul $.Values.portsPerWorker .) | int }} - {{- range untilStep 0 ($.Values.portsPerWorker | int) 1 }} - - name: {{ printf "tcp-%d" . }} - protocol: TCP - port: {{ add $minPort . }} - targetPort: {{ add $minPort . }} - {{- end }} - {{- end }} ---- -{{- end }} -{{- end }} diff --git a/mjs/templates/mjs.yaml b/mjs/templates/mjs.yaml deleted file mode 100644 index 8de754e..0000000 --- a/mjs/templates/mjs.yaml +++ /dev/null @@ -1,377 +0,0 @@ -# Templates for the MATLAB Job Scheduler config files and controller deployment. -# Copyright 2024 The MathWorks, Inc. - -{{- $jobManagerHostname := "mjs-job-manager" }} -{{- $logBase := "/mjs/log" }} -{{- $isNonRoot := ne (int .Values.jobManagerUserID) 0 }} -{{- if (and $isNonRoot (empty .Values.logPVC)) }} # If running as non-root user and not mounting log directory, use a directory that a non-root user can create -{{- $logBase = "/tmp/log" }} -{{- end }} -{{- $matlabRoot := "/opt/matlab" }} -{{- $mjsDefDir := "/mjs/config" }} -{{- $secretDir := "/mjs/secret" }} -{{- $secretFileName := "secret.json" }} -{{- $certFileName := "certificate.json" }} -{{- $checkpointBase := "/mjs/checkpoint" }} -{{- if (and $isNonRoot (empty .Values.checkpointPVC)) }} # If running as non-root user and not mounting checkpointbase, use a directory that a non-root user can create -{{- $checkpointBase = "/tmp/checkpoint" }} -{{- end }} -{{- $localMJSDef := "/tmp/mjs_def.sh" }} -{{- $secretFile := printf "%s/%s" $secretDir $secretFileName }} -{{- $certFile := printf "%s/%s" $secretDir $certFileName }} -{{- $binDir := printf "%s/toolbox/parallel/bin/" $matlabRoot }} -{{- $jobManagerUID := uuidv4 }} -{{- $mjsVolName := "mjs-volume" }} -{{- $logVolName := "log-volume" }} -{{- $checkpointVolName := "checkpoint-volume" }} -{{- $matlabVolName := "matlab-volume" }} -{{- $secretVolName := "secret-volume" }} -{{- $configVolName := "config-volume" }} -{{- $workerStartedFile := "/tmp/worker-started" }} -{{- $matlabImage := .Values.matlabImage | default (printf "mathworks/matlab-deps:%s" .Values.matlabRelease) }} -{{- $basePort := .Values.basePort | int }} -{{- $enableServiceLinks := .Values.enableServiceLinks | default false }} -{{- $commandListenerRestartHours := .Values.commandListenerRestartPeriod | default 12 }} -{{- $commandListenerRestartSeconds := mulf $commandListenerRestartHours 3600 }} - -# Create a ConfigMap containing scripts for the job manager pod and worker pods -{{- $mjsConfigMap := "mjs-config" }} -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ $mjsConfigMap }} -data: - mjs_def.sh: | - # Common mjs_def.sh file for the job manager and workers - BASE_PORT={{ .Values.basePort }} - MAX_LINUX_WORKERS={{ .Values.maxWorkers }} - CHECKPOINTBASE={{ $checkpointBase }} - PIDBASE=/tmp/pid - USE_SECURE_COMMUNICATION={{ .Values.useSecureCommunication }} - REQUIRE_CLIENT_CERTIFICATE={{ .Values.requireClientCertificate }} - REQUIRE_SCRIPT_VERIFICATION={{ .Values.requireScriptVerification }} - SECURITY_LEVEL={{ .Values.securityLevel }} - SHARED_SECRET_FILE={{ $secretFile }} - USE_ONLINE_LICENSING={{ .Values.useOnlineLicensing }} - jobManager.sh: | - # Script to run on the MATLAB Job Scheduler job manager pod - # Set up the mjs_def file - cp {{ printf "%s/mjs_def.sh" $mjsDefDir }} {{ $localMJSDef }} - echo "HOSTNAME={{ $jobManagerHostname }}" >> {{ $localMJSDef }} - echo "LOGBASE={{ $logBase }}" >> {{ $localMJSDef }} - - # Start the MJS service - {{ printf "%s/mjs" $binDir }} start -mjsdef {{ $localMJSDef }} -loglevel {{ .Values.logLevel }} -disablereliableconnections - - # Start the job manager - {{- $jmCommand := printf "%s/startjobmanager -name \"%s\" -baseport %d" $binDir .Values.jobManagerName $basePort }} - {{- if .Values.requireClientCertificate }} - {{- $jmCommand = printf "%s -certificate \"%s\"" $jmCommand $certFile }} - {{- end }} - {{- if .Values.requireScriptVerification }} - {{- $jmCommand = printf "%s -secretfile \"%s\"" $jmCommand $secretFile }} - {{- end }} - {{ $jmCommand }} || echo "startjobmanager failed; there may already be a job manager running" - - # Keep the container running - sleep infinity - worker.sh: | - # Script to run on worker pods - # Set up the mjs_def file - cp {{ printf "%s/mjs_def.sh" $mjsDefDir }} {{ $localMJSDef }} - LOGBASE={{ $logBase }}/${WORKER_NAME} - echo "LOGBASE=${LOGBASE}" >> {{ $localMJSDef }} - echo "HOSTNAME=${HOSTNAME}" >> {{ $localMJSDef }} - - # Ensure log directory exists and is writeable by workers - if [ ! -d "${LOGBASE}" ]; then - mkdir "${LOGBASE}" - fi - chmod o+w "${LOGBASE}" - - # Create a user to run MATLAB as - useradd --create-home {{ .Values.workerUsername }} - echo {{ printf "%s:%s" .Values.workerUsername .Values.workerPassword }} | chpasswd - - # Start the MJS service - {{ printf "%s/mjs" $binDir }} start -mjsdef {{ $localMJSDef }} -loglevel {{ .Values.logLevel }} -disablereliableconnections - - # Start the worker - {{- $workerCmd := printf "%s/startworker -jobmanager \"%s\" -jobmanagerhost \"%s\" -name \"${WORKER_NAME}\" -baseport %d" $binDir .Values.jobManagerName $jobManagerHostname $basePort }} - {{- if .Values.requireScriptVerification }} - {{- $workerCmd = printf "%s -secretfile \"%s\"" $workerCmd $secretFile }} - {{- end }} - {{ $workerCmd }} - - # Add a file to indicate that startworker is complete - touch {{ $workerStartedFile }} - - # Keep the container running - sleep infinity - stopWorker.sh: | - # Script to gracefully shut down a worker - # First, wait for startworker to have finished successfully - while [ ! -f {{ $workerStartedFile | quote }} ]]; do - echo "Waiting for startworker to finish" - sleep 1 - done - - # Stop the worker - {{- $stopCmd := printf "%s/stopworker -clean -name ${WORKER_NAME}" $binDir }} - {{- if .Values.requireScriptVerification }} - {{- $stopCmd = printf "%s -secretfile \"%s\"" $stopCmd $secretFile }} - {{- end }} - {{ $stopCmd }} ---- - -{{- $loadBalancerPrefix := "mjs-ingress-proxy" }} -{{- $loadBalancerName := $loadBalancerPrefix }} -{{- if .Values.autoCreateLoadBalancer }} -{{- $loadBalancerName = printf "%s-%s" $loadBalancerPrefix $jobManagerUID | trunc 63 }} # Use a unique name for the auto-generated service -# Create a LoadBalancer service to route external traffic to HAproxy -{{- $lookupPort := add .Values.basePort 6 | int }} -{{- $jobManagerPort := add .Values.basePort 9 | int }} -{{- $numProxies := divf .Values.maxWorkers .Values.workersPerPoolProxy | ceil | int }} -{{- if (not .Values.internalClientsOnly) }} # Load balancer only needed for external clients -apiVersion: v1 -kind: Service -metadata: - name: {{ $loadBalancerName }} - labels: - app: {{ $loadBalancerPrefix }} -spec: - type: LoadBalancer - selector: - app: {{ $loadBalancerPrefix }} - ports: - # Job manager ports - - name: "tcp-lookup" - protocol: TCP - appProtocol: TCP - port: {{ $lookupPort }} - targetPort: {{ $lookupPort }} - - name: "tcp-jobmanager" - protocol: TCP - appProtocol: TCP - port: {{ $jobManagerPort }} - targetPort: {{ $jobManagerPort }} - - # Pool proxy ports -{{- range untilStep 0 $numProxies 1 }} - {{- $poolProxyPort := add $.Values.poolProxyBasePort . }} - - name: {{ printf "tcp-pool-proxy-%d" (add . 1) }} - protocol: TCP - appProtocol: TCP - port: {{ $poolProxyPort }} - targetPort: {{ $poolProxyPort }} -{{- end }} ---- -{{- end }} -{{- end }} - -# Create an internal Service for workers to use to communicate with the job manager -apiVersion: v1 -kind: Service -metadata: - name: {{ $jobManagerHostname }} - labels: - app: {{ $jobManagerHostname }} -spec: - type: ClusterIP - - # Match the job manager pod - selector: - app: {{ $jobManagerHostname }} - job-manager-uid: {{ $jobManagerUID }} - - ports: - {{- $minPort := $basePort }} - {{- $maxPort := add $minPort 10 | int }} - {{- range untilStep $minPort $maxPort 1 }} - - name: {{ printf "tcp-%d" . }} - protocol: TCP - appProtocol: TCP - port: {{ . }} - targetPort: {{ . }} - {{- end }} ---- - -# Create the controller config file -{{- $controllerName := "mjs-controller" }} -{{- $controllerConfigMap := printf "%s-config" $controllerName }} -{{- $configFileName := "config.json" }} -{{- $controllerLogFile := printf "%s/controller.log" $logBase }} -{{- if empty .Values.logPVC }} # If not mounting logs, do not write controller logs to a file -{{- $controllerLogFile = "" }} -{{- end }} -{{- $poolProxyImageTag := .Values.poolProxyImageTag | default .Values.matlabRelease }} -{{- $controllerImageTag := .Values.controllerImageTag | default .Chart.AppVersion }} -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ $controllerConfigMap }} -data: - {{ $configFileName }}: | - { - "BasePort": {{ $basePort }}, - "CertFileName": {{ $certFileName | quote }}, - "CheckpointBase": {{ $checkpointBase | quote }}, - "CheckpointPVC": {{ .Values.checkpointPVC | quote }}, - "ClusterHost": {{ .Values.clusterHost | quote }}, - "ControllerLogfile": {{ $controllerLogFile | quote }}, - "Debug": {{ .Values.debug | default false }}, - "DeploymentName": {{ $controllerName | quote}}, - "EnableServiceLinks": {{ $enableServiceLinks }}, - "JobManagerUID": {{ $jobManagerUID | quote }}, - "IdleStop": {{ .Values.idleStop }}, - "InternalClientsOnly": {{ .Values.internalClientsOnly }}, - "MatlabImage": {{ $matlabImage | quote }}, - "MatlabImagePullPolicy": {{ .Values.matlabImagePullPolicy | quote }}, - "JobManagerName": {{ .Values.jobManagerName | quote }}, - "JobManagerCPULimit": {{ .Values.jobManagerCPULimit | quote }}, - "JobManagerCPURequest": {{ .Values.jobManagerCPURequest | quote }}, - "JobManagerMemoryLimit": {{ .Values.jobManagerMemoryLimit | quote }}, - "JobManagerMemoryRequest": {{ .Values.jobManagerMemoryRequest | quote }}, - "JobManagerGroupID": {{ .Values.jobManagerGroupID }}, - "JobManagerUserID": {{ .Values.jobManagerUserID }}, - "LivenessProbeFailureThreshold": {{ .Values.livenessProbeFailureThreshold | default 3 }}, - "LivenessProbePeriod": {{ .Values.livenessProbePeriod | default 300 }}, - "LivenessProbeTimeout": {{ .Values.livenessProbeTimeout | default 30 }}, - "LoadBalancerName": {{ $loadBalancerName | quote }}, - "LogBase": {{ $logBase | quote }}, - "LogLevel": {{ .Values.logLevel }}, - "LogPVC": {{ .Values.logPVC | quote }}, - "MatlabPVC": {{ .Values.matlabPVC | default "" | quote }}, - "MatlabRoot": {{ $matlabRoot | quote }}, - "MaxWorkers": {{ .Values.maxWorkers }}, - "MinWorkers": {{ .Values.minWorkers }}, - "MJSDefConfigMap": {{ $mjsConfigMap | quote }}, - "MJSDefDir" : {{ $mjsDefDir | quote }}, - "Namespace": {{ .Release.Namespace | quote }}, - "NetworkLicenseManager": {{ .Values.networkLicenseManager | quote }}, - "OverrideWrapperPhoenix": {{ not .Values.useDefaultWrapperPhoenix }}, - "Period": {{ .Values.autoScalingPeriod }}, - "PortsPerWorker": {{ .Values.portsPerWorker | default 2 }}, - "PoolProxyBasePort": {{ .Values.poolProxyBasePort }}, - "PoolProxyCPULimit": {{ .Values.poolProxyCPULimit | quote }}, - "PoolProxyCPURequest": {{ .Values.poolProxyCPURequest | quote }}, - "PoolProxyImage": {{ printf "%s:%s" .Values.poolProxyImage $poolProxyImageTag | quote }}, - "PoolProxyImagePullPolicy": {{ .Values.poolProxyImagePullPolicy | quote }}, - "PoolProxyMemoryLimit": {{ .Values.poolProxyMemoryLimit | quote }}, - "PoolProxyMemoryRequest": {{ .Values.poolProxyMemoryRequest | quote }}, - "ResizePath": {{ printf "%s/toolbox/parallel/bin/resize" $matlabRoot | quote }}, - "RequireClientCertificate": {{ .Values.requireClientCertificate }}, - "RequireScriptVerification": {{ .Values.requireScriptVerification }}, - "SecretDir": {{ $secretDir | quote }}, - "SecretFileName": {{ $secretFileName | quote }}, - "SecurityLevel": {{ .Values.securityLevel }}, - "StartupProbeFailureThreshold": {{ .Values.startupProbeFailureThreshold | default 60 }}, - "StartupProbeInitialDelay": {{ .Values.startupProbeInitialDelay | default 5 }}, - "StartupProbePeriod": {{ .Values.startupProbePeriod | default 1 }}, - "StopWorkerGracePeriod": {{ .Values.stopWorkerGracePeriod }}, - "WorkerCPULimit": {{ .Values.workerCPULimit | quote }}, - "WorkerCPURequest": {{ .Values.workerCPURequest | quote }}, - "WorkerMemoryLimit": {{ .Values.workerMemoryLimit | quote }}, - "WorkerMemoryRequest": {{ .Values.workerMemoryRequest | quote }}, - "WorkerLogPVC": {{ .Values.workerLogPVC | quote }}, - "WorkerPassword": {{ .Values.workerPassword | quote }}, - "WorkersPerPoolProxy": {{ .Values.workersPerPoolProxy }}, - "WorkerUsername": {{ .Values.workerUsername | quote }}, - "UsePoolProxy": {{ .Values.usePoolProxy | default true }}, - "UseSecureCommunication": {{ .Values.useSecureCommunication }} - } ---- - -# Create the controller deployment -{{- $controllerAccount := printf "%s-account" $controllerName }} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ $controllerName }} -spec: - selector: - matchLabels: - app: {{ $controllerName }} - replicas: 1 - template: - metadata: - labels: - app: {{ $controllerName }} - spec: - # Controller requires elevated Kubernetes permissions - serviceAccountName: {{ $controllerAccount }} - - # If set to false, disable creation of environment variables for services - enableServiceLinks: {{ $enableServiceLinks }} - - # Define the controller container - containers: - - name: {{ $controllerName }} - image: {{ printf "%s:%s" .Values.controllerImage $controllerImageTag }} - imagePullPolicy: {{ .Values.controllerImagePullPolicy }} - - # The controller process requires the path to a config file as an input argument - # This file is mounted from a ConfigMap (defined in mjs.yaml) - {{- $configMapDir := "/config/" }} - args: - - {{ printf "-config=%s/%s" $configMapDir $configFileName }} - - # Mount the config file from the ConfigMap - volumeMounts: - - name: {{ $configVolName }} - mountPath: {{ $configMapDir }} - - # Store controller logs in the same directory as the job manager logs - {{- if .Values.logPVC }} - - name: {{ $logVolName }} - mountPath: {{ $logBase }} - {{- end }} - - volumes: - - name: {{ $configVolName }} - configMap: - name: {{ $controllerConfigMap }} - {{- if .Values.logPVC }} - - name: {{ $logVolName }} - persistentVolumeClaim: - claimName: {{ .Values.logPVC }} - {{- end }} ---- - -# Create a service account for the controller -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ $controllerAccount }} ---- - -# Create a role with permissions to interact with the Kubernetes cluster -{{- $controllerRole := printf "%s-role" $controllerName }} -kind: Role -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: {{ $controllerRole }} -rules: -- apiGroups: [""] - resources: ["pods", "services", "secrets"] - verbs: ["create", "get", "list", "delete", "update"] -- apiGroups: [""] - resources: ["pods/exec"] - verbs: ["create"] -- apiGroups: ["apps"] - resources: ["deployments"] - verbs: ["create", "get", "list", "delete", "update"] ---- - -# Bind the role to the service account -kind: RoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: {{ printf "%s-rolebinding" $controllerName }} -subjects: -- kind: ServiceAccount - name: {{ $controllerAccount }} -roleRef: - kind: Role - name: {{ $controllerRole }} - apiGroup: rbac.authorization.k8s.io diff --git a/mjs/templates/phoenix.yaml b/mjs/templates/phoenix.yaml deleted file mode 100644 index c0c157b..0000000 --- a/mjs/templates/phoenix.yaml +++ /dev/null @@ -1,387 +0,0 @@ -{{- if (not .Values.useDefaultWrapperPhoenix) }} -# Define a custom wrapper-phoenix file with configurable heap memory -# Copyright 2024 The MathWorks, Inc. -apiVersion: v1 -kind: ConfigMap -metadata: - name: mjs-phoenix-config -data: - wrapper-phoenix.config: | - #******************************************************************** - # - # Wrapper config file for starting the phoenix RMI daemon - # - # Service Name : phoenixd - # - # Prerequisites for this wrapper config to work are that the following - # environment variables have been set or will be set in the environment - # specific include files listed below : - # - # JRECMD The location of the java executable to call - # - # JREBASE The location of the jre that will be used - # MATBASE The MATLABROOT directory - # MDCEBASE The DISTCOMP toolbox directory - # LOGBASE The directory to log the service stdout - # CHECKPOINTBASE The directory to CHECKPOINT the service - # - # ARCH The architecture we are running on - defines the location of wrapper library - # HOSTNAME The name of the host this service is running on - # - # WORKER_START_TIMEOUT - # - # JOB_MANAGER_HOST - # - # BASE_PORT - # - # The following are used when phoenix creates the service descriptor for - # a job manager. - # DEFAULT_JOB_MANAGER_NAME - # MDCEQE_JOBMANAGER_DEBUG_PORT - # - # The following are used when phoenix creates the service descriptor for - # a worker. - # MATLAB_EXECUTABLE - # DEFAULT_WORKER_NAME - # - # The following are used for security purposes. - # WORKER_DOMAIN (Windows only) - # SECURITY_LEVEL - # SECURITY_DIR - # USE_SECURE_COMMUNICATION - # SHARED_SECRET_FILE - # DEFAULT_KEYSTORE_PATH - # KEYSTORE_PASSWORD - # ALLOW_CLIENT_PASSWORD_CACHE - # ADMIN_USER - # ALLOWED_USERS - # ALLOW_RESIZING - # MAX_CAPACITY - # USE_LDAP_SERVER_AUTHENTICATION - # LDAP_URL - # LDAP_SECURITY_PRINCIPAL_FORMAT - # LDAP_SYNCHRONIZATION_INTERVAL_SECS - # SCHEDULING_ALGORITHM - # SAVE_JOB_HISTORY - # - # The following are used for on-demand operation - # RELEASE_LICENSE_WHEN_IDLE - # - # Copyright 2004-2023 The MathWorks, Inc. - #******************************************************************** - - # Including the following file as defined by an environment variable - # provides a way for us to set environment variables in NT. The - # problem is that we wish a call to service start to pick up any - # changes to mjs_def.bat. To do this we actually write the - # requested environment variables to %MDCE_CONFIG_FILE% - # and simply set the variable MDCE_CONFIG_FILE in the call to wrapper. - # This allows all the required variables to be set by the scripts - # and picked up in this config. To write this include we use - # MATLABROOT/toolbox/parallel/bin/win32/writeconfig.bat - # Currently this facility is NOT used on unix but could be. Also - # note that on windows it is expected that this file will set - # the variable %MDCE_PLATFORM_WRAPPER_CONF% which will be used - # in the next line to source platform specific behaviour - #include %MDCE_CONFIG_FILE% - - # Include the platform specific wrapper configuration file from the - # configuration directory. This environment variable should be set to - # something like %MDCEBASE%/config/wrapper-phoenix-$ARCH.config by the - # setup scripts or the config file - #include %MDCE_PLATFORM_WRAPPER_CONF% - - # Java Application - wrapper.java.command=%JRECMD_FOR_MDCS% - - # All parameters that might have spaces in them must be in double quotes, - # and wrapper.java.additional.X.stripquotes must then also be set to TRUE. - wrapper.java.additional.1=-Dcom.mathworks.toolbox.distcomp.base_port=%BASE_PORT% - - wrapper.java.additional.2="-Dcom.mathworks.toolbox.distcomp.matlabroot=%MATBASE%" - wrapper.java.additional.2.stripquotes=TRUE - - wrapper.java.additional.3="-Dcom.mathworks.toolbox.distcomp.toolboxroot=%MDCEBASE%" - wrapper.java.additional.3.stripquotes=TRUE - - wrapper.java.additional.4="-Dcom.mathworks.toolbox.distcomp.checkpointdir=%CHECKPOINTBASE%" - wrapper.java.additional.4.stripquotes=TRUE - - wrapper.java.additional.5="-Dcom.mathworks.toolbox.distcomp.configbase=%CONFIGBASE%" - wrapper.java.additional.5.stripquotes=TRUE - - wrapper.java.additional.6="-Dcom.mathworks.toolbox.distcomp.mdceDefFile=%MDCE_DEFFILE%" - wrapper.java.additional.6.stripquotes=TRUE - - # Logging - wrapper.java.additional.7="-Dcom.mathworks.toolbox.distcomp.logdir=%LOGBASE%" - wrapper.java.additional.7.stripquotes=TRUE - wrapper.java.additional.8=-Dcom.mathworks.toolbox.distcomp.loglevel=%LOG_LEVEL% - - # Security policy for phoenix - wrapper.java.additional.9="-Djava.security.policy=%MDCEBASE%/config/jsk-all.policy" - wrapper.java.additional.9.stripquotes=TRUE - - # Use urandom as source of entropy - wrapper.java.additional.10=-Djava.security.egd=file:/dev/urandom - - # Hostname - wrapper.java.additional.11="-Dcom.mathworks.toolbox.distcomp.hostname=%HOSTNAME%" - wrapper.java.additional.11.stripquotes=TRUE - - wrapper.java.additional.12="-Djava.rmi.server.hostname=%HOSTNAME%" - wrapper.java.additional.12.stripquotes=TRUE - - # Job manager - wrapper.java.additional.13="-Dcom.mathworks.toolbox.distcomp.default_jobmanager_name=%DEFAULT_JOB_MANAGER_NAME%" - wrapper.java.additional.13.stripquotes=TRUE - wrapper.java.additional.14=-Dcom.mathworks.toolbox.distcomp.job_manager_maximum_memory=%JOB_MANAGER_MAXIMUM_MEMORY% - wrapper.java.additional.15="-Dcom.mathworks.toolbox.distcomp.lookup_hosts=%JOB_MANAGER_HOST%" - wrapper.java.additional.15.stripquotes=TRUE - wrapper.java.additional.16=-Dcom.mathworks.toolbox.distcomp.debug_jobmanager_port=%MDCEQE_JOBMANAGER_DEBUG_PORT% - wrapper.java.additional.17=-Dcom.mathworks.toolbox.distcomp.jobmanager_gcInterval=10000 - - # Workers - wrapper.java.additional.18="-Dcom.mathworks.toolbox.distcomp.matlabexecutable=%MATLAB_EXECUTABLE%" - wrapper.java.additional.18.stripquotes=TRUE - wrapper.java.additional.19=-Dcom.mathworks.toolbox.distcomp.workerstarttimeout=%WORKER_START_TIMEOUT% - wrapper.java.additional.20="-Dcom.mathworks.toolbox.distcomp.default_worker_name=%DEFAULT_WORKER_NAME%" - wrapper.java.additional.20.stripquotes=TRUE - wrapper.java.additional.21=-Dcom.mathworks.toolbox.distcomp.worker_maximum_memory=%WORKER_MAXIMUM_MEMORY% - - # Jini/RMI settings used by the services - wrapper.java.additional.22=-Dcom.mathworks.toolbox.distcomp.membergroups=default_group - wrapper.java.additional.23=-Dcom.mathworks.toolbox.distcomp.RMI_readTimeout=300000 - wrapper.java.additional.24=-Dcom.mathworks.toolbox.distcomp.DNS_lookupInterval=300 - wrapper.java.additional.25=-Dcom.mathworks.toolbox.distcomp.RMI_connectionTimeout=10000 - - # This is the java.library.path used by the services - wrapper.java.additional.26="-Dcom.mathworks.toolbox.distcomp.library_path=%MATBASE%/bin/%ARCH%" - wrapper.java.additional.26.stripquotes=TRUE - - # The JRE flags passed to services - wrapper.java.additional.27="-Dcom.mathworks.toolbox.distcomp.jreflags=%JREFLAGS%" - wrapper.java.additional.27.stripquotes=TRUE - - # Security Level settings - wrapper.java.additional.28=-Dcom.mathworks.toolbox.distcomp.securityLevel=%SECURITY_LEVEL% - wrapper.java.additional.29="-Dcom.mathworks.toolbox.distcomp.securityDir=%SECURITY_DIR%" - wrapper.java.additional.29.stripquotes=TRUE - wrapper.java.additional.30=-Dcom.mathworks.toolbox.distcomp.rmi.useSecureCommunication=%USE_SECURE_COMMUNICATION% - wrapper.java.additional.31=-Dcom.mathworks.toolbox.distcomp.rmi.requireClientCertificate=%REQUIRE_CLIENT_CERTIFICATE% - wrapper.java.additional.32="-Dcom.mathworks.toolbox.distcomp.mjs.security.keystorePath=%SHARED_SECRET_FILE%" - wrapper.java.additional.32.stripquotes=TRUE - wrapper.java.additional.33="-Dcom.mathworks.toolbox.distcomp.mjs.security.defaultKeystorePath=%DEFAULT_KEYSTORE_PATH%" - wrapper.java.additional.33.stripquotes=TRUE - wrapper.java.additional.34=-Dcom.mathworks.toolbox.distcomp.mjs.auth.allowClientPasswordCache=%ALLOW_CLIENT_PASSWORD_CACHE% - wrapper.java.additional.35=-Dcom.mathworks.toolbox.distcomp.mjs.auth.adminUser=%ADMIN_USER% - wrapper.java.additional.36="-Dcom.mathworks.toolbox.distcomp.mjs.auth.allowedUsers=%ALLOWED_USERS%" - wrapper.java.additional.36.stripquotes=TRUE - wrapper.java.additional.37=-Dcom.mathworks.toolbox.distcomp.worker.windowsDomain=%WORKER_DOMAIN% - - # Configure the jobmanager ports - wrapper.java.additional.38=-Dcom.mathworks.toolbox.distcomp.allServerSocketsInCluster=%MDCS_ALL_SERVER_SOCKETS_IN_CLUSTER% - - # Configure the lifecycle reporter and heartbeat intervals - wrapper.java.additional.39=-Dcom.mathworks.toolbox.distcomp.worker.lifecycleReporter=%MDCS_LIFECYCLE_REPORTER% - wrapper.java.additional.40=-Dcom.mathworks.toolbox.distcomp.worker.workerLifecycleHeartBeat=%MDCS_LIFECYCLE_WORKER_HEARTBEAT% - wrapper.java.additional.41=-Dcom.mathworks.toolbox.distcomp.worker.taskLifecycleHeartBeat=%MDCS_LIFECYCLE_TASK_HEARTBEAT% - - # Additional jar files to add to classpath - wrapper.java.additional.42="-Dcom.mathworks.toolbox.distcomp.additionalClasspath=%MDCS_ADDITIONAL_CLASSPATH%" - wrapper.java.additional.42.stripquotes=TRUE - - # Peer Lookup Service configuration - wrapper.java.additional.43=-Dcom.mathworks.toolbox.distcomp.mjs.peerlookupservice.enabled=%MDCS_PEER_LOOKUP_SERVICE_ENABLED% - - # On demand flags - wrapper.java.additional.44=-Dcom.mathworks.toolbox.distcomp.worker.onDemand=%RELEASE_LICENSE_WHEN_IDLE% - - # Web licensing - wrapper.java.additional.45=-Dcom.mathworks.toolbox.distcomp.requireWebLicensing=%MDCS_REQUIRE_WEB_LICENSING% - - wrapper.java.additional.46="-Dcom.mathworks.toolbox.distcomp.jrecmd=%JRECMD_FOR_MDCS%" - wrapper.java.additional.46.stripquotes=TRUE - - # Limit the GC threads - wrapper.java.additional.47=-XX:ParallelGCThreads=6 - - # Send notifications of the state of the job manager queue - wrapper.java.additional.48=-Dcom.mathworks.toolbox.distcomp.sendActivityNotifications=%MDCS_SEND_ACTIVITY_NOTIFICATIONS% - - # Used to define the root directory containing the scripts to call to notify listeners of the job manager's state - wrapper.java.additional.49="-Dcom.mathworks.toolbox.distcomp.scriptRoot=%MDCS_SCRIPT_ROOT%" - wrapper.java.additional.49.stripquotes=TRUE - - # Defines whether workers are used to proxy interactive parallel pool connections - wrapper.java.additional.50=-Dcom.mathworks.toolbox.distcomp.workerProxiesPoolConnections=%MDCS_OPTIMIZED_POOL_BROADCAST% - - # Enables Peer RMI for all job manager communications when duplex peer rmi is enabled - wrapper.java.additional.51=-Dcom.mathworks.toolbox.distcomp.duplexPeerRmiEnabled=%MDCS_DUPLEX_PEER_RMI% - - # Sets the frequency of keep alive messages sent over peer sessions. - wrapper.java.additional.52=-Dcom.mathworks.toolbox.distcomp.pmode.keepAlivePeriod=%MDCS_PEERSESSION_KEEP_ALIVE_PERIOD% - wrapper.java.additional.53=-Dcom.mathworks.toolbox.distcomp.pmode.keepAliveTimeUnit=%MDCS_PEERSESSION_KEEP_ALIVE_TIME_UNIT% - - # Enables MATLAB Drive Path Translation on workers - wrapper.java.additional.54=-Dcom.mathworks.toolbox.distcomp.matlabDriveEnabledOnWorker=%MDCS_MATLAB_DRIVE_ENABLED_ON_WORKER% - wrapper.java.additional.55=-Dcom.mathworks.toolbox.distcomp.matlabDriveFolderLocationCfg=%MW_MATLAB_DRIVE_FOLDER_LOCATION_CFG% - - # Increase the size of the young generation to prevent triggering GC during VM initialization - wrapper.java.additional.56=-XX:NewSize=2304k - - # Use reliable connections - wrapper.java.additional.57=-Dcom.mathworks.toolbox.distcomp.useReliableConnections=%MDCS_USE_RELIABLE_CONNECTIONS% - - # SPF specifically exports services with IPv4. To prevent exporting two services on the same port (one IPv4 the other IPv6) we - # need to tell Java to prefer IPv4 so that our RMI services also export on IPv4. - - - # Use multicast for discovery - wrapper.java.additional.58=-Dcom.mathworks.toolbox.distcomp.mjs.enableMulticast=%MDCS_USE_MULTICAST% - - # Override for the default MATLAB release string used by the MJS services - wrapper.java.additional.59=-Dcom.mathworks.toolbox.distcomp.releaseOverride=%RELEASE_OVERRIDE% - - # Verify mjs commands before executing them - wrapper.java.additional.60=-Dcom.mathworks.toolbox.distcomp.requireScriptVerification=%REQUIRE_SCRIPT_VERIFICATION% - - # Resizing - wrapper.java.additional.61=-Dcom.mathworks.toolbox.distcomp.allowResizingDefault=%ALLOW_RESIZING% - wrapper.java.additional.62=-Dcom.mathworks.toolbox.distcomp.mjs.max_capacity_default=%MAX_CAPACITY% - - # LDAP server authentication - wrapper.java.additional.63=-Dcom.mathworks.toolbox.distcomp.mjs.useLDAPServerAuthenticationDefault=%USE_LDAP_SERVER_AUTHENTICATION% - wrapper.java.additional.64="-Dcom.mathworks.toolbox.distcomp.mjs.ldapURLDefault=%LDAP_URL%" - wrapper.java.additional.64.stripquotes=TRUE - wrapper.java.additional.65="-Dcom.mathworks.toolbox.distcomp.mjs.ldapSecurityPrincipalFormatDefault=%LDAP_SECURITY_PRINCIPAL_FORMAT%" - wrapper.java.additional.65.stripquotes=TRUE - wrapper.java.additional.66=-Dcom.mathworks.toolbox.distcomp.mjs.ldapSynchronizationIntervalSecsDefault=%LDAP_SYNCHRONIZATION_INTERVAL_SECS% - - # Service type to help identify this process - wrapper.java.additional.67=-Dcom.mathworks.toolbox.distcomp.mjs.service.serviceType=phoenix - - # Scheduling algorithm - wrapper.java.additional.68=-Dcom.mathworks.toolbox.distcomp.mjs.schedulingAlgorithmDefault=%SCHEDULING_ALGORITHM% - - wrapper.java.additional.69=-Dcom.mathworks.toolbox.distcomp.mjs.saveJobHistoryDefault=%SAVE_JOB_HISTORY% - - # Uncomment the following to enable debugging for the phoenix CommandListener service - #wrapper.java.additional.70=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=4455 - - # If you add more properties to the list above, you must also update - # the numbers on the properties used in wrapper-phoenix-ARCH.config. - - - # Java Main class. This class must implement the WrapperListener interface - # or guarantee that the WrapperManager class is initialized. Helper - # classes are provided to do this for you. See the Integration section - # of the documentation for details. - wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp - - # Application parameters. Add parameters as needed starting from 1 - wrapper.app.parameter.1=com.mathworks.toolbox.distcomp.control.PhoenixStarter - wrapper.app.parameter.2="%MDCEBASE%/config/start-phoenix.config" - wrapper.app.parameter.2.stripquotes=TRUE - - # Java Classpath (include wrapper.jar) Add class path elements as - # needed starting from 1. - # Remember that phoenix creates the service descriptors for the worker and - # the job manager, which is the reason for a few of these libraries. - wrapper.java.classpath.1=%JAREXTBASE%/wrapper.jar - wrapper.java.classpath.2=%JINILIB%/start.jar - wrapper.java.classpath.3=%JINILIB%/destroy.jar - wrapper.java.classpath.4=%JINILIB%/phoenix.jar - wrapper.java.classpath.5=%JARBASE%/parallel/util.jar - wrapper.java.classpath.6=%JARBASE%/parallel/pctutil.jar - wrapper.java.classpath.7=%JARBASE%/distcomp.jar - wrapper.java.classpath.8=%JINILIB%/reggie.jar - wrapper.java.classpath.9=%JINILIB%/jini-ext.jar - wrapper.java.classpath.10=%JINILIB%/group.jar - wrapper.java.classpath.11=%JINILIB%/phoenix-init.jar - wrapper.java.classpath.12=%MATBASE%/java/jar/util.jar - wrapper.java.classpath.13=%JARBASE%/parallel/admincenter.jar - wrapper.java.classpath.14=%JAREXTBASEUTIL%/commons-lang.jar - wrapper.java.classpath.15=%JAREXTBASEUTIL%/commons-io.jar - wrapper.java.classpath.16=%JAREXTBASEUTIL%/commons-cli.jar - wrapper.java.classpath.17=%MATBASE%/java/jar/resource_core.jar - wrapper.java.classpath.18=%MATBASE%/java/jar/foundation_libraries.jar - wrapper.java.classpath.19=%MATBASE%/java/jar/resources/parallel_res.jar - wrapper.java.classpath.20=%JAREXTBASEUTIL%/webservices/ws_client_core/mw-service-client-core.jar - wrapper.java.classpath.21=%JAREXTBASEUTIL%/webservices/gds_jobs_client/gds-jobs-client.jar - wrapper.java.classpath.22=%MATBASE%/java/jar/instutil.jar - wrapper.java.classpath.23=%MATBASE%/java/jar/mlwebservices.jar - wrapper.java.classpath.24=%MATBASE%/java/jar/webproxy.jar - wrapper.java.classpath.25=%MATBASE%/java/jar/net.jar - wrapper.java.classpath.26=%MATBASE%/java/jarext/gson.jar - wrapper.java.classpath.27=%MATBASE%/java/jar/jmi.jar - wrapper.java.classpath.28=%MATBASE%/java/jar/mvm.jar - wrapper.java.classpath.29=%MATBASE%/java/jar/services.jar - wrapper.java.classpath.30=%JAREXTBASEUTIL%/jdom2.jar - wrapper.java.classpath.31=%JAREXTBASEUTIL%/jackson/jackson-annotations.jar - wrapper.java.classpath.32=%JAREXTBASEUTIL%/jackson/jackson-core.jar - wrapper.java.classpath.33=%JAREXTBASEUTIL%/jackson/jackson-databind.jar - wrapper.java.classpath.34=%JAREXTBASEUTIL%/jackson/jackson-jaxrs-base.jar - wrapper.java.classpath.35=%JAREXTBASEUTIL%/jackson/jackson-jaxrs-json-provider.jar - wrapper.java.classpath.36=%JAREXTBASEUTIL%/jackson/jackson-module-jaxb-annotations.jar - wrapper.java.classpath.37=%JAREXTBASE%/h2.jar - wrapper.java.classpath.38=%JARBASE%/parallel/keytool.jar - wrapper.java.classpath.39=%JAREXTBASEUTIL%/commons-codec.jar - - # Java Library Path (location of Wrapper.DLL or libwrapper.so) - wrapper.java.library.path.1=%MDCEBASE%/bin/%ARCH% - wrapper.java.library.path.2=%MATBASE%/bin/%ARCH% - - # Initial Java Heap Size (in MB) - wrapper.java.initmemory=3 - - # Maximum Java Heap Size (in MB) - wrapper.java.maxmemory={{ .Values.commandListenerHeapMemory | default 1000 }} - - #******************************************************************** - # Wrapper Logging Properties - #******************************************************************** - # Format of output for the console. (See docs for formats) - wrapper.console.format=PM - - # Log Level for console output. (See docs for log levels) - wrapper.console.loglevel=INFO - - # Log file to use for wrapper output logging. - wrapper.logfile=%LOGBASE%/mjs-service.log - - # File to hold the pid of the wrapper process. This (in reality) - # simply proves that the wrapper process can write a file in the - # checkpoint directory, getting round filesystem issues where we - # don't have write access to this directory. - wrapper.pidfile=%CHECKPOINTBASE%/mjs_writetest.pid - - # Format of output for the log file. (See docs for formats) - wrapper.logfile.format=LPTM - - # Log Level for log file output. (See docs for log levels) - wrapper.logfile.loglevel=INFO - - # Maximum size that the log file will be allowed to grow to before - # the log is rolled. Size is specified in bytes. The default value - # of 0, disables log rolling. May abbreviate with the 'k' (kb) or - # 'm' (mb) suffix. For example: 10m = 10 megabytes. - wrapper.logfile.maxsize=2500k - - # Maximum number of rolled log files which will be allowed before old - # files are deleted. The default value of 0 implies no limit. - wrapper.logfile.maxfiles=4 - - # Log Level for sys/event log output. (See docs for log levels) - wrapper.syslog.loglevel=NONE - - # If false, the wrapper creates a background thread which enters a light weight - # loop and increments an internal "tick" counter. This is expected to make - # spurious timeouts due to high CPU loads very unlikely. - wrapper.use_system_time=false - - # Disable the ping between the wrapper and the JVM so that the wrapper will - # never try to kill and restart the JVM. It also has the effect of disabling - # the JVM monitoring of the wrapper. - wrapper.ping.timeout=0 -{{- end }}