├── .gitignore ├── README.md ├── managed-scripts ├── groovy │ ├── README.md │ ├── enableShallowCloneOnAllAbstractProjects.groovy │ ├── enableShallowCloneOnAllWorkflowMultiBranchProjects.groovy │ └── enableShallowCloneOnAllWorkflowProjects.groovy ├── python │ ├── README.md │ └── gen-dep-graph │ │ ├── LICENSE.txt │ │ ├── gen-dep-graph.py │ │ ├── project.properties │ │ └── screenshots │ │ └── output.svg ├── ruby │ └── README.md └── shell │ ├── README.md │ ├── installManagedJDK.sh │ └── provision_jenkins.sh └── scriptler ├── BulkDeleteViews.groovy ├── README.md ├── addAnsiColorToAllJobs.groovy ├── addCredentials.groovy ├── addCredentialsToFolder.groovy ├── addGitCleanCheckout.groovy ├── addJabberNotification.groovy ├── addShellPreBuildStepToProject.groovy ├── addSlackNotification-1.8.groovy ├── barchartGitTagList.groovy ├── buildJobsMatchingPattern.groovy ├── bulkDeleteBuilds.groovy ├── bulkDeleteJenkinsBuildsExceptOne.groovy ├── bulkDeleteJobs.groovy ├── changeCredentialPassword.groovy ├── changeSecretText.groovy ├── checkDiskUsage.groovy ├── checkNodesLauncherVersion.groovy ├── checkPluginUpdateServer.groovy ├── checkSSLConnection.groovy ├── clearBuildQueue.groovy ├── clonebranches.groovy ├── configMavenAutoInstaller.groovy ├── countExecutors.groovy ├── deleteAllGlobalCredentials.groovy ├── deleteBuildLogHistory.groovy ├── disableAllJobs.groovy ├── disableAllJobsInAllFolders.groovy ├── disableAndCleanUpOldJobs.groovy ├── disableAutomaticMavenArchiving.groovy ├── disableBrokenJobs.groovy ├── disableEnableJobsMatchingPattern.groovy ├── disableJobsInFolder.groovy ├── disableSlaveNodeStartsWith.groovy ├── discardOldBuilds.groovy ├── downloadRemoteWorkspace.groovy ├── export-role-strategy-permissions-to-csv.groovy ├── findOfflineSlaves.groovy ├── findRunningPipelineJobs.groovy ├── getGitPollingRepositories.groovy ├── getJavaSecurityAlgorithmReport.groovy ├── getNextBuildNumbers.groovy ├── hashifyAllScmTriggers.groovy ├── injectAndManipulateBuildParameters.groovy ├── interruptPollingThreads.groovy ├── jMavenMultiModuleJobsDisasterRecovery.groovy ├── jMavenMultiModuleProjectBuildsCleaner.groovy ├── jira-publisher.groovy ├── jobExecutedInDateRange.groovy ├── listAllBuilds.groovy ├── listEC2Instances.groovy ├── listdisabledjobs.groovy ├── pluginDependenciesReport.groovy ├── pluginManagerSimpleReport.groovy ├── pluglist_print.groovy ├── purgeDockers.groovy ├── purgeM2Repo.groovy ├── purgeOldBuilds.groovy ├── reloadJobConfig.groovy ├── removeGitPluginBuildsByBranchBuildData.groovy ├── removeInvalidCredentials.groovy ├── restartDeadExecutors.groovy ├── searchJobConfiguration.groovy ├── setNextBuildNumbers.groovy ├── show-labels-overview.groovy ├── showAgentJavaVersion.groovy ├── showJavaVersionUseOnJob.groovy ├── svnChangeBranch.groovy ├── testMetaFormat.groovy ├── trigger-manipulator.groovy ├── trigger-via-snapshot-deps.groovy ├── updateEmailAddress.groovy ├── updateJobParameterDefinition.groovy ├── vaultAppRoleCredential.groovy ├── vaultTokenCredential.groovy ├── warn-if-looped-triggers.groovy ├── wipeout-workspace.groovy ├── workspace-cleaner.groovy └── zipFolder.groovy /.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 -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /managed-scripts/groovy/README.md: -------------------------------------------------------------------------------- 1 | # Groovy Jenkins scripts 2 | 3 | Scripts for Jenkins written in Groovy. 4 | -------------------------------------------------------------------------------- /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 -------------------------------------------------------------------------------- /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 -------------------------------------------------------------------------------- /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 -------------------------------------------------------------------------------- /managed-scripts/python/README.md: -------------------------------------------------------------------------------- 1 | # Python Jenkins scripts 2 | 3 | Scripts for Jenkins written in Python. 4 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /managed-scripts/python/gen-dep-graph/project.properties: -------------------------------------------------------------------------------- 1 | [jenkins] 2 | url=http://ci.jenkins-ci.org/api/python 3 | -------------------------------------------------------------------------------- /managed-scripts/python/gen-dep-graph/screenshots/output.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | G 11 | 12 | 13 | infra_update_center 14 | 15 | infra_update_center 16 | 17 | 18 | infra_update_center_mirror 19 | 20 | infra_update_center_mirror 21 | 22 | 23 | infra_update_center->infra_update_center_mirror 24 | 25 | 26 | 27 | 28 | libs_htmlunit 29 | 30 | libs_htmlunit 31 | 32 | 33 | kohsuke_github_api 34 | 35 | kohsuke_github_api 36 | 37 | 38 | libs_htmlunit->kohsuke_github_api 39 | 40 | 41 | 42 | 43 | plugins_jswidgets 44 | 45 | plugins_jswidgets 46 | 47 | 48 | libs_htmlunit->plugins_jswidgets 49 | 50 | 51 | 52 | 53 | libs_jexl 54 | 55 | libs_jexl 56 | 57 | 58 | libs_jelly 59 | 60 | libs_jelly 61 | 62 | 63 | libs_jexl->libs_jelly 64 | 65 | 66 | 67 | 68 | libs_json_lib 69 | 70 | libs_json_lib 71 | 72 | 73 | plugins_mercurial 74 | 75 | plugins_mercurial 76 | 77 | 78 | libs_json_lib->plugins_mercurial 79 | 80 | 81 | 82 | 83 | libs_svnkit 84 | 85 | libs_svnkit 86 | 87 | 88 | plugins_subversion 89 | 90 | plugins_subversion 91 | 92 | 93 | libs_svnkit->plugins_subversion 94 | 95 | 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /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/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/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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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/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/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/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/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/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/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/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/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 | } -------------------------------------------------------------------------------- /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/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/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 | -------------------------------------------------------------------------------- /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/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/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/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/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/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/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/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 | -------------------------------------------------------------------------------- /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/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/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/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/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/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/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/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/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/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/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 | -------------------------------------------------------------------------------- /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/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/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/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/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/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/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/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/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/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 | } -------------------------------------------------------------------------------- /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/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/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/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/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/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/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/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/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/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/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/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/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/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 | -------------------------------------------------------------------------------- /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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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 | --------------------------------------------------------------------------------