Jenkins Pipeline: Build docker within docker container - java

I'm trying to do the following
Checkout the code
Do some prechecks using some other docker images (don't want to install these on Jenkins node)
Build jar using docker image maven:3.6-jdk-8
Then run Dockerfile to build app image
Push the image to repository
Now, I don't want to install anything apart from Docker on Jenkins node. I want to run the full pipeline in Docker container to achieve this. What I'm struggling is how to build the 4th step from within the container.
I wrote the Jenkinsfile as below
pipeline {
agent none
stages {
stage('Maven build') {
agent {
docker {
image 'maven:3.6-jdk-8'
args '-u root:root'
}
}
steps {
checkout(
[
$class: 'GitSCM',
branches: [
[name: '*/master']
],
doGenerateSubmoduleConfigurations: false,
extensions: [],
submoduleCfg: [],
userRemoteConfigs: [
[
credentialsId: '<cred-id>',
url: '<github-url>']
]
])
sh '''
set -eux pipefail
mvn -e clean install
'''
}
}
stage('Build docker image') {
// Which docker image to use?
}
}
}
But I'm not sure how to build a docker image within container. The search didn't help that much. I tried using the Jenkins node for the docker image building but it seems I cannot mix and match. I totally understand this is quite an open question but I think it would be helpful to know the straightforward answer(s).

Have a look at this Jenkins Plugin: https://docs.cloudbees.com/docs/admin-resources/latest/plugins/docker-workflow

Related

Deployment pipeline with Jenkins

I have been trying to do cicd with jenkin pipeline.
I have pull project from git, create jar and run the jar file
Jar file starts the server
and after the server starts the next stage doesn't gets executed
next step is to run karate test cases.
Got stuck here.
This is my pipeline script::
node {
def mavenHome = tool name: "Maven", type: "maven"
stage('git clone') {
checkout([$class: 'GitSCM', branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: 'b6423164-b18d-43e0-a48f-edd10f90396d', url: 'https://github.com/prajdshakya93/Employee-Record-Managment-System.git']]])
}
stage('build artifact with dependencies'){
bat "${mavenHome}/bin/mvn clean compile assembly:single"
bat("xcopy config.properties C:\\ProgramData\\Jenkins\\.jenkins\\workspace\\ermsPipelinePratice\\target")
}
stage('run jar file'){
dir("target") {
bat "java -jar erms-1.0-SNAPSHOT-jar-with-dependencies.jar"
}
}
stage('run karate'){
bat "${mavenHome}/bin/mvn test -Dtest=KarateTests"
}
}

Jenkinsfile Parameters Issue : Issue while running with multiple parameters to bat maven

I have an issue while running my job through the Jenkins file, whatever parameters I gave its updated in the place where I called it, but when it runs with bat mvn command it tool goal as that of the parameter itself. Suppose I Specified the parameter name is QA from my Jenkins build with parameter and run it ..it complete all the steps except the last one where i have build, bat mvn, it tried to run taking goal and lifecycle as QA instead of clean test-compile.
I have attached the Jenkinfile herewith.
pipeline {
agent { label 'TESTING' }
tools {
maven 'maven'
}
parameters{
choice(name: 'ENVIRONMENT' , choices: ['QA' , 'UAT' , 'PREPROD'] , description: '')
choice(name: 'SUITE' , choices: ['Regression' , 'Smoke'] , description: '')
}
stages {
stage('Clone') {
steps {
git branch: 'master' , credentialsId: 'xyzabc' , url: "https://git.xyz.com/project/automation.git"
}
}
stage('Git Checkout') {
steps {
git(branch: 'development',
credentialsId: 'xyzabc',
url: "https://git.xyz.com/project/automation.git")
}
}
stage('Build') {
steps {
echo "parameter name from jenkinsfile Environment is ${params.ENVIRONMENT}"
echo "parameter name from jenkinsfile SUITE is ${params.SUITE}"
bat "mvn clean test-compile exec:java -Dexec.mainClass='com.test.mainClass' -Dexec.args='${params.ENVIRONMENT} ${params.SUITE}' -Dexec.classpathScope=test"
}
}
}
}
ERROR MESSAGE IN JENKINS RUN,

Docker Selenium standalone server is Unable to upload a file to the grid browser in the container

I have a selenium script that to upload an attachment runs on maven and java and is working fine when run from Local.
When I run it on docker container using selenium standalone server receiving the following exception
org.openqa.selenium.InvalidArgumentException: invalid argument: File not found :
Not sure how to resolve it inside the container, I have verified the file is available
The docker compose file Iam using is as follows:
version : '3'
services :
maven:
container_name : Maven-Java
image : maven:3.5.3-jdk-8-alpine
volumes :
- .:/workspace
- ~/.m2:/root/.m2
depends_on :
- selenium
command : mvn -f /workspace test
selenium:
container_name : selenium
image : selenium/standalone-chrome:latest
volumes:
- /dev/shm:/dev/shm
ports :
- 4444:4444
You mounted the volume to container where your test code is running. However you need to mount the volume to the container where the browser is running.
The thing is that when your code says to the web app "hey, this is the file that you need to upload", the test code sends not a file itself but a path that is passed to the browser. Then browser tries to look up that file and build appropriate request to the server.
So the file hast to be within the container where the browser is running.
You need to add a path configuration.
Create a file browsers.json
add this script there
{
"chrome": {
"default": "85.0",
"versions": {
"85.0": {
"image": "selenoid/vnc:chrome_85.0",
"port": "4444",
"volumes": ["/home/ubuntu/your-project:/opt/docker"]
}
}
}
}
and run with this --browsers-json browsers.json argument
this example is for selenoid, but if you don't use selenoid, just add this "volumes": ["/home/ubuntu/your-project:/opt/docker"] to your selenium grid config.
thank you all for the answer's so the working solution I found are two one is as #Alexey mentioned I should also volume map my script folder to the selenium container as well as below:
selenium:
volumes :
- .:/workspace
Above is a docker oriented solution, the other one I found is with selenium grid where the grid can detect the files using a file detector, it can be done by adding the following snipet.
remoteDriver.setFileDetector(new LocalFileDetector());
Both the solutions are working and have solved my problem.

