Correctly override "settings.xml" in Jenkinsfile Maven build on kubernetes?

11/21/2019

We are setting up a Jenkins-based CI pipeline on our Kubernetes cluster (Rancher if that matters) and up to now we have used the official maven:3-jdk-11-slim image for experiments. Unfortunately it does not provide any built-in way of overriding the default settings.xml to use a mirror, which we need - preferably just by setting an environment variable. I am not very familar with kubernetes so I may be missing something simple.

Is there a simple way to add a file to the image? Should I use another image with this functionality built in?

pipeline {
    agent {
        kubernetes {
            yaml """
kind: Pod
metadata:
  name: kaniko
spec:
  containers:
  - name: maven
    image: maven:3-jdk-11-slim
    command:
    - cat
    tty: true
  - name: kaniko
.... etc
-- Thorbjørn Ravn Andersen
jenkins
jenkins-pipeline
kubernetes
maven

4 Answers

11/26/2019

If you versioned the settings.xml of the project with the code, it makes sense to build with mvn install -s settings.xml using sh step. It what I did at work. If settings.xml is not versioned with the project, it indeed makes sens to mount the file with Crou's solution.

To answer your question "Should I use another image with this functionality built in?" I would recommend to avoid a maximum to build custom images because you will end up having to maintain them

-- fredericrous
Source: StackOverflow

11/21/2019

This worked for me:

  • Install Config File Provider Plugin
  • Go to Manage Jenkins > Config File Management > Add a new config and insert here your settings.xml
  • In your jenkinsfile just put your rtMavenRun inside a configFileProvider block, and put the same fileId of the jenkins config file you created before
    stage('Build Maven') {
                steps {
                    configFileProvider([configFile(fileId: 'MavenArtifactorySettingId', variable: 'MAVEN_SETTINGS_XML')]) {
                        retry(count: 3) {
                            rtMavenRun(
                                tool: "Maven 3.6.2", //id specified in Global Tool Configuration
                                pom: 'pom.xml',
                                goals: '-U -s $MAVEN_SETTINGS_XML clean install',
                            )
                        }
                    }
                }
            }

this is exactly the pipeline that I used if you want to see more: https://gist.github.com/robertobatts/42da9069e13b61a238f51c36754de97b

-- robertobatts
Source: StackOverflow

11/26/2019

Summary: you can mount your settings.xml file on the pod at some specific path and use that file with command mvn -s /my/path/to/settings.xml.

Crou's ConfigMap approach is one way to do it. However, since the settings.xml file usually contains credentials, I would treat it as Secrets.

You can create a Secret in Kubernetes with command:

$ kubectl create secret generic mvn-settings --from-file=settings.xml=./settings.xml

The pod definition will be something like this:

apiVersion: v1
kind: Pod
metadata:
  name: kaniko
spec:
  containers:
    - name: maven
      image: maven:3-jdk-11-slim
      command:
      - cat
      tty: true
      volumeMounts:
      - name: mvn-settings-vol
        mountPath: /my/path/to
  volumes:
    - name: mvn-settings-vol
      secret:
        secretName: mvn-settings

Advanced/Optional: If you practice "Infrastructure as Code", you might want to save the manifest file for that secret for recovery. This can be achieved by this command after secret already created:

$ kubectl get secrets mvn-settings -o yaml

You can keep secrets.yml file but do not check into any VCS/Github repo since this version of secrets.yml contains unencrypted data.

Some k8s administrators may have kubeseal installed. In that case, I'd recommend using kubeseal to get encrypted version of secrets.yml.

$ kubectl create secret generic mvn-settings --from-file=settings.xml=./settings.xml --dry-run -o json | kubeseal --controller-name=controller --controller-namespace=k8s-sealed-secrets --format=yaml >secrets.yml

# Actually create secrets
$ kubectl apply -f secrets.yml

The controller-name and controller-namespace should be obtained from k8s administrators. This secrets.yml contains encrypted data of your settings.xml and can be safely checked into VCS/Github repo.

-- tdongsi
Source: StackOverflow

11/21/2019

If you want to override a file inside pod you can use ConfigMap to store the changed file and mount it instead of previous one.

You can create the ConfigMap from a file using

kubectl create configmap settings-xml --from-file=settings.xml

Your pod definition might look like this:

apiVersion: v1
kind: Pod
metadata:
  name: kaniko
spec:
  containers:
    - name: maven
      image: maven:3-jdk-11-slim
      command:
      - cat
      tty: true
      volumeMounts:
      - name: config-settings
        mountPath: /usr/share/maven/ref/settings.xml
  volumes:
    - name: config-settings
      configMap:
        # Provide the name of the ConfigMap containing the files you want
        # to add to the container
        name: settings-xml
...
-- Crou
Source: StackOverflow