bicepjai
bicepjai

Reputation: 1665

In jenkins job, create file using system groovy in current workspace

my task is to collect node details and list them in certail format. I need to write data to a file and save it as csv file and attach it as artifacts. But i am not able to create a file using groovy scripts in the jenkins using plugin "Execute System Groovy" as build step

import jenkins.model.Jenkins
import hudson.model.User
import hudson.security.Permission
import hudson.EnvVars

EnvVars envVars = build.getEnvironment(listener);

filename = envVars.get('WORKSPACE') + "\\node_details.txt";
//filename = "${manager.build.workspace.remote}" + "\\node_details.txt"
targetFile = new File(filename);
println "attempting to create file: $targetFile"

if (targetFile.createNewFile()) {
    println "Successfully created file $targetFile"
} else {
    println "Failed to create file $targetFile"
}
print "Deleting ${targetFile.getAbsolutePath()} : "
println targetFile.delete()

Output obtained

attempting to create file: /home/jenkins/server-name/workspace/GET_NODE_DETAILS\node_details.txt
FATAL: No such file or directory
java.io.IOException: No such file or directory
    at java.io.UnixFileSystem.createFileExclusively(Native Method)
    at java.io.File.createNewFile(File.java:947)
    at java_io_File$createNewFile.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:42)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:112)
    at Script1.run(Script1.groovy:13)
    at groovy.lang.GroovyShell.evaluate(GroovyShell.java:682)
    at groovy.lang.GroovyShell.evaluate(GroovyShell.java:666)
    at hudson.plugins.groovy.SystemGroovy.perform(SystemGroovy.java:81)
    at hudson.tasks.BuildStepMonitor$1.perform(BuildStepMonitor.java:20)
    at hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:772)
    at hudson.model.Build$BuildExecution.build(Build.java:199)
    at hudson.model.Build$BuildExecution.doRun(Build.java:160)
    at hudson.model.AbstractBuild$AbstractBuildExecution.run(AbstractBuild.java:535)
    at hudson.model.Run.execute(Run.java:1732)
    at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:43)
    at hudson.model.ResourceController.execute(ResourceController.java:88)
    at hudson.model.Executor.run(Executor.java:234)

Some time i see people use "manager" object, how can i get access to it ? Alos any ideas on how to accomplish the task ?

Upvotes: 23

Views: 65843

Answers (5)

Abdessamad DH
Abdessamad DH

Reputation: 1

I tried to use the solution in a pipeline and i got : hudson.remoting.ProxyException: groovy.lang.MissingPropertyException: No such property: build for class: WorkflowScript

This issue is caused by executing a plain Groovy script instead of a system Groovy script.

Some predefined variables from Groovy plugin (build; launcher; listener; out) are only accessible within system Groovy scripts, not plain Groovy scripts.

Upvotes: 0

gaoithe
gaoithe

Reputation: 4358

The manager object is not available depending on how the groovy is invoked. e.g. in "execute system groovy script".

You can find the BadgeManager class in jenkins GroovyPostBuild plugin API here: https://javadoc.jenkins.io/plugin/groovy-postbuild/org/jvnet/hudson/plugins/groovypostbuild/GroovyPostbuildRecorder.BadgeManager.html#addShortText-java.lang.String-

ANSWER: Import the GroovyPostBuild plugin and create a new manager object. e.g. here a job with "Execute System Groovy Script" create a manager object and call the addShortText method:

// java.lang.Object
// org.jvnet.hudson.plugins.groovypostbuild.GroovyPostbuildRecorder.BadgeManager
// Constructor and Description
// BadgeManager(hudson.model.Run<?,?> build, hudson.model.TaskListener listener, hudson.model.Result scriptFailureResult) 

import hudson.model.*
import org.jvnet.hudson.plugins.groovypostbuild.GroovyPostbuildAction

def build = Thread.currentThread().executable

manager = new org.jvnet.hudson.plugins.groovypostbuild.GroovyPostbuildRecorder.BadgeManager(build, null, null)
manager.addShortText("MANAGER TEST", "black", "limegreen", "0px", "white")

This question gives a hint: See here for a nearly working answer: In jenkins job, create file using system groovy in current workspace org.jvnet.hudson.plugins.groovypostbuild.GroovyPostbuildAction and build.getActions().add(GroovyPostbuildAction.createShortText(text, "black", "limegreen", "0px", "white"));

Upvotes: 0

mainframer
mainframer

Reputation: 22069

I suspect the error was caused by the path format, could you try below:

change

filename = envVars.get('WORKSPACE') + "\\node_details.txt";

to

filename = envVars.get('WORKSPACE') + "/node_details.txt";

Because when I tried in my local jenkins server, I get it successfully executed.

enter image description here

enter image description here

Upvotes: 0

Satish Gupta
Satish Gupta

Reputation: 1467

Answer by @Larry Cai covers one part to write a file to slave node from System Groovy Script (as it runs on Master Node).

The part I am answering is "Some time i see people use "manager" object, how can i get access to it " This is the object already available in Post Build Groovy Script for accessing a lot of things like environment variables, Build Status, Build Display Name etc.

Quoted from https://wiki.jenkins-ci.org/display/JENKINS/Groovy+Postbuild+Plugin :

"The groovy script can use the variable manager, which provides various methods to decorate your builds. Those methods can be classified into whitelisted methods and non-whitelisted methods."

To access it, we can directly call it in the post build groovy script. e.g

manager.build.setDescription("custom description") manager.addShortText("add your message here")

All methods available on manager objects are documented here.

https://wiki.jenkins-ci.org/display/JENKINS/Groovy+Postbuild+Plugin#GroovyPostbuildPlugin-Whitelistedmethods

Upvotes: 0

Larry Cai
Larry Cai

Reputation: 59943

Problem Groovy system script is always run in jenkins master node, while the workspace is the file path in your jenkins slave node, which doesn't exist in your master node.

You can verify by the code

theDir = new File(envVars.get('WORKSPACE'))
println theDir.exists()

It will return false

If you don't use slave node, it will return true

Solution As we can't use normal File, we have to use FilePath http://javadoc.jenkins-ci.org/hudson/FilePath.html

if(build.workspace.isRemote())
{
    channel = build.workspace.channel;
    fp = new FilePath(channel, build.workspace.toString() + "/node_details.txt")
} else {
    fp = new FilePath(new File(build.workspace.toString() + "/node_details.txt"))
}

if(fp != null)
{
    fp.write("test data", null); //writing to file
} 

Then it works in both case.

Upvotes: 63

Related Questions