jenkinsfile-runner
jenkinsfile-runner copied to clipboard
How do I run this from within a multibranch pipeline?
What I'm trying to do
Run the docker version of Jenkinsfile-runner from within a multibranch pipeline. I want to do something similar to this post https://www.jenkins.io/blog/2019/02/28/serverless-jenkins/ . However instead of using TravisCI as the blog author does I want to use our companies existing Jenkins mutlibranch pipeline infrastructure.
What I have done already
I have successfully managed to build a customised Jenkinsfile-runner Docker image and added it to my local registry. When I execute this from the command line using docker run
it correctly picks up my Jenkinsfile and executes it.
Now I want to do this automatically from within a multibranch pipeline but I am getting a bit stuck. Do I need a small bootstrap Jenkinsfile that is configured in the mutlibranch configuration page that simply runs the Jenkinsfile-runner? I'd like to pass some environment values to the main Jenkinsfile such as branch name like the blog post does too.
I must admit I don't know enough about Docker and especially Docker inside of Jenkins so this may seem like an obvious question.
To update this after some experimentation:
- I have started Jenkins using Docker and created a multibranch pipeline job. This is how I start the Jenkins Docker container.
docker run -p 8080:8080 -p 50000:50000 -v $(pwd)/jenkins_home:/var/jenkins_home -v $(pwd)/test-project:/testgitrepo:ro --group-add $(stat -c '%g' /var/run/docker.sock) -v /var/run/docker.sock:/var/run/docker.sock jenkins/jenkins:lts
I have modified this run
command from the jenkinsci/docker README and this blog about some of the troubles trying to run Docker within an already running Jenkins Docker. I also mount my git repo into the running image to be able to quickly reference a Git project using the file://
git schema. This if for quick testing purposes.
-
In the global tool configuration I have added a Docker installation and asked Jenkins to automatically install Docker.
- In the future I could customise the Jenkins Docker image to bundle the Docker client as well, but this was easier to start with.
-
I have added a
Jenkinsfile.bootstrap
file and told the pipeline configuration to use this instead of the mainJenkinsfile
that Jenkinsfile-runner will use.
node {
def dockerHome = tool 'docker'
env.PATH = "${dockerHome}/bin:${env.PATH}"
sh "ls -alt"
sh "pwd"
sh "docker run --rm -v \$(pwd):/workspace:ro -v /tmp -e BRANCH_NAME=\$BRANCH_NAME experiment/jenkinsfile-custom-experiment"
}
The run
command is modified from the blog post I linked above.
-
When I run the last line of that boostrap script outside of the Dockerised Jenkins it runs correctly as in the
Jenkinsfile-runner
Docker image runs, picks up theJenkinsfile
, and runs it. -
When I run the multibranch pipeline runs, however, it give me this error:
Started by user admin
Replayed #42
> git rev-parse --is-inside-work-tree # timeout=10
Setting origin to file:///testgitrepo
> git config remote.origin.url file:///testgitrepo # timeout=10
Fetching origin...
Fetching upstream changes from origin
> git --version # timeout=10
> git config --get remote.origin.url # timeout=10
> git fetch --tags --progress -- origin +refs/heads/*:refs/remotes/origin/* # timeout=10
Seen branch in repository origin/add-jenkinsfile
Seen branch in repository origin/master
Seen 2 remote branches
Obtained Jenkinsfile.bootstrap from 24fcde91505ac324e46056a45735c55e597060fc
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] Start of Pipeline
[Pipeline] node
Running on Jenkins in /var/jenkins_home/workspace/ibranch-pipeline_add-jenkinsfile
[Pipeline] {
[Pipeline] tool
[Pipeline] sh
+ ls -alt
total 24
drwxr-xr-x 8 jenkins jenkins 4096 Jun 16 21:52 .git
drwxr-xr-x 3 jenkins jenkins 4096 Jun 16 21:36 .
-rw-r--r-- 1 jenkins jenkins 477 Jun 16 21:36 Jenkinsfile.bootstrap
drwxr-xr-x 6 jenkins jenkins 4096 Jun 16 19:46 ..
-rw-r--r-- 1 jenkins jenkins 221 Jun 16 19:38 Jenkinsfile
-rw-r--r-- 1 jenkins jenkins 12 Jun 16 19:38 README
[Pipeline] sh
+ pwd
/var/jenkins_home/workspace/ibranch-pipeline_add-jenkinsfile
[Pipeline] sh
+ pwd
+ docker run --rm -v /var/jenkins_home/workspace/ibranch-pipeline_add-jenkinsfile:/workspace:ro -v /tmp -e BRANCH_NAME=add-jenkinsfile experiment/jenkinsfile-custom-experiment
2020-06-21 15:55:06.940+0000 [id=1] WARNING j.branch.WorkspaceLocatorImpl#getWorkspaceRoot: JENKINS-2111 path sanitization ineffective when using legacy Workspace Root Directory ‘/build’; switch to ‘${JENKINS_HOME}/workspace/${ITEM_FULL_NAME}’ as in JENKINS-8446 / JENKINS-21942
2020-06-21 15:55:07.138+0000 [id=46] WARNING o.j.p.w.flow.FlowExecutionList#unregister: Owner[job/1:job #1] was not in the list to begin with: []
Started
java.io.IOException: File '/workspace/Jenkinsfile' exists but is a directory
at org.apache.commons.io.FileUtils.openInputStream(FileUtils.java:291)
at org.apache.commons.io.FileUtils.readFileToString(FileUtils.java:1805)
at org.apache.commons.io.FileUtils.readFileToString(FileUtils.java:1838)
at io.jenkins.jenkinsfile.runner.SetJenkinsfileLocation.create(SetJenkinsfileLocation.java:31)
at org.jenkinsci.plugins.workflow.cps.CpsScmFlowDefinition.create(CpsScmFlowDefinition.java:105)
at org.jenkinsci.plugins.workflow.cps.CpsScmFlowDefinition.create(CpsScmFlowDefinition.java:69)
at org.jenkinsci.plugins.workflow.job.WorkflowRun.run(WorkflowRun.java:309)
at hudson.model.ResourceController.execute(ResourceController.java:97)
at hudson.model.Executor.run(Executor.java:428)
Finished: FAILURE
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
ERROR: script returned exit code 2
Finished: FAILURE
I can see from the ls
commands prior to the Docker command that Jenkinsfile
is definitely not a directory.
Again, I'm fairly new to Docker and am trying to hack my way through this so I am very much open to being told that I am doing something wrong. Apologies if so.
Seems my novice Docker skills are causing issues here. I did manage to get this to work by modifying my Jenkinsfile.bootstrap
to this:
node {
def dockerHome = tool 'docker'
env.PATH = "${dockerHome}/bin:${env.PATH}"
sh "docker run --rm -v /path/to/project/on/host/machine/test-project:/workspace:ro -v /tmp -e BRANCH_NAME=\$BRANCH_NAME experiment/jenkinsfile-custom-experiment"
}
The issue I had above was because I was trying to mount a volume that itself was a mounted volume (Docker in Docker) and that doesn't work. But explicitly pointing to location on the host machine did.
That's still not great. But it is a step further. I'll keep hacking.
Yes, more patches are needed to make Multi-branch work natively. I am open to change the engine to make it more easy though my first objective is to emulate the folder structure