Helm Jenkins JCasC Automatic Reload of Configuration as Code

305 Views Asked by At

I have created a Jenkins instance in which I am using Jenkins Configuration as Code (JCasC) and I am using Helm to manage the deploys/upgrades.

As a test, I created a welcome-message.yaml file:

jenkins:
  systemMessage: "JCasC used to configure Jenkins"

I placed this into a directory called JCasC in the Helm chart for Jenkins:

helm-charts/
  charts/
    jenkins/
      jcasc/
        - welcome-message.yaml

In the templates folder, I place the jenkins-custom-casc-config.yaml file:

apiVersion: v1
kind: ConfigMap
metadata:
  name: jenkins-custom-casc-config
data:
{{ (.Files.Glob "jcasc/*").AsConfig | indent 2 }}

in

helm-charts/
  charts/
    jenkins/
      templates/
        - jenkins-custom-casc-config.yaml

In values.yaml I create the config map info for the volumes:

  volumes:
    - name: jenkins-custom-casc-config
      configMap:
        name: jenkins-custom-casc-config
  mounts:
    - mountPath: /var/jenkins_home/custom_casc_configs
      name: jenkins-custom-casc-config

This all works as it should, placing the welcome-message.yaml in /var/jenkins_home/custom_casc_configs properly. I have set CASC_JENKINS_CONFIG to look for files in the standard CASC directory as well as the new custom directory.

containerEnv:
  - name: CASC_JENKINS_CONFIG
    value: "/var/jenkins_home/casc_configs,/var/jenkins_home/custom_casc_configs"

For sidecars, I have this set up in the values.yaml file:

sidecars:
    configAutoReload:
      enabled: true
      image: kiwigrid/k8s-sidecar:1.24.4
      imagePullPolicy: IfNotPresent
      resources: {}
      reqRetryConnect: 10
      folder: /var/jenkins_home/casc_configs

No matter what I do, the JCasC is never reloaded when I perform a helm upgrade... even though the new/updated config files are placed into the /var/jenkins_home/custom_casc_configs directory. I can intervene by going to the Configuration as Code console in the Jenkins UI and updating the configuration by manually entering the directory and applying.

I have crisscrossed the web looking for the answer, but there is no clear solution. How do I make JCasC automatically reload when I perform an upgrade via Helm?

1

There are 1 best solutions below

5
VonC On BEST ANSWER

The official Jenkins Configuration as Code (JCasC) plugin documentation for the Kubernetes Helm implementation does not mention a "folders" attribute for the sidecar configuration.
Instead, it uses a singular "folder" attribute, which means the sidecar is configured to monitor only one directory for changes.

sidecars:
  configAutoReload:
    enabled: true
    image: shadwell/k8s-sidecar:0.0.2
    imagePullPolicy: IfNotPresent
    sshTcpPort: 1044
    label: jenkins_config
    folder: /var/jenkins_home/casc_configs
    # Additional configurations

In your case, the sidecar is set to monitor the /var/jenkins_home/casc_configs directory. Since you are also using a custom configuration directory (/var/jenkins_home/custom_casc_configs), the sidecar, in its current state, will not monitor this directory.


If feasible, you might need to move all JCasC files to the same directory that the sidecar monitors (/var/jenkins_home/casc_configs). That will make sure any changes in this directory trigger the auto-reload.


But if you need to keep the custom configuration directory separate, another option is to implement a custom solution (such as a script or a secondary sidecar) to monitor the /var/jenkins_home/custom_casc_configs directory and trigger a reload when changes are detected.

Something that continuously monitors the specified directory for changes. That can be achieved using a shell script with a simple loop and checksum comparison:

#!/bin/bash

# Define the directory to monitor
MONITOR_DIR="/var/jenkins_home/custom_casc_configs"

# Initialize the last checksum
LAST_CHECKSUM=$(find $MONITOR_DIR -type f -exec md5sum {} + | md5sum)

while true; do
    # Calculate current checksum
    CURRENT_CHECKSUM=$(find $MONITOR_DIR -type f -exec md5sum {} + | md5sum)

    # Compare checksums
    if [ "$LAST_CHECKSUM" != "$CURRENT_CHECKSUM" ]; then
        echo "Change detected, reloading JCasC..."

        # Command to reload JCasC
        # Example: using Jenkins CLI or Jenkins REST API call
        # jenkins-cli.sh -s http://jenkins:8080 reload-configuration
        # or
        # curl -X POST http://jenkins:8080/reload-configuration --user user:token

        # Update last checksum
        LAST_CHECKSUM=$CURRENT_CHECKSUM
    fi

    # Wait for a bit before checking again
    sleep 60
done

The script needs to be deployed and run within the Jenkins environment, either with:

  • an init container in your Kubernetes pod to deploy and run the script. The script can be started as a background process during pod initialization.
  • a sidecar container, with the script running in its own container alongside Jenkins. That method provides isolation from the Jenkins container.
  • a direct execution, where you include the script directly in the Jenkins container and run it as a background process. That can be done through a custom Docker image or by mounting the script into the container and running it.

The script can then reload the JCasC using either:

  • the Jenkins CLI, if it is set up, to trigger a configuration reload.
  • the REST API, used to send a POST request to the reload URL.
  • direct file manipulation, modifying a tracked file to trigger a reload.