Jenkins Groovy pipeline #tmp dir() AccessDenied exception for createDirectory - jenkins

I'm trying to set-up a simple (single) Groovy pipeline script that would deploy my PHP project using webhooks. Sounds like a simple script and I've had it working in an older Jenkins version (which used bash script) but when I use the dir(String) {} method I get the following exception:
java.nio.file.AccessDeniedException: /srv/www/staging#tmp
at sun.nio.fs.UnixException.translateToIOException(UnixException.java:84)
at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102)
at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107)
at sun.nio.fs.UnixFileSystemProvider.createDirectory(UnixFileSystemProvider.java:384)
at java.nio.file.Files.createDirectory(Files.java:674)
at java.nio.file.Files.createAndCheckIsDirectory(Files.java:781)
at java.nio.file.Files.createDirectories(Files.java:767)
at hudson.FilePath.mkdirs(FilePath.java:3563)
The server itself runs on CentOS 7 and Jenkins is using version 2.303.3. I've added the jenkins user to the apache group, which is the owner+group of the relative webroot, located in /srv/www/staging. The permissions for the /srv/www and /srv/www/staging directories are set to 0773 apache:apache.
When I simulate a bash session with user jenkins using su -s /bin/bash jenkins, I am able to create directories and files within the /srv/www/staging directory - without any issue. So I'm wondering how the pipeline itself doesn't have permissions to do so!..
The pipeline script is as follows:
pipeline {
agent any
stages {
stage('Git Pull') {
steps {
sh "whoami"
dir ('/srv/www/staging') {
sh "pwd"
}
}
}
}
}
The sh "whoami" returns jenkins, so I'm sure the proper user is executing the commands.
I can't really find a descriptive similar issue, thus why I'm posting this.
Hopefully someone is able to guide me in the right direction.

Related

current working directory in Jenkins pipeline script

I want to do SCP from Windows Jenkins node to Linux server. In this set up, Windows machine is a Jenkins slave and the target server where i want to copy is Linux.
Below is my Jenkins pipeline script
stage('SCP JAR file') {
steps {
bat 'scp c:\\Jenkins\\workspace\\migration\\test-project\\build\\libs\\ssupservice-0.0.1-SNAPSHOT.jar rxp096p#server:/home/rxp096p/testing'
}
}
}
Above script works but we need to use ${env.WORKSPACE} as the current directory might change.So i tried below
bat 'scp ${env.WORKSPACE}\\build\\libs\\ssupservice-0.0.1-SNAPSHOT.jar
rxp096p#server:/home/rxp096p/testing'
But it gives me error ${env.WORKSPACE}/build/libs/ssupservice-0.0.1-SNAPSHOT.jar no such file or directory.
It seems single quote used after bat command is not interpolating the Jenkins environment variable (env.WORKSPACE).
Please change
bat 'scp ${env.WORKSPACE}\\build\\libs\\ssupservice-0.0.1-SNAPSHOT.jar rxp096p#server:/home/rxp096p/testing'
to
bat "scp ${env.WORKSPACE}\\build\\libs\\ssupservice-0.0.1-SNAPSHOT.jar rxp096p#server:/home/rxp096p/testing"

'Cannot run program "docker"' when using withDockerRegistry in Declarative Jenkins Pipeline

I'm in the middle of refactoring our old scripted jenkins pipeline and am trying to take advantage of the nice jenkins declarative syntax.
However I'm having issue trying to authenticate with our private docker registry.
The resources online tell me this should work:
steps {
sh 'docker -v'
withDockerRegistry([url: DOCKER_REGISTRY_URL, credentialsId: DOCKER_REGISTRY_CREDENTIALS]) {
pushDockerImage()
}
}
The first line, "docker -v", executes correctly and the current docker version is printed out.
However when it tries to execute "withDockerRegistry" it fails with:
Cannot run program "docker": error=2, No such file or directory
Do I have the syntax wrong or am I missing some sort of global config?
Cheers,
Add a toolName to the withDockerRegistry:
withDockerRegistry(registry: [url: DOCKER_REGISTRY_URL, credentialsId: DOCKER_REGISTRY_CREDENTIALS], toolName: 'docker')
Also setup docker in Global Tool Configuration.

Jenkins error "No such property: docker for class: groovy.lang.Binding"