Jenkins pipeline DSL Maven Error due to #tmp dir

I just created a Jenkins Pipeline DSL job where I cloned a Java code from SCM and tried to run mvn clean. But the pipeline continuously throwing an error saying:
mvn clean install -Dmaven.test.skip=true -Dfindbugs.skip=true
/var/lib/jenkins/workspace/<project>#tmp/durable-77d8d13c/script.sh: 2:
/var/lib/jenkins/workspace/<project>#tmp/durable-77d8d13c/script.sh: mvn: not found
Seems like it tries to find pom.xml inside the <project>#tmp directory which is empty. Actual code is cloned successfully inside the <project> directory. Below is my Jenkinsfile:
node {
stage ("Clean Workspace") {
echo "${WORKSPACE}"
cleanWs()
}
stage ("Get Code") {
git branch: "${params.branch}", url: 'git#bitbucket.org:xx/xxxxxxx.git'
}
stage ("mvn clean") {
sh "mvn clean install -Dmaven.test.skip=true -Dfindbugs.skip=true"
}
}
I also tried with ${WORKSPACE} env variable but still does not work.
The issue was resolved, I modified the Pipeline DSL jobs by including Maven tool step as:
stage ("mvn clean") {
withEnv( ["PATH+MAVEN=${tool name: 'mvn', type: 'maven'}/bin"] ) {
sh "mvn clean install -Dmaven.test.skip=true -Dfindbugs.skip=true"
}
}
Instead of doing like that you can directly add mvn to path itself. for that, open your ~/.bash_profile and add these lines.
MAVEN_HOME="<path to maven folder>"
export MAVEN_HOME
PATH=$PATH:$MAVEN_HOME/bin
Don't forget to do source ~/.bash_profile to get the changes. This will provide mvn to path so that you can access mvn directly.
So if you do that your code can be now like...
stage ("mvn clean") {
sh "mvn clean install -Dmaven.test.skip=true -Dfindbugs.skip=true"
}
The error message mvn: not found means that mvn command could not be found by Jenkins pipeline.
You should use a withMaven pipeline step to provide a valid maven environnement.
For example :
node {
stage ("Clean Workspace") {
echo "${WORKSPACE}"
cleanWs()
}
stage ("Get Code") {
git branch: "${params.branch}", url: 'git#bitbucket.org:xx/xxxxxxx.git'
}
stage ("mvn clean") {
withMaven {
sh "mvn clean install -Dmaven.test.skip=true -Dfindbugs.skip=true"
}
}
}
Check that Jenkins is properly configured to use maven (Under 'Manage Jenkins > Configure System') and the 'Pipeline Maven Plugin' is installed (Under 'Manage Jenkins > Manage Plugins').
More information here : https://wiki.jenkins.io/display/JENKINS/Pipeline+Maven+Plugin

Jenkinsfile maven plugin inside a docker container

I'm using Jenkins with a Jenkinsfile that runs my builds inside a docker container. I have a simple Java application that I'd like to build and deploy to artifactory using the Jenkins Artifactory plugin.
My Jenkinsfile is below -
node {
def server = Artifactory.server "my-artifactory"
def rtMaven = Artifactory.newMavenBuild()
stage("Prepare environment"){
docker.image('driv/docker-maven-java-oracle').inside {
checkout scm
stage("Artifactory configuration") {
rtMaven.deployer releaseRepo:'libs-release-local', snapshotRepo:'libs-snapshot-local', server: server
rtMaven.resolver releaseRepo:'libs-release', snapshotRepo:'libs-snapshot', server: server
}
stage("Maven build") {
def buildInfo = rtMaven.run pom: 'pom.xml', goals: 'clean install'
}
}
}
}
However, when I run builds with the above Jenkinsfile I get the error -
java.lang.RuntimeException: Couldn't find maven installation
I know that I can add a line to my Jenkinsfile like this -
rtMaven.tool = MAVEN_TOOL
...that I can use to specify a pre-configured Jenkins Tool to point the Artifactory plugin at Maven. However, it seems to me that such a pre-configured tool would have to be on the Jenkins machine, or a build node, and not inside my docker container.
So, is it possible to point the Artifactory plugin at a maven installation inside my docker container?
Thanks.
This should probably be fixed in their jenkins plugin itself but as "Christopher Orr" suggested mapping environment vars at the pipeline stage level to the same ones set in the container work
For example
stage('mystage') {
environment {
// If your using the official maven image, these are probably where it puts it
MAVEN_HOME = '/usr/share/maven'
JAVA_HOME= '/usr/local/openjdk-8'
}
steps {
sh """
# confirm location of MAVEN_HOME and JAVA_HOME in container and set in environment directive
printenv
"""
...
// call rtMavenRun()

Categories

Resources