├── managed-scripts
├── ruby
│ └── README.md
├── shell
│ ├── README.md
│ ├── installManagedJDK.sh
│ └── provision_jenkins.sh
├── groovy
│ ├── README.md
│ ├── enableShallowCloneOnAllAbstractProjects.groovy
│ ├── enableShallowCloneOnAllWorkflowProjects.groovy
│ └── enableShallowCloneOnAllWorkflowMultiBranchProjects.groovy
└── python
│ ├── README.md
│ └── gen-dep-graph
│ ├── project.properties
│ ├── gen-dep-graph.py
│ ├── screenshots
│ └── output.svg
│ └── LICENSE.txt
├── .gitignore
├── scriptler
├── checkPluginUpdateServer.groovy
├── clearBuildQueue.groovy
├── purgeOldBuilds.groovy
├── workspace-cleaner.groovy
├── deleteAllGlobalCredentials.groovy
├── wipeout-workspace.groovy
├── countExecutors.groovy
├── disableAllJobs.groovy
├── buildJobsMatchingPattern.groovy
├── README.md
├── zipFolder.groovy
├── disableAllJobsInAllFolders.groovy
├── showAgentJavaVersion.groovy
├── listAllBuilds.groovy
├── bulkDeleteBuilds.groovy
├── getJavaSecurityAlgorithmReport.groovy
├── jobExecutedInDateRange.groovy
├── purgeM2Repo.groovy
├── showJavaVersionUseOnJob.groovy
├── restartDeadExecutors.groovy
├── checkDiskUsage.groovy
├── configMavenAutoInstaller.groovy
├── getGitPollingRepositories.groovy
├── disableJobsInFolder.groovy
├── reloadJobConfig.groovy
├── findRunningPipelineJobs.groovy
├── purgeDockers.groovy
├── addAnsiColorToAllJobs.groovy
├── trigger-via-snapshot-deps.groovy
├── addGitCleanCheckout.groovy
├── pluglist_print.groovy
├── listdisabledjobs.groovy
├── addCredentials.groovy
├── disableEnableJobsMatchingPattern.groovy
├── interruptPollingThreads.groovy
├── BulkDeleteViews.groovy
├── addCredentialsToFolder.groovy
├── disableAutomaticMavenArchiving.groovy
├── findOfflineSlaves.groovy
├── addShellPreBuildStepToProject.groovy
├── testMetaFormat.groovy
├── warn-if-looped-triggers.groovy
├── updateJobParameterDefinition.groovy
├── discardOldBuilds.groovy
├── vaultAppRoleCredential.groovy
├── vaultTokenCredential.groovy
├── hashifyAllScmTriggers.groovy
├── checkNodesLauncherVersion.groovy
├── bulkDeleteJenkinsBuildsExceptOne.groovy
├── bulkDeleteJobs.groovy
├── changeCredentialPassword.groovy
├── changeSecretText.groovy
├── jMavenMultiModuleProjectBuildsCleaner.groovy
├── deleteBuildLogHistory.groovy
├── searchJobConfiguration.groovy
├── getNextBuildNumbers.groovy
├── addSlackNotification-1.8.groovy
├── jira-publisher.groovy
├── disableBrokenJobs.groovy
├── setNextBuildNumbers.groovy
├── listEC2Instances.groovy
├── show-labels-overview.groovy
├── injectAndManipulateBuildParameters.groovy
├── clonebranches.groovy
├── pluginManagerSimpleReport.groovy
├── trigger-manipulator.groovy
├── checkSSLConnection.groovy
├── disableSlaveNodeStartsWith.groovy
├── barchartGitTagList.groovy
├── removeInvalidCredentials.groovy
├── updateEmailAddress.groovy
├── removeGitPluginBuildsByBranchBuildData.groovy
├── export-role-strategy-permissions-to-csv.groovy
├── svnChangeBranch.groovy
├── pluginDependenciesReport.groovy
├── disableAndCleanUpOldJobs.groovy
├── addJabberNotification.groovy
├── jMavenMultiModuleJobsDisasterRecovery.groovy
└── downloadRemoteWorkspace.groovy
└── README.md
/managed-scripts/ruby/README.md:
--------------------------------------------------------------------------------
1 | # Ruby Jenkins scripts
2 |
3 | Scripts for Jenkins written in Ruby.
4 |
--------------------------------------------------------------------------------
/managed-scripts/shell/README.md:
--------------------------------------------------------------------------------
1 | # Shell Jenkins scripts
2 |
3 | Scripts for Jenkins written in shell.
4 |
--------------------------------------------------------------------------------
/managed-scripts/groovy/README.md:
--------------------------------------------------------------------------------
1 | # Groovy Jenkins scripts
2 |
3 | Scripts for Jenkins written in Groovy.
4 |
--------------------------------------------------------------------------------
/managed-scripts/python/README.md:
--------------------------------------------------------------------------------
1 | # Python Jenkins scripts
2 |
3 | Scripts for Jenkins written in Python.
4 |
--------------------------------------------------------------------------------
/managed-scripts/python/gen-dep-graph/project.properties:
--------------------------------------------------------------------------------
1 | [jenkins]
2 | url=http://ci.jenkins-ci.org/api/python
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | #
3 | # eclipse meta data
4 | #
5 | /.project
6 | /.classpath
7 | /.settings
8 |
9 | # Mac OSX
10 | .DS_Store
11 |
12 | # IDEA IntelliJ
13 | .idea
--------------------------------------------------------------------------------
/scriptler/checkPluginUpdateServer.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Check Update Server",
3 | "comment" : "check Plugin Update Server - workaround for JENKINS-27694",
4 | "parameters" : [],
5 | "core": "1.300",
6 | "authors" : [
7 | { name : "Radek Antoniuk" }
8 | ]
9 | } END META**/
10 |
11 | import jenkins.model.*
12 |
13 | Jenkins j = Jenkins.getInstance()
14 | j.pluginManager.doCheckUpdatesServer()
15 |
--------------------------------------------------------------------------------
/scriptler/clearBuildQueue.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Clear build queue",
3 | "comment" : "If you accidently trigger a lot of unneeded builds, it is useful to be able to cancel them all",
4 | "parameters" : [],
5 | "core": "1.300",
6 | "authors" : [
7 | { name : "Niels Harremoes" }
8 | ]
9 | } END META**/
10 | import hudson.model.*
11 | def queue = Hudson.instance.queue
12 | println "Queue contains ${queue.items.length} items"
13 | queue.clear()
14 | println "Queue cleared"
15 |
--------------------------------------------------------------------------------
/scriptler/purgeOldBuilds.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Purge Old Builds",
3 | "comment" : "Runs the log rotator for each job, purging old builds if needed.",
4 | "parameters" : [],
5 | "core": "1.409",
6 | "authors" : [
7 | { name : "Andrew Bayer" }, { name : "Sam Gleske" }
8 | ]
9 | } END META**/
10 |
11 | import hudson.model.Job
12 | import jenkins.model.Jenkins
13 |
14 | Jenkins.instance.getAllItems(Job.class).findAll { it.hasProperty('logRotator') && it.logRotator != null }.each { job ->
15 | job.logRotate()
16 | }
17 |
--------------------------------------------------------------------------------
/scriptler/workspace-cleaner.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Workspace Cleaner",
3 | "comment" : "This script will go through all workspaces for any/all jobs and remove them.",
4 | "parameters" : [],
5 | "core": "1.300",
6 | "authors" : [
7 | { name : "EJ Ciramella" }
8 | ]
9 | } END META**/
10 |
11 | import hudson.FilePath;
12 |
13 | for (slave in hudson.model.Hudson.instance.slaves)
14 | {
15 | FilePath fp = slave.createPath(slave.getRootPath().toString() + File.separator + "workspace");
16 | fp.deleteRecursive();
17 | }
--------------------------------------------------------------------------------
/scriptler/deleteAllGlobalCredentials.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Delete all global credentials",
3 | "comment" : "Delete all global credentials in Jenkins",
4 | "parameters" : [],
5 | "core": "1.625",
6 | "authors" : [
7 | { name : "Amit Modak" }
8 | ]
9 | } END META**/
10 |
11 | import com.cloudbees.plugins.credentials.domains.Domain
12 |
13 | def credentialsStore = jenkins.model.Jenkins.instance.getExtensionList('com.cloudbees.plugins.credentials.SystemCredentialsProvider')[0].getStore()
14 |
15 | allCreds = credentialsStore.getCredentials(Domain.global())
16 | allCreds.each{
17 | credentialsStore.removeCredentials(Domain.global(), it)
18 | }
19 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # jenkins-scripts
2 |
3 | This is a collection of utility scripts for use with
4 | [Jenkins](http://jenkins-ci.org), the leading continuous integration
5 | server.
6 |
7 | They can cover a range of use cases - automating Jenkins management,
8 | end-user tools, etc. They're organized by function
9 |
10 | - [Scriptler](https://wiki.jenkins-ci.org/display/JENKINS/Scriptler+Plugin)
11 | scripts, for use in the Jenkins Plugin, are in the "scriptler"
12 | directory and should follow the convention as described in [scriptler README.md](scriptler/README.md)
13 | - and other scripts are in the "managed-scripts" directory,
14 | and then organized by scripting language.
15 |
--------------------------------------------------------------------------------
/scriptler/wipeout-workspace.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Wipeout Workspace",
3 | "comment" : "This script will go through all workspaces for all jobs and wipe them.",
4 | "parameters" : [ 'dryRun' ],
5 | "core": "1.499",
6 | "authors" : [
7 | { name : "Vincent Dupain" }
8 | ]
9 | } END META**/
10 | // For each project
11 | jenkins.model.Jenkins.instance.getAllItems(hudson.model.AbstractProject).each { job ->
12 | if (job.building) {
13 | println "Skipping job $job.name, currently building"
14 | } else {
15 | println "Wiping out workspace of $job.name"
16 | if (dryRun != 'true') {
17 | job.doDoWipeOutWorkspace()
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/scriptler/countExecutors.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Count executors",
3 | "comment" : "Shows the total number of nodes and executors on Jenkins",
4 | "parameters" : [ ],
5 | "core": "1.350",
6 | "authors" : [
7 | { name : "Andy Pemberton" }
8 | ]
9 | } END META**/
10 | import jenkins.model.Jenkins
11 |
12 | println("All Nodes - executor count:")
13 | println()
14 | Jenkins.instance.computers.eachWithIndex() { c, i -> println " [${i+1}] ${c.displayName}: ${c.numExecutors}" };
15 | println()
16 | println("Total nodes: [" + Jenkins.instance.computers.size() + "]")
17 | println("Total executors: [" + Jenkins.instance.computers.inject(0, {a, c -> a + c.numExecutors}) + "]")
--------------------------------------------------------------------------------
/scriptler/disableAllJobs.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "disable all jobs",
3 | "comment" : "disables all jobs",
4 | "parameters" : [],
5 | "core": "1.300",
6 | "authors" : [
7 | { name : "Nicolas Mommaerts" }
8 | ]
9 | } END META**/
10 | import hudson.model.*
11 |
12 |
13 | disableChildren(Hudson.instance.items)
14 |
15 | def disableChildren(items) {
16 | for (item in items) {
17 | if (item.class.canonicalName != 'com.cloudbees.hudson.plugins.folder.Folder') {
18 | item.disabled=true
19 | item.save()
20 | println(item.name)
21 | } else {
22 | disableChildren(((com.cloudbees.hudson.plugins.folder.Folder) item).getItems())
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/scriptler/buildJobsMatchingPattern.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Build Jobs Matching Pattern",
3 | "comment" : "Find all jobs with names matching the given pattern and builds them.",
4 | "parameters" : [ "jobPattern" ],
5 | "core": "1.409",
6 | "authors" : [
7 | { name : "Kristian Kraljic" }
8 | ]
9 | } END META**/
10 |
11 | import jenkins.model.*
12 | import hudson.model.*
13 |
14 | // Pattern to search for. Regular expression.
15 | //def jobPattern = "some-pattern-.*"
16 |
17 | def matchedJobs = Jenkins.instance.items.findAll { job ->
18 | job.name =~ /$jobPattern/
19 | }
20 |
21 | matchedJobs.each { job ->
22 | println "Scheduling matching job ${job.name}"
23 | job.scheduleBuild(new Cause.UserIdCause())
24 | }
--------------------------------------------------------------------------------
/managed-scripts/groovy/enableShallowCloneOnAllAbstractProjects.groovy:
--------------------------------------------------------------------------------
1 | import hudson.model.AbstractProject
2 | import hudson.plugins.git.GitSCM
3 | import hudson.plugins.git.extensions.impl.*
4 |
5 | Jenkins.instance.getAllItems(AbstractProject.class)
6 | .findAll { job -> job.isBuildable()}
7 | .findAll { job -> job.scm != null && job.scm instanceof GitSCM}
8 | .each { project ->
9 | scm = project.scm
10 |
11 | cloneOption = scm.extensions.find {it instanceof CloneOption}
12 | if (!cloneOption) {
13 | scm.extensions.add(new CloneOption(true, false, "", 10))
14 | } else {
15 | scm.extensions.remove(cloneOption)
16 | scm.extensions.add(new CloneOption(true, cloneOption.noTags, cloneOption.reference, cloneOption.timeout))
17 | }
18 |
19 | project.save()
20 | }
21 | null
--------------------------------------------------------------------------------
/scriptler/README.md:
--------------------------------------------------------------------------------
1 | # Scriptler scripts
2 |
3 | Groovy scripts in this directory are made available via the
4 | [Scriptler](https://wiki.jenkins-ci.org/display/JENKINS/Scriptler+Plugin)
5 | catalog to be published at jenkins-ci.org.
6 |
7 | In order for a script to be included in the catalog, metadata
8 | describing it must be included in its file, like the below:
9 |
10 | /*** BEGIN META {
11 | "name" : "Hello World example",
12 | "comment" : "print some cool stuff",
13 | "parameters" : [],
14 | "core": "1.300",
15 | "authors" : [
16 | { name : "Joe Bloggs" }
17 | ]
18 | } END META**/
19 | println("hello world")
20 |
21 |
22 | To validate the format of the META information, please run the provided script:
23 |
24 | &> groovy testMetaFormat.groovy
25 |
--------------------------------------------------------------------------------
/managed-scripts/groovy/enableShallowCloneOnAllWorkflowProjects.groovy:
--------------------------------------------------------------------------------
1 | import org.jenkinsci.plugins.workflow.job.WorkflowJob
2 | import hudson.plugins.git.GitSCM
3 | import hudson.plugins.git.extensions.impl.*
4 |
5 | Jenkins.instance.getAllItems(WorkflowJob.class)
6 | .each { project ->
7 | if (project.definition.class.toString() == 'class org.jenkinsci.plugins.workflow.multibranch.SCMBinder') return
8 | scm = project.definition.scm
9 |
10 | cloneOption = scm.extensions.find {it instanceof CloneOption}
11 | if (!cloneOption) {
12 | scm.extensions.add(new CloneOption(true, false, "", 10))
13 | } else {
14 | scm.extensions.remove(cloneOption)
15 | scm.extensions.add(new CloneOption(true, cloneOption.noTags, cloneOption.reference, cloneOption.timeout))
16 | }
17 | project.save()
18 | }
19 | null
--------------------------------------------------------------------------------
/scriptler/zipFolder.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "zip a folder",
3 | "comment" : "zip a folder using AntBuilder",
4 | "parameters" : [],
5 | "core": "1.300",
6 | "authors" : [
7 | { name : "Thomas Froehlich - mail@thomas-froehlich.net" }
8 | ]
9 | } END META**/
10 |
11 | import hudson.model.*
12 |
13 | // get current thread / Executor
14 | def thr = Thread.currentThread()
15 | // get current build
16 | def build = thr?.executable
17 |
18 | def resolver = build.buildVariableResolver
19 | def destinationFile = resolver.resolve("DESTINATION_FILE")
20 | def sourceFolder = resolver.resolve("SOURCE_FOLDER")
21 |
22 | File f = new File(destinationFile);
23 | if(f.exists() && !f.isDirectory()) {
24 | f.delete();
25 | }
26 |
27 | (new AntBuilder()).zip(destfile: destinationFile, basedir: sourceFolder)
28 |
--------------------------------------------------------------------------------
/scriptler/disableAllJobsInAllFolders.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Disable all jobs in all folders",
3 | "comment" : "Disables all jobs in all folders in your Jenkins server",
4 | "parameters" : [],
5 | "core": "1.300",
6 | "authors" : [
7 | { name : "Christian Haeussler - https://github.com/cniweb" }
8 | ]
9 | } END META**/
10 | import hudson.model.*
11 |
12 | disableChildren(Hudson.instance.items)
13 |
14 | def disableChildren(items) {
15 | for (item in items) {
16 | if (item.class.canonicalName != 'com.cloudbees.hudson.plugins.folder.Folder') {
17 | item.disabled=true
18 | item.save()
19 | println(item.name)
20 | } else {
21 | disableChildren(((com.cloudbees.hudson.plugins.folder.Folder) item).getItems())
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/scriptler/showAgentJavaVersion.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Show Agent Java Version",
3 | "comment" : "It lists name and java version installed on each Agents",
4 | "parameters" : [],
5 | "core": "1.609",
6 | "authors" : [
7 | { name : "Ben Walding (kuisathaverat)" }
8 | ]
9 | } END META**/
10 |
11 | import hudson.model.Node
12 | import hudson.model.Slave
13 | import jenkins.model.Jenkins
14 |
15 | Jenkins jenkins = Jenkins.instance
16 | for (Node node in jenkins.nodes) {
17 | // Make sure slave is online
18 | if (!node.toComputer().online) {
19 | println "Node '$node.nodeName' is currently offline - skipping check"
20 | continue;
21 | } else {
22 | props = node.toComputer().getSystemProperties();
23 | println "Node '$node.nodeName' is running " + props.get('java.runtime.version');
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/scriptler/listAllBuilds.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "List all builds from all jobs",
3 | "comment" : "List all builds from all jobs in your Jenkins server",
4 | "parameters" : [],
5 | "core": "1.300",
6 | "authors" : [
7 | { name : "Christian Haeussler - https://github.com/cniweb" }
8 | ]
9 | } END META**/
10 | import hudson.model.*
11 | def items = Hudson.instance.allItems
12 |
13 | items.each { item ->
14 |
15 | if (item instanceof Job) {
16 |
17 | def builds = item.getBuilds()
18 |
19 | builds.each { build ->
20 | def since = groovy.time.TimeCategory.minus( new Date(), build.getTime() )
21 | def status = build.getBuildStatusSummary().message
22 | println "Build: ${build} | Since: ${since} | Status: ${status}"
23 | }
24 | }
25 | }
26 | return
27 |
--------------------------------------------------------------------------------
/scriptler/bulkDeleteBuilds.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Bulk Delete Builds",
3 | "comment" : "For a given job and a given range of possible build numbers, delete those builds.",
4 | "parameters" : [ 'jobName', 'buildRange' ],
5 | "core": "1.409",
6 | "authors" : [
7 | { name : "Andrew Bayer" }
8 | ]
9 | } END META**/
10 |
11 |
12 | // NOTE: uncomment parameters below if not using Scriptler >= 2.0, or if you're just pasting
13 | // the script in manually.
14 |
15 | // The name of the job.
16 | //def jobName = "some-job"
17 |
18 | // The range of build numbers to delete.
19 | //def buildRange = "1-5"
20 |
21 | import jenkins.model.*;
22 | import hudson.model.Fingerprint.RangeSet;
23 | def j = jenkins.model.Jenkins.instance.getItem(jobName);
24 |
25 | def r = RangeSet.fromString(buildRange, true);
26 |
27 | j.getBuilds(r).each { it.delete() }
28 |
29 |
30 |
--------------------------------------------------------------------------------
/scriptler/getJavaSecurityAlgorithmReport.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Get java security algorithms",
3 | "comment" : "Report disabled and supported java security algorithms",
4 | "parameters" : [ ],
5 | "core": "1.609",
6 | "authors" : [
7 | { name : "Allan Burdajewicz" }
8 | ]
9 | } END META**/
10 |
11 | import java.security.Provider
12 | import java.security.Security
13 |
14 | //Check disabled algorithms
15 | println "Disabled Algorithms:\n jdk.tls.disabledAlgorithms=${Security.getProperty("jdk.tls.disabledAlgorithms")}"
16 |
17 | //Check all supported algorithms
18 | println "\nSupported Algorithms"
19 | for (Provider provider : Security.getProviders()) {
20 | println(" Provider: " + provider.getName())
21 | for (Provider.Service service : provider.getServices()) {
22 | println(" Type: ${service.getType()} - Algorithm: ${service.getAlgorithm()}")
23 | }
24 | }
--------------------------------------------------------------------------------
/scriptler/jobExecutedInDateRange.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "List executed Jobs",
3 | "comment" : "List Jobs executed in a range of time",
4 | "core": "1.609",
5 | "authors" : [
6 | { name : "Kuisathaverat" }
7 | ]
8 | } END META**/
9 |
10 | jenkins = Jenkins.instance
11 |
12 | Calendar after = Calendar.getInstance()
13 | Calendar before = Calendar.getInstance()
14 | //set(int year, int month, int date, int hourOfDay, int minute,int second)
15 | after.set(2016,1,5,0,0,0)
16 | before.set(2016,1,23,0,0,0)
17 | println "Jobs executed between " + after.getTime() + " - " + before.getTime()
18 |
19 | for (job in jenkins.getAllItems(Job.class)) {
20 | for(Run run in job.getBuilds()){
21 | if (run.getTimestamp()?.before(before) && run.getTimestamp()?.after(after)) {
22 | println "" + run.getResult() + " " + job.name + " " + job.getLastBuild().getTime()
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/scriptler/purgeM2Repo.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Purge M2 repo",
3 | "comment" : "remove specified packages from m2 repo. Pass parameters to narrow down what's deleted: 'com.example.package1 com.example.package2'",
4 | "parameters" : ["packages"],
5 | "core": "1.300",
6 | "authors" : [
7 | { name : "Emily Bache" }
8 | ]
9 | } END META**/
10 |
11 | def env = System.getenv()
12 | def home = env["HOME"]
13 | def m2_home = "${home}/.m2"
14 | if (env["M2_HOME"]) {
15 | m2_home = env["M2_HOME"]
16 | }
17 |
18 | List packageList = [""]
19 |
20 | if (packages) {
21 | packageList = packages.split().collect(new ArrayList()) {p -> p.replace(".", "/")}
22 | }
23 |
24 |
25 | def mvnDirsToDelete = packageList.collect(new ArrayList()) { p -> new File("${m2_home}/repository/${p}")}
26 |
27 | mvnDirsToDelete.each { dir -> dir.deleteDir() }
28 | mvnDirsToDelete.each { dir -> println("deleted dir: ${dir} ${!dir.exists()}")}
29 |
30 | true
--------------------------------------------------------------------------------
/scriptler/showJavaVersionUseOnJob.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Show Java Version of job",
3 | "comment" : "Show Java Version used on job",
4 | "parameters" : [],
5 | "core": "1.609",
6 | "authors" : [
7 | { name : "kuisathaverat" }
8 | ]
9 | } END META**/
10 |
11 | import com.cloudbees.hudson.plugins.folder.Folder
12 | import hudson.triggers.TimerTrigger
13 | import jenkins.model.Jenkins
14 | import hudson.model.AbstractProject
15 |
16 | findAllItems(Jenkins.instance.items)
17 |
18 | def findAllItems(items){
19 | items.each{
20 | if (!(it instanceof Folder)) {
21 | if(it instanceof AbstractProject && !it.disabled && it.getJDK()) {
22 | println 'Job : ' + it.getName() + ' - Name : ' + it.getJDK().getName() + ' - Home : ' + it.getJDK().getHome()
23 | println it.getJDK().getProperties()
24 | }
25 | } else {
26 | findAllItems(((Folder) it).getItems())
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/scriptler/restartDeadExecutors.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Restart Dead Executors",
3 | "comment" : "Search for dead executors and throws away them and get a new ones.",
4 | "core": "1.609",
5 | "authors" : [
6 | { name : "Kuisathaverat" }
7 | ]
8 | } END META**/
9 |
10 | import hudson.model.Node
11 | import jenkins.model.Jenkins
12 |
13 | Jenkins jenkins = Jenkins.instance
14 | for (Node node in jenkins.nodes) {
15 | // Make sure slave is online
16 | if (!node.toComputer().online) {
17 | println "Node '$node.nodeName' is currently offline - skipping check"
18 | } else {
19 | props = node.toComputer().getSystemProperties();
20 | println "Node '$node.nodeName' is running ";
21 | //check if has executors dead
22 | for (Executor ex : node.toComputer().getExecutors()){
23 | Throwable cause = ex.getCauseOfDeath()
24 | if(cause instanceof Throwable){
25 | println '[Dead]' + cause
26 | ex.doYank()
27 | }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/scriptler/checkDiskUsage.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Check Disk Usage",
3 | "comment" : "put disk usage info and check used percentage.",
4 | "parameters" : [ "root", "threshold" ],
5 | "core": "1.300",
6 | "authors" : [
7 | { name : "ITO Hayato" }
8 | ]
9 | } END META**/
10 | columns = ["path","size","used","free","used%"]
11 | println columns.join("\t")
12 |
13 | result = true;
14 |
15 | File.listRoots().each{
16 | if (!"".equals(root) && !root.equals(it.getAbsolutePath())) return
17 | percent = Math.ceil((it.getTotalSpace() - it.getFreeSpace()) * 100 / it.getTotalSpace())
18 | columns = []
19 | columns << it.getAbsolutePath()
20 | columns << Math.ceil(it.getTotalSpace() /1024/1024)
21 | columns << Math.ceil((it.getTotalSpace() - it.getFreeSpace()) /1024/1024)
22 | columns << Math.ceil(it.getFreeSpace() /1024/1024)
23 | columns << percent + "%"
24 |
25 | println columns.join("\t")
26 |
27 | if (percent >= Double.valueOf(threshold)) { result = false }
28 | }
29 |
30 | return result
31 |
32 |
--------------------------------------------------------------------------------
/managed-scripts/groovy/enableShallowCloneOnAllWorkflowMultiBranchProjects.groovy:
--------------------------------------------------------------------------------
1 | import org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject
2 | import jenkins.plugins.git.traits.CloneOptionTrait
3 | import hudson.plugins.git.extensions.impl.CloneOption
4 |
5 | Jenkins.instance.getAllItems(AbstractItem.class)
6 | .findAll {it instanceof WorkflowMultiBranchProject}
7 | .each { project ->
8 | sources = project.sources.find {it.source instanceof jenkins.plugins.git.GitSCMSource}
9 | traits = sources.source.traits
10 | cloneOptionTrait = traits.findAll {it instanceof CloneOptionTrait}
11 |
12 | if (!cloneOptionTrait) {
13 | traits.add(new CloneOptionTrait(new CloneOption(true, false, "", 10)))
14 |
15 | } else {
16 | cloneOption = cloneOptionTrait.extension.find {it instanceof CloneOption}
17 | traits.removeIf {it instanceof CloneOptionTrait}
18 | traits.add(new CloneOptionTrait(new CloneOption(true, cloneOption.noTags, cloneOption.reference, cloneOption.timeout)))
19 | }
20 | project.save()
21 | }
22 |
23 | null
--------------------------------------------------------------------------------
/scriptler/configMavenAutoInstaller.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Configure Maven Auto Installer",
3 | "comment" : "Configure maven auto-installer in Jenkins global configuration",
4 | "parameters" : [],
5 | "core": "1.625",
6 | "authors" : [
7 | { name : "Amit Modak" }
8 | ]
9 | } END META**/
10 |
11 | import hudson.tasks.Maven.MavenInstallation;
12 | import hudson.tools.InstallSourceProperty;
13 | import hudson.tools.ToolProperty;
14 | import hudson.tools.ToolPropertyDescriptor;
15 | import hudson.util.DescribableList;
16 |
17 | def mavenDesc = jenkins.model.Jenkins.instance.getExtensionList(hudson.tasks.Maven.DescriptorImpl.class)[0]
18 |
19 | def isp = new InstallSourceProperty()
20 | def autoInstaller = new hudson.tasks.Maven.MavenInstaller("3.3.3")
21 | isp.installers.add(autoInstaller)
22 |
23 | def proplist = new DescribableList, ToolPropertyDescriptor>()
24 | proplist.add(isp)
25 |
26 | def installation = new MavenInstallation("M3", "", proplist)
27 |
28 | mavenDesc.setInstallations(installation)
29 | mavenDesc.save()
30 |
--------------------------------------------------------------------------------
/scriptler/getGitPollingRepositories.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Get all Polling Repos",
3 | "comment" : "Print all the Git branches and repositories of jobs that have polling configured",
4 | "parameters" : [ ],
5 | "core": "1.609",
6 | "authors" : [
7 | { name : "Allan Burdajewicz" }
8 | ]
9 | } END META**/
10 |
11 | import hudson.model.AbstractProject
12 | import hudson.plugins.git.GitSCM
13 | import hudson.triggers.SCMTrigger
14 | import jenkins.model.Jenkins
15 |
16 | def activeJobs = Jenkins.instance.getAllItems(AbstractProject.class)
17 | .findAll { job -> job.isBuildable()}
18 | .findAll { job -> job.getTrigger(SCMTrigger)}
19 | .findAll { job -> job.scm != null && job.scm instanceof GitSCM}
20 | .collect();
21 |
22 | for (project in activeJobs) {
23 | scm = project.scm;
24 | println("${project.name}: " +
25 | "repositories: ${scm.repositories.collectMany{ it.getURIs() }}" +
26 | ", branches: ${scm.branches.collect{ it.name }}" +
27 | ", cronTab: ${project.getTrigger(SCMTrigger.class).getSpec()}")
28 | }
--------------------------------------------------------------------------------
/scriptler/disableJobsInFolder.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Disable All Jobs In Folder",
3 | "comment" : "Disable all the buildable projects inside a Folder (full name must be provided)",
4 | "parameters" : [ 'folderFullName' ],
5 | "core": "1.609",
6 | "authors" : [
7 | { name : "Allan Burdajewicz" }
8 | ]
9 | } END META**/
10 |
11 | import com.cloudbees.hudson.plugins.folder.AbstractFolder
12 | import hudson.model.AbstractProject
13 | import jenkins.model.Jenkins
14 |
15 | // I want to disable jobs
16 | def disableJobs = { println "Disabling '${it.fullName}'"; it.disable() }
17 |
18 | //Function to retrieve all buildable Project in a specific Folder
19 | def doAllItemsInFolder(folderName, closure) {
20 | AbstractFolder folder = Jenkins.instance.getAllItems(AbstractFolder.class)
21 | .find {folder -> folderName == folder.fullName };
22 |
23 | folder.getAllJobs()
24 | .findAll {job -> job instanceof AbstractProject}
25 | .findAll {job -> job.isBuildable()}
26 | .each {closure(it)};
27 | }
28 |
29 | doAllItemsInFolder("${folderFullName}", disableJobs);
--------------------------------------------------------------------------------
/scriptler/reloadJobConfig.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "reload job config",
3 | "comment" : "Reload the job config of a specific job.",
4 | "parameters" : [],
5 | "core": "1.300",
6 | "authors" : [
7 | { name : "Thomas Froehlich - mail@thomas-froehlich.net" }
8 | ]
9 | } END META**/
10 |
11 |
12 | import java.io.InputStream;
13 | import java.io.FileInputStream
14 | import java.io.File;
15 | import javax.xml.transform.stream.StreamSource
16 |
17 | def hudson = hudson.model.Hudson.instance;
18 | //def env = System.getenv();
19 | //def toBeCopiedJobName = env['JOB_NAME_TO_REPORT_FOR'];
20 | String toBeCopiedJobName = "copiedJob";
21 |
22 | //to get a single job
23 | //def job = hudson.model.Hudson.instance.getItem('my-job');
24 |
25 | for(job in hudson.model.Hudson.instance.items) {
26 |
27 | if (job.name == toBeCopiedJobName) {
28 |
29 | def configXMLFile = job.getConfigFile();
30 | def file = configXMLFile.getFile();
31 |
32 | InputStream is = new FileInputStream(file);
33 |
34 | job.updateByXml(new StreamSource(is));
35 | job.save();
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/scriptler/findRunningPipelineJobs.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Find running pipeline jobs.",
3 | "comment" : "Find all pipeline jobs running for at least a given amount of time (delay).",
4 | "parameters" : [],
5 | "core": "1.612.1",
6 | "authors" : [
7 | { name : "Arnaud Héritier" }
8 | ]
9 | } END META**/
10 |
11 | import groovy.time.*
12 |
13 | def abortJobs = false
14 |
15 | use(TimeCategory) {
16 |
17 | def delay = 1.day
18 |
19 | println "List of running jobs : "
20 | Jenkins.instance.getAllItems(org.jenkinsci.plugins.workflow.job.WorkflowJob).each{
21 | job -> job.builds.findAll{it.isBuilding() && new Date(it.startTimeInMillis) < ( new Date() - delay ) }.each{
22 | build ->
23 | TimeDuration duration = TimeCategory.minus(new Date(), new Date(build.startTimeInMillis))
24 | println "* $job.fullName#$build.number started since $duration"
25 | if ( abortJobs ) {
26 | build.finish(hudson.model.Result.ABORTED, new java.io.IOException("Aborting build"))
27 | println "* $job.fullName#$build.number aborted"
28 | }
29 | }
30 | }
31 | }
32 | return;
33 |
--------------------------------------------------------------------------------
/scriptler/purgeDockers.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Purge Dockers",
3 | "comment" : "stop and remove all docker containers, remove all dangling and SNAPSHOT images.",
4 | "parameters" : [],
5 | "core": "1.300",
6 | "authors" : [
7 | { name : "Emily Bache" }
8 | ]
9 | } END META**/
10 |
11 |
12 | def env = System.getenv()
13 |
14 | if (env["DOCKER_HOST"]) {
15 | println("This script will not work without a properly set up docker environment. Please define the environment variable 'DOCKER_HOST'")
16 | false
17 | } else {
18 | runningDockers = "docker ps -q".execute().text.split(/\n/)
19 | runningDockers.each {id -> println("docker stop ${id}".execute().text)}
20 |
21 | stoppedDockers = "docker ps -a -f status=exited -q".execute().text.split(/\n/)
22 | stoppedDockers.each {id -> println("docker rm ${id}".execute().text)}
23 |
24 | dockerImages = "docker images".execute().text.split(/\n/)
25 | snapshotImages = dockerImages.findAll{ it.contains("SNAPSHOT") || it.contains("") }
26 | snapshotImages.each {output -> println("docker rmi ${output.split()[2]}".execute().text)}
27 |
28 | true
29 | }
30 |
--------------------------------------------------------------------------------
/scriptler/addAnsiColorToAllJobs.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Add AnsiColor to all jobs",
3 | "comment" : "Add AnsiColor to all jobs",
4 | "parameters" : [ 'colorMapName' ],
5 | "core": "1.409",
6 | "authors" : [
7 | { name : "Owen Wood" }
8 | ]
9 | } END META**/
10 |
11 | import jenkins.model.*
12 | import hudson.model.*
13 | import hudson.util.*
14 | import hudson.tasks.*
15 | import hudson.maven.*
16 | import hudson.plugins.ansicolor.AnsiColorBuildWrapper
17 |
18 | colorMapName = colorMapName ?: "xterm"
19 |
20 | Jenkins.instance.getAllItems(Job.class)
21 | .findAll { it instanceof FreeStyleProject || it instanceof MavenModuleSet }
22 | .findAll { ! it.buildWrappersList.collect {it.class}.contains(AnsiColorBuildWrapper.class) }
23 | .each {
24 |
25 | println "${it.fullName} - ${it.class}"
26 |
27 | def buildWrappers = new DescribableList>()
28 | buildWrappers.add(new AnsiColorBuildWrapper(colorMapName, 0, 0))
29 |
30 | buildWrappers.addAll(it.getBuildWrappersList())
31 | it.getBuildWrappersList().clear()
32 | it.getBuildWrappersList().addAll(buildWrappers)
33 |
34 | it.save()
35 | }
36 |
--------------------------------------------------------------------------------
/scriptler/trigger-via-snapshot-deps.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Trigger via Snapshot",
3 | "comment" : "This script will make sure ALL of your maven jobs are triggered by builds on any snapshot dependencies. There is a basic example of how to exclude jobs by name in the top of this script.",
4 | "parameters" : [],
5 | "core": "1.300",
6 | "authors" : [
7 | { name : "EJ Ciramella" }
8 | ]
9 | } END META**/
10 |
11 | import hudson.model.*
12 |
13 | for(item in Hudson.instance.items)
14 | {
15 | // Don't run if the projet is a sonar call AND if the job isn't a maven 2/3 job
16 | if(!item.getDisplayName().contains("sonar") && item.getDescriptor().getDisplayName().contains("Build a maven2"))
17 | {
18 | println("-----------------------------------------------");
19 | println(item.getDisplayName());
20 | println(item.getDescriptor().getDisplayName());
21 | println(item.getApi().getDisplayName());
22 | println(item.ignoreUpstremChanges());
23 | println(item.getBuildTriggerUpstreamProjects().size());
24 | item.setIgnoreUpstremChanges(false);
25 | println("-----------------------------------------------");
26 | }
27 | }
--------------------------------------------------------------------------------
/scriptler/addGitCleanCheckout.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "add git clean before checkout",
3 | "comment" : "This script will add git clean after checkout to all Jenkins items ",
4 | "parameters" : [],
5 | "authors" : [
6 | { name : "Zamir Ivry - zamir.ivry@gmail.com" }
7 | ]
8 | } END META**/
9 |
10 | for(item in Hudson.instance.items) {
11 | println item.getSCMs();
12 | for(scm in item.getSCMs())
13 | {
14 | if(scm instanceof hudson.plugins.git.GitSCM)
15 | {
16 | es = scm.getExtensions()
17 | if(hasCheckOutPlugin(es, b))
18 | {
19 | println "already exists in " + item.getName()
20 | continue;
21 | }
22 | println "adding clean to " + item.getName()
23 | es.add(new hudson.plugins.git.extensions.impl.CleanCheckout())
24 | item.save()
25 | }
26 | }
27 | }
28 |
29 | private java.lang.Boolean hasCheckOutPlugin(es, java.lang.Boolean b) {
30 | for(s in es) {
31 | if(s instanceof hudson.plugins.git.extensions.impl.CleanCheckout) {
32 | return true;
33 | }
34 | }
35 | return false;
36 | }
37 |
--------------------------------------------------------------------------------
/scriptler/pluglist_print.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "plugins lister",
3 | "comment" : "print list of plugins (optionally set build.displayName)",
4 | "parameters" : [],
5 | "core": "0.601",
6 | "authors" : [
7 | { name : "Mark Hudson" }
8 | ]
9 | } END META**/
10 |
11 | def pcount = 0 ; def pstr = ''
12 | def plist = jenkins.model.Jenkins.instance.pluginManager.plugins
13 |
14 | plist.sort{it} // plugins list `it` defaults to shortName
15 |
16 | plist.each {
17 | pcount = pcount + 1
18 | pname = (pcount + ' ' + it).replaceAll("Plugin:", '')
19 | pstr = pstr + ' ' + pname + ' ' + it.getVersion() + "\n" // + "
"
20 | }
21 |
22 | println pstr // Console Output
23 |
24 | if ( "executable" in Thread.currentThread().getProperties() ) {
25 | // print Thread.currentThread().getProperties()
26 | def manager_build = Thread.currentThread().executable ; assert manager_build // non-Postbuild context
27 | manager_build.displayName = "#" + manager_build.number + " had " + pcount + " plugins"
28 | } else { // Pipeline Workflow DSL
29 | // currentBuild.displayName = "#" + currentBuild.number + " had " + pcount + " plugins"
30 | def skipForNow = "fixLater"
31 | }
32 |
33 | return
34 |
35 |
--------------------------------------------------------------------------------
/scriptler/listdisabledjobs.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "List Disabled Jobs",
3 | "comment" : "This script came about because there were many jobs that were disabled and interlaced between active jobs in the hundreds. If you don't want to set up a new view that lists out just the disabled (or never run) jobs, this is a quick fix that will provide counts at the end of the run.",
4 | "parameters" : [],
5 | "core": "1.300",
6 | "authors" : [
7 | { name : "EJ Ciramella" }
8 | ]
9 | } END META**/
10 |
11 | import hudson.model.*
12 |
13 | int nonbuildable = 0;
14 | int buildable = 0;
15 | for (item in Hudson.instance.items)
16 | {
17 | buildable++
18 | if(!item.buildable)
19 | {
20 | //println(item.name + " " + "\"" + item.lastBuild + "\"");
21 | if(item.lastBuild != null && item.lastBuild.time != "")
22 | {
23 | println(item.name + " " + item.lastBuild.time);
24 | }
25 | else
26 | {
27 | println(item.name + " " + "Never Built")
28 | }
29 | nonbuildable++
30 | }
31 | }
32 | println(nonbuildable)
33 | println(buildable)
34 | int merge = 0;
35 | for (item in Hudson.instance.items)
36 | {
37 | if(item.name.contains("erge"))
38 | {
39 | println(item.name + " active=" + item.buildable);
40 | merge++
41 | }
42 | }
43 | println(merge);
44 |
--------------------------------------------------------------------------------
/scriptler/addCredentials.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "add credentials",
3 | "comment" : "Sample groovy script to add credentials to Jenkins",
4 | "core": "1.609",
5 | "authors" : [
6 | { name : "Kuisathaverat" }
7 | ]
8 | } END META**/
9 |
10 | import com.cloudbees.plugins.credentials.impl.*;
11 | import com.cloudbees.plugins.credentials.*;
12 | import com.cloudbees.plugins.credentials.domains.*;
13 |
14 | String keyfile = "/tmp/key"
15 |
16 | Credentials c = (Credentials) new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL,java.util.UUID.randomUUID().toString(), "description", "user", "password")
17 |
18 |
19 | def ksm1 = new CertificateCredentialsImpl.FileOnMasterKeyStoreSource(keyfile)
20 | Credentials ck1 = new CertificateCredentialsImpl(CredentialsScope.GLOBAL,UUID.randomUUID().toString(), "description", "password", ksm1)
21 |
22 | def ksm2 = new CertificateCredentialsImpl.UploadedKeyStoreSource(keyfile)
23 | Credentials ck2 = new CertificateCredentialsImpl(CredentialsScope.GLOBAL,UUID.randomUUID().toString(), "description", "password", ksm2)
24 |
25 | SystemCredentialsProvider.getInstance().getStore().addCredentials(Domain.global(), c)
26 | SystemCredentialsProvider.getInstance().getStore().addCredentials(Domain.global(), ck1)
27 | SystemCredentialsProvider.getInstance().getStore().addCredentials(Domain.global(), ck2)
28 |
--------------------------------------------------------------------------------
/scriptler/disableEnableJobsMatchingPattern.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Disable/Enable Jobs Matching Pattern",
3 | "comment" : "Find all jobs with names matching the given pattern and either disables or enables them, depending on the flag.",
4 | "parameters" : [ 'jobPattern', 'disableOrEnable' ],
5 | "core": "1.409",
6 | "authors" : [
7 | { name : "Andrew Bayer" }
8 | ]
9 | } END META**/
10 |
11 | import jenkins.model.*
12 |
13 | // Pattern to search for. Regular expression.
14 | //def jobPattern = "some-pattern-.*"
15 |
16 | // Should we be disabling or enabling jobs? "disable" or "enable", case-insensitive.
17 | //def disableOrEnable = "enable"
18 |
19 | def lcFlag = disableOrEnable.toLowerCase()
20 |
21 | if (lcFlag.equals("disable") || lcFlag.equals("enable")) {
22 | def matchedJobs = Jenkins.instance.items.findAll { job ->
23 | job.name =~ /$jobPattern/
24 | }
25 |
26 | matchedJobs.each { job ->
27 | if (lcFlag.equals("disable")) {
28 | println "Disabling matching job ${job.name}"
29 | job.disable()
30 | } else if (lcFlag.equals("enable")) {
31 | println "Enabling matching job ${job.name}"
32 | job.enable()
33 | }
34 | }
35 | } else {
36 | println "disableOrEnable parameter ${disableOrEnable} is not a valid option."
37 | }
--------------------------------------------------------------------------------
/scriptler/interruptPollingThreads.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Interrupt Polling Threads",
3 | "comment" : "Interrupt Polling Threads running for a certain amount of time. Script based on a comment in JENKINS-5413.",
4 | "parameters" : [ "duration" ],
5 | "core": "1.609",
6 | "authors" : [
7 | { name : "Allan Burdajewicz" }
8 | ]
9 | } END META**/
10 |
11 | import jenkins.model.Jenkins
12 |
13 | /**
14 | * Interrupt any running Polling Threads that are currently running for more than `duration` seconds. This can be tuned.
15 | */
16 | Jenkins.instance.getTrigger("SCMTrigger").getRunners().each() {
17 | runner ->
18 | println(runner.getTarget().asItem().name)
19 | println(runner.getDuration())
20 | println(runner.getStartTime())
21 | long millis = Calendar.instance.time.time - runner.getStartTime()
22 |
23 | if (millis > (1000 * Integer.parseInt(duration))) {
24 | Thread.getAllStackTraces().keySet().each() {
25 | tItem ->
26 | if (tItem.getName().contains("SCM polling") && tItem.getName().contains(runner.getTarget().asItem().name)) {
27 | println "Interrupting thread " + tItem.getId() + " " + tItem.getName()
28 | tItem.interrupt()
29 | }
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/scriptler/BulkDeleteViews.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {"name" : "Bulk delete of views",
2 | "comment" : "It will delete all views provided and optionally the jobs inside them (dry run mode available)",
3 | "parameters" : [ 'dry', 'views', 'deleteJobs' ],
4 | "core": "2.0",
5 | "authors" : [{ name : "Luis del Toro" }]} END META**/
6 |
7 |
8 | import jenkins.model.*
9 |
10 | dry = dry.toBoolean()
11 | println "Dry Run mode: $dry"
12 | views = views.split(',')
13 | println "Views To Delete: $views"
14 | deleteJobs = deleteJobs.toBoolean()
15 | println "Delete Jobs Mode: $deleteJobs"
16 |
17 | def jenkins = Jenkins.instance
18 |
19 | def deletedViews = 0
20 | def deletedJobs = 0
21 |
22 | views.each {
23 |
24 | def view = jenkins.getView(it.trim())
25 | println "Candidate for deletion found: view '${view.name}'"
26 | if (deleteJobs) {
27 | view.items.each {
28 | println "Candidate for deletion found: job '${it.name}' in view '${view.name}'"
29 | if (!dry) {
30 | it.delete()
31 | deletedJobs++
32 | println "Job '${it.name}' deleted"
33 | }
34 | }
35 | }
36 | if (!dry) {
37 | view.owner.deleteView(view)
38 | deletedViews++
39 | println "View '${view.name}' deleted"
40 | }
41 | }
42 |
43 | println "Deleted ${deletedViews} views and ${deletedJobs} jobs"
44 |
--------------------------------------------------------------------------------
/scriptler/addCredentialsToFolder.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "add credentials to folder",
3 | "comment" : "Sample groovy script to add credentials to Jenkins's folder into global domain",
4 | "core": "1.609",
5 | "authors" : [
6 | { name : "Kuisathaverat" }
7 | ]
8 | } END META**/
9 |
10 | import com.cloudbees.hudson.plugins.folder.properties.FolderCredentialsProvider.FolderCredentialsProperty
11 | import com.cloudbees.hudson.plugins.folder.AbstractFolder
12 | import com.cloudbees.hudson.plugins.folder.Folder
13 | import com.cloudbees.plugins.credentials.impl.*
14 | import com.cloudbees.plugins.credentials.*
15 | import com.cloudbees.plugins.credentials.domains.*
16 |
17 | String id = UUID.randomUUID().toString()
18 | Credentials c = new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, id, "description:"+id, "user", "password")
19 |
20 | Jenkins.instance.getAllItems(Folder.class)
21 | .findAll{it.name.equals('FolderName')}
22 | .each{
23 | AbstractFolder> folderAbs = AbstractFolder.class.cast(it)
24 | FolderCredentialsProperty property = folderAbs.getProperties().get(FolderCredentialsProperty.class)
25 | if (property == null) {
26 | property = new FolderCredentialsProperty()
27 | folderAbs.addProperty(property)
28 | }
29 | property.getStore().addCredentials(Domain.global(), c)
30 | println property.getCredentials().toString()
31 | }
32 |
--------------------------------------------------------------------------------
/scriptler/disableAutomaticMavenArchiving.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Disable Maven Artifact Archiving",
3 | "comment" : "This script disables artifact archiving for maven projects, if you use an enterprise repository this rarely usefull.",
4 | "parameters" : [ 'dryRun' ],
5 | "core": "1.350",
6 | "authors" : [
7 | { name : "Mestachs" }, { name : "Dominik Bartholdi" }
8 | ]
9 | } END META**/
10 |
11 | // NOTES:
12 | // dryRun: to list current configuration only
13 |
14 | String format ='%-45s | %-20s | %-10s | %-10s | %-30s'
15 | activeJobs = hudson.model.Hudson.instance.items.findAll
16 | {job -> job.isBuildable() && job instanceof hudson.maven.MavenModuleSet}
17 | def oneline= { str -> if (str==null) return ""; str.replaceAll("[\n\r]", " - ")}
18 | println String.format(format , "job", "scm trigger","last status"," logrot","archiving disabled?")
19 | println "-------------------------------------------------------------------------------------------------------------------------------"
20 | activeJobs.each{run ->
21 | if (!run.isArchivingDisabled() && !"true".equals(dryRun)) {
22 | run.setIsArchivingDisabled(true);
23 | run.save()
24 | }
25 | println String.format(format ,run.name,oneline(run.getTrigger(hudson.triggers.Trigger.class)?.spec), run?.lastBuild?.result, run.logRotator.getDaysToKeep()+" "+run.logRotator.getNumToKeepStr(), ""+run.isArchivingDisabled()) ;
26 | }
--------------------------------------------------------------------------------
/scriptler/findOfflineSlaves.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Find Offline Slaves",
3 | "comment" : "Find offline slaves with a given name prefix.",
4 | "parameters" : [ 'namePrefix' ],
5 | "core": "1.409",
6 | "authors" : [
7 | { name : "Gareth Bowles" }
8 | ]
9 | } END META**/
10 |
11 |
12 | // NOTE: uncomment parameter below if not using Scriptler >= 2.0, or if you're just pasting
13 | // the script in manually.
14 |
15 | // The name prefix for the slaves.
16 | //def namePrefix = "my-slave"
17 |
18 |
19 | import hudson.model.*
20 | import hudson.node_monitors.*
21 | import hudson.slaves.*
22 | import java.util.concurrent.*
23 |
24 | hudson = Hudson.instance
25 |
26 | def getEnviron(computer) {
27 | def env
28 | def thread = Thread.start("Getting env from ${computer.name}", { env = computer.environment })
29 | thread.join(2000)
30 | if (thread.isAlive()) thread.interrupt()
31 | env
32 | }
33 |
34 | def slaveAccessible(computer) {
35 | getEnviron(computer)?.get('JAVA_HOME') != null
36 | }
37 |
38 | for (slave in hudson.slaves) {
39 | if (slave.name.startsWith(${namePrefix})) {
40 | def computer = slave.computer
41 | print "Checking computer ${computer.name}:"
42 | def isOK = slaveAccessible(computer)
43 | if (isOK) {
44 | println "\t\tOK"
45 | } else {
46 | println " can't get JAVA_HOME from slave: must be wedged."
47 | }
48 | }
49 | }
--------------------------------------------------------------------------------
/scriptler/addShellPreBuildStepToProject.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Add a pre-build shell script step",
3 | "comment" : "Add a pre-build shell script step to all Maven and Frestyle Projects",
4 | "parameters" : ["filePath"],
5 | "core": "1.609",
6 | "authors" : [
7 | { name : "Kuisathaverat" }
8 | ]
9 | } END META**/
10 |
11 | import hudson.util.*
12 | import hudson.tasks.*
13 | import hudson.maven.*
14 |
15 | //def filePath = '/path/to/script.sh'
16 | def scriptFile = new File(filePath)
17 |
18 | if(!scriptFile.exists() && scriptFile.isDirectory()) {
19 | throw new IOException("Check file name")
20 | }
21 | String script = scriptFile.text
22 |
23 | Jenkins.instance.getAllItems(Job.class)
24 | .findAll{ it instanceof FreeStyleProject || it instanceof MavenModuleSet }
25 | .each{
26 | println it.name + " - " + it.class
27 |
28 | DescribableList> builders = new DescribableList>()
29 | builders.add(new hudson.tasks.Shell(script))
30 |
31 | if(it instanceof FreeStyleProject){
32 | builders.addAll(it.getBuildersList())
33 | it.getBuildersList().clear()
34 | it.getBuildersList().addAll(builders)
35 | } else if (it instanceof MavenModuleSet ){
36 | builders.addAll(it.getPrebuilders())
37 | it.getPrebuilders().clear()
38 | it.getPrebuilders().addAll(builders)
39 | }
40 |
41 | it.save()
42 | }
43 |
--------------------------------------------------------------------------------
/scriptler/testMetaFormat.groovy:
--------------------------------------------------------------------------------
1 | import net.sf.json.*
2 |
3 | @Grapes([
4 | @Grab('org.kohsuke.stapler:json-lib:2.4-jenkins-1')
5 | ])
6 |
7 | /**
8 | * This script is used to check if the format of the contributed scripts META information is correct.
9 | *
10 | * Please execute it befor sending your pull request.
11 | *
12 | * $> groovy testMetaFormat.groovy
13 | */
14 |
15 | def json = [];
16 |
17 | def scriptlerDir = new File(".")
18 |
19 | scriptlerDir.eachFileMatch(~/.+\.groovy/) { File f ->
20 | if(f.name.equals('testMetaFormat.groovy')) {
21 | return
22 | }
23 | println "parsing $f"
24 | def m = (f.text =~ /(?ms)BEGIN META(.+?)END META/)
25 | if (m) {
26 | try {
27 | def metadata = JSONObject.fromObject(m[0][1]);
28 | assert metadata.name != null : "name version must be set for: ${f.name}"
29 | assert metadata.comment != null : "comment must be set for: ${f.name}"
30 | metadata['script'] = f.name
31 | json << metadata
32 | } catch (Exception e) {
33 | println "metadata for [${f.name}] not correct json"
34 | e.printStackTrace(System.err);
35 | throw e
36 | }
37 | } else {
38 | throw new RuntimeException("no metadata in [${f.name}] found")
39 | }
40 | }
41 |
42 | //lib.DataWriter.write("org.jenkinsci.plugins.scriptler.CentralScriptJsonCatalog",JSONObject.fromObject([list:json]));
43 |
--------------------------------------------------------------------------------
/scriptler/warn-if-looped-triggers.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Warn if looped triggers",
3 | "comment" : "This script will warn the user if any jobs have dependencies on other jobs and the trigger flow is a loop.",
4 | "parameters" : [],
5 | "core": "1.300",
6 | "authors" : [
7 | { name : "EJ Ciramella" }
8 | ]
9 | } END META**/
10 |
11 | import hudson.model.*
12 |
13 | for(item in Hudson.instance.items)
14 | {
15 | println("-----------------------------------------------");
16 | println(item.getDisplayName());
17 | ArrayList dsprojects = item.getDownstreamProjects();
18 | println(dsprojects.size());
19 | for(int x = 0; x < dsprojects.size(); x++)
20 | {
21 | println("Here is the downstream project name - " + dsprojects.get(x).getDisplayName());
22 | }
23 | ArrayList usprojects = item.getUpstreamProjects();
24 | println(usprojects.size());
25 | for(int x = 0; x < usprojects.size(); x++)
26 | {
27 | println("Here is the upstream project name - " + usprojects.get(x).getDisplayName());
28 | }
29 |
30 | for (int x = 0; x < dsprojects.size(); x++)
31 | {
32 | for (int y = 0; y < usprojects.size(); y++)
33 | {
34 | String upstreamname = usprojects.get(y).getDisplayName();
35 | String downstreamname = dsprojects.get(x).getDisplayName();
36 | if (upstreamname.equalsIgnoreCase(downstreamname))
37 | {
38 | println("Yerfooked");
39 | }
40 | }
41 |
42 | }
43 | println("-----------------------------------------------");
44 | }
--------------------------------------------------------------------------------
/scriptler/updateJobParameterDefinition.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Update Job Parameters",
3 | "comment" : "Update the definition of Job Parameters (update or override existing)",
4 | "parameters" : [ "jobName" , "paramName" , "paramDefaultValue"],
5 | "core": "1.609",
6 | "authors" : [
7 | { name : "Allan Burdajewicz" }
8 | ]
9 | } END META**/
10 |
11 | import hudson.model.Job
12 | import hudson.model.ParametersDefinitionProperty
13 | import hudson.model.StringParameterDefinition
14 | import jenkins.model.Jenkins
15 |
16 | /**
17 | * Add a parameter. Override if it does already exist.
18 | */
19 | //Retrieve the Job by name
20 | Job job = Jenkins.instance.getAllItems(Job.class).find { job -> jobName == job.name }
21 | //Retrieve the ParametersDefinitionProperty that contains the list of parameters.
22 | ParametersDefinitionProperty jobProp = job.getProperty(ParametersDefinitionProperty.class)
23 | if (jobProp != null) {
24 | //Retrieve the ParameterDefinition by name
25 | def param = jobProp.getParameterDefinition(paramName)
26 | //If the parameter exists, remove it
27 | if (param) {
28 | println("--- Parameter ${paramName} already exists, removing it ---")
29 | jobProp.getParameterDefinitions().remove(param)
30 | }
31 | //Add the parameter (here a StringParameter)
32 | println("--- Add Parameter(key=${jobName}, defaultValue=${paramName}) ---")
33 | jobProp.getParameterDefinitions().add(new StringParameterDefinition(paramName, paramDefaultValue))
34 | //Save the job
35 | job.save()
36 | }
--------------------------------------------------------------------------------
/scriptler/discardOldBuilds.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Discard old builds",
3 | "comment" : "Changes the config of the builds to discard old builds (only if no log rotation is configured).",
4 | "parameters" : [ 'dryRun', 'daysToKeep', 'numToKeep', 'artifactDaysToKeep', 'artifactNumToKeep'],
5 | "core": "2.46.2",
6 | "authors" : [
7 | { name : "Mestachs" }, { name : "Dominik Bartholdi" }, { name: "Denys Digtiar" }
8 | ]
9 | } END META**/
10 |
11 | // NOTES:
12 | // dryRun: to only list the jobs which would be changed
13 | // daysToKeep: If not -1, history is only kept up to this days.
14 | // numToKeep: If not -1, only this number of build logs are kept.
15 | // artifactDaysToKeep: If not -1 nor null, artifacts are only kept up to this days.
16 | // artifactNumToKeep: If not -1 nor null, only this number of builds have their artifacts kept.
17 |
18 | import jenkins.model.Jenkins
19 | import hudson.model.Job
20 | import jenkins.model.BuildDiscarderProperty
21 | import hudson.tasks.LogRotator
22 |
23 | Jenkins.instance.allItems(Job).each { job ->
24 | if (job.isBuildable() && job.supportsLogRotator() && job.getProperty(BuildDiscarderProperty) == null) {
25 | println "Processing \"${job.fullDisplayName}\""
26 | if (!"true".equals(dryRun)) {
27 | // adding a property implicitly saves so no explicit one
28 | job.addProperty(new BuildDiscarderProperty(new LogRotator ( daysToKeep, numToKeep, artifactDaysToKeep, artifactNumToKeep)))
29 | println "${job.displayName} is updated"
30 | }
31 | }
32 | }
33 | return;
34 |
--------------------------------------------------------------------------------
/scriptler/vaultAppRoleCredential.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Update VaultAppRoleCredential of hashicorp-vault-plugin",
3 | "comment" : "Update the Secret ID for a specific Role ID for a VaultAppRoleCredential of https://plugins.jenkins.io/hashicorp-vault-plugin",
4 | "parameters" : ["vaultRoleID", "newSecret"],
5 | "core": "2.107.3",
6 | "authors" : [
7 | { name : "Ray Kivisto" }
8 | ]
9 | } END META**/
10 |
11 | // https://github.com/jenkinsci/hashicorp-vault-plugin/blob/master/src/main/java/com/datapipe/jenkins/vault/credentials/VaultAppRoleCredential.java
12 |
13 | import com.cloudbees.plugins.credentials.*
14 | import com.cloudbees.plugins.credentials.domains.*
15 | import com.datapipe.jenkins.vault.credentials.*
16 | import hudson.util.Secret
17 |
18 | def updateVaultAppRoleCredential = { roleID, newPassword ->
19 | def credentialsStore = jenkins.model.Jenkins.instance.getExtensionList('com.cloudbees.plugins.credentials.SystemCredentialsProvider')[0].getStore()
20 | def credentials = credentialsStore.getCredentials(Domain.global())
21 | credentials.each{
22 | if (it.getRoleId()==roleID){
23 | if ( credentialsStore.updateCredentials(
24 | com.cloudbees.plugins.credentials.domains.Domain.global(),
25 | it,
26 | new VaultAppRoleCredential(it.scope, it.id, it.description, it.roleId, new Secret(newPassword) ) ) ) {
27 | println "${roleID} updated"
28 | } else {
29 | println "ERROR: unable to update ${roleID}"
30 | }
31 | }
32 | }
33 | }
34 |
35 | updateVaultAppRoleCredential(vaultRoleID, newSecret)
36 |
--------------------------------------------------------------------------------
/scriptler/vaultTokenCredential.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Update a VaultTokenCredential of hashicorp-vault-plugin",
3 | "comment" : "Update the Token for a specific credential ID for a VaultTokenCredential of https://plugins.jenkins.io/hashicorp-vault-plugin",
4 | "parameters" : ["vaultCredentialID", "newTokenValue"],
5 | "core": "2.107.3",
6 | "authors" : [
7 | { name : "Ray Kivisto" }
8 | ]
9 | } END META**/
10 |
11 | // https://github.com/jenkinsci/hashicorp-vault-plugin/blob/master/src/main/java/com/datapipe/jenkins/vault/credentials/VaultTokenCredential.java
12 |
13 | import com.cloudbees.plugins.credentials.*
14 | import com.cloudbees.plugins.credentials.domains.*
15 | import com.datapipe.jenkins.vault.credentials.*
16 | import hudson.util.Secret
17 |
18 | def updateVaultTokenCredential = { credentialID, newPassword ->
19 | def credentialsStore = jenkins.model.Jenkins.instance.getExtensionList('com.cloudbees.plugins.credentials.SystemCredentialsProvider')[0].getStore()
20 | def credentials = credentialsStore.getCredentials(Domain.global())
21 | credentials.each{
22 | if (it.id==credentialID){
23 | if ( credentialsStore.updateCredentials(
24 | com.cloudbees.plugins.credentials.domains.Domain.global(),
25 | it,
26 | new VaultTokenCredential(it.scope, it.id, it.description, new Secret(newPassword) ) ) ) {
27 | println "${credentialID} updated"
28 | } else {
29 | println "ERROR: unable to update ${credentialID}"
30 | }
31 | }
32 | }
33 | }
34 |
35 | updateVaultTokenCredential(vaultCredentialID, newTokenValue)
36 |
--------------------------------------------------------------------------------
/scriptler/hashifyAllScmTriggers.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Hashify All SCM Triggers",
3 | "comment" : "Hashify all SCM triggers. See JENKINS-17311.",
4 | "parameters" : [ "dry" ],
5 | "core": "1.511",
6 | "authors" : [
7 | { "name" : "Wisen Tanasa" },
8 | { "name" : "Benjamin Francisoud" }
9 | ]
10 | } END META**/
11 | import hudson.scheduler.*
12 | import hudson.model.*
13 | import hudson.triggers.*
14 | import hudson.scm.*
15 |
16 | dry = dry.toBoolean()
17 | println "Dry mode: $dry. \n"
18 |
19 | TriggerDescriptor SCM_TRIGGER_DESCRIPTOR = Hudson.instance.getDescriptorOrDie(SCMTrigger.class)
20 | assert SCM_TRIGGER_DESCRIPTOR != null;
21 |
22 | items = Hudson.instance.items.findAll{job -> ((job instanceof hudson.model.AbstractProject) && (job.scm instanceof SubversionSCM) && job.disabled == false) }
23 |
24 | for(item in items) {
25 | def trigger = item.getTriggers().get(SCM_TRIGGER_DESCRIPTOR)
26 | if(trigger != null && trigger instanceof SCMTrigger) {
27 | def newSpec = CronTab.hashify(trigger.spec)
28 | if (newSpec) {
29 | def newTrigger = new SCMTrigger(newSpec)
30 | print "$item.name".padRight(80)
31 | print "Old spec: $trigger.spec".padRight(30)
32 | print "New spec: $newTrigger.spec".padRight(30)
33 |
34 | if (!dry) {
35 | newTrigger.job = item
36 | item.removeTrigger(SCM_TRIGGER_DESCRIPTOR)
37 | item.addTrigger(newTrigger)
38 | item.save()
39 | }
40 | } else {
41 | print "$item.name".padRight(80)
42 | print "Already hashified: $trigger.spec"
43 | }
44 | println()
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/scriptler/checkNodesLauncherVersion.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Check Nodes Version",
3 | "comment" : "Check the .jar version and the java version of the Nodes against the Master versions",
4 | "parameters" : [ ],
5 | "core": "1.609",
6 | "authors" : [
7 | { name : "Allan Burdajewicz" }
8 | ]
9 | } END META**/
10 |
11 | import hudson.remoting.Launcher
12 | import hudson.slaves.SlaveComputer
13 | import jenkins.model.Jenkins
14 |
15 | def expectedAgentVersion = Launcher.VERSION
16 | def expectedJavaVersion = System.getProperty("java.version")
17 | println "Master"
18 | println " Expected Agent Version = '${expectedAgentVersion}'"
19 | println " Expected Java Version = '${expectedJavaVersion}'"
20 | Jenkins.instance.getComputers()
21 | .findAll { it instanceof SlaveComputer }
22 | .each { computer ->
23 | println "Node '${computer.name}'"
24 | if (!computer.getChannel()) {
25 | println " is disconnected."
26 | } else {
27 | def isOk = true
28 | def agentVersion = computer.getSlaveVersion()
29 | if (!expectedAgentVersion.equals(agentVersion)) {
30 | println " expected agent version '${expectedAgentVersion}' but got '${agentVersion}'"
31 | isOk = false
32 | }
33 | def javaVersion = computer.getSystemProperties().get("java.version")
34 | if (!expectedJavaVersion.equals(javaVersion)) {
35 | println " expected java version '${expectedJavaVersion}' but got '${javaVersion}'"
36 | isOk = false
37 | }
38 |
39 | if(isOk) {
40 | println " OK"
41 | }
42 | }
43 | }
44 | return;
--------------------------------------------------------------------------------
/scriptler/bulkDeleteJenkinsBuildsExceptOne.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Bulk Delete Builds except the given build number",
3 | "comment" : "For a given job and a given build numnber, delete all build except the user provided one.",
4 | "parameters" : [ 'jobName', 'buildNumber' ],
5 | "core": "1.410",
6 | "authors" : [
7 | { name : "Arun Sangal" }
8 | ]
9 | } END META **/
10 |
11 |
12 | // NOTE: Uncomment parameters below if not using Scriptler >= 2.0, or if you're just pasting the script in manually.
13 | // ----- Logic in this script takes 5000 as the infinite number, decrease / increase this value from your own experience.
14 | // The name of the job.
15 | //def jobName = "some-job"
16 |
17 | // The range of build numbers to delete.
18 | //def buildNumber = "5"
19 |
20 | def lastBuildNumber = buildNumber.toInteger() - 1;
21 | def nextBuildNumber = buildNumber.toInteger() + 1;
22 |
23 |
24 | import jenkins.model.*;
25 | import hudson.model.Fingerprint.RangeSet;
26 |
27 | def jij = jenkins.model.Jenkins.instance.getItem(jobName);
28 |
29 | println("Keeping Job_Name: ${jobName} and build Number: ${buildNumber}");
30 | println ""
31 |
32 | def setBuildRange = "1-${lastBuildNumber}"
33 |
34 | //println setBuildRange
35 |
36 | def range = RangeSet.fromString(setBuildRange, true);
37 |
38 | jij.getBuilds(range).each { it.delete() }
39 |
40 | println("Builds have been deleted - Range: " + setBuildRange)
41 |
42 |
43 | setBuildRange = "${nextBuildNumber}-5000"
44 |
45 | //println setBuildRange
46 |
47 | range = RangeSet.fromString(setBuildRange, true);
48 |
49 | jij.getBuilds(range).each { it.delete() }
50 |
51 | println("Builds have been deleted - Range: " + setBuildRange)
52 |
53 |
--------------------------------------------------------------------------------
/scriptler/bulkDeleteJobs.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Bulk Delete Jobs",
3 | "comment" : "Delete jobs disabled and where last build is older than specified param",
4 | "parameters" : [ 'dryRun', 'numberOfDays', 'excludeRegexp' ],
5 | "core": "2.0",
6 | "authors" : [
7 | { name : "Benjamin Francisoud" }
8 | ]
9 | } END META**/
10 |
11 |
12 |
13 | import jenkins.model.*
14 | import java.util.regex.Pattern
15 | import java.util.Date
16 |
17 | jenkins = Jenkins.instance
18 |
19 | dryRun = dryRun.toBoolean()
20 | println "Dry mode: $dryRun"
21 | numberOfDays = numberOfDays.toInteger() ?: 365
22 | println "numberOfDays: $numberOfDays"
23 | excludeRegexp = excludeRegexp ?: '(Template).*'
24 | println "excludeRegexp: ${excludeRegexp}"
25 | pattern = Pattern.compile(excludeRegexp)
26 |
27 | int count = 0
28 | Date now = new Date()
29 | Date xDaysAgo = new Date(((long)now.time-(1000L*60*60*24*numberOfDays)))
30 | println "\nNow: ${now}"
31 | println "X days ago: ${xDaysAgo}\n"
32 |
33 | jobs = jenkins.items.findAll{job -> (job instanceof hudson.model.AbstractProject && job.disabled == true && (job.lastSuccessfulBuild?.time?.before(xDaysAgo) || job.lastSuccessfulBuild == null) && !pattern.matcher(job.name).matches()) }
34 |
35 | jobs.each { job ->
36 | if (job.firstBuild?.time?.after(xDaysAgo)) {
37 | println "No successful builds for ${job.name}, but we won't disable it yet as it's less than ${numberOfDays} days old; first build was at ${job.firstBuild?.time}"
38 | } else {
39 | println "Deleting ${job.name} at ${now}. lastSuccessfulBuild ${job.lastSuccessfulBuild?.time}"
40 | if (!dryRun) {
41 | job.delete()
42 | }
43 | count++
44 | }
45 | }
46 |
47 | println "\nDeleted ${count} jobs.\n"
--------------------------------------------------------------------------------
/scriptler/changeCredentialPassword.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Change credential password",
3 | "comment" : "Modify the password for an existing credential identified by username",
4 | "parameters" : ['username', 'password'],
5 | "core": "1.609",
6 | "authors" : [
7 | { name : "Thomas LÉVEIL" }
8 | ]
9 | } END META**/
10 |
11 | import com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl
12 |
13 | def changePassword = { username, new_password ->
14 | def creds = com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials(
15 | com.cloudbees.plugins.credentials.common.StandardUsernameCredentials.class,
16 | jenkins.model.Jenkins.instance
17 | )
18 |
19 | def c = creds.findResult { it.username == username ? it : null }
20 |
21 | if ( c ) {
22 | println "found credential ${c.id} for username ${c.username}"
23 |
24 | def credentials_store = jenkins.model.Jenkins.instance.getExtensionList(
25 | 'com.cloudbees.plugins.credentials.SystemCredentialsProvider'
26 | )[0].getStore()
27 |
28 | def result = credentials_store.updateCredentials(
29 | com.cloudbees.plugins.credentials.domains.Domain.global(),
30 | c,
31 | new UsernamePasswordCredentialsImpl(c.scope, c.id, c.description, c.username, new_password)
32 | )
33 |
34 | if (result) {
35 | println "password changed for ${username}"
36 | } else {
37 | println "failed to change password for ${username}"
38 | }
39 | } else {
40 | println "could not find credential for ${username}"
41 | }
42 | }
43 |
44 | changePassword("$username", "$password")
--------------------------------------------------------------------------------
/scriptler/changeSecretText.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Change secret text",
3 | "comment" : "Modify the secret text for an existing credential identified by the ID",
4 | "parameters" : ['id', 'scope', 'secret'],
5 | "core": "1.609",
6 | "authors" : [
7 | { name : "Hans Schulz" }
8 | ]
9 | } END META**/
10 |
11 |
12 | import org.jenkinsci.plugins.plaincredentials.StringCredentials
13 | import org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl
14 | import hudson.util.Secret
15 | import jenkins.model.Jenkins
16 |
17 | def changeSecret = { id, scope, newSecret ->
18 | List creds = com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials(
19 | StringCredentials.class,
20 | Jenkins.instance)
21 |
22 | def c = creds.findResult { it.id == id && (scope == null || scope == "" || it.scope.name() == scope) ? it : null}
23 |
24 | if (c) {
25 | def credentials_store = Jenkins.instance.getExtensionList(
26 | 'com.cloudbees.plugins.credentials.SystemCredentialsProvider'
27 | )[0].getStore()
28 |
29 | def result = credentials_store.updateCredentials(
30 | com.cloudbees.plugins.credentials.domains.Domain.global(),
31 | c,
32 | new StringCredentialsImpl(c.scope, c.id, c.description, Secret.fromString(newSecret))
33 | )
34 |
35 | if (result) {
36 | println "Secret changed for credential ${c.id}"
37 | } else {
38 | throw new RuntimeException("Failed to change secret for ${c.id}")
39 | }
40 | } else {
41 | throw new RuntimeException("No existing credential with ID ${id}")
42 | }
43 | }
44 |
45 | changeSecret("${id}", "${scope}", "${secret}")
46 |
--------------------------------------------------------------------------------
/scriptler/jMavenMultiModuleProjectBuildsCleaner.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Maven Multi-Module Project Batch Builds Remover",
3 | "comment" : "Removes all the builds (modules included) of a given Maven Multi-module Project job ('jobName') and resets the number of the next build to 'newNextBuildNumber' (default 1). It's possible to conduct a dry run test using a parameter (default true) you could never guess ;)",
4 | "parameters" : [ 'jobName', 'newNextBuildNumber', 'dryRun' ],
5 | "authors" : [
6 | { name : "Giacomo Boccardo" }
7 | ]
8 | } END META**/
9 |
10 | import hudson.model.*
11 |
12 | // If you are not using Scriptler plugin, uncomment and change properly the following parameters.
13 | // def jobName = "XYZ"
14 | // def newNextBuildNumber = 1
15 | // def dryRun = true
16 |
17 |
18 | def dryRunBool = dryRun.toBoolean()
19 | def newNBNInt = newNextBuildNumber.toInteger()
20 |
21 | !dryRunBool ?: println("!!! DRY RUN !!!")
22 |
23 | // Remove job's build
24 | def job = Hudson.instance.getItem(jobName)
25 | def builds = job.getBuilds()
26 | builds.each {
27 | dryRunBool ?: it.delete()
28 | println("Build removed: [" + it + "]")
29 | }
30 |
31 | // Reset job's 'nextBuildNumber'
32 | dryRunBool ?: job.updateNextBuildNumber(newNBNInt)
33 | def jNBN = dryRunBool ? newNBNInt : job.getNextBuildNumber()
34 | println(job.name + ". NextBuildNumber set to [" + jNBN + "]")
35 |
36 | // Reset job's modules' 'nextBuildNumber'
37 | job.getModules().each{module ->
38 | def prevNBN = module.getNextBuildNumber()
39 | dryRunBool ?: module.updateNextBuildNumber(newNBNInt)
40 | def mNBN = dryRunBool ? newNBNInt : module.getNextBuildNumber()
41 | println("Module: " + module.name + ". NextBuildNumber changed from " + prevNBN + " to " + mNBN)
42 | }
43 |
--------------------------------------------------------------------------------
/scriptler/deleteBuildLogHistory.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Delete Logs from Build History",
3 | "comment" : "Deletes Log-Files for a Job from the Build History.",
4 | "parameters" : [ 'jobName', 'period' ],
5 | "core": "1.409",
6 | "authors" : [
7 | { name : "Steffen Legler" }
8 | ]
9 | } END META**/
10 |
11 |
12 | // NOTE: uncomment parameters below if not using Scriptler >= 2.0, or if you're just pasting
13 | // the script in manually.
14 |
15 | // The name of the job.
16 | //def jobName = "some-job"
17 |
18 | // The range of build numbers to delete.
19 | //def buildRange = "1-5"
20 |
21 | import jenkins.model.*;
22 |
23 | def deleteLogHistory(job) {
24 | long timestampPeriod = period.toLong() * 24l * 60l * 60l * 1000l
25 | long refDate = new Date().getTime() - timestampPeriod
26 | def j = jenkins.model.Jenkins.instance.getItem(job);
27 | long lastBuildTime = new File(j.getLastBuild().getRootDir().getAbsolutePath() + "/log").lastModified()
28 | int lastBuildNumber = j.getLastBuild().getNumber()
29 | if(j == null) {
30 | println "Job was not found. Script exits."
31 | return
32 | }
33 | j.getBuilds().byTimestamp(0,refDate).each {
34 | if (it.getNumber() == lastBuildNumber){
35 | println "Files from last Build will not be deleted."
36 | }else{
37 | File file = new File(it.getRootDir().getAbsolutePath() + "/log");
38 | if(file.exists()){
39 | println "Delete " + file.getAbsolutePath()
40 | file.delete()
41 | }
42 | }
43 | }
44 | }
45 |
46 |
47 |
48 | if(jobName != null && jobName.length() > 0){
49 | deleteLogHistory(jobName)
50 | }else{
51 | jenkins.model.Jenkins.instance.getItems().each{
52 | deleteLogHistory(it.getName())
53 | }
54 | }
55 |
56 |
57 |
--------------------------------------------------------------------------------
/scriptler/searchJobConfiguration.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Search Job Configuration",
3 | "comment" : "Searches job names and configurations for a matching plain text for regexp pattern",
4 | "parameters" : ['pattern', 'details', 'disabled'],
5 | "core": "1.300",
6 | "authors" : [
7 | { name : "Sebastian Schuberth" }
8 | ]
9 | } END META**/
10 |
11 | count = 0
12 |
13 | if (pattern.startsWith('/') && pattern.endsWith('/')) {
14 | println "Searching jobs for regexp ${pattern}..."
15 | pattern = pattern.substring(1, pattern.length() - 1)
16 | search = 'matches'
17 | } else {
18 | println "Searching jobs for string '${pattern}'..."
19 | search = 'contains'
20 | }
21 |
22 | def isFolder(item) {
23 | item instanceof com.cloudbees.hudson.plugins.folder.Folder
24 | }
25 |
26 | def isJob(item) {
27 | item instanceof hudson.model.FreeStyleProject || item instanceof hudson.matrix.MatrixProject || item instanceof com.tikal.jenkins.plugins.multijob.MultiJobProject
28 | }
29 |
30 | def processItem(item) {
31 | if (isFolder(item)) {
32 | item.items.each { processItem(it) }
33 | } else if (isJob(item)) {
34 | if (disabled.toBoolean() || !item.disabled) {
35 | def match = item.configFile.file.find { it."$search"(pattern) } != null
36 | if (match || item.name."$search"(pattern)) {
37 | println "${item.name} matches"
38 | ++count
39 |
40 | if (details.toBoolean()) {
41 | item.configFile.file.findAll { it."$search"(pattern) }.each { println ' ' + it.trim() }
42 | }
43 | }
44 | }
45 | } else {
46 | println "NOTE: Skipping item '${item.name}' of '${item.getClass()}'."
47 | }
48 | }
49 |
50 | hudson.model.Hudson.instance.items.each { processItem(it) }
51 |
52 | println "${count} match(es) in total"
53 |
54 | null
55 |
--------------------------------------------------------------------------------
/scriptler/getNextBuildNumbers.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Print next build numbers for all jobs",
3 | "comment" : "This script ouputs a JSON-formatted listing of the next build numbers for all jobs recursively. If you are interested in only a subset of the jobs, please specify the root folder explicitly. The output JSON can be captured in a file, copied over to another Jenkins server and used with the setNextBuildNumbers.groovy script. The idea is to ensure that build numbers do not get reset to 1 when migrating jobs from one Jenkins server to another.",
4 | "parameters" : ['rootItem'],
5 | "core": "1.625",
6 | "authors" : [
7 | { name : "Amit Modak" }
8 | ]
9 | } END META**/
10 |
11 | import jenkins.model.*
12 |
13 | def getBuildNumber(def item, def node) {
14 |
15 | if(item instanceof com.cloudbees.hudson.plugins.folder.Folder) {
16 | node[item.getName()] = [:]
17 | item.getItems().each {
18 | getBuildNumber(it, node[item.getName()])
19 | }
20 | } else {
21 | node[item.getName()] = item.nextBuildNumber
22 | }
23 | }
24 |
25 | //
26 | // main
27 | //
28 |
29 | def root = [:]
30 | def node = root
31 |
32 | if(rootItem) {
33 |
34 | if(Jenkins.instance.getItemByFullName(rootItem) && (Jenkins.instance.getItemByFullName(rootItem) instanceof com.cloudbees.hudson.plugins.folder.Folder)) {
35 |
36 | rootItem.split('/').each {
37 | node[it] = [:]
38 | node = node[it]
39 | }
40 |
41 | Jenkins.instance.getItemByFullName(rootItem).getItems().each {
42 | getBuildNumber(it, node)
43 | }
44 |
45 | } else {
46 | println "Error: '" + rootItem + "' does not exist or is not a folder"
47 | return
48 | }
49 |
50 | } else {
51 |
52 | Jenkins.instance.getItems().each {
53 | getBuildNumber(it, node)
54 | }
55 | }
56 |
57 | def output = groovy.json.JsonOutput.toJson(root)
58 | println groovy.json.JsonOutput.prettyPrint(output)
59 |
--------------------------------------------------------------------------------
/scriptler/addSlackNotification-1.8.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Add Slack notification",
3 | "comment" : "This script will add slack notifications with slack plugin version 1.8 ",
4 | "parameters" : [],
5 | "authors" : [
6 | { name : "Zamir Ivry - zamir.ivry@gmail.com" }
7 | ]
8 | } END META**/
9 |
10 | def addSlack(item)
11 | {
12 | println("adding slack to: "+ item.name);
13 | for (Iterator publishersItr = item.publishersList.iterator(); publishersItr.hasNext();) {
14 | def publisher = publishersItr.next();
15 | if(publisher instanceof jenkins.plugins.slack.SlackNotifier)
16 | {
17 | publishersItr.remove()
18 | break;
19 | }
20 | }
21 |
22 | item.publishersList.add(new jenkins.plugins.slack.SlackNotifier(teamDomain, token, room,buildServerUrl,null) );
23 |
24 |
25 |
26 | ps = item.getAllProperties()
27 | def f;
28 | for(p in ps) {
29 | if(p instanceof jenkins.plugins.slack.SlackNotifier.SlackJobProperty)
30 | {
31 |
32 | f= p;
33 | break;
34 | }
35 |
36 | }
37 | if(f!=null)
38 | item.removeProperty(f)
39 | hudson.model.JobProperty pr = new jenkins.plugins.slack.SlackNotifier.SlackJobProperty(null,null,null,false,false,true,false,false,true,true,false,true,true,false,null);
40 | item.addProperty(pr)
41 |
42 |
43 | }
44 | def getAllDependencies(item)
45 | {
46 | println(item.name +" dependencies:" + item.getDownstreamProjects())
47 | addSlack(item)
48 | for(i in item.getDownstreamProjects())
49 | {
50 | getAllDependencies(i)
51 | }
52 | }
53 |
54 |
55 | teamDomain = null //your slack team name
56 | token = null // your slack token for jenkins
57 | buildServerUrl = null //jenkins build server address
58 | room = null //slack channel
59 |
60 | for (item in Hudson.instance.items) {
61 |
62 |
63 |
64 | if(item.name.equals("common")){
65 | getAllDependencies(item)
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/scriptler/jira-publisher.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Jira issue update publisher",
3 | "comment" : 'Activate the Jira plugin publisher',
4 | "parameters" : ['dryRun','jobs','jobsPattern'],
5 | "core": "1.424",
6 | "authors" : [
7 | { name : "Julien Carsique" }
8 | ]
9 | } END META**/
10 | import hudson.model.*
11 |
12 | if (dryRun == "true") {
13 | println("Dry run")
14 | }
15 | def jobsList = []
16 | if (!jobs.isEmpty()) {
17 | println("Working with jobs list: $jobs")
18 | for (jobName in jobs.split()) {
19 | jobItem = Hudson.getInstance().getItem(jobName)
20 | if (jobItem == null) {
21 | println("WARN $jobName not found!")
22 | continue
23 | }
24 | jobsList.add(jobItem)
25 | }
26 | }
27 | if (!jobsPattern.isEmpty()) {
28 | println("Working with jobs pattern: $jobsPattern")
29 | for (jobItem in Hudson.getInstance().getItems()) {
30 | for (jobPattern in jobsPattern.split()) {
31 | if (jobItem.getName() =~ jobPattern) {
32 | jobsList.add(jobItem)
33 | break
34 | }
35 | }
36 | }
37 | }
38 | if (jobs.isEmpty() && jobsPattern.isEmpty()) {
39 | jobsList = Hudson.getInstance().getItems()
40 | }
41 |
42 | for(item in jobsList) {
43 | println("\n[$item.name]")
44 | hasJira = false;
45 | for(p in item.getPublishersList()) {
46 | if(p instanceof hudson.plugins.jira.JiraIssueUpdater) {
47 | println("Jira publisher already active on $item.name")
48 | hasJira = true
49 | }
50 | }
51 | if(!hasJira) {
52 | println("Adding Jira publisher to $item.name")
53 | if (dryRun != "true") {
54 | item.getPublishersList().add(new hudson.plugins.jira.JiraIssueUpdater())
55 | item.save()
56 | }
57 | }
58 | }
--------------------------------------------------------------------------------
/scriptler/disableBrokenJobs.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Disable Broken Jobs",
3 | "comment" : "Disable jobs that haven't had a successful build for at least X days (default 90).",
4 | "parameters" : [ 'dryRun', 'jobName', 'numberOfDays' ],
5 | "core": "1.409",
6 | "authors" : [
7 | { name : "Gareth Bowles"},{ name: "Benjamin Francisoud" }
8 | ]
9 | } END META**/
10 |
11 |
12 | import hudson.model.*
13 | import java.util.Date
14 |
15 | hudson = Hudson.instance
16 |
17 | dryRun = dryRun.toBoolean()
18 | println "Dry mode: $dryRun"
19 | maintenanceJobName = maintenanceJobName ?: "disableBrokenJobs.groovy"
20 | println "maintenanceJobName: $maintenanceJobName"
21 | numberOfDays = numberOfDays.toInteger() ?: 90
22 | println "numberOfDays: $numberOfDays"
23 |
24 | int count = 0
25 | Date now = new Date()
26 | Date xDaysAgo = new Date(((long)now.time-(1000L*60*60*24*numberOfDays)))
27 | println "\nNow: ${now}"
28 | println "X days ago: ${xDaysAgo}\n"
29 |
30 | for (job in hudson.projects) {
31 | if (!job.isDisabled()) {
32 | if (job.lastSuccessfulBuild?.time?.before(xDaysAgo)) {
33 | if (job.firstBuild?.time?.after(xDaysAgo)) {
34 | println "No successful builds for ${job.name}, but we won't disable it yet as it's less than ${numberOfDays} days old; first build was at ${job.firstBuild?.time}"
35 | } else {
36 | println "Disabling ${job.name} at ${now}. lastSuccessfulBuild ${job.lastSuccessfulBuild?.time}"
37 | def description = "Disabled by [[${maintenanceJobName}]] on [[${now}]]"
38 | if (job.description) {
39 | job.setDescription("${job.description} - ${description}")
40 | } else {
41 | job.setDescription(" - ${description}")
42 | }
43 | if (!dryRun) {
44 | job.doDisable()
45 | }
46 | count++
47 | }
48 | }
49 | }
50 | }
51 | println "\nDisabled ${count} jobs.\n"
52 |
--------------------------------------------------------------------------------
/scriptler/setNextBuildNumbers.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Print next build numbers for all jobs",
3 | "comment" : "This script consumes a JSON-formatted input file the lists the next build numbers for a collection of jobs and sets the next build numbers of matching jobs as per the input file. The input JSON can be generated using the getNextBuildNumbers.groovy script. The idea is to ensure that build numbers do not get reset to 1 when migrating jobs from one Jenkins server to another.",
4 | "parameters" : ['inputFilePath'],
5 | "core": "1.625",
6 | "authors" : [
7 | { name : "Amit Modak" }
8 | ]
9 | } END META**/
10 |
11 | import jenkins.model.*
12 |
13 | def setBuildNumber(def key, def value, def path = []) {
14 |
15 | path.push(key)
16 | if(value instanceof java.util.Map) {
17 | value.each { k, v ->
18 | setBuildNumber(k, v, path)
19 | }
20 |
21 | } else {
22 | jobName = path.join('/')
23 | job = Jenkins.instance.getItemByFullName(jobName)
24 |
25 | if(job && !(job instanceof com.cloudbees.hudson.plugins.folder.Folder)) {
26 |
27 | //println "Setting build number for " + jobName + " to " + value
28 | job.nextBuildNumber = value
29 | job.saveNextBuildNumber()
30 |
31 | } else {
32 | println "Warning: Failed to set next build number for '" + jobName + "'"
33 | }
34 | }
35 | path.pop()
36 | }
37 |
38 | //
39 | // main
40 | //
41 |
42 | if(!inputFilePath) {
43 |
44 | println "Error: Please specify inputFilePath and retry"
45 | return
46 |
47 | }
48 |
49 | try {
50 |
51 | String input = new File(inputFilePath).getText('UTF-8')
52 |
53 | def jsonSlurper = new groovy.json.JsonSlurper()
54 | def root = jsonSlurper.parseText(input)
55 |
56 | root.each { k, v ->
57 | setBuildNumber(k, v)
58 | }
59 |
60 | } catch (java.io.FileNotFoundException e) {
61 | println "Error: Could not open " + inputFilePath + " for reading"
62 |
63 | } catch (groovy.json.JsonException e) {
64 | println "Error: Failed to parse " + inputFilePath
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/scriptler/listEC2Instances.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "List EC2 Cloud instances",
3 | "comment" : "Iterate all EC2 Clouds and every template on them, to list the instances running",
4 | "parameters" : [],
5 | "core": "2.32",
6 | "authors" : [{ name : "kuisathaverat" }]
7 | } END META**/
8 |
9 | import com.amazonaws.services.ec2.model.InstanceStateName
10 |
11 | Jenkins.instance.clouds
12 | .findAll{ it -> it instanceof hudson.plugins.ec2.AmazonEC2Cloud}
13 | .each{ c ->
14 | println c.getCloudName() + ' - ' + c.getRegion() + ' - CAP:' + c.instanceCap
15 | c.getTemplates()
16 | .each{ t->
17 | println '\t' + t.description + ' - CAP:' + t.instanceCap
18 | String description = t?.description;
19 | int running = 0
20 | int terminated = 0
21 | int shuttingdown = 0
22 | c.connect()?.describeInstances()?.getReservations().each{ r ->
23 | r?.getInstances().each{ i ->
24 | if (t.getAmi().equals(i.getImageId())) {
25 | InstanceStateName stateName = InstanceStateName.fromValue(i.getState().getName());
26 | if (stateName != InstanceStateName.Terminated && stateName != InstanceStateName.ShuttingDown) {
27 | running++
28 | } else if (stateName == InstanceStateName.Terminated) {
29 | terminated++
30 | } else if (stateName == InstanceStateName.ShuttingDown) {
31 | shuttingdown++
32 | }
33 | println "\t\tExisting instance found: " + i.getInstanceId() + " AMI: " + i.getImageId() + ' - State:' + stateName
34 | }
35 | }
36 | }
37 | println "\tTotal Intances Running:" + running
38 | println "\tTotal Intances Terminated:" + terminated
39 | println "\tTotal Intances ShuttingDown:" + shuttingdown
40 | }
41 | }
42 | return
43 |
--------------------------------------------------------------------------------
/scriptler/show-labels-overview.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Show labels overview",
3 | "comment" : "Show an overview of all labels defined and which slaves have which labels",
4 | "parameters" : [],
5 | "core": "1.300",
6 | "authors" : [
7 | { name : "Stefan Heintz" },
8 | { name : "Nico Mommaerts" },
9 | { name : "Rob Fagen" }
10 | ]
11 | } END META**/
12 | import jenkins.model.Jenkins;
13 |
14 | def uniqueLabels = []
15 | def slave_label_map = [:]
16 | for (slave in Jenkins.instance.slaves) {
17 | words = slave.labelString.split()
18 | def labelListForSlave = []
19 | words.each() {
20 | labelListForSlave.add(it);
21 | uniqueLabels.add(it)
22 | }
23 | slave_label_map.put(slave.name, labelListForSlave)
24 | }
25 | uniqueLabels.unique()
26 |
27 | maxLen=0
28 | uniqueLabels.each() {
29 | if (it.length() > maxLen) {
30 | maxLen=it.length()
31 | }
32 | }
33 |
34 | def vertLabels = []
35 |
36 | for (int idx=0;idx
62 | boolean found = false
63 | entry.value.each() { valueList ->
64 | if(lab.equals(valueList)) {
65 | found = true
66 | }
67 | }
68 | if(found) {
69 | print "X"
70 | } else {
71 | print " "
72 | }
73 | print "|"
74 | }
75 | printLine()
76 | }
77 |
78 |
79 | def printSign(int count, String sign) {
80 | for (int i = 0; i < count; i++) {
81 | print sign
82 | }
83 | }
84 |
85 | def printLine() {
86 | print "\n";
87 | printSign(120, "-")
88 | print "\n";
89 | }
90 |
--------------------------------------------------------------------------------
/scriptler/injectAndManipulateBuildParameters.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "inject and manipulate build parameters",
3 | "comment" : "This allows you to manipulate the build parameters and also add new ones depending on existing ones.",
4 | "parameters" : [],
5 | "core": "1.300",
6 | "authors" : [
7 | { name : "Thomas Froehlich - mail@thomas-froehlich.net" }
8 | ]
9 | } END META**/
10 |
11 | /*
12 | * Parameters to inject
13 | */
14 | def custom_parameters(Map all_parameters) {
15 | def new_parameters = new ArrayList();
16 |
17 | //** INSERT YOUR CODE HERE ! **//
18 |
19 | for (e in all_parameters) {
20 | if(e.key.toString().equals("SPRINT_NUMBER")) {
21 | new_parameters.add(new StringParameterValue("DATE_PARAM", (new Date()).toString() + "_SPRINT_" + e.value.toString()));
22 | } else if (e.key.toString().equals("BROWSER")) {
23 | if(e.value.toString().equals("IE9")) {
24 | new_parameters.add(new StringParameterValue("IEWORKAROUND", "true"));
25 | } else {
26 | new_parameters.add(new StringParameterValue("IEWORKAROUND", "false"));
27 | }
28 | }
29 | }
30 |
31 | //** END **//
32 | return new_parameters;
33 | }
34 |
35 | /*
36 | * PLEASE DON'T CHANGE THE FOLLOWING CODE
37 | */
38 | import hudson.model.*
39 | import java.util.Map;
40 |
41 | // init
42 | def thr = Thread.currentThread()
43 | def build = thr?.executable
44 | def all_parameters = build.getBuildVariables();
45 | def new_parameters = custom_parameters(all_parameters);
46 |
47 | // Inject the new parameters into the existing list
48 | def modified_parameters = null
49 | def old_parameters = build.getAction(ParametersAction.class)
50 | if (old_parameters != null) {
51 | build.actions.remove(old_parameters)
52 | modified_parameters = old_parameters.createUpdated(new_parameters)
53 | } else {
54 | modified_parameters = new ParametersAction(new_parameters)
55 | }
56 |
57 | // Reattach the parameters with the additions
58 | build.actions.add(modified_parameters)
59 |
60 |
--------------------------------------------------------------------------------
/scriptler/clonebranches.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Clone Branches",
3 | "comment" : "This script was written to create NEW jobs based on a series of other jobs and append a version string to the name of the job. For instance, if you have foo, bar, bat jobs AND they've all been branched to support 2.0 work, you can feed this script the name and the version you'd like to create the jobs for. This will create the new jobs with the proper name and will make sure the Mercurial scm configuration is pointed at that new branch.",
4 | "parameters" : [],
5 | "core": "1.300",
6 | "authors" : [
7 | { name : "EJ Ciramella" }
8 | ]
9 | } END META**/
10 |
11 | import jenkins.model.*
12 |
13 | instance = jenkins.model.Jenkins.instance;
14 | /*
15 |
16 | Here's how this works.
17 |
18 | You change the "thingyouarecloning" to be the name of the thing you want to clone.
19 |
20 | If one were so inclinded, you could change line 20 to be a regex or even String.contains().
21 |
22 | Then plug in the version string for the "newbranch" string object.
23 |
24 | */
25 | String thingyouarecloning = "nameofjob";
26 | String newbranch = "2.0";
27 |
28 | for(item in Jenkins.instance.items)
29 | {
30 | if(item.name.equals(thingyouarecloning))
31 | {
32 | println("Ok, found " + thingyouarecloning + ", about to clone that");
33 | println( item.getScm().getBranch());
34 | if(item.getScm().getType().contains("mercurial"))
35 | {
36 | instance.copy(item, item.name+"-"+newbranch);
37 |
38 | String installation = item.scm.getInstallation();
39 | String source = item.scm.getSource();
40 | String branch = newbranch;
41 | String modules = item.scm.getModules();
42 | String subdir = item.scm.getSubdir();
43 | hudson.plugins.mercurial.browser.HgBrowser browser = item.scm.getBrowser();
44 | boolean clean = item.scm.isClean();
45 | hudson.plugins.mercurial.MercurialSCM newscm = new hudson.plugins.mercurial.MercurialSCM(installation, source, branch, modules, subdir, browser, clean);
46 | println( instance.getItem(item.name+"-"+newbranch).setScm(newscm));
47 | }
48 | }
49 | }
--------------------------------------------------------------------------------
/scriptler/pluginManagerSimpleReport.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Plugins Manager Simple Report",
3 | "comment" : "Simple report of Installed/Disabled/Bundled/Failed/Forced by Pinning/Inactive plugins of a Jenkins Instance",
4 | "parameters" : [],
5 | "core": "1.609",
6 | "authors" : [
7 | { name : "Allan Burdajewicz" }
8 | ]
9 | } END META**/
10 |
11 | import jenkins.model.Jenkins
12 |
13 | println "\nINSTALLED:\n---"
14 | /**
15 | * Get the list of installed plugins.
16 | */
17 | Jenkins.instance.getPluginManager().getPlugins().each {
18 | println "${it.getShortName()} (${it.getVersion()})"
19 | }
20 |
21 | println "\nFAILED:\n---"
22 | /**
23 | * Get failed plugins: getFailedPlugins()
24 | */
25 | Jenkins.instance.getPluginManager().getFailedPlugins()
26 | .each {
27 | println "${it.getShortName()} (${it.getVersion()})}"
28 | }
29 |
30 | println "\nPINNED:\n---"
31 | /**
32 | * Get pinned plugins: isPinned()
33 | */
34 | Jenkins.instance.getPluginManager().getPlugins()
35 | .findAll { plugin -> plugin.isPinned() }
36 | .each {
37 | println "${it.getShortName()} (${it.getVersion()})}"
38 | }
39 |
40 | println "\nBUNDLED:\n---"
41 | /**
42 | * Get bundled plugins: isBundled()
43 | */
44 | Jenkins.instance.getPluginManager().getPlugins()
45 | .findAll { plugin -> plugin.isBundled() }
46 | .each {
47 | println "${it.getShortName()} (${it.getVersion()})}"
48 | };
49 |
50 | println "\nFORCED BY PINNING:\n---"
51 | /**
52 | * Get plugins forced to an older version because of Pinning
53 | */
54 | Jenkins.instance.getPluginManager().getPlugins()
55 | .findAll { plugin -> plugin.isPinningForcingOldVersion() }
56 | .each {
57 | println "${it.getShortName()} (${it.getVersion()})}"
58 | }
59 |
60 | println "\nDISABLED:\n---"
61 | /**
62 | * Get Disabled plugins.
63 | */
64 | Jenkins.instance.getPluginManager().getPlugins()
65 | .findAll { plugin -> !plugin.isEnabled() }
66 | .each {
67 | println "${it.getShortName()} (${it.getVersion()})}"
68 | }
69 |
70 | println "\nINACTIVE:\n---"
71 | /**
72 | * Get Inactive plugins.
73 | */
74 | Jenkins.instance.getPluginManager().getPlugins()
75 | .findAll { plugin -> !plugin.isActive() }
76 | .each {
77 | println "${it.getShortName()} (${it.getVersion()})}"
78 | }
79 | return;
--------------------------------------------------------------------------------
/scriptler/trigger-manipulator.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Trigger Manipulator",
3 | "comment" : "This script came about because there were many jobs that were both scheduled to run @midnight AND were polling the scm truth server. Doing one or the other makes sense, but having polling AND @midnight doesn't. This script will iterate over all the projects and pull out the timer based trigger as well as set the minute interval for how often it should poll. Initially, I used this to move from a really slopply written polling interval string to */5 (run every 5 minutes).",
4 | "parameters" : [],
5 | "core": "1.300",
6 | "authors" : [
7 | { name : "EJ Ciramella" }
8 | ]
9 | } END META**/
10 | import hudson.model.*
11 | import hudson.triggers.*
12 |
13 | TriggerDescriptor SCM_TRIGGER_DESCRIPTOR = Hudson.instance.getDescriptorOrDie(SCMTrigger.class)
14 | TriggerDescriptor TIMER_TRIGGER_DESCRIPTOR = Hudson.instance.getDescriptorOrDie(TimerTrigger.class)
15 |
16 | assert SCM_TRIGGER_DESCRIPTOR != null;
17 | assert TIMER_TRIGGER_DESCRIPTOR != null;
18 |
19 | for(item in Hudson.instance.items)
20 | {
21 | println("Looking at "+ item.name);
22 |
23 | def trigger = item.getTriggers().get(SCM_TRIGGER_DESCRIPTOR)
24 | def timertrigger = item.getTriggers().get(TIMER_TRIGGER_DESCRIPTOR)
25 | String triggertoreplace = "some string here";
26 | String newtriggervalue = "new trigger value";
27 |
28 | if(timertrigger != null && trigger != null)
29 | {
30 | println(item.name + " has a both triggers DUH!");
31 | item.removeTrigger(TIMER_TRIGGER_DESCRIPTOR)
32 | }
33 |
34 | if(trigger != null && trigger instanceof SCMTrigger)
35 | {
36 | println("> $trigger.spec");
37 | String[] triggerbits = trigger.spec.split(" ");
38 | if(triggerbits[0] == triggertoreplace )
39 | {
40 | triggerbits[0] = newtriggervalue;
41 | }
42 |
43 | println("about to build up the new string builder trigger spec");
44 | StringBuilder newtriggerbits = new StringBuilder();
45 | for(bits in triggerbits)
46 | {
47 | newtriggerbits.append(bits+" ");
48 | }
49 |
50 | println(" here is the new schedule " + newtriggerbits.toString());
51 |
52 | def newTrigger = new SCMTrigger(newtriggerbits.toString())
53 |
54 | item.removeTrigger(SCM_TRIGGER_DESCRIPTOR)
55 | item.addTrigger(newTrigger)
56 | }
57 | else
58 | {
59 | println("no modifications needed");
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/scriptler/checkSSLConnection.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Check SSL handshake with Server",
3 | "comment" : "Check Jenkins can reach out to a Server via SSL. The script also reports all trusted certificates",
4 | "parameters" : ["serverUrl"],
5 | "core": "1.609",
6 | "authors" : [
7 | { name : "Allan Burdajewicz" }
8 | ]
9 | } END META**/
10 |
11 | import javax.net.ssl.HttpsURLConnection
12 | import javax.net.ssl.TrustManager
13 | import javax.net.ssl.TrustManagerFactory
14 | import javax.net.ssl.X509TrustManager
15 | import java.security.KeyStore
16 | import java.security.Principal
17 | import java.security.cert.Certificate
18 | import java.security.cert.X509Certificate
19 |
20 | try {
21 |
22 | println("## DUMP JVM TRUST MANAGERS ##")
23 | TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
24 | tmf.init((KeyStore) null)
25 | for (TrustManager trustManager : tmf.getTrustManagers()) {
26 | println(trustManager)
27 |
28 | if (trustManager instanceof X509TrustManager) {
29 | X509TrustManager x509TrustManager = (X509TrustManager) trustManager
30 | for (X509Certificate certificate: x509TrustManager.getAcceptedIssuers()) {
31 | println("\t" + certificate.getSubjectDN())
32 | }
33 | println("\tAccepted issuers count : " + x509TrustManager.getAcceptedIssuers().length)
34 | println("###################")
35 | } else {
36 | println("Skip " + trustManager + " - " + trustManager.getClass())
37 | }
38 | }
39 | } catch (Exception e) {
40 | e.printStackTrace()
41 | println "See stacktrace outputted in system.out for " + e
42 | }
43 | try {
44 | String url = "${serverUrl}"
45 | HttpsURLConnection urlConnection = (HttpsURLConnection) new URL(url).openConnection()
46 | println(url + "->" + urlConnection.getResponseCode() + " " + urlConnection.getResponseMessage())
47 | for (Certificate certificate : urlConnection.getServerCertificates()) {
48 | if (certificate instanceof X509Certificate) {
49 | X509Certificate x509Certificate = (X509Certificate) certificate
50 | Principal subjectDN = x509Certificate.getSubjectDN()
51 | println("\t" + subjectDN.getClass() + " - " + subjectDN)
52 | } else {
53 | println(certificate)
54 | }
55 | }
56 | } catch (Exception e) {
57 | println "See stacktrace outputted in system.out for " + e
58 | e.printStackTrace()
59 | }
--------------------------------------------------------------------------------
/scriptler/disableSlaveNodeStartsWith.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Disable Jenkins Hudson slaves nodes gracefully for all slaves starting with a given value",
3 | "comment" : "Disables Jenkins Hudson slave nodes gracefully - waits until running jobs are complete.",
4 | "parameters" : [ 'slaveStartsWith'],
5 | "core": "1.350",
6 | "authors" : [
7 | { name : "GigaAKS" }, { name : "Arun Sangal" }
8 | ]
9 | } END META**/
10 |
11 | // This scriptler script will mark Jenkins slave nodes offline for all slaves which starts with a given value.
12 | // It will wait for any slave nodes which are running any job(s) and then delete them.
13 | // It requires only one parameter named: slaveStartsWith and value can be passed as: "swarm-".
14 |
15 | import java.util.*
16 | import jenkins.model.*
17 | import hudson.model.*
18 | import hudson.slaves.*
19 |
20 | def atleastOneSlaveRunnning = true;
21 | def time = new Date().format("HH:mm MM/dd/yy z",TimeZone.getTimeZone("EST"))
22 |
23 | while (atleastOneSlaveRunnning) {
24 |
25 | //First thing - set the flag to false.
26 | atleastOneSlaveRunnning = false;
27 | time = new Date().format("HH:mm MM/dd/yy z",TimeZone.getTimeZone("EST"))
28 |
29 | for (aSlave in hudson.model.Hudson.instance.slaves) {
30 |
31 | println "-- Time: " + time;
32 | println ""
33 | //Dont do anything if the slave name is "ansible01"
34 | if ( aSlave.name == "ansible01" ) {
35 | continue;
36 | }
37 | if ( aSlave.name.indexOf(slaveStartsWith) == 0) {
38 | println "Active slave: " + aSlave.name;
39 |
40 | println('\tcomputer.isOnline: ' + aSlave.getComputer().isOnline());
41 | println('\tcomputer.countBusy: ' + aSlave.getComputer().countBusy());
42 | println ""
43 | if ( aSlave.getComputer().isOnline()) {
44 | aSlave.getComputer().setTemporarilyOffline(true,null);
45 | println('\tcomputer.isOnline: ' + aSlave.getComputer().isOnline());
46 | println ""
47 | }
48 | if ( aSlave.getComputer().countBusy() == 0 ) {
49 | time = new Date().format("HH:mm MM/dd/yy z",TimeZone.getTimeZone("EST"))
50 | println("-- Shutting down node: " + aSlave.name + " at " + time);
51 | aSlave.getComputer().doDoDelete();
52 | } else {
53 | atleastOneSlaveRunnning = true;
54 | }
55 | }
56 | }
57 | //Sleep 60 seconds
58 | if(atleastOneSlaveRunnning) {
59 | println ""
60 | println "------------------ sleeping 60 seconds -----------------"
61 | sleep(60*1000);
62 | println ""
63 | }
64 | }
65 |
66 |
--------------------------------------------------------------------------------
/scriptler/barchartGitTagList.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Barchart : Git Tag List",
3 | "comment" : "returns reverse sorted git tag list, assuming X.Y.Z version format in the tag; for use with https://wiki.jenkins-ci.org/display/JENKINS/Jenkins+Dynamic+Parameter+Plug-in",
4 | "parameters" : [ "paramTag" ],
5 | "core": "1.450",
6 | "authors" : [
7 | { "name" : "Andrei Pozolotin", "email" : "Andrei.Pozolotin@gmail.com" }
8 | ]
9 | } END META**/
10 |
11 | import hudson.model.*
12 |
13 | import java.util.regex.Pattern
14 |
15 | /**
16 | * provided script parameter or default value
17 | *
18 | * @return paramTag - tag filter pattern
19 | */
20 | def paramTag() {
21 | try{
22 | // provided script parameter, if present
23 | paramTag
24 | } catch( e ) {
25 | // "all tags" : http://www.kernel.org/pub/software/scm/git/docs/git-tag.html
26 | "*"
27 | }
28 | }
29 |
30 | /**
31 | * @return current jenkins job
32 | */
33 | def jenkinsJob() {
34 | def threadName = Thread.currentThread().getName()
35 | def pattern = Pattern.compile("job/(.*)/build")
36 | def matcher = pattern.matcher(threadName); matcher.find()
37 | def jobName = matcher.group(1)
38 | def jenkinsJob = Hudson.instance.getJob(jobName)
39 | }
40 |
41 | /**
42 | * @return repository tag list using default git on os path
43 | */
44 | def tagList(dir, tag) {
45 | def command = [ "/bin/bash", "-c", "cd '${dir}' ; git fetch --tags &> /dev/null ; git tag -l '${tag}'" ]
46 | def process = command.execute(); process.waitFor()
47 | def result = process.in.text.tokenize("\n")
48 | }
49 |
50 | /**
51 | * version number model: prefix-X.Y.Z
52 | */
53 | class Version {
54 |
55 | static def pattern = Pattern.compile("(\\d+)\\.(\\d+)\\.(\\d+)")
56 |
57 | /** parse version from text */
58 | static def from(text){
59 | def matcher = pattern.matcher(text);
60 | if(matcher.find()){
61 | new Version( major:matcher.group(1), minor:matcher.group(2), patch:matcher.group(3) )
62 | } else{
63 | new Version( major:"0", minor:"0", patch:"0" )
64 | }
65 | }
66 |
67 | String prefix, major, minor, patch
68 |
69 | /** padded form for alpha sort */
70 | def String toString() {
71 | String.format('%010d-%010d-%010d', major.toInteger(), minor.toInteger(), patch.toInteger())
72 | }
73 |
74 | }
75 |
76 | /**
77 | * @return sorted tag list as script result
78 | */
79 | try {
80 |
81 | def tagList = tagList( jenkinsJob().workspace, paramTag() )
82 |
83 | if (tagList) {
84 | tagList.sort{ tag -> Version.from(tag).toString() }.reverse()
85 | } else {
86 | [ 'master' ] // no tags in git repo
87 | }
88 |
89 | } catch( e ) {
90 |
91 | [ e.toString() ]
92 |
93 | }
94 |
--------------------------------------------------------------------------------
/scriptler/removeInvalidCredentials.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "List and remove invalid credential not present in a whitelist regexp",
3 | "comment" : "Prevent people from use their own login/password (which expire every X months therefore breaking build/jobs) and forcing usage of service accounts with no expiration limit",
4 | "parameters" : [ 'dryRun', 'whitelistRegexp', 'moreInfo' ],
5 | "core": "1.642",
6 | "authors" : [
7 | { name : "Benjamin Francisoud" }
8 | ]
9 | } END META**/
10 |
11 | import hudson.scm.*
12 | import com.cloudbees.plugins.credentials.CredentialsProvider
13 | import com.cloudbees.plugins.credentials.common.StandardUsernameCredentials
14 | import java.util.regex.Pattern
15 |
16 | Date now = new Date()
17 |
18 | // parameters
19 | dryRun = dryRun ? dryRun.toBoolean(): true;
20 | println "dryRun: ${dryRun}"
21 | whitelistRegexp = whitelistRegexp ?: '(user|root|svcaccount).*'
22 | println "whitelistRegexp: ${whitelistRegexp}"
23 | pattern = Pattern.compile(whitelistRegexp)
24 | description = "disable by removeInvalidCredentials.groovy on [[${now}]] (use valid service account regexp: [[${whitelistRegexp}]]) (${moreInfo})"
25 | println "description: ${description}"
26 |
27 | hudsonInstance = hudson.model.Hudson.instance
28 | credentials = CredentialsProvider.lookupCredentials(StandardUsernameCredentials.class, hudsonInstance, null, null);
29 |
30 | println '\n---- authorizedCredentials ---'
31 | authorizedCredentials = credentials.findAll { credential -> pattern.matcher(credential.username).matches() }
32 | authorizedCredentials.each { credential -> println "[${credential.id}] ${credential.username} (${credential.description})" }
33 |
34 | println '\n---- invalidCredentials ---'
35 | invalidCredentials = credentials.minus(authorizedCredentials)
36 | invalidCredentials.each { credential -> println "[${credential.id}] ${credential.username} (${credential.description})" }
37 |
38 | // No SCM-Configuration possible for External Jobs!
39 | jobs = hudsonInstance.items.findAll{job -> (job.disabled == false && (job instanceof hudson.model.AbstractProject) && (job.scm instanceof SubversionSCM)) }
40 |
41 | println '\n---- matching jobs ---'
42 | jobs.each { job ->
43 | job.scm.locations.each { location ->
44 | isAuthorized = authorizedCredentials.any { authorizedCredential -> authorizedCredential.id == location.credentialsId }
45 | if (!isAuthorized) {
46 | println "${job.name} (isDisabled:${job.disabled} - isAuthorized:${isAuthorized} - credentialsId:${location.credentialsId})"
47 | if(!dryRun) {
48 | job.disabled = true
49 | if (job.description) {
50 | job.setDescription("${job.description} - ${description}")
51 | } else {
52 | job.setDescription(" - ${description}")
53 | }
54 | }
55 | }
56 | }
57 | }
58 |
59 | println '---- done ---\n'
60 |
--------------------------------------------------------------------------------
/scriptler/updateEmailAddress.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Update Email Recipients",
3 | "comment" : "Update Email Recipients for multiple jobs/views",
4 | "parameters" : [ 'views', 'jobs', 'recipients' ],
5 | "core": "1.409",
6 | "authors" : [
7 | { name : "Eric Dalquist" }
8 | ]
9 | } END META**/
10 |
11 | import hudson.plugins.emailext.*
12 | import hudson.model.*
13 | import hudson.maven.*
14 | import hudson.maven.reporters.*
15 | import hudson.tasks.*
16 |
17 | def viewNames = "${views}";
18 | viewNames = viewNames.split(",");
19 | def jobNames = "${jobs}";
20 | jobNames = jobNames.split(",");
21 | def newRecipients = "${recipients}";
22 |
23 | println("Views: " + viewNames);
24 | println("Jobs: " + jobNames);
25 | println("Recipients: " + newRecipients);
26 | println();
27 |
28 | def items = new LinkedHashSet();
29 |
30 | if (viewNames != null && viewNames != "") {
31 | for (viewName in viewNames) {
32 | viewName = viewName.trim();
33 | def view = Hudson.instance.getView(viewName)
34 | items.addAll(view.getItems());
35 | }
36 | }
37 |
38 | if (jobNames != null && jobNames != "") {
39 | for (jobName in jobNames) {
40 | jobName = jobName.trim();
41 | def job = Hudson.instance.getJob(jobName)
42 | items.add(job);
43 | }
44 | }
45 |
46 | // For each project
47 | for(item in items) {
48 | println(item.name + ": Checking for email notifiers");
49 | // Find current recipients defined in project
50 | if(!(item instanceof ExternalJob)) {
51 | if(item instanceof MavenModuleSet) {
52 | // Search for Maven Mailer Reporter
53 | for(reporter in item.reporters) {
54 | if(reporter instanceof MavenMailer) {
55 | println(item.name + " - Updating reporter: " + reporter + " changing recipients from '" + reporter.recipients + "' to '" + newRecipients + "'");
56 | reporter.recipients = newRecipients;
57 | }
58 | }
59 | }
60 |
61 | for(publisher in item.publishersList) {
62 | // Search for default Mailer Publisher (doesn't exist for Maven projects)
63 | if(publisher instanceof Mailer) {
64 | println(item.name + " - Updating publisher: " + publisher + " changing recipients from '" + publisher.recipients + "' to '" + newRecipients + "'");
65 | publisher.recipients = newRecipients;
66 | }
67 | // Or for Extended Email Publisher
68 | else if(publisher instanceof ExtendedEmailPublisher) {
69 | println(item.name + " - Updating publisher: " + publisher + " changing recipients from '" + publisher.recipientList + "' to '" + newRecipients + "'");
70 | publisher.recipientList = newRecipients;
71 | }
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/scriptler/removeGitPluginBuildsByBranchBuildData.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Remove Git Plugin BuildsByBranch BuildData",
3 | "comment" : "This script is used to remove the static list of BuildsByBranch that is uselessly stored for each build by the Git Plugin. This is a workaround for the problem described here: https://issues.jenkins-ci.org/browse/JENKINS-19022 Updated to handle Matrix Project types. Updated to better support SCM Polling",
4 | "parameters" : [],
5 | "core": "1.509.4",
6 | "authors" : [
7 | { name : "Scott Hebert" }
8 | ]
9 | } END META**/
10 |
11 | import hudson.matrix.*
12 | import hudson.model.*
13 |
14 | hudsonInstance = hudson.model.Hudson.instance
15 | allItems = hudsonInstance.items
16 |
17 | // Iterate over all jobs and find the ones that have a hudson.plugins.git.util.BuildData
18 | // as an action.
19 | //
20 | // We then clean it by removing the useless array action.buildsByBranchName
21 | //
22 |
23 | for (job in allItems) {
24 | println("job: " + job.name);
25 | def counter = 0;
26 | for (build in job.getBuilds()) {
27 | // It is possible for a build to have multiple BuildData actions
28 | // since we can use the Mulitple SCM plugin.
29 | def gitActions = build.getActions(hudson.plugins.git.util.BuildData.class)
30 | if (gitActions != null) {
31 | for (action in gitActions) {
32 | action.buildsByBranchName = new HashMap();
33 | hudson.plugins.git.Revision r = action.getLastBuiltRevision();
34 | if (r != null) {
35 | for (branch in r.getBranches()) {
36 | action.buildsByBranchName.put(branch.getName(), action.lastBuild)
37 | }
38 | }
39 | build.actions.remove(action)
40 | build.actions.add(action)
41 | build.save();
42 | counter++;
43 | }
44 | }
45 | if (job instanceof MatrixProject) {
46 | def runcounter = 0;
47 | for (run in build.getRuns()) {
48 | gitActions = run.getActions(hudson.plugins.git.util.BuildData.class)
49 | if (gitActions != null) {
50 | for (action in gitActions) {
51 | action.buildsByBranchName = new HashMap();
52 | hudson.plugins.git.Revision r = action.getLastBuiltRevision();
53 | if (r != null) {
54 | for (branch in r.getBranches()) {
55 | action.buildsByBranchName.put(branch.getName(), action.lastBuild)
56 | }
57 | }
58 | run.actions.remove(action)
59 | run.actions.add(action)
60 | run.save();
61 | runcounter++;
62 | }
63 | }
64 | }
65 | if (runcounter > 0) {
66 | println(" -->> cleaned: " + runcounter + " runs");
67 | }
68 | }
69 | }
70 | if (counter > 0) {
71 | println("-- cleaned: " + counter + " builds");
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/managed-scripts/python/gen-dep-graph/gen-dep-graph.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | # Licensed to the Apache Software Foundation (ASF) under one
4 | # or more contributor license agreements. See the NOTICE file
5 | # distributed with this work for additional information
6 | # regarding copyright ownership. The ASF licenses this file
7 | # to you under the Apache License, Version 2.0 (the
8 | # "License"); you may not use this file except in compliance
9 | # with the License. You may obtain a copy of the License at
10 | #
11 | # http://www.apache.org/licenses/LICENSE-2.0
12 | #
13 | # Unless required by applicable law or agreed to in writing,
14 | # software distributed under the License is distributed on an
15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | # KIND, either express or implied. See the License for the
17 | # specific language governing permissions and limitations
18 | # under the License.
19 |
20 | import urllib
21 | import sys
22 | import os
23 | import ConfigParser
24 | import shlex
25 |
26 | from subprocess import check_call
27 |
28 | JENKINS_URL = ""
29 | IGNORED = []
30 |
31 | file_name = "project.properties"
32 |
33 | if os.path.exists("personal.properties"):
34 | file_name = "personal.properties"
35 |
36 | if os.path.exists(file_name):
37 | cp = ConfigParser.RawConfigParser()
38 | cp.read(file_name)
39 |
40 | JENKINS_URL = cp.get("jenkins", "url")
41 | try:
42 | IGNORED = cp.get("jenkins", "ignore")
43 | IGNORED = map((lambda foo: foo.strip()), IGNORED.split(","))
44 | except ConfigParser.NoOptionError:
45 | pass
46 |
47 | print "Using url %s" % (JENKINS_URL)
48 | print "Ignoring %d job(s)" % (len(IGNORED))
49 |
50 | if len(JENKINS_URL) == 0:
51 | print "Please provide JENKINS_URL"
52 | sys.exit(1)
53 |
54 | try:
55 | print "Opening url %s" % JENKINS_URL
56 | obj = eval(urllib.urlopen(JENKINS_URL).read());
57 | print "Done fetching list of all jobs."
58 | except SyntaxError:
59 | print "Unable to parse the API result from %s" % JENKINS_URL
60 | print "Exiting..."
61 | sys.exit(1)
62 |
63 |
64 | result = []
65 | print "Analyzing %d job(s)" % (len(obj['jobs']))
66 |
67 | for job in obj['jobs']:
68 | job['name'] = job['name'].replace("-", "_")
69 | if job['name'] in IGNORED:
70 | continue
71 | job_info = job['url']
72 | url = job['url'] + "api/python/"
73 | job_obj = eval(urllib.urlopen(url+"api/python").read())
74 | for proj in job_obj['downstreamProjects']:
75 | proj['name'] = proj['name'].replace("-", "_")
76 | result.append('"%s" -> "%s"' % (job['name'], proj['name']))
77 |
78 | print "Writing output.dot for Graphviz"
79 | f = open("output.dot", "w")
80 | f.write("digraph G {\n")
81 | for line in result:
82 | f.write(line)
83 | f.write("\n")
84 | f.write("}")
85 | f.close()
86 |
87 | print "Generating output.svg with Graphviz"
88 | path = os.path.join(os.path.abspath("."), "output.svg")
89 | result = check_call(shlex.split("dot -Tsvg output.dot -o%s" % (path),posix=(os.name == 'posix')))
90 | print "All done. For quick browser view follow the url:"
91 | print "file://%s" % path
92 |
--------------------------------------------------------------------------------
/scriptler/export-role-strategy-permissions-to-csv.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Export role-strategy permissions to CSV",
3 | "comment" : "Export the permissions defined in the role-strategy plugin in a CSV format.
Further information in the ticket JENKINS-8075",
4 | "parameters" : [],
5 | "core": "1.424.2",
6 | "authors" : [
7 | { name : "Daniel PETISME " }
8 | ]
9 | } END META**/
10 | import hudson.model.Hudson
11 | import com.michelin.cio.hudson.plugins.rolestrategy.RoleBasedAuthorizationStrategy
12 |
13 | def cleanUsers = { it.flatten().sort().unique() - "null"}
14 |
15 | /*
16 | * UI part
17 | * The matrix is composed by the match between the roles (columns) and the users (rows).
18 | * Basically, you can start with this data structure to generate an export in the format you want.
19 | */
20 | def export = {matrix, formatter -> formatter(matrix)}
21 |
22 | /**
23 | * The default CSV formatter
24 | */
25 | def csv = { matrix -> matrix.collect{ key, value -> "\n$key, ${value.join(",").replace("true", "x").replace("false", " ")}" } + "\n" }
26 |
27 | /*
28 | * The script only work with the role-strategy plugin
29 | * https://wiki.jenkins-ci.org/display/JENKINS/Role+Strategy+Plugin
30 | */
31 | def authStrategy = Hudson.instance.getAuthorizationStrategy()
32 |
33 | if(authStrategy instanceof RoleBasedAuthorizationStrategy){
34 |
35 | /*
36 | * Get a [role]:[users] map
37 | */
38 | def permissions = authStrategy.roleMaps.inject([:]){map, it -> map + it.value.grantedRoles}
39 |
40 | /*
41 | * Get all the users defined in the role-strategy plugin
42 | */
43 | def users = cleanUsers(permissions*.value)
44 |
45 | /*
46 | * Get a [user]:[roles] map
47 | */
48 | def permissionsByUser = users.inject([:]){ map, user ->
49 | map[user] = permissions.findAll{ it.value.contains(user)}.collect{it.key.name}
50 | map
51 | }
52 |
53 | /*
54 | * The matrix building
55 | */
56 | def usersPermissionsMatrix =[:]
57 |
58 | /*
59 | * Get all the roles defined in the role-strategy plugin
60 | */
61 | def roles = authStrategy.getRoleMap(authStrategy.GLOBAL).grantedRoles*.key.name.sort() + authStrategy.getRoleMap(authStrategy.PROJECT).grantedRoles*.key.name.sort()
62 |
63 | usersPermissionsMatrix["roles"] = roles
64 |
65 | /*
66 | * Algo:
67 | * For each user
68 | * For each role
69 | * matrix[user][role] = hasPermission(user, role)
70 | * Done
71 | * Done
72 | */
73 | users.each{ user ->
74 | usersPermissionsMatrix[user] = roles.inject([]){ list, role ->
75 | list << permissionsByUser[user].contains(role)
76 | }
77 | }
78 |
79 | /*
80 | * We're done!! it's time to export the work.
81 | */
82 | println export(usersPermissionsMatrix, csv)
83 |
84 | }else{
85 | println "Not able to list the permissions by user"
86 | }
87 |
--------------------------------------------------------------------------------
/scriptler/svnChangeBranch.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "svnChangeBranch",
3 | "comment" : "Batch switch svn jobs to a different branch. JobFilter and URL filter are regular expression to select Job/SVN urls to replace. newBranch is the new value to set, oldBranch is the expression to replace (defaults to \'/branches/[^/]* /\' which replaces the url part after branches. No actual changes will be made unless applyChanges is set to \'true\'",
4 | "parameters" : [ 'jobFilter', 'urlFilter', 'newBranch', 'oldBranch', 'applyChanges' ],
5 | "core": "1.499",
6 | "authors" : [
7 | { name : "thosor" }, { name : "AVee" }
8 | ]
9 | } END META**/
10 |
11 | /*
12 | * Based on http://scriptlerweb.appspot.com/script/show/48001
13 | *
14 | * Currently largely untested, although it seems to work, check your results!
15 | */
16 |
17 | import hudson.scm.*
18 |
19 | // Default to replacing the part after .../branches/ with the value of newBranch.
20 | if(null == oldBranch || "".equals(oldBranch)) {
21 | oldBranch = "/branches/([^/])*/"
22 | newBranch = "/branches/$newBranch/"
23 | }
24 |
25 | /** Display Configuration */
26 | println "### Overwrite SVN-Version ###"
27 | println "oldVersion: " + oldBranch
28 | println "New branch: " + newBranch
29 | println "Job Filter: " + jobFilter
30 | println "Url Filter: " + urlFilter
31 | println "Apply Changes: " + applyChanges
32 |
33 |
34 | // Access to the Hudson Singleton
35 | hudsonInstance = hudson.model.Hudson.instance
36 |
37 | // Retrieve matching jobs
38 | allItems = hudsonInstance.items
39 | chosenJobs = allItems.findAll{job -> job.name =~ /$jobFilter/}
40 |
41 | // Do work and create the result table
42 | chosenJobs.each { job ->
43 | if(!(job instanceof hudson.model.ExternalJob)) {
44 | // No SCM-Configuration possible for External Jobs!
45 | if (job.scm instanceof SubversionSCM) {
46 | println ""
47 | println job.name
48 |
49 | // Job has a SubversionSCM-Configuration
50 | def newSvnPath = [][]
51 |
52 | job.scm.locations.each{
53 | //For every Subversion-Location
54 | println "- $it.remote"
55 |
56 | if (it.remote =~ /$urlFilter/) {
57 | //SVN-Path contains the given Path
58 |
59 | newRemote = it
60 |
61 | match = it.remote =~ /$oldBranch/
62 |
63 | if(match) {
64 | newRemote = match.replaceFirst(newBranch)
65 | println " -> $newRemote"
66 | newSvnPath.add(it.withRemote(newRemote))
67 | } else {
68 | println " Doesn't match oldBranch"
69 | newSvnPath.add(it)
70 | }
71 | } else {
72 | println " Doesn't match urlFilter"
73 | }
74 | }
75 |
76 | // Every Location was checked. Building new SVN-Configuration with the new SVN-Locations
77 | newscm = new hudson.scm.SubversionSCM(newSvnPath, job.scm.workspaceUpdater, job.scm.browser,
78 | job.scm.excludedRegions, job.scm.excludedUsers, job.scm.excludedRevprop,
79 | job.scm.excludedCommitMessages, job.scm.includedRegions,
80 | job.scm.ignoreDirPropChanges, job.scm.filterChangelog, job.scm.additionalCredentials)
81 | if(newscm.getLocations().size() == newSvnPath.size())
82 | {
83 | if ("true".equals(applyChanges)){
84 | // Only write values, when applyChanges is true
85 | println "Saving $job.name"
86 | job.scm = newscm
87 | }
88 | } else {
89 | println "ERROR: SVN SubversionSCM didn't pick up the new path."
90 | }
91 | //Job is done
92 | }
93 | }
94 | }
95 | //done
96 |
--------------------------------------------------------------------------------
/scriptler/pluginDependenciesReport.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Plugin Dependencies Report",
3 | "comment" : "Get information about direct and recursive (JSON object) dependencies of/to a specific plugin.",
4 | "parameters" : [ "pluginShortName" ],
5 | "core": "1.609",
6 | "authors" : [
7 | { name : "Allan Burdajewicz" }
8 | ]
9 | } END META**/
10 |
11 | import hudson.PluginWrapper
12 | import jenkins.model.Jenkins
13 |
14 | /***********************************************************************************************
15 | * Following methods analyze dependencies of a particular plugin, for example the `git-plugin`.*
16 | ***********************************************************************************************/
17 |
18 | def pluginByName = Jenkins.instance.getPluginManager().getPlugin(pluginShortName);
19 |
20 | /**
21 | * Get the dependencies (direct) of a particular plugin.
22 | */
23 | println "\nDEPENDENCIES (DIRECT) of ${pluginByName.getShortName()} (${pluginByName.getVersion()}):"
24 | /**
25 | * Get the direct dependencies of a particular plugin.
26 | */
27 | pluginByName.getDependencies().each {
28 | println "${it.shortName} (${it.version})"
29 | };
30 |
31 | println "\nDEPENDENCIES (Recursive JSON) of ${pluginByName.getShortName()} (${pluginByName.getVersion()}):"
32 | /**
33 | * Get a complete JSON object of the dependencies (recursively) of a particular plugin.
34 | * @param plugin The Plugin
35 | */
36 | def void getDependenciesJSON(PluginWrapper plugin) {
37 | print "{\"plugin\":\"${plugin.getShortName()}\", \"version\":\"${plugin.getVersion()}\"";
38 | def deps = plugin.getDependencies();
39 | if (!deps.isEmpty()) {
40 | def i;
41 | print ", \"dependencies\":["
42 | for (i = 0; i < deps.size() - 1; i++) {
43 | getDependenciesJSON(Jenkins.instance.getPluginManager().getPlugin(deps.get(i).shortName));
44 | print ","
45 | }
46 | getDependenciesJSON(Jenkins.instance.getPluginManager().getPlugin(deps.get(i).shortName));
47 | print "]"
48 | }
49 | print "}"
50 | }
51 | getDependenciesJSON(pluginByName);
52 |
53 | println "\n\nDEPENDANTS (DIRECT) of ${pluginByName.getShortName()} (${pluginByName.getVersion()}):"
54 | /**
55 | * Get the plugins that depend (directly) on a particular plugin.
56 | */
57 | Jenkins.instance.getPluginManager().getPlugins()
58 | .findAll { plugin ->
59 | plugin.getDependencies().find {
60 | dependency -> pluginShortName.equals(dependency.shortName)
61 | }
62 | }.each {
63 | println "${it.getShortName()} (${it.getVersion()})"
64 | };
65 |
66 | println "\nDEPENDANTS (Recursive JSON) of ${pluginByName.getShortName()} (${pluginByName.getVersion()}):"
67 | /**
68 | * Get a complete JSON object of the dependants (recursively) of a particular plugin.
69 | * @param plugin The Plugin
70 | */
71 | def void getDependantsJSON(PluginWrapper plugin) {
72 | print "{\"plugin\":\"${plugin.getShortName()}\", \"version\":\"${plugin.getVersion()}\"";
73 | def deps = Jenkins.instance.getPluginManager().getPlugins().findAll { depCandidate ->
74 | depCandidate.getDependencies().find {
75 | dependency -> plugin.shortName.equals(dependency.shortName)
76 | }
77 | }
78 | if (!deps.isEmpty()) {
79 | def i;
80 | print ", \"dependants\":["
81 | for (i = 0; i < deps.size() - 1; i++) {
82 | getDependantsJSON(Jenkins.instance.getPluginManager().getPlugin(deps.get(i).shortName));
83 | print ","
84 | }
85 | getDependantsJSON(Jenkins.instance.getPluginManager().getPlugin(deps.get(i).shortName));
86 | print "]"
87 | }
88 | print "}"
89 | }
90 | println(getDependantsJSON(pluginByName));
91 |
--------------------------------------------------------------------------------
/scriptler/disableAndCleanUpOldJobs.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "disable and clean up workspace for old jobs",
3 | "comment" : "Disable and clean up workspace for jobs that were built more than 90 day ago",
4 | "parameters" : [],
5 | "core": "1.300",
6 | "authors" : [
7 | { name : "Dmitriy Slupytskyi" }
8 | ]
9 | } END META**/
10 |
11 | import hudson.model.*
12 | import hudson.node_monitors.*
13 | import hudson.slaves.*
14 | import hudson.FilePath
15 | import java.util.concurrent.*
16 |
17 | jenkins = Hudson.instance
18 |
19 | // Define day to compare (will find builds that were built more than n day ago)
20 | day=90;
21 | hour=24;
22 | minute=60;
23 | second=60;
24 | daysInSecond=day*hour*minute*second;
25 | now=Calendar.instance;
26 | list=[];
27 | listFreezeBuild=[];
28 | listProceeded=[];
29 |
30 | println("The build is run at ${now.time}");
31 |
32 | println("\n### GET LIST OF ALL JOBS ###\n")
33 |
34 | for (item in jenkins.items) {
35 | println("\tProcessing ${item.name}...")
36 | // ignore project that contains freeze or patch case insensitive
37 | if (item.name ==~ /(?i)(freeze|patch).*/) {
38 | // add item to list
39 | listFreezeBuild << item;
40 | } else if (!item.disabled&&item.getLastBuild()!=null) {
41 | // caculate build time
42 | build_time=item.getLastBuild().getTimestamp();
43 | // compare build time with current time
44 | if (now.time.time/1000-build_time.time.time/1000>daysInSecond) {
45 | // add item to list
46 | list << item;
47 | }
48 | }
49 | }
50 |
51 | println("\n### DISABLE OLD JOBS ###\n")
52 |
53 | def disableJob(item) {
54 | if (item.class.canonicalName != 'com.cloudbees.hudson.plugins.folder.Folder') {
55 | // disable item
56 | item.disabled=true;
57 | // save
58 | item.save();
59 | }
60 | }
61 |
62 | def pushLogRotate(item) {
63 | // perform log rotation
64 | item.logRotate();
65 | }
66 |
67 | def wipeOutWorkspace(item) {
68 | // check if build is not in building stage
69 | if(!item.isBuilding()) {
70 | try {
71 | // wipe out the workspace
72 | item.doDoWipeOutWorkspace();
73 | }
74 | catch (ex) {
75 | println("Error: " + ex);
76 | }
77 | }
78 | }
79 |
80 | def wipeOutWorkspaceFromSlaves(item) {
81 | for (slave in hudson.model.Hudson.instance.slaves) {
82 | // get slave name
83 | slaveNodeName = slave.getNodeName();
84 | println("\t\tCheck ${slaveNodeName} slave...");
85 | // get workspace root for specify slave
86 | workspaceRoot = slave.getWorkspaceRoot();
87 | // create path slave with workspace
88 | FilePath fp = slave.createPath(workspaceRoot.toString() + File.separator + item.name);
89 | // check that workspace root exists and path to workspace exists
90 | if ((workspaceRoot != null) && (fp.exists())) {
91 | // delete workspace recursively
92 | println("\t\tWipe out ${fp}...")
93 | try {
94 | fp.deleteRecursive();
95 | }
96 | catch (ex) {
97 | println("Error: " + ex);
98 | }
99 | }
100 | }
101 | }
102 |
103 | if (list.size() > 0) {
104 | for (item in list) {
105 | println("\tDisabling ${item.name}...");
106 | disableJob(item);
107 | println("\tPush log rotate for ${item.name}...");
108 | pushLogRotate(item);
109 | println("\tWipe out workspace for ${item.name}...");
110 | wipeOutWorkspace(item);
111 | println("\tWipe out workspace for ${item.name} from slaves...")
112 | wipeOutWorkspaceFromSlaves(item);
113 | // add item to list
114 | listProceeded << item;
115 | }
116 | }
117 |
118 | println("\n### SUMMARY INFORMATION ###\n");
119 |
120 | if (listFreezeBuild.size() > 0) {
121 | println("Next jobs were ignored as it is a freeze or patch build:")
122 | for (item in listFreezeBuild) {
123 | println("\t${item.name}");
124 | }
125 | }
126 |
127 | if (listProceeded.size() > 0) {
128 | println("Next jobs were procced, disabled and cleaned workspace:")
129 | for (item in listProceeded) {
130 | println("\t${item.name}");
131 | }
132 | }
133 |
134 | return 0;
135 |
--------------------------------------------------------------------------------
/scriptler/addJabberNotification.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Add Jabber Notification",
3 | "comment" : "Add jabber notifications to the specified jobs",
4 | "parameters" : [ 'views', 'jobs', 'targets', 'strategy', 'notifyOnBuildStart', 'notifySCMCommitters', 'notifySCMCulprits', 'notifyUpstreamCommitters', 'notifySCMFixers'],
5 | "core": "1.409",
6 | "authors" : [
7 | { name : "Eric Dalquist" }
8 | ]
9 | } END META**/
10 |
11 | import hudson.maven.*
12 | import hudson.maven.reporters.*
13 | import hudson.model.*
14 | import hudson.plugins.im.*
15 | import hudson.plugins.im.build_notify.*
16 | import hudson.plugins.jabber.im.transport.*
17 | import hudson.tasks.*
18 |
19 | def viewNames = "${views}";
20 | viewNames = viewNames.split(",");
21 | def jobNames = "${jobs}";
22 | jobNames = jobNames.split(",");
23 |
24 | println("Views: " + viewNames);
25 | println("Jobs: " + jobNames);
26 | println();
27 |
28 | def targetsAsString = "${targets}"; //chat@conferences.example.com
29 | def notificationStrategy = "${strategy}"; //"failure and fixed"
30 | def notifyGroupChatsOnBuildStart = "${notifyOnBuildStart}".toBoolean(); // true/false
31 | def notifySuspects = "${notifySCMCommitters}".toBoolean(); // true/false
32 | def notifyCulprits = "${notifySCMCulprits}".toBoolean(); // true/false
33 | def notifyUpstreamCommitter = "${notifyUpstreamCommitters}".toBoolean(); // true/false
34 | def notifyFixers = "${notifySCMFixers}".toBoolean(); // true/false
35 |
36 | def items = new LinkedHashSet();
37 |
38 | if (viewNames != null && viewNames != "") {
39 | for (viewName in viewNames) {
40 | viewName = viewName.trim();
41 | def view = Hudson.instance.getView(viewName)
42 | items.addAll(view.getItems());
43 | }
44 | }
45 |
46 | if (jobNames != null && jobNames != "") {
47 | for (jobName in jobNames) {
48 | jobName = jobName.trim();
49 | def job = Hudson.instance.getJob(jobName)
50 | items.add(job);
51 | }
52 | }
53 |
54 | def conv = new JabberIMMessageTargetConverter();
55 | def targetsSplit = targetsAsString.split("\\s");
56 | println(targetsSplit);
57 |
58 | List targets = new ArrayList(targetsSplit.length);
59 | for (String target : targetsSplit) {
60 | def msgTarget = conv.fromString(target);
61 | if (msgTarget != null) {
62 | targets.add(msgTarget);
63 | }
64 | }
65 | def printPublisher = { publisher ->
66 | println(publisher);
67 | println("\t" + publisher.getTargets());
68 | println("\t" + publisher.getNotificationStrategy());
69 | println("\t" + publisher.getStrategy());
70 | println("\t" + publisher.getNotifyOnStart());
71 | println("\t" + publisher.getNotifySuspects());
72 | println("\t" + publisher.getNotifyCulprits());
73 | println("\t" + publisher.getNotifyFixers());
74 | println("\t" + publisher.getNotifyUpstreamCommitters());
75 | };
76 |
77 |
78 | // For each project
79 | for(item in items) {
80 | println(item.name + ": Checking for jabber notifiers");
81 | // Find current recipients defined in project
82 | if(!(item instanceof ExternalJob)) {
83 | for (Iterator publishersItr = item.publishersList.iterator(); publishersItr.hasNext();) {
84 | def publisher = publishersItr.next();
85 | if (publisher instanceof JabberPublisher) {
86 | addedToPublisher = true;
87 | println("Deleting:");
88 | printPublisher(publisher);
89 |
90 | publishersItr.remove();
91 | }
92 | }
93 |
94 | def newPublisher = new JabberPublisher(
95 | targets,
96 | notificationStrategy,
97 | notifyGroupChatsOnBuildStart,
98 | notifySuspects,
99 | notifyCulprits,
100 | notifyFixers,
101 | notifyUpstreamCommitter,
102 | new DefaultBuildToChatNotifier(),
103 | MatrixJobMultiplier.ONLY_CONFIGURATIONS);
104 |
105 | println("Adding:");
106 | printPublisher(newPublisher);
107 | item.publishersList.add(newPublisher);
108 | }
109 | }
--------------------------------------------------------------------------------
/scriptler/jMavenMultiModuleJobsDisasterRecovery.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "Maven Multi-module Jobs Disaster Recovery",
3 | "comment" : "If for any reason (e.g., an incorrect global configuration) many builds of many jobs fail, you'd have to spend a lot of time cleaning them. This plugin removes, for each job, all the builds to the last successful and resets the number of the next build properly (lastSuccessful+1). It seems to work also for multi-configuration multi-module maven projects. It's possible to conduct a dry run test using a parameter (default true) you could never guess;)",
4 | "parameters" : [ 'dryRun' ],
5 | "authors" : [
6 | { name : "Giacomo Boccardo" }
7 | ]
8 | } END META**/
9 |
10 |
11 | import hudson.matrix.MatrixConfiguration
12 | import hudson.matrix.MatrixProject
13 | import hudson.maven.MavenModuleSet
14 | import hudson.model.*
15 | import hudson.model.Fingerprint.RangeSet;
16 |
17 |
18 | // If you are not using Scriptler plugin, uncomment and change properly the following parameter
19 | // def dryRun = true
20 |
21 | def dryRunBool = dryRun.toBoolean()
22 |
23 |
24 | !dryRunBool ?: println("\n\n\n!!! DRY RUN !!!\n\n\n")
25 |
26 |
27 | def jobs = Hudson.instance.items
28 |
29 |
30 | // Disable all jobs to avoid dirty states,
31 | // but remember the jobs already disabled to avoid re-enabling them
32 | def disabledJobs = [:]
33 | println("[Disabling all the enabled jobs]")
34 | jobs.each{job ->
35 | disabledJobs[job.name] = job.disabled
36 | println(" * " + job.name + (job.disabled? " already": "") + " disabled")
37 | dryRunBool ?: (job.disabled=true)
38 | }
39 |
40 |
41 | println("\n[Cleaning all the jobs]")
42 | jobs.each{job ->
43 | // The builds' range to remove is [lastStableBuild + 1, lastBuild]
44 | def lSBNumber = job.getLastStableBuild()?.getNumber() ?: 1
45 | def lBNumber = job.getLastBuild()?.getNumber() ?: 1
46 | def jobName = job.name
47 |
48 | if ( job instanceof MavenModuleSet || job instanceof MatrixProject ) {
49 | if ( lSBNumber == lBNumber ) {
50 | println(" * " + jobName + " is already clean")
51 | } else {
52 | cleanJobRange(job, lSBNumber+1, lBNumber, dryRunBool, 2)
53 | }
54 | } else {
55 | println("Unknown job type " + job)
56 | }
57 | println "\n\n"
58 |
59 | }
60 |
61 | println("\n[Re-enabling only the jobs previously enabled]")
62 | jobs.each{job ->
63 | dryRunBool ?: (job.disabled=disabledJobs[job.name])
64 | println(" > " + job.name + (job.disabled ? " still disabled" : " enabled"))
65 | }
66 |
67 |
68 | def cleanJobRange(job, fromBuildNum, toBuildNum, dryRunBool, tab) {
69 | def delRange = fromBuildNum + "-" + toBuildNum
70 | def delRangeSet = RangeSet.fromString(delRange, true);
71 |
72 | def jobName = job.name
73 | println(" "*(tab-2) + " * " + jobName + " - Removing builds " + delRangeSet.min() + " -> " + (delRangeSet.max()-1))
74 |
75 | // Remove job's build
76 | def builds = job.getBuilds(delRangeSet)
77 | builds.each {
78 | dryRunBool ?: it.delete()
79 | println(" "*tab + " > " + it + " removed.")
80 | }
81 |
82 | def newNBNInt = fromBuildNum
83 | // Reset job's 'nextBuildNumber'
84 | dryRunBool ?: job.updateNextBuildNumber(newNBNInt)
85 | def jPNBN = job.getNextBuildNumber()
86 | def jNBN = dryRunBool ? newNBNInt : jPNBN
87 | println(" "*(tab+1) + jobName + "'s nextBuildNumber changed from " + jPNBN + " to " + jNBN + ".")
88 |
89 |
90 | if ( job instanceof MavenModuleSet ) {
91 | // Reset job's modules' 'nextBuildNumber'
92 | job.getModules().each{module ->
93 | def prevNBN = module.getNextBuildNumber()
94 | dryRunBool ?: module.updateNextBuildNumber(newNBNInt)
95 | def mNBN = dryRunBool ? newNBNInt : module.getNextBuildNumber()
96 | println(" "*(tab+1) + " > " + module.name + "'s nextBuildNumber changed from " + prevNBN + " to " + mNBN)
97 | }
98 | } else if ( job instanceof MatrixProject ) {
99 | def mConfs = job.getActiveConfigurations()
100 | mConfs.each{ mConf ->
101 | cleanJobRange(mConf, fromBuildNum, toBuildNum, dryRunBool, tab+2)
102 | }
103 | } else if ( job instanceof MatrixConfiguration ) {
104 | // NOP
105 | } else {
106 | println("Something very strange happened if you read this message. Job: " + job)
107 | }
108 | }
--------------------------------------------------------------------------------
/managed-scripts/shell/installManagedJDK.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | usage() {
4 | cat <<_eof_
5 |
6 | Why this? Because Oracle doesn't want you to download the JDK from Jenkins.
7 | As many times as the Jenkins team updates the FetcherCrawler, it breaks again
8 | the next week.
9 |
10 | Keep in mind that this will be downloaded and run for every Java step in every
11 | project, so make it run quick if it's a no-op. Might want to cache it locally,
12 | but I don't mind the small load this makes on my web server.
13 |
14 | This script needs a pretty specific file layout to work the way I wrote it. I
15 | intend to convert it to Groovy at some point and make it more automagical.
16 |
17 | What might break? Permissions, permissions, permissions. Creating, updating
18 | and deleting directories might not work if your system is all wonky. If you
19 | get permissions problems, just delete the ${jdkName} and ${thisJdkDir}
20 | directories and make sure that ${toolsDir} is writable.
21 |
22 | 1) Download whichever .bin or .sh files you want for whichever platforms you
23 | need. We are a Linux/Solaris shop, so I get all of those and put them in a
24 | directory.
25 |
26 | e.g.
27 | jdk-6u32-linux-i586.bin
28 | jdk-6u32-linux-x64.bin
29 | jdk-6u32-solaris-i586.sh
30 | jdk-6u32-solaris-sparc.sh
31 | jdk-6u32-solaris-sparcv9.sh
32 | jdk-6u32-solaris-x64.sh
33 |
34 | 2) Now create the .list files for each platform. It's pretty easy. The script
35 | uses jdk-6-\$(uname -s)_\$(uname -m) to find the correct file. Note that current
36 | Solaris sparc comes in sun4u and sun4v flavors on the machine side, so
37 | symlink the sparc one. Don't use binary (-b) mode with md5sum here because we
38 | parse the output of that file later.
39 |
40 | e.g.
41 | md5sum jdk-6u32-linux-i586.bin > jdk-6-Linux_i686.list
42 | md5sum jdk-6u32-linux-x64.bin > jdk-6-Linux_x86_64.list
43 | md5sum jdk-6u32-solaris-sparc*.sh > jdk-6-SunOS_sparc.list
44 | ln -s ./jdk-6-SunOS_sparc.list jdk-6-SunOS_sun4u.list
45 | ln -s ./jdk-6-SunOS_sparc.list jdk-6-SunOS_sun4v.list
46 | md5sum jdk-6u32-solaris-*6*.sh > jdk-6-SunOS_i86pc.list
47 |
48 | 3) Update this script with the version you are using. Should probably make
49 | that updatable externally, but there's a lot of other manual stuff already.
50 | You'll also need to set your webroot and jdkName once.
51 |
52 | 4) Make all of this available from a web server.
53 |
54 | 5) Configure Jenkins JDK Installations with this:
55 | Name: ${jdkName}
56 | Install automatically: checked
57 | Add Installer -> Run Command
58 | Label: Either blank or something that includes only your Unix boxes
59 | Command: env -i PATH=/usr/bin:/usr/sfw/bin wget -q $webroot/$(basename $0) -O - | bash
60 | Tool Home: .
61 |
62 | _eof_
63 | exit 1
64 | }
65 |
66 |
67 | cd /
68 |
69 | version=1.6.0_32
70 | webroot=http://your.web.url/tools
71 | jdkName=sun-java6-jdk
72 |
73 | unset http_proxy https_proxy ftp_proxy
74 | PATH=/usr/xpg4/bin:/usr/bin:/usr/sfw/bin:$PATH
75 |
76 | if ! type wget >/dev/null 2>&1; then
77 | echo "ERROR: Unable to run wget"
78 | exit 1
79 | fi
80 |
81 | : ${JENKINS_HOME:=~jenkins}
82 | toolsDir=$JENKINS_HOME/tools
83 | jdkDir=$toolsDir/$jdkName
84 | thisJdkDir=$toolsDir/jdk$version
85 |
86 | while getopts h Option
87 | do
88 | case "$Option" in
89 | h) usage ;;
90 | esac
91 | done
92 | shift $((OPTIND - 1))
93 |
94 |
95 |
96 | if [ -x $jdkDir/bin/java ]; then
97 | JAVA_HOME=$jdkDir
98 | if $JAVA_HOME/bin/java -version 2>&1 | grep -q "$version"; then
99 | exit 0
100 | fi
101 | fi
102 |
103 | rm -rf /tmp/jdkInstaller.$$ $thisJdkDir
104 | mkdir -p /tmp/jdkInstaller.$$ $thisJdkDir
105 |
106 | pushd /tmp/jdkInstaller.$$
107 |
108 | # Download and check md5sum
109 | md5Done=0
110 | jdkList=jdk-6-$(uname -s)_$(uname -m).list
111 | wget --no-verbose $webroot/$jdkList -O $jdkList
112 | while read md5sum file
113 | do
114 | wget --no-verbose $webroot/$file -O $file
115 |
116 | if type md5sum >/dev/null 2>&1; then
117 | if [[ $md5Done -eq 0 ]]; then
118 | if ! md5sum --check --status $jdkList; then
119 | echo "ERROR: md5sum --check $jdkList doesn't match"
120 | exit 1
121 | else
122 | md5Done=1
123 | fi
124 | fi
125 |
126 | elif type digest >/dev/null 2>&1; then
127 | digest=$(digest -a md5 $file 2>/dev/null)
128 | if [[ ${#digest} -eq 32 ]]; then
129 | if ! grep -q "$digest" $jdkList; then
130 | echo "ERROR: digest -a md5 of $file doesn't match"
131 | exit 1
132 | fi
133 | fi
134 |
135 | else
136 | echo "ERROR: No md5sum or digest -a md5 found."
137 | exit 1
138 |
139 | fi
140 |
141 | chmod 0755 $file
142 |
143 | pushd $toolsDir
144 | /tmp/jdkInstaller.$$/$file -noregister
145 | popd
146 |
147 | done < $jdkList
148 |
149 | popd
150 |
151 | rm -rf /tmp/jdkInstaller.$$
152 |
153 | rm -rf $jdkDir
154 | ln -s ./$(basename $thisJdkDir) $jdkDir
155 |
156 | exit 0
157 |
--------------------------------------------------------------------------------
/managed-scripts/python/gen-dep-graph/screenshots/output.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
99 |
--------------------------------------------------------------------------------
/scriptler/downloadRemoteWorkspace.groovy:
--------------------------------------------------------------------------------
1 | /*** BEGIN META {
2 | "name" : "sync two jenkins servers",
3 | "comment" : "This allows you to download a remote workspace folder and extract it to your present Jenkins.",
4 | "parameters" : [],
5 | "core": "1.300",
6 | "authors" : [
7 | { name : "Thomas Froehlich - mail@thomas-froehlich.net" }
8 | ]
9 | } END META**/
10 |
11 | import hudson.model.*
12 |
13 | import java.io.BufferedInputStream;
14 | import java.io.BufferedOutputStream;
15 | import java.io.File;
16 | import java.io.FileOutputStream;
17 | import java.io.IOException;
18 | import java.io.InputStream;
19 | import java.io.OutputStream;
20 | import java.net.URI;
21 | import java.util.Enumeration;
22 | import java.util.zip.ZipEntry;
23 | import java.util.zip.ZipFile;
24 |
25 | import org.apache.http.HttpEntity;
26 | import org.apache.http.HttpHost;
27 | import org.apache.http.HttpResponse;
28 | import org.apache.http.auth.AuthScope;
29 | import org.apache.http.auth.UsernamePasswordCredentials;
30 | import org.apache.http.client.AuthCache;
31 | import org.apache.http.client.ClientProtocolException;
32 | import org.apache.http.client.CredentialsProvider;
33 | import org.apache.http.client.methods.HttpGet;
34 | import org.apache.http.client.protocol.HttpClientContext;
35 | import org.apache.http.impl.auth.BasicScheme;
36 | import org.apache.http.impl.client.BasicAuthCache;
37 | import org.apache.http.impl.client.BasicCredentialsProvider;
38 | import org.apache.http.impl.client.CloseableHttpClient;
39 | import org.apache.http.impl.client.HttpClients;
40 |
41 | /*********************************************************************
42 | * Downloader
43 | */
44 |
45 | public static String getMethod(String urlString, String username, String password, String targetFolder) throws ClientProtocolException, IOException {
46 | URI uri = URI.create(urlString);
47 | HttpHost host = new HttpHost(uri.getHost(), uri.getPort(), uri.getScheme());
48 | CredentialsProvider credsProvider = new BasicCredentialsProvider();
49 | credsProvider.setCredentials(new AuthScope(uri.getHost(), uri.getPort()), new UsernamePasswordCredentials(username, password));
50 |
51 | // Create AuthCache instance
52 | AuthCache authCache = new BasicAuthCache();
53 |
54 | // Generate BASIC scheme object and add it to the local auth cache
55 | BasicScheme basicAuth = new BasicScheme();
56 | authCache.put(host, basicAuth);
57 | CloseableHttpClient httpClient = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build();
58 | HttpGet httpGet = new HttpGet(uri);
59 |
60 | // Add AuthCache to the execution context
61 | HttpClientContext localContext = HttpClientContext.create();
62 | localContext.setAuthCache(authCache);
63 |
64 | HttpResponse response = httpClient.execute(host, httpGet, localContext);
65 | HttpEntity entity = response.getEntity();
66 |
67 | File returnedFile = null;
68 | if(entity != null) {
69 | InputStream instream = entity.getContent();
70 |
71 | returnedFile = saveTmpFile(instream, new File(targetFolder));
72 | }
73 |
74 | if(returnedFile != null)
75 | return returnedFile.getAbsolutePath();
76 | else
77 | return "Failure.";
78 |
79 | //return EntityUtils.toString(response.getEntity());
80 | }
81 |
82 | public static File saveTmpFile(InputStream instream, File targetDir) throws IOException {
83 | if (!targetDir.exists()) {
84 | targetDir.mkdirs();
85 | }
86 |
87 | // make sure we get the actual file
88 | File zip = File.createTempFile("remote_workspace", ".zip", targetDir);
89 | OutputStream out = new BufferedOutputStream(new FileOutputStream(zip));
90 | copyInputStream(instream, out);
91 | out.close();
92 |
93 | return zip;
94 | }
95 |
96 | public static void copyInputStream(InputStream instream, OutputStream out) throws IOException {
97 | byte[] buffer = new byte[1024];
98 | int len = instream.read(buffer);
99 | while (len >= 0) {
100 | out.write(buffer, 0, len);
101 | len = instream.read(buffer);
102 | }
103 | instream.close();
104 | out.close();
105 | }
106 | /**************************************************************************************************************
107 | * Extractor and Timestamp updater
108 | */
109 | public void extractFolder(String zipFile, String targetFolder)
110 | {
111 | System.out.println(zipFile);
112 | int BUFFER = 2048;
113 | File file = new File(zipFile);
114 |
115 | ZipFile zip = new ZipFile(file);
116 |
117 | new File(targetFolder).mkdir();
118 | Enumeration zipFileEntries = zip.entries();
119 |
120 | // Process each entry
121 | while (zipFileEntries.hasMoreElements())
122 | {
123 | // grab a zip file entry
124 | ZipEntry entry = (ZipEntry) zipFileEntries.nextElement();
125 | String currentEntry = entry.getName();
126 | File destFile = new File(targetFolder, currentEntry);
127 | //destFile = new File(targetFolder, destFile.getName());
128 | File destinationParent = destFile.getParentFile();
129 |
130 | // create the parent directory structure if needed
131 | destinationParent.mkdirs();
132 |
133 | if (!entry.isDirectory())
134 | {
135 | BufferedInputStream is = new BufferedInputStream(zip
136 | .getInputStream(entry));
137 | int currentByte;
138 | // establish buffer for writing file
139 | byte[] data = new byte[BUFFER];
140 |
141 | // write the current file to disk
142 | FileOutputStream fos = new FileOutputStream(destFile);
143 | BufferedOutputStream dest = new BufferedOutputStream(fos,
144 | BUFFER);
145 |
146 | // read and write until last byte is encountered
147 | while ((currentByte = is.read(data, 0, BUFFER)) != -1) {
148 | dest.write(data, 0, currentByte);
149 | }
150 | dest.flush();
151 | dest.close();
152 | is.close();
153 | }
154 |
155 | if (currentEntry.endsWith(".zip"))
156 | {
157 | // found a zip file, try to open
158 | extractFolder(destFile.getAbsolutePath());
159 | }
160 | }
161 | }
162 |
163 | /**************************************************************************************************************
164 | * Script
165 | */
166 |
167 | // get current thread / Executor
168 | def thr = Thread.currentThread()
169 | // get current build
170 | def build = thr?.executable
171 |
172 | def resolver = build.buildVariableResolver
173 | def user_name = resolver.resolve("REMOTE_JENKINS_USER_NAME")
174 | def user_pw = resolver.resolve("REMOTE_JENKINS_USER_PW")
175 | def server = resolver.resolve("REMOTE_JENKINS_SERVER")
176 | def job = resolver.resolve("REMOTE_JENKINS_JOB")
177 | def target_folder = build.getWorkspace().toString()
178 |
179 | println "Using workspace folder " + target_folder;
180 | String file = getMethod(server + "/job/" + job + "/ws/*zip*/workspace.zip", user_name, user_pw, target_folder + "\\archives\\");
181 | println "Extracting " + file + " to " + target_folder;
182 | extractFolder(file, target_folder + "\\..\\");
183 |
--------------------------------------------------------------------------------
/managed-scripts/python/gen-dep-graph/LICENSE.txt:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright 2012 Toomas Römer
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
203 |
--------------------------------------------------------------------------------
/managed-scripts/shell/provision_jenkins.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #Created by Sam Gleske (https://github.com/samrocketman/home)
3 | #Wed May 20 11:09:18 EDT 2015
4 | #Mac OS X 10.9.5
5 | #Darwin 13.4.0 x86_64
6 | #GNU bash, version 3.2.53(1)-release (x86_64-apple-darwin13)
7 | #curl 7.30.0 (x86_64-apple-darwin13.0) libcurl/7.30.0 SecureTransport zlib/1.2.5
8 | #awk version 20070501
9 | #java version "1.7.0_55"
10 | #Java(TM) SE Runtime Environment (build 1.7.0_55-b13)
11 | #Java HotSpot(TM) 64-Bit Server VM (build 24.55-b03, mixed mode)
12 |
13 | #DESCRIPTION
14 | # Provisions a fresh Jenkins on a local laptop, updates the plugins, and runs
15 | # it.
16 | # 1. Creates a JENKINS_HOME.
17 | # 2. Downloads Jenkins.
18 | # 3. Updates the Jenkins plugins to the latest version.
19 |
20 | #USAGE
21 | # Automatically provision and start Jenkins on your laptop.
22 | # mkdir ~/jenkins_testing
23 | # cd ~/jenkins_testing
24 | # provision_jenkins.sh bootstrap
25 | # Kill and completely delete your provisioned Jenkins.
26 | # cd ~/jenkins_testing
27 | # provision_jenkins.sh purge
28 | # Update all plugins to the latest version using jenkins-cli
29 | # cd ~/jenkins_testing
30 | # provision_jenkins.sh update-plugins
31 | # Start or restart Jenkins.
32 | # cd ~/jenkins_testing
33 | # provision_jenkins.sh start
34 | # provision_jenkins.sh restart
35 | # Stop Jenkins.
36 | # provision_jenkins.sh stop
37 |
38 | #
39 | # USER CUSTOMIZED VARIABLES
40 | #
41 |
42 | #Latest Release
43 | jenkins_url="${jenkins_url:-http://mirrors.jenkins-ci.org/war/latest/jenkins.war}"
44 | #LTS Jenkins URL
45 | #jenkins_url="${jenkins_url:-http://mirrors.jenkins-ci.org/war-stable/latest/jenkins.war}"
46 | JENKINS_HOME="${JENKINS_HOME:-my_jenkins_home}"
47 | JENKINS_WEB="${JENKINS_WEB:-http://localhost:8080/}"
48 | JENKINS_CLI="${JENKINS_CLI:-java -jar ./jenkins-cli.jar -s ${JENKINS_WEB} -noKeyAuth}"
49 | JENKINS_START="${JENKINS_START:-java -jar jenkins.war}"
50 | #remove trailing slash
51 | JENKINS_WEB="${JENKINS_WEB%/}"
52 | CURL="${CURL:-curl}"
53 |
54 | #Get JAVA_HOME for java on Mac OS X
55 | #will only run if OS X is detected
56 | if uname -rms | grep Darwin &> /dev/null; then
57 | JAVA_HOME="$(/usr/libexec/java_home)"
58 | PATH="${JAVA_HOME}/bin:${PATH}"
59 | echo "JAVA_HOME=${JAVA_HOME}"
60 | java -version
61 | fi
62 |
63 | export jenkins_url JENKINS_HOME JAVA_HOME PATH JENKINS_CLI CURL
64 |
65 | #
66 | # SCRIPT CONSOLE SCRIPTS
67 | #
68 |
69 | function script_skip_wizard() {
70 | cat <<'EOF'
71 | import hudson.util.PluginServletFilter
72 | def j=Jenkins.instance
73 | if('getSetupWizard' in j.metaClass.methods*.name.sort().unique()) {
74 | def w=j.getSetupWizard()
75 | if(w != null) {
76 | try {
77 | w.completeSetup()
78 | }
79 | catch(Exception e) {
80 | //pre Jenkins 2.6
81 | w.completeSetup(j)
82 | PluginServletFilter.removeFilter(w.FORCE_SETUP_WIZARD_FILTER)
83 | }
84 | j.save()
85 | println 'Wizard skipped.'
86 | }
87 | }
88 | EOF
89 | }
90 |
91 | function script_disable_usage_stats() {
92 | echo 'Jenkins.instance.setNoUsageStatistics(true)'
93 | }
94 |
95 | function script_upgrade_plugins() {
96 | cat <<'EOF'
97 | import hudson.model.UpdateSite
98 |
99 | def j = Jenkins.instance
100 |
101 | /*
102 | Install Jenkins plugins
103 | */
104 | def install(Collection c, Boolean dynamicLoad, UpdateSite updateSite) {
105 | c.each {
106 | println "Installing ${it} plugin."
107 | UpdateSite.Plugin plugin = updateSite.getPlugin(it)
108 | Throwable error = plugin.deploy(dynamicLoad).get().getError()
109 | if(error != null) {
110 | println "ERROR installing ${it}, ${error}"
111 | }
112 | }
113 | null
114 | }
115 |
116 | //upgrade plugins
117 | UpdateSite s = (UpdateSite) j.getUpdateCenter().getSite(UpdateCenter.ID_DEFAULT)
118 |
119 | //download latest JSON update data
120 | s.updateDirectlyNow(true)
121 |
122 | install(s.getUpdates()*.getInstalled()*.getShortName(), false, s)
123 | EOF
124 | }
125 |
126 | function script_install_plugins() {
127 | cat < /dev/null; then
189 | export CURL="${CURL} -d ${CSRF_CRUMB}"
190 | echo "Using crumbs for CSRF support."
191 | fi
192 | fi
193 | }
194 |
195 | function is_auth_enabled() {
196 | no_authentication="$( $CURL -s ${JENKINS_WEB}/api/json?pretty=true 2> /dev/null | python -c 'import sys,json;exec "try:\n j=json.load(sys.stdin)\n print str(j[\"useSecurity\"]).lower()\nexcept:\n pass"' )"
197 | #check if authentication is required.;
198 | #if the value of no_authentication is anything but false; then assume authentication
199 | if [ ! "${no_authentication}" = "false" ]; then
200 | echo -n "Authentication required..."
201 | if [ -e "${JENKINS_HOME}/secrets/initialAdminPassword" ]; then
202 | echo "DONE"
203 | return 0
204 | else
205 | echo "FAILED"
206 | echo "Could not set authentication."
207 | echo "Missing file: ${JENKINS_HOME}/secrets/initialAdminPassword"
208 | exit 1
209 | fi
210 | fi
211 | return 1
212 | }
213 |
214 | function url_ready() {
215 | url="$1"
216 | echo -n "Waiting for ${url} to become available."
217 | while [ ! "200" = "$(curl -sLiI -w "%{http_code}\\n" -o /dev/null ${url})" ]; do
218 | echo -n '.'
219 | sleep 1
220 | done
221 | echo 'ready.'
222 | }
223 |
224 | function download_file() {
225 | #see bash man page and search for Parameter Expansion
226 | if [ "$#" = 1 ]; then
227 | url="$1"
228 | file="${1##*/}"
229 | else
230 | url="$1"
231 | file="$2"
232 | fi
233 | url_ready "${url}"
234 | if [ ! -e "${file}" ]; then
235 | curl -SLo "${file}" "${url}"
236 | fi
237 | }
238 |
239 | function jenkins_status() {
240 | #check to see if jenkins is running
241 | #will return exit status 0 if running or 1 if not running
242 | STATUS=1
243 | if [ -e "jenkins.pid" ]; then
244 | ps aux | grep -v 'grep' | grep 'jenkins\.war' | grep "$(cat jenkins.pid)" &> /dev/null
245 | STATUS=$?
246 | fi
247 | return ${STATUS}
248 | }
249 |
250 | function start_or_restart_jenkins() {
251 | #start Jenkins, if it's already running then stop it and start it again
252 | if [ -e "jenkins.pid" ]; then
253 | echo -n 'Jenkins might be running so attempting to stop it.'
254 | kill $(cat jenkins.pid)
255 | #wait for jenkins to stop
256 | while jenkins_status; do
257 | echo -n '.'
258 | sleep 1
259 | done
260 | rm jenkins.pid
261 | echo 'stopped.'
262 | fi
263 | echo 'Starting Jenkins.'
264 | ${JENKINS_START} >> console.log 2>&1 &
265 | echo "$!" > jenkins.pid
266 | }
267 |
268 | function stop_jenkins() {
269 | if [ -e "jenkins.pid" ]; then
270 | echo -n 'Jenkins might be running so attempting to stop it.'
271 | kill $(cat jenkins.pid)
272 | #wait for jenkins to stop
273 | while ps aux | grep -v 'grep' | grep "$(cat jenkins.pid)" &> /dev/null; do
274 | echo -n '.'
275 | sleep 1
276 | done
277 | rm jenkins.pid
278 | echo 'stopped.'
279 | fi
280 | }
281 |
282 | function update_jenkins_plugins() {
283 | #download the jenkins-cli.jar client
284 | download_file "${JENKINS_WEB}/jnlpJars/jenkins-cli.jar"
285 | echo 'Updating Jenkins Plugins using jenkins-cli.'
286 | UPDATE_LIST="$( ${JENKINS_CLI} list-plugins | awk '$0 ~ /\)$/ { print $1 }' )"
287 | if [ ! -z "${UPDATE_LIST}" ]; then
288 | ${JENKINS_CLI} install-plugin ${UPDATE_LIST}
289 | fi
290 | }
291 |
292 | function jenkins_cli() {
293 | #download the jenkins-cli.jar client
294 | download_file "${JENKINS_WEB}/jnlpJars/jenkins-cli.jar"
295 | echo "Executing: ${JENKINS_CLI} $@"
296 | ${JENKINS_CLI} $@
297 | }
298 |
299 | function force-stop() {
300 | if [ -e 'jenkins.pid' ]; then
301 | kill -9 $(cat jenkins.pid) 2> /dev/null
302 | rm -f jenkins.pid
303 | fi
304 | }
305 |
306 | #
307 | # main execution
308 | #
309 |
310 | case "$1" in
311 | bootstrap)
312 | shift
313 | skip_restart='false'
314 | while [ "$#" -gt '0' ]; do
315 | case $1 in
316 | --skip-restart)
317 | skip_restart='true'
318 | shift
319 | ;;
320 | *)
321 | echo "Error invalid arument provided to bootstrap command: $1"
322 | exit 1
323 | ;;
324 | esac
325 | done
326 |
327 | #provision Jenkins by default
328 | #download jenkins.war
329 | download_file ${jenkins_url} jenkins.war
330 |
331 | echo "JENKINS_HOME=${JENKINS_HOME}"
332 |
333 | start_or_restart_jenkins
334 |
335 | url_ready "${JENKINS_WEB}/jnlpJars/jenkins-cli.jar"
336 |
337 | #try enabling authentication
338 | if is_auth_enabled; then
339 | export CURL="${CURL} -u admin:$(<${JENKINS_HOME}/secrets/initialAdminPassword)"
340 | fi
341 |
342 | #try enabling CSRF protection support
343 | csrf_set_curl
344 |
345 | jenkins_script_console script_skip_wizard
346 | jenkins_script_console script_disable_usage_stats
347 | jenkins_script_console script_upgrade_plugins
348 | jenkins_script_console script_install_plugins "credentials-binding,git,github,github-oauth,job-dsl,matrix-auth,matrix-project,pipeline-stage-view,ssh-slaves,workflow-aggregator"
349 |
350 | if ! ${skip_restart}; then
351 | start_or_restart_jenkins
352 | url_ready "${JENKINS_WEB}/jnlpJars/jenkins-cli.jar"
353 | fi
354 |
355 | echo "Jenkins is ready. Visit ${JENKINS_WEB}/"
356 | if is_auth_enabled &> /dev/null; then
357 | echo "User: admin"
358 | echo "Password: $(<${JENKINS_HOME}/secrets/initialAdminPassword)"
359 | fi
360 | ;;
361 | download-file)
362 | shift
363 | download_file "$1"
364 | ;;
365 | clean)
366 | force-stop
367 | rm -f console.log jenkins.pid
368 | rm -rf "${JENKINS_HOME}"
369 | ;;
370 | cli)
371 | shift
372 | jenkins_cli $@
373 | ;;
374 | install-plugins)
375 | shift
376 | #try enabling authentication
377 | if is_auth_enabled; then
378 | export CURL="${CURL} -u admin:$(<${JENKINS_HOME}/secrets/initialAdminPassword)"
379 | fi
380 | #try enabling CSRF protection support
381 | csrf_set_curl
382 | jenkins_script_console script_install_plugins "$@"
383 | ;;
384 | update-plugins)
385 | update_jenkins_plugins
386 | echo 'Jenkins may need to be restarted.'
387 | ;;
388 | purge)
389 | force-stop
390 | rm -f console.log jenkins-cli.jar jenkins.pid jenkins.war
391 | rm -rf "${JENKINS_HOME}"
392 | ;;
393 | start|restart)
394 | start_or_restart_jenkins
395 | ;;
396 | status)
397 | if jenkins_status; then
398 | echo 'Jenkins is running.'
399 | exit 0
400 | else
401 | echo 'Jenkins is not running.'
402 | exit 1
403 | fi
404 | ;;
405 | stop)
406 | stop_jenkins
407 | ;;
408 | url-ready)
409 | shift
410 | url_ready "$1"
411 | ;;
412 | *)
413 | cat <<- "EOF"
414 | SYNOPSIS
415 | provision_jenkins.sh [command] [additional arguments]
416 |
417 | DESCRIPTION
418 | Additional arguments are only available for commands that support it.
419 | Otherwise, additional arguments will be ignored.
420 |
421 | Provisions a fresh Jenkins on a local laptop, updates the plugins, and runs
422 | it. Creates a JAVA_HOME. Downloads Jenkins. Updates the Jenkins plugins to
423 | the latest version.
424 |
425 | COMMANDS
426 | bootstrap The bootstrap behavior is to provision Jenkins.
427 | This command creates a JAVA_HOME, downloads
428 | Jenkins, and updates the plugins to the latest
429 | version. Additionally, it will install the git,
430 | github, and github-oauth plugins.
431 |
432 | cli [args] This command takes additional arguments. All
433 | arguments are passed through to jenkins-cli.jar.
434 |
435 | clean WARNING: destructive command. Kills the current
436 | instance of Jenkins, deletes JENKINS_HOME, removes
437 | the jenkins.pid file, and removes the console.log.
438 | Use this when you want start from scratch but don't
439 | want to download the latest Jenkins.
440 |
441 | download-file URL Wait for a file to become available and then
442 | download it. This command is useful for
443 | automation.
444 |
445 | install-plugins [args] This command takes additional arguments. The
446 | additional arguments are one or more Jenkins plugin
447 | IDs.
448 |
449 | purge WARNING: destructive command. Deletes all files
450 | related to the provisioned Jenkins including the
451 | war file and JENKINS_HOME. If Jenkins is running
452 | it will be sent SIGKILL.
453 |
454 | start or start and restart do the same thing. If Jenkins is
455 | restart not running then it will start it. If Jenkins is
456 | already running then it will stop Jenkins and start
457 | it again.
458 |
459 | stop Will gracefully shutdown Jenkins and leave the
460 | JENKINS_HOME intact.
461 |
462 | update-plugins Updates all unpinned plugins in Jenkins to their
463 | latest versions.
464 |
465 | url-ready URL Wait for a URL to become available. This command
466 | is useful for automation.
467 |
468 | EXAMPLE USAGE
469 | Automatically provision and start Jenkins on your laptop.
470 | mkdir ~/jenkins_testing
471 | cd ~/jenkins_testing
472 | provision_jenkins.sh bootstrap
473 |
474 | Kill and completely delete your provisioned Jenkins.
475 | cd ~/jenkins_testing
476 | provision_jenkins.sh purge
477 |
478 | Update all plugins to the latest version using jenkins-cli
479 | cd ~/jenkins_testing
480 | provision_jenkins.sh update-plugins
481 |
482 | Install additional plugins e.g. the slack plugin.
483 | cd ~/jenkins_testing
484 | provision_jenkins.sh install-plugins slack
485 |
486 | Start or restart Jenkins.
487 | cd ~/jenkins_testing
488 | provision_jenkins.sh start
489 | provision_jenkins.sh restart
490 |
491 | Stop Jenkins.
492 | provision_jenkins.sh stop
493 |
494 | See Jenkins CLI help documentation.
495 | provision_jenkins.sh cli help
496 |
497 | Create a Job using Jenkins CLI.
498 | provision_jenkins.sh cli create-job my_job < config.xml
499 |
500 | EOF
501 | esac
502 |
503 |
--------------------------------------------------------------------------------