From e8feb911b9d0292833fcb2ae856b7f672e5e2141 Mon Sep 17 00:00:00 2001 From: DJ Gregor Date: Wed, 1 Nov 2023 12:24:39 -0400 Subject: [PATCH 1/2] NMS-15822: Add support for configmaps that get copied to the overlay Since config map values can't have "/" in them, we need to support multiple config maps (which we already do), so a new "path" key is required for plain configmaps so we can specify different paths the files are rooted at (this "path" key is not required for "unzip" configmaps mentioned below). Add an optional "unzip" flag that can be specified for a configmap entry, and in that case, any *.zip files in the configmap will be extracted at the root of the overlay volume (any other files in that configmap will be ignored). Co-authored-by: mershad-manesh <105240903+mershad-manesh@users.noreply.github.com> --- horizon/README.md | 1 + horizon/scripts/onms-core-init.sh | 20 +++++++++++++++++++ .../templates/opennms-core.statefulset.yaml | 19 ++++++++++++++++++ horizon/values.yaml | 1 + 4 files changed, 41 insertions(+) diff --git a/horizon/README.md b/horizon/README.md index 8e03c44..82ee16e 100644 --- a/horizon/README.md +++ b/horizon/README.md @@ -64,6 +64,7 @@ helm install monms opennms/horizon --set domain=domain1.com --create-namespace | core.image.repository | string | `"opennms/horizon"` | | | core.image.tag | string | `""` | | | core.inspector.enabled | bool | `false` | | +| core.overlayConfigMaps | list | `[]` | | | core.postConfigJob.ttlSecondsAfterFinished | int | `300` | | | core.resources.limits.cpu | string | `"2"` | | | core.resources.limits.memory | string | `"8Gi"` | | diff --git a/horizon/scripts/onms-core-init.sh b/horizon/scripts/onms-core-init.sh index c85c257..6444a2f 100644 --- a/horizon/scripts/onms-core-init.sh +++ b/horizon/scripts/onms-core-init.sh @@ -141,6 +141,8 @@ DEPLOY_DIR="/opennms-deploy" # Mounted Externally CONFIG_DIR_OVERLAY=${OVERLAY_DIR}/etc +OVERLAY_CONFIG_MAPS="/opennms-overlay-configmaps" # Mounted externally + KARAF_FILES=( \ "config.properties" \ "startup.properties" \ @@ -619,3 +621,21 @@ else echo "We are unable to update Admin password. Exiting." exit 1 fi + +if [ -d ${OVERLAY_CONFIG_MAPS} ]; then + echo "Processing overlay config maps ..." + # We need to make sure the directories are numerically sorted to match the configured configmap order. + for dir in $(ls -1d ${OVERLAY_CONFIG_MAPS}/* | sort -t/ -k3 -n); do + if [[ $(basename $dir) =~ .*-unzip ]]; then + for zip in $(ls -1 ${dir}/*.zip | sort); do + echo " Extracting files from $zip to ${OVERLAY_DIR}/ ..." + unzip -o -d ${OVERLAY_DIR} ${zip} | sed 's/^/ /' + done + else + # When we first copy off of the configmap volume, we copy symlinks as files and ignore Kubernetes configmap volume ".." files. + # See: https://github.com/spring-projects/spring-boot/issues/23232 + echo " Copying files from $dir to ${OVERLAY_DIR}/ ..." + rsync -arO -L --exclude='..*' --no-perms --no-owner --no-group --out-format="%n %C" $dir/ ${OVERLAY_DIR}/ | sed 's/^/ /' + fi + done +fi diff --git a/horizon/templates/opennms-core.statefulset.yaml b/horizon/templates/opennms-core.statefulset.yaml index 3161fd5..0fa9d13 100644 --- a/horizon/templates/opennms-core.statefulset.yaml +++ b/horizon/templates/opennms-core.statefulset.yaml @@ -121,6 +121,20 @@ spec: mountPath: /opt/opennms-overlay # Required by the script - OVERLAY_DIR - name: scripts mountPath: /scripts # Required by the script + {{- range $k, $r := .Values.core.overlayConfigMaps }} + - name: overlay-configmap-{{ $k }} + {{- if $r.unzip }} + {{- if $r.path }} + {{- printf "path not allowed when unzip is true for core.overlayConfigMaps with name '%s'" $r.name | fail }} + {{- end }} + mountPath: /opennms-overlay-configmaps/{{ $k }}-unzip + {{- else }} + {{- if empty $r.path }} + {{- printf "path required for core.overlayConfigMaps with name '%s'" $r.name | fail }} + {{- end }} + mountPath: /opennms-overlay-configmaps/{{ $k }}/{{ $r.path }} + {{- end }} + {{- end }} nodeSelector: {{- toYaml .Values.core.configuration.nodeSelector | nindent 8 }} affinity: @@ -290,3 +304,8 @@ spec: claimName: onms-mibs-pvc readOnly: false {{- end }} + {{- range $k, $r := .Values.core.overlayConfigMaps }} + - name: overlay-configmap-{{ $k }} + configMap: + name: {{ $r.name | quote }} + {{- end }} diff --git a/horizon/values.yaml b/horizon/values.yaml index e191071..e80e897 100644 --- a/horizon/values.yaml +++ b/horizon/values.yaml @@ -108,6 +108,7 @@ ingress: core: inspector: enabled: false + overlayConfigMaps: [] terminationGracePeriodSeconds: 120 image: repository: opennms/horizon From 42cf80fce9504db30d3cf0c06da0055420ed5eee Mon Sep 17 00:00:00 2001 From: DJ Gregor Date: Fri, 17 Nov 2023 11:06:44 -0500 Subject: [PATCH 2/2] Update documentation for overlay configmaps --- horizon/Chart.yaml | 2 +- horizon/README.md | 65 ++++++++++++++++++++++++++++++++++++++++ horizon/README.md.gotmpl | 65 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 131 insertions(+), 1 deletion(-) diff --git a/horizon/Chart.yaml b/horizon/Chart.yaml index 00e06f3..6d348b8 100644 --- a/horizon/Chart.yaml +++ b/horizon/Chart.yaml @@ -17,7 +17,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 1.1.2 +version: 1.1.3 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/horizon/README.md b/horizon/README.md index 82ee16e..f0750a0 100644 --- a/horizon/README.md +++ b/horizon/README.md @@ -25,6 +25,71 @@ helm install monms opennms/horizon --set domain=domain1.com --create-namespace | ----------- | ----------- | ----------- | | 1.x | Horizon 32.x | Meridian 2023.x | +## Overlay ConfigMaps + +The chart supports specifying a list of ConfigMaps with `core.overlayConfigMaps` that will be copied to the OpenNMS container overlay directory in the init container. This can be used to provide configuration files for OpenNMS. There are two ways to provide content in each ConfigMap: + +### Plain files + +Provide one or more plain files (text and/or binary) in the ConfigMap and specify the directory where these files we be copied. + +Here is a configuration example: + +``` +core: + overlayConfigMaps: + - name: "my-etc-files" + path: "etc" +``` + +Here is an example of how to create the ConfigMap: + +``` +instance= # make sure to set to your Helm release name +configmap=my-etc-files + +mkdir etc +date > etc/testing-configmap + +kubectl create configmap -n $instance $configmap --from-file=etc +``` + +### ZIP files + +Provide one or more ZIP files in the ConfigMap, and each will be extracted in alphabetical order at the root of the overlay directory. + +Here is a configuration example: + +``` +core: + overlayConfigMaps: + - name: "my-zip-files" + unzip: true +``` + +Here is an example of how to create the ConfigMap: + +``` +instance= # make sure to set to your Helm release name +configmap=my-zip-files + +mkdir -p zip/etc +dd if=/dev/zero bs=1k count=5000 of=zip/etc/lots-of-zeros # make a 5 MB test file +( cd zip && zip -r -o ../lots-of-zeros.zip . ) + +kubectl create configmap -n $instance $configmap --from-file=lots-of-zeros.zip +``` + +### Overlay ConfigMap Notes + +1. This mechanism can only be used to *add* files. When `etc` files are copied into the `onms-etc-pvc` PVC, removing a file from the ConfigMap will not cause the file in the PVC to be *deleted*. In this case, you will need to delete the file manually **after** updating the ConfigMap to remove the file. You can do this with `kubectl exec -n $instance onms-core-0 -- rm etc/testing-configmap`. +2. ConfigMaps cannot contain recursive directory structures--only files. If you need to put files into multiple directories, each directory will need to be its own ConfigMap. `kubectl create configmap` will silently ignore sub-directories. +3. ConfigMaps can't be larger than 1 MB (see the note [here](https://kubernetes.io/docs/concepts/configuration/configmap/#motivation). If you have more content, it will need to be split across multiple ConfigMaps or compressed into ZIP files. +4. Use `kubectl delete configmap -n $instance $configmap` to delete an existing ConfigMap before updating. +5. After updating a ConfigMap, you will need to restart the pod, for example: `kubectl rollout restart -n $instance statefulset/onms-core` +6. You can use `kubectl get configmap -n $instance $configmap -o yaml` to view the ConfigMap that is created. +7. Due to file ownership, some files/directories might not be updatable in the container at runtime. A workaround is to build a modified container that updates permissions with `chmod -R g=u ...` on the affected files/directories. See the OpenNMS [core Dockerfile](https://github.com/OpenNMS/opennms/blob/develop/opennms-container/core/Dockerfile) for which directories have been updated to allow writes out-of-the-box. + ## Values | Key | Type | Default | Description | diff --git a/horizon/README.md.gotmpl b/horizon/README.md.gotmpl index 231d5fa..352e959 100644 --- a/horizon/README.md.gotmpl +++ b/horizon/README.md.gotmpl @@ -25,6 +25,71 @@ helm install monms opennms/horizon --set domain=domain1.com --create-namespace | ----------- | ----------- | ----------- | | 1.x | Horizon 32.x | Meridian 2023.x | +## Overlay ConfigMaps + +The chart supports specifying a list of ConfigMaps with `core.overlayConfigMaps` that will be copied to the OpenNMS container overlay directory in the init container. This can be used to provide configuration files for OpenNMS. There are two ways to provide content in each ConfigMap: + +### Plain files + +Provide one or more plain files (text and/or binary) in the ConfigMap and specify the directory where these files we be copied. + +Here is a configuration example: + +``` +core: + overlayConfigMaps: + - name: "my-etc-files" + path: "etc" +``` + +Here is an example of how to create the ConfigMap: + + +``` +instance= # make sure to set to your Helm release name +configmap=my-etc-files + +mkdir etc +date > etc/testing-configmap + +kubectl create configmap -n $instance $configmap --from-file=etc +``` + +### ZIP files + +Provide one or more ZIP files in the ConfigMap, and each will be extracted in alphabetical order at the root of the overlay directory. + +Here is a configuration example: + +``` +core: + overlayConfigMaps: + - name: "my-zip-files" + unzip: true +``` + +Here is an example of how to create the ConfigMap: + +``` +instance= # make sure to set to your Helm release name +configmap=my-zip-files + +mkdir -p zip/etc +dd if=/dev/zero bs=1k count=5000 of=zip/etc/lots-of-zeros # make a 5 MB test file +( cd zip && zip -r -o ../lots-of-zeros.zip . ) + +kubectl create configmap -n $instance $configmap --from-file=lots-of-zeros.zip +``` + +### Overlay ConfigMap Notes + +1. This mechanism can only be used to *add* files. When `etc` files are copied into the `onms-etc-pvc` PVC, removing a file from the ConfigMap will not cause the file in the PVC to be *deleted*. In this case, you will need to delete the file manually **after** updating the ConfigMap to remove the file. You can do this with `kubectl exec -n $instance onms-core-0 -- rm etc/testing-configmap`. +2. ConfigMaps cannot contain recursive directory structures--only files. If you need to put files into multiple directories, each directory will need to be its own ConfigMap. `kubectl create configmap` will silently ignore sub-directories. +3. ConfigMaps can't be larger than 1 MB (see the note [here](https://kubernetes.io/docs/concepts/configuration/configmap/#motivation). If you have more content, it will need to be split across multiple ConfigMaps or compressed into ZIP files. +4. Use `kubectl delete configmap -n $instance $configmap` to delete an existing ConfigMap before updating. +5. After updating a ConfigMap, you will need to restart the pod, for example: `kubectl rollout restart -n $instance statefulset/onms-core` +6. You can use `kubectl get configmap -n $instance $configmap -o yaml` to view the ConfigMap that is created. +7. Due to file ownership, some files/directories might not be updatable in the container at runtime. A workaround is to build a modified container that updates permissions with `chmod -R g=u ...` on the affected files/directories. See the OpenNMS [core Dockerfile](https://github.com/OpenNMS/opennms/blob/develop/opennms-container/core/Dockerfile) for which directories have been updated to allow writes out-of-the-box. {{ template "chart.valuesSection" . }}