jenins grovy to call sh script - jenkins

Hi I have the following groovy script that I want to use to build a project in Jenkins
#!/usr/bin/env groovy
def deploymentPaths = '[]'
pipeline{
agent {
label 'jenkins-agent'
}
stages{
stage('Build debug'){
steps{
sh './make_debug.sh'
}
}
}
}
How can I make it wait till make_debug finishes and print its output? I tried
#!/usr/bin/env groovy
def deploymentPaths = '[]'
pipeline{
agent {
label 'jenkins-agent'
}
stages{
stage('Build debug'){
steps{
def sout = new StringBuilder(), serr = new StringBuilder()
def proc = './make_debug.sh'.execute()
proc.consumeProcessOutput(sout, serr)
proc.waitForOrKill(10000)
println "out> $sout\nerr> $serr"
}
}
}
}
But this doesn't work. Got following errors:
WorkflowScript: 13: Expected a step # line 13, column 7.
def sout = new StringBuilder(), serr = new StringBuilder()
^
WorkflowScript: 13: Expected a step # line 13, column 39.
def sout = new StringBuilder(), serr = new StringBuilder()
^
WorkflowScript: 14: Expected a step # line 14, column 7.
def proc = './make_debug.sh'.execute()
^
WorkflowScript: 15: Method calls on objects not allowed outside "script" blocks. # line 15, column 13.
proc.consumeProcessOutput(sout, serr)
^
WorkflowScript: 16: Method calls on objects not allowed outside "script" blocks. # line 16, column 13.
proc.waitForOrKill(1000)
^
WorkflowScript: 12: Missing required parameter: "delegate" # line 12, column 5.
step{
^
WorkflowScript: 15: Arguments to "error" must be explicitly named. # line 15, column 13.
proc.consumeProcessOutput(sout, serr)
^
WorkflowScript: 16: Expecting "class java.lang.String" but got "1000" of type class java.lang.Integer instead # line 16, column 32.
proc.waitForOrKill(1000)

Related

Jenkins - How to run job only if another job failed for n-times

i want to trigger/start a job (jobB) only if another job (jobA) failed for n-times after the last success.
i saw this parameterized trigger plugin - but for triggers you only can say "Failed" but you can't define whether it should trigger after a failed counter.
Thanks
Chris
here my groovy script thats solved the issue. Used groovy-postbuild plugin to exec the script on jobA. Thanks Ian W for your input.
import hudson.model.*
import jenkins.model.Jenkins
job_name = "jobA"
job_name_to_run = "jobB"
triggerThreshold = 2
last_succ_num = 0
last_job_num = 0
def currentBuild = Thread.currentThread().executable
def job = Hudson.instance.getJob(job_name)
def job_data = Jenkins.instance.getItemByFullName(job.fullName)
println 'Job: ' + job_data.fullName
if (job_data.getLastBuild()) {
last_job_num = job_data.getLastBuild().getNumber()
}
println 'last_job_num: ' + last_job_num
if (job_data.getLastSuccessfulBuild()) {
last_succ_num = job_data.getLastSuccessfulBuild().getNumber()
}
println 'last_succ_num: ' + last_succ_num
doRunJob =(last_job_num - last_succ_num >= triggerThreshold)
println 'do run job? ' + doRunJob
if (doRunJob){
def jobToRun = Hudson.instance.getJob(job_name_to_run)
def cause = new Cause.UpstreamCause(currentBuild)
def causeAction = new hudson.model.CauseAction(cause)
Hudson.instance.queue.schedule(jobToRun, 0, causeAction)
}

Error while trying to capture artifacts in Jenkins

I have been tasked with capturing artifacts in the build process of a Jenkin's build. It is a multi-stage pipeline and I have added, as the last stage, a stage to hopefully accomplish this. I am fairly new to Jenkin's so this may be an obvious error / mistake to more advances users out there.
stage('collect and upload kickstart artifact') {
steps {
def server = Artifactory.server SERVER_ID
def uploadSpec = """{
"files": [
{
"pattern": "ks/*.cfg",
"target": "bin-local-cei/ks/"
},
]
}"""
server.upload(uploadSpec)
def buildInfo = Artifactory.newBuildInfo()
buildInfo.env.capture = true
buildInfo.env.collect()
buildInfo=server.upload(uploadSpec)
server.publishBuildInfo(buildInfo)
}
}
I am getting the following errors ...
WorkflowScript: 117: Expected a step # line 117, column 9.
def server = Artifactory.server SERVER_ID
^
WorkflowScript: 119: Expected a step # line 119, column 9.
def uploadSpec = """{
^
WorkflowScript: 127: Method calls on objects not allowed outside "script" blocks. # line 127, column 9.
server.upload(uploadSpec)
^
WorkflowScript: 129: Expected a step # line 129, column 9.
def buildInfo = Artifactory.newBuildInfo()
^
WorkflowScript: 130: Expected a step # line 130, column 9.
buildInfo.env.capture = true
^
WorkflowScript: 131: Expected a symbol # line 131, column 9.
buildInfo.env.collect()
^
WorkflowScript: 132: Expected a step # line 132, column 9.
buildInfo=server.upload(uploadSpec)
^
WorkflowScript: 133: Method calls on objects not allowed outside "script" blocks. # line 133, column 9.
server.publishBuildInfo(buildInfo)
^
WorkflowScript: 131: Missing required parameter: "message" # line 131, column 9.
buildInfo.env.collect()
^
9 errors
I've dug through blogs, posts, and articles but I am missing something here. Any assistance would be appreciated. Thanks!
you need to add some definitions like, node and script
I'm just not sure if the Artifactory will work, because I dont have this plugin installed.
#!/usr/bin/env groovy
pipeline {
agent none
stages {
stage('collect and upload kickstart artifact') {
steps {
node('master') {
script {
def server = Artifactory.server SERVER_ID
def uploadSpec = """{
"files": [
{
"pattern": "ks/*.cfg",
"target": "bin-local-cei/ks/"
},
]
}"""
server.upload(uploadSpec)
def buildInfo = Artifactory.newBuildInfo()
buildInfo.env.capture = true
buildInfo.env.collect()
buildInfo=server.upload(uploadSpec)
server.publishBuildInfo(buildInfo)
}
}
}
}
}
}

Can groovy string interpolation be nested?

I'm trying to add parameter in Jenkins groovy shell script, then wonder if groovy string interpolation can be used nested way like this.
node{
def A = 'C'
def B = 'D'
def CD = 'Value what I want'
sh "echo ${${A}${B}}"
}
Then what I expected is like this;
'Value what I want'
as if I do;
sh "echo ${CD}"
But it gives some error that $ is not found among steps [...]
Is it not possible?
Like this?
import groovy.text.GStringTemplateEngine
// processes a string in "GString" format against the bindings
def postProcess(str, Map bindings) {
new GStringTemplateEngine().createTemplate(str).make(bindings).toString()
}
node{
def A = 'C'
def B = 'D'
def bindings = [
CD: 'Value what I want'
]
// so this builds the "template" echo ${CD}
def template = "echo \${${"${A}${B}"}}"​
// post-process to get: echo Value what I want
def command = postProcess(template, bindings)
sh command
}
In regard to the accepted answer, if you're putting values in a map anyway then you can just interpolate your [key]:
def A = 'C'
def B = 'D'
def bindings = [ CD: 'Value what I want' ]
bindings["${A}${B}"] == 'Value what I want'
${A}${B} is not a correct groovy syntax.
The interpolation just insert the value of expression between ${}.
Even if you change to the correct syntax and create $ method, the result will not be what you want.
def nested = "${${A}+${B}}"
println nested
static $(Closure closure) { //define $ method
closure.call()
}
CD will be printed.

Jenkins with groovy script

I'm using groovy to get some parameters to run jobs in jenkins.
My question is why script A work's and B and C don't
A
def sout = new StringBuilder(), serr = new StringBuilder()
def proc = 'ls -D --format=single-column /path/folder'.execute()
proc.consumeProcessOutput(sout, serr)
proc.waitForOrKill(1000)
println "out> $sout err> $serr"
return sout.tokenize()
B The \\ is to escape \
def proc = 'find /path/folder/ -type f \\( -iname \\*.ear -o -iname \\*.war \\)'.execute()
proc.consumeProcessOutput(sout, serr)
proc.waitForOrKill(1000)
println "out> $sout err> $serr"
return sout.tokenize()
C script.sh return a list of files
def sout = new StringBuilder(), serr = new StringBuilder()
def proc = '/scripts/script.sh'.execute()
proc.consumeProcessOutput(sout, serr)
proc.waitForOrKill(1000)
println "out> $sout err> $serr"
return sout.tokenize()
There is some jenkins restriction to run scripts from groovy or certainly shell commands?
After a lot of tries I can make this work.
if (Origem.equals('FILE')) {
def cmd = ["/bin/bash","-c","/opt/scripts/SearchPackage.sh"]
def sout = new StringBuffer()
def serr = new StringBuffer()
def proc = cmd.execute()
proc.consumeProcessOutput ( sout, serr )
proc.waitForProcessOutput ()
return sout.tokenize()
}
Groovy was not recognizing the // character as an escape for '/'. I just decide put everything in a shell script and use groovy to call this script. THe problem was solved but if someone has a better aproach I will be glad.

Running a production SPSS job on remote server from command line

We have a Windows based SPSS server say 10.20.30.40. We would like to kick off a SPSS Production job from another server 10.20.30.50.
Can we kick off the job using a batch file?
1.Create an SPJ file in production.
2.make a bat file to run spj
"C:\Program Files\IBM\SPSS\Statistics\21\stats.exe" -production "K:\Meinzer\Production\SPJ\DashBoardInsert.spj"
create a 'scheduled task' in windows.
The real issue is getting your output from the job. for that, i use python.
I use syntax like this
begin program.
AlertDays=4
Files=['k:\meinzer/Production\dashboarddatasets/aod_network_report.sps',
'k:\meinzer/Production\push/aod_network_reportpush.sps',
'k:\meinzer/Production\pushproduction/aod_network_reportpushP.sps']
end program.
insert file='k:/meinzer/production/ps/errorTestPickles.sps'.
to trigger this
*still needs error info passed.
set mprint=off /printback=on.
begin program.
#test files to observe - uncomment out 8 or 9
#Files=['k:\meinzer/Production\dashboarddatasets/test.sps']
#Files=['k:\meinzer/Production\dashboarddatasets/testfail.sps']
#Files=['k:\meinzer/Production\dashboarddatasets/clinfo.sps']
#Files=['k:\meinzer/Production\dashboarddatasets/CSOC_Consecutive_High_Level_Svcs.sps']
import shutil
import spss
import re, os, pickle
from datetime import datetime
def main(Files):
"""The parser and processor for Syntax Error Reporting """
try:
for FilePath in Files:
Start = datetime.now().replace( microsecond=0)
DBname, init_Syntax = init_Vars(FilePath)
cmds = init_cmds(init_Syntax)
cmd=''
cmd2=''
cmd3=''
try:
for cmd in cmds:
cmd=cmd.replace('\r\n','\n ')
cmd=cmd.replace('\t',' ')
print cmd
spss.Submit(cmd)
cmd3=cmd2
cmd2=cmd
# cmd, cmd2, cmd3=run_cmds(cmd,cmd2,cmd3,cmds)
Finish = datetime.now().replace( microsecond=0)
spss_Output(DBname)
SavedNewname=check_saved_new_name(DBname)
if SavedNewname==1:
send_result(DBname,'Failure',Start,Finish,0,cmd,cmd2,cmd3)
break
if SavedNewname==0:
send_result(DBname,'Success',Start,Finish,1,AlertDays)
except Exception,e:
Finish = datetime.now().replace( microsecond=0)
errorLevel, errorMsg = get_spss_error(e)
send_result(DBname,"Failure in code",Start,Finish,0,AlertDays,cmd,cmd2,cmd3,errorLevel, errorMsg )
spss_Output(DBname)
break
except IOError:
print "can't open file or difficulty initializing comands from spss"
send_result('Can not open File %s' % DBname,Start,Finish)
spss_Output(DBname)
def init_Vars(FilePath):
FilePath=FilePath.encode('string-escape')
#FilePath= map(os.path.normpath, FilePath)
FilePath=FilePath.replace('\\','/')
FilePath=FilePath.replace('/x07','/a')
FilePath=FilePath.replace('//','/')
FilePath=FilePath.replace('/x08','/b')
FilePath=FilePath.replace('/x0b','/v')
FilePath=FilePath.replace('/x0c','/v')
print 'this is the file path..................... '+FilePath
DBname = os.path.split(os.path.normpath(FilePath))[-1]
#if '\\' in FilePath:
# DBname=FilePath.rpartition('\\')[-1]
#if '/' in FilePath:
# DBname=FilePath.rpartition('/')[-1]
init_Syntax=FilePath
OutputClose="output close name=%s." % DBname
OutputNew="output new name=%s." % DBname
spss.Submit(OutputClose)
spss.Submit(OutputNew)
return (DBname, init_Syntax)
def init_cmds(init_Syntax):
with open(init_Syntax,'rb') as f:
BOM_UTF8 = "\xef\xbb\xbf"
code = f.read().lstrip(BOM_UTF8)
#r = re.compile('(?<=\.)\s*?^\s*',re.M)
r = re.compile('(?<=\.)\s*?^\s*|\s*\Z|\A\s*',re.M)
cmds = r.split(code)
#cmds = re.split("(?<=\\.)%s[ \t]*" % os.linesep, code, flags=re.M)
#cmds = re.split(r'(?<=\.)[ \t]*%s' % os.linesep, code, flags=re.M)
cmds = [cmdx.lstrip() for cmdx in cmds if not cmdx.startswith("*")]
return cmds
def run_cmds(cmd,cmd2,cmd3,cmds):
for cmd in cmds:
cmd=cmd.replace('\r\n','\n ')
cmd=cmd.replace('\t',' ')
print cmd
spss.Submit(cmd)
cmd3=cmd2
cmd2=cmd
return (cmd, cmd2, cmd3)
def send_result(DBname,result,Start,Finish,status,AlertDays,cmd='',cmd2='',cmd3='',errorLevel='', errorMsg=''):
""" """
print result + ' was sent for '+DBname
FinishText = Finish.strftime("%m-%d-%y %H:%M")
StartText = Start.strftime("%m-%d-%y %H:%M")
Runtimex = str(Finish-Start)[0:7]
error_result="""%s %s
Start Finish Runtime Hrs:Min:Sec
%s %s %s """ % (DBname,result,StartText,FinishText,Runtimex)
error_result_email="""%s <br>
%s <br> Runtime %s <br>\n""" % (result,DBname,Runtimex)
with open("k:/meinzer/production/output/Error Log.txt", "r+") as myfile:
old=myfile.read()
myfile.seek(0)
if status==1:
myfile.write(error_result+"\n\n"+ old)
if status==0:
myfile.write(error_result+'\n'+'This was the problem\n'+errorLevel+" "+ errorMsg+'\n'+cmd3+'\n'+cmd2+'\n'+cmd+"\n\n"+ old)
# with open("k:/meinzer/production/output/email Log.txt", "r+") as emailtext:
# olde=emailtext.read()
# emailtext.seek(0)
# emailtext.write(error_result_email+ olde)
with open("k:/meinzer/production/output/ErrorCSV.txt", "r+") as ErrorCSV:
oldcsv=ErrorCSV.read()
ErrorCSV.seek(0)
ErrorCSV.write(DBname+','+str(status)+','+FinishText+",0"+','+str(AlertDays)+"\n"+ oldcsv)
def check_saved_new_name(DBname):
""" check saved new name"""
with open("k:/meinzer/production/output/text/"+DBname+".txt", "r") as searchfile:
if 'Warning # 5334' in open("k:/meinzer/production/output/text/"+DBname+".txt", "r").read():
SavedNewname=True
else:
SavedNewname=False
return SavedNewname
def get_spss_error(e):
print 'Error', e
errorLevel=str(spss.GetLastErrorLevel())
errorMsg=spss.GetLastErrorMessage()
return (errorLevel, errorMsg)
def spss_Output(DBname):
""" """
outputtext="output export /text documentfile='k:/meinzer/production/output/text/%s.txt'." % DBname
outputspv="output save outfile='k:/meinzer/production/output/%s.spv'." % DBname
spss.Submit(outputspv)
spss.Submit(outputtext)
main(Files)
end program.

Resources