I'm trying to follow this tutorial to create a simple docker environment in as part of my Jenkins pipeline build.
I'm trying to build a couple of Docker images just as a test before I do my maven build. At the moment I have the following Groovy for my Jenkinsfile:
#!groovy
node {
stage 'Building docker env'
def dbImage = docker.build('oracle', 'docker/oracle')
def wlpImage = docker.build('liberty', 'docker/liberty')
stage 'Running maven build'
git url: 'https://mysite/myproject.git', branch: 'docker'
def mvnHome = tool 'maven 3.3.9'
sh "${mvnHome}/bin/mvn -B clean install"
}
I'm trying to have the Docker build look in the directory "docker/oracle" and call the Dockerfile in that directory, and build the Docker images named oracle, and liberty. At the moment though it's giving me this error:
Running on master in /root/.jenkins/workspace/pipeline_test
[Pipeline] {
[Pipeline] stage (Building docker env)
Using the ‘stage’ step without a block argument is deprecated
Entering stage Building docker env
Proceeding
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
groovy.lang.MissingPropertyException: No such property: docker for class: groovy.lang.Binding
at groovy.lang.Binding.getVariable(Binding.java:63)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:224)
at org.kohsuke.groovy.sandbox.impl.Checker$4.call(Checker.java:241)
at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:238)
at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:221)
at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.getProperty(SandboxInvoker.java:28)
at com.cloudbees.groovy.cps.impl.PropertyAccessBlock.rawGet(PropertyAccessBlock.java:20)
...
Any ideas what could be the problem with the docker build command I'm using? (or could it be something I forgot to install in Jenkins?)
The issue was I needed to install the Docker Pipeline plugin in Jenkins.
To install the plugin using the GUI:
Dashboard > Manage Jenkins > Manage Plugins > Available (tab) > docker-workflow.
As Pete says you will have to install the Docker Pipeline plugin. You can do that though the Jenkins UI.
Maybe I'm missing some part of your code, but where do you define the docker? If that's the complete Groovy script, you're trying to bind a variable which isn't declared anything, so it's not to weird that it fails, right?
Just define a docker it that's what you want, like:
def docker = "my docker" // something similar like this
And it will at-least resolve your missing property exception.
Whenever we see the error like below :
groovy.lang.MissingPropertyException: No such property:
It means , groovey script did not able to find the property mentioned post the colon sign : , so we need to either define the user defined variable/property or use the correct one from API.
If you have this issue:
groovy.lang.MissingPropertyException: No such property: docker for class: groovy.lang.Binding.
We most likely encountered the same issue, in order to fix it I only had to install the Docker Pipeline plugin in Jenkins, so all you have to do is go to:
Jenkins Homepage > Manage Jenkins > Manage Plugins > Available
Search for Docker Pipeline install it restart jenkins and you are ready to go.
For more info about Docker Pipeline Plugin Scripts click here.
I had the same issue but after I installed the Docker Pipeline plugin as #Affes Salem suggested it is working now.

Execute a script from jenkins pipeline

I have a jenkins pipeline that builds a java artifact,
copies it to a directory and then attempts to execute a external script.
I am using this syntax within the pipeline script to execute the external script
dir('/opt/script-directory') {
sh './run.sh'
}
The script is just a simple docker build script, but the build will fail
with this exception:
java.io.IOException: Failed to mkdirs: /opt/script-directory#tmp/durable-ae56483c
The error is confusing because the script does not create any directories. It is just building a docker image and placing the freshly built java artifact in that image.
If I create a different job in jenkins that executes the external script as
its only build step and then call that job from my pipeline script using this syntax:
build 'docker test build'
everything works fine, the script executes within the other job and the pipeline
continues as expected.
Is this the only way to execute a script that is external to the workspace?
What am I doing wrong with my attempt at executing the script from within
the pipeline script?
The issue is that the jenkins user (or whatever the user is that runs the Jenkins slave process) does not have write permission on /opt and the sh step wants to create the script-directory#tmp/durable-ae56483c sub-directory there.
Either remove the dir block and use the absolute path to the script:
sh '/opt/script-directory/run.sh'
or give write permission to jenkins user to folder /opt (not preferred for security reasons)
Looks like a bug in Jenkins, durable directories are meant to store recovery information e.g. before executing an external script using sh.
For now all you can do is make sure that /opt/script-directory has +r +w and +x set for jenkins user.
Another workaround would be not to change the current directory, just execute sh with it:
sh '/opt/script-directory/run.sh'
I had a similar concern when trying to execute a script in a Jenkins pipeline using a Jenkinsfile.
I was trying to run a script restart_rb.sh with sudo.
To run it I specified the present working directory ($PWD):
sh 'sudo sh $PWD/restart_rb.sh'

Why won't groovy run in Jenkins pipeline?

I am currently trying to run a groovy script from my pipeline as one of my nodes, but I ran into this error:
[CompanyName] Running shell script
+ ./ideainspect.groovy
env: groovy: No such file or directory
Also, I tried installing the plugin for groovy, but for some reason, it won't install. Whenever I refresh the page for tools, the installer goes away. Am I installing groovy wrong? Please help!
Edit: Relevant Data
stage 'Static Analysis'
node {
dir("Android/btMobileApp") {
sh "./ideainspect.groovy"
sh "./gradlew checkstyle lintDebug"
}
}
And the ideainspect.groovy file is an executable with the shebang #!/usr/bin/env groovy, which could be the problem.
Does your jenkins user have groovy on its path? If so ditch the shebang and try
sh 'groovy ideainspect.groovy'
If it's not on the path, you can try
sh '/usr/bin/groovy ideainspect.groovy'
(or wherever groovy is installed)
Or alternatively add it to the path environment variable using Manage Jenkins -> Configure Systems. This may not be appropriate if you have lots of projects using different versions of groovy

Resources