Execute a script from jenkins pipeline - jenkins

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'

Related

User Interactive shell script not running in Jenkinsfile

I have a user interactive shell script that runs successfully on my Linux server. But when I try to run it via jenkins, it doesn't run.
I have created a Jenkinsfile.
Jenkinsfile
node('slaves') {
try
{
def app
stage('Remmove Docker service') {
sh 'sshpass ssh docusr#10.26.13.12 "/path/to/shell/script"'
}
}
}
Shell Script
#!/bin/bash
read -p "Hi kindly enter the api name : " api
docker service logs $api --raw
The shell Scipt runs successfully on my local server, when I try to run it on Jenkins using Jenkinsfile, it doesn't accept $api variable in my shell script which is user interactive.
What you are trying to achieve doesn't serve any purpose of automating your job by jenkins, if I correctly understood. So, your job is actually seeking a user input and it's in best interest to have a parameterized jenkins build in this case.
For your case, you can still give an argument to the sshpass command $api and have it read from the jenkins environment itself Or, better make your jenkins build parameterized and use your user input $api as the parameter.

Redirecting log output of Jenkins Pipeline Docker Plugin

When I run a Jenkins Pipeline Docker Plugin step
docker.image('the-image').inside {
sh 'thing'
doSomeComplexStep()
}
and I want to capture the output of the whole inside block to a log file instead of writing to the Jenkins log, is there any way to do that?
I read the sources of the jenkins pipeline docker plugin without finding anything obvious, but that doesn't mean there's no way.

Copy file from Jenkins master to slave in Pipeline

I have some windows slave at my Jenkins so I need to copy file to them in pipeline. I heard about Copy To Slave and Copy Artifact plugins, but they doesn't have pipeline syntax manual. So I don't know how to use them in pipeline.
Direct copy doesn't work.
def inputFile = input message: 'Upload file', parameters: [file(name: 'parameters.xml')]
new hudson.FilePath(new File("${ENV:WORKSPACE}\\parameters.xml")).copyFrom(inputFile)
This code returns and error:
Caused: java.io.IOException: Failed to copy /var/lib/jenkins/jobs/_dev/jobs/(TEST)job/builds/107/parameters.xml to d:\Jenkins\workspace\_dev\(TEST)job\parameters.xml
Is there any way to copy file from master to slave in Jenkins Pipeline?
As I understand copyFrom is executed on your Windows node, therefore the source path is not accessible.
I think you want to look into the stash/unstash steps (Jenkins Pipeline: Basic Steps), which work across different nodes. Also this example might be helpful.
Pipeline DSL context runs on master node even that your write node('someAgentName') in your pipeline.
Try to use stash/unstash, but it is bad for large files.
Try External Workspace Manager Plugin. It has
pipelines steps and good for large files.
Try to use an intermediate storage. archive() and sh("wget $url") will be helpful.
If the requirement is to copy an executable to the test slave and to publish the test results, this is easy to do without the Copy to Slave plugin.
A shared folder should be created on each test slave (normal Windows shared folder).
After build: Build script copies the executable to the shared directory on each slave. A simple batch script using copy command is sufficient for this.
stage ('Copy to slaves') {
steps {
bat 'call "copy-to-slave.bat"'
}
}
During test: The test script copies the executable to another directory and runs it.
After test: Post-build action "Publish Robot Framework test results" can be used to report the test results. It is not necessary to copy the test result files back to the master first.
I recommend on Pipeline: Phoenix AutoTest plugin
Jenkins plugin website:
https://plugins.jenkins.io/phoenix-autotest/#documentation
GitHub repository of plugin:
https://github.com/jenkinsci/phoenix-autotest-plugin

Jenkins: Running groovy script with ant commands

I have a groovy script with ant commands on it. The script is successfully run in my local machine but when I tried it with Jenkins the groovy script always fail. Jenkins always return error that "ant can't create task or type p4Change". I already added Apache ant support in the global configuration. How do I configure ant to successfully run the groovy script I have. Any idea. Thanks.
Sample code snippets:
I have execute.groovy file with ant commands
ant=new AntBuilder()
def checkChanges {
ant.p4change(description:"Checking",port:'perforce:1666',user:optional,view:"'${workspace}'...")}
And I created a batch file that will run the execute.groovy file
call groovy execute.groovy project bopolz18 -c bopolz18.Workspace 150718
In my machine this works well but in Jenkins when I execute the batch command it fails giving the error mention above.

Execution a deployment script on a remote ssh server through a Jenkins pipeline

I've got a Jenkins pipeline containing stages for source loading, building and deploying on a remote machine through SSH. The problem is about the last one. I saved the script of the following template on the remote server:
#!/bin/bash
bash /<pathTo>/jboss-cli.sh --command="deploy /<anotherPath>/service.war --force"
It works fine if executed in a terminal connected to the remote server.
The best outcome I've received through Jenkins is
/<pathTo>/jboss-cli.sh: line 87: usr/bin/java/bin/java: No such file or directory
in Jenkins console output.
Tried switching between bash and sh, exporting path to java in the pipeline script etc.
Any suggestions are appreciated.
Thanks!
p.s. Execution call from Jenkins looks like:
sh """
ssh -o StrictHostKeyChecking=no $connectionName 'bash /<pathToTheScript>/<scriptName>.sh'
"""
line 87: **usr/bin/java/bin/java**: No such file or directory
As per error line it is considering path from usr not /usr. Can you check if this is what the problem is?
Sorry, I know this should be in comments section but I don't have right to add comments yet.

Resources