Created
April 2, 2012 19:09
-
-
Save mheiges/2286418 to your computer and use it in GitHub Desktop.
Groovy build step for puppet-client-manager
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Groovy script for Jenkins' puppet-client-manager job | |
to trigger downstream execution of puppet clients. | |
https://ci.apidb.org/job/puppet-client-manager | |
*/ | |
import hudson.model.* | |
import hudson.FilePath | |
import hudson.FilePath.FileCallable | |
import hudson.remoting.VirtualChannel | |
import java.io.OutputStream | |
/* **************************************************************************************** | |
CONFIGURATION | |
/* **************************************************************************************** */ | |
// replace this hard-coded list with a lookup from <somewhere> | |
def hosts = [ | |
"apricot.rcc.uga.edu", | |
"aprium.rcc.uga.edu", | |
"ares1.pcbi.upenn.edu", | |
/** "ares2.pcbi.upenn.edu", | |
"ares3.pcbi.upenn.edu", | |
"blender.pcbi.upenn.edu", | |
"caper.rcc.uga.edu", | |
"cassini.pcbi.upenn.edu", | |
"exocarp.rcc.uga.edu", | |
"gattaca.pcbi.upenn.edu", | |
"grapple.ovpr.uga.edu", | |
"lexicon1.pcbi.upenn.edu", | |
"loquat.rcc.uga.edu", | |
"mango.ctegd.uga.edu", | |
"medlar.rcc.uga.edu", | |
"meme.pcbi.upenn.edu", | |
"olive.rcc.uga.edu", | |
"pitaya.rcc.uga.edu", **/ | |
"rubus.rcc.uga.edu" | |
] | |
// Downstream jobs having a name of downstreamProjectNamePrefix + host will be run | |
def downstreamProjectNamePrefix = "puppet-run-" | |
// Checkbox parameter in the project that runs this script. If true, this script | |
// will run downstream jobs for each host listed above. | |
def runParamName = "Run_client_jobs" | |
// Build summary goes in notesFilName to be picked up by the show-build-notes plugin | |
def notesFileName = "jenkins-run-notes.html" | |
/* **************************************************************************************** */ | |
def upstreamBuild = Thread.currentThread().executable | |
def params = upstreamBuild.getAction(hudson.model.ParametersAction.class) | |
if (params == null) { | |
println "This does not look like a parameterized job. I'm expecting a parameter named " + | |
runParamName + ". Quiting." | |
return false | |
} | |
def runClients = params.createVariableResolver(upstreamBuild).resolve(runParamName) | |
if (runClients == null) { | |
println "I did not find a parameter named " + runParamName + ". Quiting." | |
return false | |
} | |
def futureMap = [:] | |
def workspace = upstreamBuild.workspace | |
// standard file writes occur on the master where this groovy script actually runs. To write to | |
// the slave's workspace, we use jenkins' FilePath remoting feature. | |
def notesFilePath = new FilePath(workspace.getChannel(), workspace.getRemote() + "/" + notesFileName) | |
def loginfo = new StringBuilder() | |
if ( runClients != "true" ) { | |
println runParamName + " is false. No client jobs run" | |
return // (do not System.exit(), that causes Jenkins process to exit) | |
} | |
def jenkins = hudson.model.Hudson.instance | |
def template = jenkins.getItem("puppet-run-template") | |
for (host in hosts) { | |
def downstreamProjectName = downstreamProjectNamePrefix + host | |
def downstreamProject = jenkins.getJob(downstreamProjectName) | |
// Create project if needed | |
if (downstreamProject == null ) { | |
println "Creating new downstream job, " + downstreamProjectName | |
downstreamProject = jenkins.copy(template, downstreamProjectName) | |
downstreamProject.setDescription("runs puppetd on " + host) | |
downstreamProject.save() | |
downstreamProject.enable() | |
} | |
// only FreeStyle projects with desired name prefix, excluding template | |
if ( ! (downstreamProject instanceof hudson.model.FreeStyleProject)) { continue } | |
if ( ! downstreamProjectName.startsWith(downstreamProjectNamePrefix)) { continue } | |
if (downstreamProjectName.equals(downstreamProjectNamePrefix + "template")) { continue } | |
if (downstreamProject.disabled) { | |
println downstreamProjectName + "is disabled. Skipping." | |
continue | |
} | |
future = downstreamProject.scheduleBuild2(0, new Cause.UpstreamCause( upstreamBuild )) | |
futureMap[downstreamProjectName] = future | |
println "Queued " + downstreamProjectName | |
} | |
println "waiting for downstream jobs to complete\n" | |
/** loop over Future jobs in queue, reporting results as | |
builds are completed | |
**/ | |
while (futureMap.size() > 0) { | |
sleep(2000) | |
iterator = futureMap.entrySet().iterator() | |
while (iterator.hasNext()) { | |
entry = iterator.next() | |
future = entry.value | |
if ( ! future.isDone()) { | |
continue | |
} | |
downstreamBuild=future.get() | |
if (downstreamBuild.result.isWorseThan(Result.SUCCESS)) { | |
upstreamBuild.setResult(Result.UNSTABLE) | |
} | |
// this goes in a file for use by show-build-notes plugin | |
loginfo = loginfo.append(makeSummaryNotes()) | |
// this prints to the Console | |
println hudson.console.HyperlinkNote.encodeTo("/" + downstreamBuild.getUrl() + "console", | |
downstreamBuild.getFullDisplayName() ) + " " + " at " + downstreamBuild.time + " - " + downstreamBuild.result | |
iterator.remove() | |
} | |
} | |
notesFilePath.write(loginfo.toString(), "UTF-8") | |
/** | |
* returns HTML formatted notes | |
**/ | |
def makeSummaryNotes() { | |
def color = "black" | |
if (downstreamBuild.result.equals(Result.FAILURE)) { | |
color = "red" | |
} | |
def name = downstreamBuild.getFullDisplayName(); | |
// client host name and build number from string like "puppet-run-ares1.pcbi.upenn.edu #30" | |
def client = name.tokenize("-").get(2) | |
return "<a href='/" + downstreamBuild.getUrl() + "console'>" + | |
client + "</a> " + | |
" - <font color='" + color + "'>" + downstreamBuild.result + "</font><br>\n" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment