I am having a groovy class in file : src/utils/versionUtil.groovy
I am trying to load it in my JenkinsFile but I got this error :
java.nio.file.NoSuchFileException: /var/lib/jenkins/jobs/TEST-web-cyclo-gitflow/workspace/src/utils/versionUtil.groovy
at sun.nio.fs.UnixException.translateToIOException(UnixException.java:86)
at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102)
at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107)
at sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:214)
at java.nio.file.Files.newByteChannel(Files.java:317)
.....etc
Jenkinsfile
node {
stage('helloWorld') {
def VersionUtils = load pwd() + '/src/utils/versionUtil.groovy'
}
}
How to load properly a groovy class in jenkinsFile?
I guess you can use shared libraries for that:
#Library('somelib') import com.mycorp.pipeline.somelib.UsefulClass
Related
I want to read some value(ex. user Login info) from config file in Jenkins pipeline script.
downloaded plugin "Config File Provider Plugin(ver.3.10.0)"
and i create config file.
I want to read that user info (line 2)
anyone have ideas ?
thank you.
Here is how you can use the Config File Provider with a Groovy script. First, you have to load it to your pipeline and then execute it. So for that, you have to restructure your Groovy script as well. Please check the below.
Jenkins Pipeline
pipeline {
agent any
stages {
stage('ConfigTest') {
steps {
configFileProvider([configFile(fileId: '078d4943-231c-4156-9b88-8334cd8a9402', variable: 'GroovyScript')]) {
echo " =========== Reading Groovy Script"
script {
def script = load("$GroovyScript")
script.setProperties()
echo "${USER_ID}"
}
}
}
}
}
}
Content of the Script
import groovy.transform.Field
#Field def USER_ID;
def setProperties() {
USER_ID = "abcd#gmail.com"
}
return this
I have the following script in a .gsh file:
build = Thread.currentThread().executable
String jobName = build.getEnvVars()["JOB_NAME"]
println "JOBNAME: " + jobName
When I execute this script within a normal freestyle project it does work fine in the step Execute system Groovy script output: JOBNAME: playground/Testing.
However if I execute the same script within a pipeline:
stage('Test') {
steps {
script {
jobName = load 'C:/Tools/getTag.gsh'
}
}
}
I do get an RejectedAccessException.
org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: No such field found: field java.lang.Thread executable
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.unclassifiedField(SandboxInterceptor.java:426)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:410)
at org.kohsuke.groovy.sandbox.impl.Checker$7.call(Checker.java:353)
at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:357)
at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.getProperty(SandboxInvoker.java:29)
at com.cloudbees.groovy.cps.impl.PropertyAccessBlock.rawGet(PropertyAccessBlock.java:20)
at Script1.run(Script1.groovy:8)
How can I execute this script within the pipeline?
Notes:
I can't approve it like Jenkins RejectedAccessException as it is already approved and works within the freestyle project.
I'm a total noob with Groovy. For context I have a Jenkins pipeline that uses a deploy.pipeline.groovy script. I also have a test.pipeline.groovy script for git PRs.
I'm trying to reduce duplicated code in both scripts so I created a Globals.groovy script to store my constants and a Functions.groovy script to store reusable functions for both pipeline scripts. All of the files are in the same directory, but I can't figure out how to import my Globals and Functions scripts into the pipeline scripts for use.
My Globals.groovy file is like this:
import groovy.transform.Field
#CompileStatic class Globals {
#Field final String test1 = 'first test'
#Field final String test2 = 'second test'
}
My Functions.groovy file is like this:
#CompileStatic class Functions {
def TestMessage1() { println globals.test1 }
def TestMessage2() { println globals.test2 }
}
Both pipeline scripts have a "Test" stage like so:
def runTests{
stage('Test') {
functions.TestMessage1()
functions.TestMessage1()
}
}
I can't figure out how to import or load my Globals.groovy script into my Functions.groovy script and then my Functions.groovy script into my scripts.
I've tried putting this at the top of my Functions.groovy scripts:
def globals = load('Globals.groovy')
And this at the top of my pipeline scripts
def functions = load('Functions.groovy')
What am I doing wrong?
You can just have functions in your groovy files and need a return at the bottom
Here is my Jenkinsfile:
def pipeline
node('master') {
checkout scm
pipeline = load 'script.groovy'
pipeline.execute()
}
This is my script.groovy (same level as Jenkinsfile in repo)
//import ...
def execute() {
println 'Test'
}
return this
Jenkins job Output:
[Pipeline] load
[Pipeline] { (script.groovy)
[Pipeline] }
[Pipeline] // load
[Pipeline] echo
Test
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
I am trying to run a groovy script in Jenkins slave node to retrieve child jobs from a folder in Jenkins slave node. Here is the groovy script I tried:
I tried some SO answers and found groovy.lang.MissingPropertyException: No such property: jenkins for class: groovy.lang.Binding
But this doesn't solve my problem.
Please find the code that I tried:
import groovy.json.JsonSlurper
import groovy.json.JsonBuilder
import jenkins.model.*
static main(args){
def childJobFolder = "childJob"
def childJobNameList = []
def env = System.getenv()
// Setting the environment properties to variables.
def jenkinsUsername = env.UAT_JENKINS_MY_USER
def jenkinsPassword = env.UAT_JENKINS_MY_PASS
def jsonSlurper = new JsonSlurper()
// Getting the child job names from "childJob" folder
Jenkins.instance.getItemByFullName(childJobFolder).allJobs.each{
def childJobName = it.name.toString()
if(childJobName.startsWith("job-")){
childJobNameList.add(childJobName)
}
}
println "\n" + "Child Jobs Available: " + childJobNameList + "\n"
}
Here is what I got in the console:
Caught: groovy.lang.MissingPropertyException: No such property: Jenkins for class: hudson3067346520259876246
groovy.lang.MissingPropertyException: No such property: Jenkins for class: hudson3067346520259876246
at hudson3067346520259876246.run(hudson3067346520259876246.groovy:17)
Build step 'Execute Groovy script' marked build as failure
Can someone help me to fix this error? Thanks in advance!
Finally, I found out the solution for this error. This is caused by running on plain groovy script instead of system groovy script. As Jayan said the Jenkins variables only available for System groovy scripts and not for plain groovy script. For that reason I could not load Jenkins instances from plain groovy script.
I need to write shared library that reads files in build workspace and shared library functions cannot read files because pipeline is on slave and shared library is executed in master. Is there any way tho change execution context of library functions?
Found out answer. You can read library file and give the file to writeFile pipeline step
writeFile(file:"foo.groovy", text: libraryResource("bar.groovy"))
"groovy foo.groovy"
writeFile neads BOTH parameters as named parameters so answer given in https://issues.jenkins-ci.org/browse/JENKINS-54646 is not fully right.
To execute Jenkins shared library functions on slave instead of master. You can implement de argument node("slaveName") in the call:
def call(Map config=[:], Closure body) {
def label = 'slave'
node("${label}") {
pipeline {
stage('Sonarqube') {
script {
withSonarQubeEnv('Sonar8') {
withMaven(maven: 'apache-maven') {
sh 'mvn sonar:sonar -Dmaven.test.skip=true -Dsonar.java.binaries=./target'
}
}
}
}//pipeline
} // call
You Can actually do it without writeFile, This shared Library Code will be executed in Master, but it will use RemoteDignostic to Execute commands to Slave
to execute uname -a in worker node
import hudson.util.RemotingDiagnostics
import jenkins.model.Jenkins
class test_exec{
def env
def propertiesFilePath
#NonCPS
def call(cmd) {
def trial_script = """
println "uname -a".execute().text
""".trim()
String result
Jenkins.instance.slaves.find { agent ->
agent.name == "${env.NODE_NAME}"
}.with { agent ->
result = RemotingDiagnostics.executeGroovy(trial_script, agent.channel)
}
return result
}
}
In your pipeline
steps{
println(new test_exec().call())
}