How can I get a gradle project.exec or Exec task to not display all information about the commandline?
code
project.exec {
workingDir = exeDir.absolutePath
executable = starter.absolutePath
args = commandLine.split().toList()
environment << envVars
project.logging.captureStandardOutput LogLevel.INFO
standardOutput = outputStream
errorOutput = outputStream
}
output
Starting process 'command 'regexIdentifier''. Working directory:
/home/code/ Command: /home/code/bin/regexIdentifier server username
password ...
Successfully started process 'command '/home/code/bin/regexIdentifier''
I need to execute a cmd with a password via gradle Exec task and want gradle to not display commandline upon execution
You can keep the gradle Exec task from printing output by default by overriding the standardOutput and errorOutput streams
standardOutput = new ByteArrayOutputStream()
errorOutput = new ByteArrayOutputStream()
However, this doesn't prevent the command from showing up when you run with the --info flag.
Related
I am trying to execute a shell scripts in a remote server over ssh using groovy scripts .
Note: Source and Destination servers are passwordless authenticated
Groovy Scripts test.groovy:
def sout = new StringBuffer(), serr = new StringBuffer()
//def proc = "sh test.sh".execute()
def proc = "sh test.sh".execute()
proc.consumeProcessOutput(sout, serr)
println proc
proc.waitForOrKill(1000)
println sout
println serr
def final_output = sout.tokenize()
println final_output
return final_output
and my test.sh contains :
cd /Users/xyz/testing_directory
#show me list of files
ssh xyz#10.56.45.67 'ls'
Now when I execute same using groovy test.groovy then I am not getting any output.
But if I am changing "ssh xyz#10.56.45.67 'ls'" line to only "ls" in test.sh it works and shows me list of files of same source servers .
working example when removing ssh part from test.sh
#show me list of files
ls
Now issue is groovy scripts unable to show outputs while connecting to remote server over ssh
Note : ssh xyz#10.56.45.67 'ls' works fine in jenkins execute shell as well as terminal only not working in groovy scripts
Please help me out and thanks in advance
Finally after hit and trail I got solution .
thanks #daggett
def sout = new StringBuffer(), serr = new StringBuffer()
def proc = "ssh username#10.x.x.xx 'ls'".execute()
proc.waitForProcessOutput(sout, serr)
println proc
proc.waitForOrKill(1000)
println sout
println serr
def final_output = sout.tokenize()
println final_output
return final_output
I have the following task in my build.gradle file:
task myTask(type:Exec) {
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'cmd', '/c', 'whoami'
standardOutput = stdout;
}
println "Output: $stdout"
}
When I run my task with ./gradlew myTask, I get the following output:
> Configure project :
Output: retrovius
> Task :myTask FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':myTask'.
> execCommand == null!
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 2s
1 actionable task: 1 executed
The task successfully outputs my username (retrovius), then fails anyway. Any pointers for what I'm doing wrong?
Depending on what you want to achieve, the answer you found is probably still not correct.
All tasks have two main stages: configuration and execution. Everything you put in the outermost block to the task definition is part of the configuration. And the exec method actually executes the command whenever that block of code is evaluated. So when you type:
task myTask() {
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'cmd', '/c', 'whoami'
standardOutput = stdout;
}
println "Output: $stdout"
}
Then it means you are running the whoami command no matter what task you specify. If you run gradle -i help, it will print the name. I expect this is not what you intend.
Most of the time, you will want to run a command only when the task is actually executed. So if you want the command to only run if you type gradle -i myTask, you will need to do defer it to the execution stage instead. There are two ways you can do that.
Either you can put everything in a doLast block like this:
task myTask() {
doLast {
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'cmd', '/c', 'whoami'
standardOutput = stdout
}
println "Output: $stdout"
}
}
Or you use the Exec type, like you already tried. The reason it didn't work for you is that you need to configure it with the command you like - and not actually run the command through the exec method. It could look like this:
task myTask(type: Exec) {
commandLine 'cmd', '/c', 'whoami'
standardOutput = new ByteArrayOutputStream()
doLast {
println "Output: $standardOutput"
}
}
You an also probably get rid of the cmd /c part. And println should only be used for debugging - use logger.info (or .warn, etc) if you need to output something to the user.
I figured out that the only thing I was doing wrong was to include the (type:Exec) in the definition of my task. If I place the following code in my build.gradle file:
task myTask() {
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'cmd', '/c', 'whoami'
standardOutput = stdout;
}
println "Output: $stdout"
}
I get the following output:
> Configure project :
Output: retrovius
BUILD SUCCESSFUL in 2s
My mistake must have been that I was defining the task to be of type exec, but not giving it a command to run. This reveals a fundamental misunderstanding of the exec task and task type on my part. If anyone knows more specifically what I did wrong, please feel free to comment and explain or post a better answer.
I have a Jenkins scripted pipeline set up where I execute a number of Maven builds. I want to treat one of them as non-fatal if the root cause is a known one.
I have tried to achieve that by inspecting the Exception's message, e.g.
try {
sh "mvn -U clean verify sonar:sonar ${sonarcloudParams}"
} catch ( Exception e ) {
if ( e.getMessage().contains("not authorized to run analysis")) {
echo "Marking build unstable due to missing SonarCloud onboarding. See https://cwiki.apache.org/confluence/display/SLING/SonarCloud+analysis for steps to fix."
currentBuild.result = 'UNSTABLE'
}
}
The problem is that the exception's message is not the one from Maven, but instead "script returned exit code 1".
There is no further information in e.getCause().
How can I access the cause of the Maven build failure inside my scripted pipeline?
You can get the command output, then parse it containers specific message.
def output = sh(
script: "mvn -U clean verify sonar:sonar ${sonarcloudParams}",
returnStdout: true
).trim()
echo "mvn cmd output: ${output}"
if(output.contains('not authorized to run analysis')) {
currentBuild.result = 'UNSTABLE'
}
// parse jenkins job build log
def logUrl = env.BUILD_URL + 'consoleText'
def cmd = "curl -u \${JENKINS_AUTH} -k ${logUrl} | tail -n 50"
def output = sh(returnStdout: true, script: cmd).trim()
echo "job build log: ${output}"
if(output.contains('not authorized to run analysis')) {
currentBuild.result = 'UNSTABLE'
}
One option is to inspect the last log lines using
def sonarCloudNotEnabled = currentBuild.rawBuild.getLog(50).find {
line -> line.contains("not authorized to run analysis")
}
However, this does not work by default. On the Jenkins instance I'm using it errors out with
Scripts not permitted to use method org.jenkinsci.plugins.workflow.support.steps.build.RunWrapper getRawBuild. Administrators can decide whether to approve or reject this signature.
I am making task which runs bash script
task wsUpload(type: Exec) {
commandLine '../scripts/ws_upload.sh ' + rootProject.ext.VERSION_CODE
}
however it returns
Caused by: java.io.IOException: Cannot run program "../scripts/ws_upload.sh 30" .... No such file or directory
if i ran same command without arguments
task wsUpload(type: Exec) {
commandLine '../scripts/ws_upload.sh'
}
then command is executed. What am i doing wrong?
Add args like this
task wsUpload(type: Exec) {
commandLine '../scripts/ws_upload.sh'
args = ["args"]
}
I am using gradle for build and release, so my gradle script executes a shell script. The shell script outputs an ip address which has to be provided as an input to my next gradle ssh task. I am able to get the output and print on the console but not able to use this output as an input to next task.
remotes {
web01 {
def ip = exec {
commandLine './returnid.sh'
}
println ip --> i am able to see the ip address on console
role 'webServers'
host = ip --> i tried referring as $ip '$ip' , both results into syntax error
user = 'ubuntu'
password = 'ubuntu'
}
}
task checkWebServers1 << {
ssh.run {
session(remotes.web01) {
execute 'mkdir -p /home/ubuntu/abc3'
}
}
}
but it results in error "
What went wrong:
Execution failed for task ':checkWebServers1'.
java.net.UnknownHostException: {exitValue=0, failure=null}"
Can anyone please help me use the output variable in proper syntax or provide some hints which could help me.
Thanks in advance
The reason it's not working is the fact, that exec call return is ExecResult (here is it's JavaDoc description) and it's not a text output of the execution.
If you need to get the text output, then you've to specify the standardOutput property of the exec task. This could be done so:
remotes {
web01 {
def ip = new ByteArrayOutputStream()
exec {
commandLine './returnid.sh'
standardOutput = ip
}
println ip
role 'webServers'
host = ip.toString().split("\n")[2].trim()
user = 'ubuntu'
password = 'ubuntu'
}
}
Just note, the ip value by default would have a multiline output, include the command itself, so it has to be parsed to get the correct output, For my Win machine, this could be done as:
ip.toString().split("\n")[2].trim()
Here it takes only first line of the output.