master ac8a7380255b cached
55 files
148.3 KB
38.6k tokens
1 requests
Download .txt
Repository: dennyzhang/cheatsheet-jenkins-groovy-A4
Branch: master
Commit: ac8a7380255b
Files: 55
Total size: 148.3 KB

Directory structure:
gitextract_5hxdtnyj/

├── .gitignore
├── 00-csrf.groovy
├── 00-disable-cli-remoting.groovy
├── 00-slave-to-master-access.groovy
├── README.org
├── addjobstoview-byregexp.groovy
├── build-monitor-views.xml
├── check-slave-jar-version.groovy
├── config-pipeline-library.groovy
├── config-slack.groovy
├── create-jenkins-job.groovy
├── create-jenkins-user.groovy
├── create-secret-text.groovy
├── delete-job-by-regexp.groovy
├── dict-to-json.groovy
├── docker-cleanup.groovy
├── enable-ldap.groovy
├── execute-command.groovy
├── files-folder.groovy
├── find-dead-executors.groovy
├── get-env.groovy
├── get-ip-by-hostname.groovy
├── git-checkout.groovy
├── git-commits-before-fail.groovy
├── git-list-tags-and-branches.groovy
├── jenkins-kubernetes-cloud.groovy
├── jenkins-permission.groovy
├── jenkins-url.groovy
├── jenkins-views.groovy
├── jenkins.security.QueueItemAuthenticatorConfiguration.xml
├── jenkinsfile-finally.groovy
├── jenkinsfile-parallelly.groovy
├── jenkinsfile-pass-parameter.groovy
├── jenkinsfile-sequentially.groovy
├── jenkinsfile-timeout-retry.groovy
├── json-file.groovy
├── keep-going-with-errors.groovy
├── kill-queued-jenkins.groovy
├── list-all-jenkins-agent.sh
├── list-all-jobs.groovy
├── logged-in-users.groovy
├── loop-map.groovy
├── manage-jenkins-jobs.groovy
├── master-executors.groovy
├── matrix-authorization-strategy.groovy
├── multi-line-string.groovy
├── print.groovy
├── regexp-match.groovy
├── relative-path.groovy
├── set-agent-env.groovy
├── slack-notification.groovy
├── split-string.groovy
├── string-to-json.groovy
├── timezone.groovy
└── validate-kubernetes-cloud.groovy

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
*.tex
.DS_Store
README.pdf


================================================
FILE: 00-csrf.groovy
================================================
// https://wiki.jenkins.io/display/JENKINS/CSRF+Protection
import hudson.security.csrf.DefaultCrumbIssuer
import jenkins.model.Jenkins
 
def instance = Jenkins.instance
instance.setCrumbIssuer(new DefaultCrumbIssuer(true))
instance.save()


================================================
FILE: 00-disable-cli-remoting.groovy
================================================
// https://stackoverflow.com/questions/44501596/jenkins-disable-cli-over-remoting-via-a-groovy-script
import jenkins.model.Jenkins

jenkins.model.Jenkins.instance.getDescriptor("jenkins.CLI").get().setEnabled(false)
Jenkins.instance.save()


================================================
FILE: 00-slave-to-master-access.groovy
================================================
// https://wiki.jenkins.io/display/JENKINS/Slave+To+Master+Access+Control
import jenkins.security.s2m.AdminWhitelistRule
import jenkins.model.Jenkins
Jenkins.instance.getInjector().getInstance(AdminWhitelistRule.class).setMasterKillSwitch(false)


================================================
FILE: README.org
================================================
* CheatSheet: Jenkins & Groovy                                    :Languages:
:PROPERTIES:
:type:     language
:export_file_name: cheatsheet-jenkins-groovy-A4.pdf
:END:

#+BEGIN_HTML
<a href="https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4"><img align="right" width="200" height="183" src="https://www.dennyzhang.com/wp-content/uploads/denny/watermark/github.png" /></a>
<div id="the whole thing" style="overflow: hidden;">
<div style="float: left; padding: 5px"> <a href="https://www.linkedin.com/in/dennyzhang001"><img src="https://www.dennyzhang.com/wp-content/uploads/sns/linkedin.png" alt="linkedin" /></a></div>
<div style="float: left; padding: 5px"><a href="https://github.com/dennyzhang"><img src="https://www.dennyzhang.com/wp-content/uploads/sns/github.png" alt="github" /></a></div>
<div style="float: left; padding: 5px"><a href="https://www.dennyzhang.com/slack" target="_blank" rel="nofollow"><img src="https://www.dennyzhang.com/wp-content/uploads/sns/slack.png" alt="slack"/></a></div>
</div>

<br/><br/>
<a href="http://makeapullrequest.com" target="_blank" rel="nofollow"><img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg" alt="PRs Welcome"/></a>
#+END_HTML

- PDF Link: [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/cheatsheet-jenkins-groovy-A4.pdf][cheatsheet-jenkins-groovy-A4.pdf]], Category: [[https://cheatsheet.dennyzhang.com/category/languages/][languages]]
- Blog URL: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-A4
- Related posts: [[https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-A4][Jenkins CheatSheet]], [[https://github.com/topics/denny-cheatsheets][#denny-cheatsheets]]

File me [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/issues][Issues]] or star [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4][this repo]].
** Jenkins Pipeline
| Name                                      | Comment                                                                   |
|-------------------------------------------+---------------------------------------------------------------------------|
| Specify parameter to run jobs             | =build job:'job1', parameters:[string(name:'name1', value:va1)]=          |
| Run job in different agents               | =node($agent_label) {...}=                                                |
| Ask for user input                        | =stage('stage2'){ input "OK to go?" }=                                    |
| Actively fail current pipeline job        | =error("Build failed because of this and that..")=                        |
| List all Jenkins plugins and versions     | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/list-all-plugins.groovy][list-all-plugins.groovy]]                                                   |
| [[https://stackoverflow.com/questions/43875093/check-if-property-exists-groovy][Check whether property exists]]             | =if (env.keep_failed_env)=                                                |
| [[https://stackoverflow.com/questions/47039924/jenkins-pipeline-enable-timestamps-in-build-log-console][Jenkins Pipeline enable timestamps]]        | =options{timestamps()}=                                                   |
| [[https://jenkins.io/doc/pipeline/steps/workflow-basic-steps/#code-withenv-code-set-environment-variables][Set envs within a jenkins pipeline]]        | =withEnv(["key1=$var1"])=                                                 |
| Install plugin via groovy                 | =Hudson.instance.updateCenter.getPlugin(plugin).deploy().get()=           |
| Keep previous job run via groovy          | =buildDiscarder(logRotator(daysToKeepStr: '20', numToKeepStr: '60'))=     |
| [[https://jenkins.io/doc/book/pipeline/syntax/][Customize job workspace]]                   | =customWorkspace "/some/other/path"=                                      |
| [[https://jenkins.io/doc/pipeline/steps/workflow-scm-step/][git scm checkout to relative directory]]    | =extensions: [[$class: 'RelativeTargetDirectory', relativeTargetDir: 'XXX']]= |
| Keep going when previous stage has failed | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/keep-going-with-errors.groovy][keep-going-with-errors.groovy]]                                             |
| Send slack notification in pipeline       | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/slack-notification.groovy][slack-notification.groovy]]                                                 |
| Pass parameter across jenkins jobs        | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/jenkinsfile-pass-parameter.groovy][jenkinsfile-pass-parameter.groovy]]                                         |
| Set timeout & retry                       | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/jenkinsfile-timeout-retry.groovy][jenkinsfile-timeout-retry.groovy]]                                          |
| Use finally to do cleanup                 | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/jenkinsfile-finally.groovy][jenkinsfile-finally.groovy]]                                                |
| Run jenkins jobs in a sequential way      | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/jenkinsfile-sequentially.groovy][jenkinsfile-sequentially.groovy]]                                           |
| Run jenkins jobs in parallel              | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/jenkinsfile-parallelly.groovy][jenkinsfile-parallelly.groovy]]                                             |
| Reference                                 | [[https://github.com/jenkinsci/pipeline-model-definition-plugin/wiki/Syntax-Reference][Link: Syntax Reference]], [[https://jenkins.io/doc/][Link: Jenkins User Documentation]]                  |
| Reference                                 | [[http://docs.groovy-lang.org/latest/html/documentation/][Link: Groovy Language Documentation]]                                       |
| Reference                                 | [[https://gist.github.com/jonico/e205b16cf07451b2f475543cf1541e70][Link: Example]], [[https://gist.github.com/vdupain/832964527b4b8d7d4c648169dae8c656][Link: Example]]                                              |
** Config Jenkins Via Groovy
| Name                                 | Comment                                                                                   |
|--------------------------------------+-------------------------------------------------------------------------------------------|
| Set timezone for jenkins             | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/timezone.groovy][timezone.groovy]]                                                                           |
| Set timezone for jenkins             | =System.setProperty('org.apache.commons.jelly.tags.fmt.timeZone', 'America/Los_Angeles')= |
| Configure default view               | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/jenkins-views.groovy][jenkins-views.groovy]]                                                                      |
| Configure Jenkins url                | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/jenkins-url.groovy][jenkins-url.groovy]]                                                                        |
| Create a Jenkins user                | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/create-jenkins-user.groovy][create-jenkins-user.groovy]]                                                                |
| Groovy manages files/folders         | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/files-folder.groovy][files-folder.groovy]]                                                                       |
| Configure max executors in Jenkins   | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/master-executors.groovy][master-executors.groovy]]                                                                   |
| Configure only 1 executor per worker | For each agent, configure # of executors                                                  |
| Configure slack plugin               | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/config-slack.groovy][config-slack.groovy]]                                                                       |
| Configure pipeline shared libraries  | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/config-pipeline-library.groovy][config-pipeline-library.groovy]]                                                            |
| [[https://stackoverflow.com/questions/34585356/get-jenkins-version-via-java-jar-jenkins-war-version-without-spam-output][Get jenkins version from CLI]]         | =java -jar /usr/share/jenkins/jenkins.war --version=                                      |
| Reference                            | [[https://github.com/cloudbees/jenkins-scripts][GitHub: cloudbees/jenkins-scripts]], [[https://github.com/jenkinsci/pipeline-examples][GitHub: jenkinsci/pipeline-examples]]                    |
** Jenkins Trouble Shooting
| Name                                             | Comment                   |
|--------------------------------------------------+---------------------------|
| List performance metrics for each Jenkins agents | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/list-all-jenkins-agent.sh][list-all-jenkins-agent.sh]] |
** Jenkins Kubernetes Via Groovy
| Name                                | Comment                                     |
|-------------------------------------+---------------------------------------------|
| Config jenkins kubernetes plugin    | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/jenkins-kubernetes-cloud.groovy][jenkins-kubernetes-cloud.groovy]]             |
| Validate Kubernetes jenkins setup   | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/validate-kubernetes-cloud.groovy][validate-kubernetes-cloud.groovy]]            |
| Kubernetes run with envs configured | [[https://github.com/jenkinsci/kubernetes-plugin/blob/master/src/test/resources/org/csanchez/jenkins/plugins/kubernetes/pipeline/runWithEnvVariables.groovy][runWithEnvVariables.groovy]]                  |
| Reference                           | [[https://github.com/jenkinsci/kubernetes-plugin/tree/master/src/test/resources/org/csanchez/jenkins/plugins/kubernetes/pipeline][GitHub: kubernetes-plugin pipeline examples]] |
** Jenkins View Via Groovy
| Name                                    | Comment                                                                    |
|-----------------------------------------+----------------------------------------------------------------------------|
| [[https://javadoc.jenkins.io/hudson/model/ListView.html#setIncludeRegex-java.lang.String-][Add a list of jobs by regexp to a view]]  | =myView.setIncludeRegex(".*Integration.*")=, [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/addjobstoview-byregexp.groovy][addjobstoview-byregexp.groovy]] |
| Create jenkins views and add jobs to it | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/jenkins-views.groovy][jenkins-views.groovy]]                                                       |
| [[https://github.com/jan-molak/jenkins-build-monitor-plugin/blob/master/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/BuildMonitorView.java][Add a view of build monitor view plugin]] | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/build-monitor-views.xml][build-monitor-views.xml]]                                                    |
| [[https://stackoverflow.com/questions/39111350/how-to-set-a-views-description-in-groovy][Change view description in groovy]]       | =myView.doSubmitDescription=                                               |
#+BEGIN_HTML
<a href="https://cheatsheet.dennyzhang.com"><img align="right" width="185" height="37" src="https://raw.githubusercontent.com/dennyzhang/cheatsheet.dennyzhang.com/master/images/cheatsheet_dns.png"></a>
#+END_HTML
** Jenkins Job Via Groovy
| Name                                            | Comment                                                 |
|-------------------------------------------------+---------------------------------------------------------|
| List all my jenkins jobs                        | =println Jenkins.instance.projects.collect { it.name }= |
| List all jenkins jobs                           | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/list-all-jobs.groovy][list-all-jobs.groovy]]                                    |
| Create and trigger a job                        | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/create-jenkins-job.groovy][create-jenkins-job.groovy]]                               |
| Manage jenkins jobs                             | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/manage-jenkins-jobs.groovy][manage-jenkins-jobs.groovy]]                              |
| Cancel queued jenkins jobs by regexp            | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/kill-queued-jenkins.groovy][kill-queued-jenkins.groovy]]                              |
| [[https://stackoverflow.com/questions/33821217/html-in-jenkins-job-descriptions][Support HTML for job and parameter descriptions]] | [[https://wiki.jenkins.io/display/JENKINS/OWASP+Markup+Formatter+Plugin][Link: OWASP Markup Formatter Plugin]]                     |
** Jenkins Different Parameters
| Name     | Comment                                                                              |
|----------+--------------------------------------------------------------------------------------|
| string   | =string(name: 'key1', defaultValue: 'Default value', description: 'some parameter')= |
| text     | =text(name: 'key1', defaultValue: 'Default value', description: 'some parameter')=   |
| boolean  | =booleanParam(name: 'key1', defaultValue: true, description: 'some parameter')=      |
| choice   | =choice(name: 'key1', choices: 'One\nTwo\nThree\n', description: 'some parameter')=  |
| password | =password(name: 'key1', defaultValue: 'SECRET', description: 'Enter a password')=    |
| file     | =file(name: 'key1', description: 'Choose a file to upload')=                         |
** Jenkins Security Via Groovy
| Name                                     | Comment                                                          |
|------------------------------------------+------------------------------------------------------------------|
| logged-in users can do anything          | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/logged-in-users.groovy][logged-in-users.groovy]]                                           |
| [[https://wiki.jenkins.io/display/JENKINS/LDAP+Plugin][Enable ldap in Jenkins]]                   | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/enable-ldap.groovy][enable-ldap.groovy]]                                               |
| Create a jenkins secret text             | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/create-secret-text.groovy][create-secret-text.groovy]]                                        |
| Configure authorization in Jenkins       | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/matrix-authorization-strategy.groovy][matrix-authorization-strategy.groovy]]                             |
| [[https://stackoverflow.com/questions/35960883/how-to-unlock-jenkins][Jenkins skip wizzard when initialization]] | -Djenkins.install.runSetupWizard=false                           |
| [[https://stackoverflow.com/questions/35960883/how-to-unlock-jenkins][Jenkins skip wizzard when initialization]] | =instance.setInstallState(InstallState.INITIAL_SETUP_COMPLETED)= |
| [[https://wiki.jenkins.io/display/JENKINS/Slave+To+Master+Access+Control][Slave To Master Access Control]]           | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/00-slave-to-master-access.groovy][00-slave-to-master-access.groovy]]                                 |
| [[https://wiki.jenkins.io/display/JENKINS/CSRF+Protection][CSRF Protection]]                          | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/00-csrf.groovy][00-csrf.groovy]]                                                   |
| Add Jenkins permission                   | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/jenkins-permission.groovy][jenkins-permission.groovy]]                                        |
| Disable CLI over Remoting                | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/00-disable-cli-remoting.groovy][00-disable-cli-remoting.groovy]]                                   |
| Disable jnlp                             | =jenkins.setSlaveAgentPort(-1)=                                  |
| [[https://wiki.jenkins.io/display/JENKINS/Authorize+Project+plugin][Access Control for Builds]]                | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/jenkins.security.QueueItemAuthenticatorConfiguration.xml][jenkins.security.QueueItemAuthenticatorConfiguration.xml]]         |
** Load Jenkins settings via folder copy
| Name                                 | Comment                                                                  |
|--------------------------------------+--------------------------------------------------------------------------|
| [[https://stackoverflow.com/questions/43691539/create-jenkins-docker-image-with-pre-configured-jobs][Add default jobs]]                     | =Copy jobs/ /usr/share/jenkins/ref/jobs/=                                |
| Copy custom built plugins            | =COPY plugins/*.hpi /usr/share/jenkins/ref/plugins/=                     |
| Use jenkins cli                      | =COPY config/jenkins.properties /usr/share/jenkins/ref/=                 |
| Add jenkins groovy scripts           | =COPY config/*.groovy /usr/share/jenkins/ref/init.groovy.d/=             |
| Configure Jenkins with some defaults | =COPY config/*.xml /usr/share/jenkins/ref/=                              |
| [[https://github.com/jenkinsci/docker/tree/587b2856cd225bb152c4abeeaaa24934c75aa460#script-usage][Install jenkins plugins]]              | =/usr/local/bin/install-plugins.sh < /usr/share/jenkins/ref/plugins.txt= |
#+BEGIN_HTML
<a href="https://cheatsheet.dennyzhang.com"><img align="right" width="185" height="37" src="https://raw.githubusercontent.com/dennyzhang/cheatsheet.dennyzhang.com/master/images/cheatsheet_dns.png"></a>
#+END_HTML
** Jenkins Plugins
| Plugin                     | Summary                                                                   |
|----------------------------+---------------------------------------------------------------------------|
| [[https://github.com/jenkinsci/kubernetes-plugin][Kubernetes Plugin]]          | Jenkins plugin to run dynamic agents in a Kubernetes/Docker environment   |
| [[https://wiki.jenkins-ci.org/display/JENKINS/Credentials+Plugin][Credentials Plugin]]         | Load the ssh key                                                          |
| [[https://wiki.jenkins.io/display/JENKINS/SiteMonitor+Plugin][SiteMonitor Plugin]]         | Monitor URLs                                                              |
| [[https://wiki.jenkins-ci.org/display/JENKINS/Timestamper][Timestamper Plugin]]         | Add timestamp to job output                                               |
| [[https://wiki.jenkins-ci.org/display/JENKINS/Dashboard+View][Dashboard View Plugin]]      | Create dashboard                                                          |
| [[https://wiki.jenkins.io/display/JENKINS/Log+Parser+Plugin][Log Parser Plugin]]          | Parse the console output and highlight error/warning/info lines.          |
| [[https://wiki.jenkins-ci.org/display/JENKINS/Build-timeout+Plugin][Build-timeout Plugin]]       | Abort if job takes too long                                               |
| [[https://wiki.jenkins-ci.org/display/JENKINS/Naginator+Plugin][Naginator Plugin]]           | Retry failed a job                                                        |
| [[https://wiki.jenkins-ci.org/display/JENKINS/thinBackup][ThinBackup Plugin]]          | Backup jenkins                                                            |
| [[https://plugins.jenkins.io/jobConfigHistory][JobConfigHistory Plugin]]    | Backup job configuration                                                  |
| [[https://wiki.jenkins.io/pages/viewpage.action?pageId=60915753]["Anything Goes" formatter]]  | use JavaScript inside your project description                            |
| [[https://wiki.jenkins.io/display/JENKINS/AnsiColor+Plugin][AnsiColor Plugin]]           | Add support for ANSI escape sequences, including color, to Console Output |
| [[https://wiki.jenkins.io/display/JENKINS/Build+User+Vars+Plugin][Build User Vars Plugin]]     | Describe the user who started the build                                   |
| [[https://wiki.jenkins.io/display/JENKINS/GitLab+Plugin][Gitlab Plugin]]              | Allows GitLab to trigger Jenkins builds                                   |
| [[https://wiki.jenkins.io/display/JENKINS/Workspace+Cleanup+Plugin][Workspace Cleanup]]          | Plugin to delete the build workspace.                                     |
| [[https://wiki.jenkins.io/display/JENKINS/UpdateSites+Manager+plugin][UpdateSites Manager plugin]] | manage update sites, where Jenkins accesses in order to retrieve plugins  |
** Jenkins Git Via Groovy
| Name                                   | Comment                           |
|----------------------------------------+-----------------------------------|
| Git checkout code                      | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/git-checkout.groovy][git-checkout.groovy]]               |
| Get all git commits since last success | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/git-commits-before-fail.groovy][git-commits-before-fail.groovy]]    |
| List git tags and branches             | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/git-list-tags-and-branches.groovy][git-list-tags-and-branches.groovy]] |

** Jenkins networking Via Groovy
| Name                            | Comment                                                                  |
|---------------------------------+--------------------------------------------------------------------------|
| Get hostname                    | =println InetAddress.localHost.canonicalHostName=                        |
| Get IP address                  | =println InetAddress.localHost.hostAddress=                              |
| Get hostname by ip              | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/get-ip-by-hostname.groovy][get-ip-by-hostname.groovy]]                                                |
| validate user input: ip address | =assert ip_address.matches("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}")= |
** Jenkins with Kubernetes/Docker
| Name                                               | Comment                                                                 |
|----------------------------------------------------+-------------------------------------------------------------------------|
| [[https://github.com/jenkinsci/kubernetes-plugin][Kubernetes Plugin]]                                  | Jenkins plugin to run dynamic agents in a Kubernetes/Docker environment |
| Config jenkins kubernetes plugin                   | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/jenkins-kubernetes-cloud.groovy][jenkins-kubernetes-cloud.groovy]]                                         |
| Cleanup for Docker stale containers/images/volumes | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/docker-cleanup.groovy][docker-cleanup.groovy]]                                                   |
| Jenkins customize docker build args                | =additionalBuildArgs '--build-arg SSH_PRIVATE_KEY...'=                  |
** Groovy Common Errors/Exceptions
| Name               | Comment                                    |
|--------------------+--------------------------------------------|
| Illegal class name | [[https://stackoverflow.com/questions/22839352/jenkins-groovy-post-build-script-to-evaluate-file-with-function][JVM doesn't like class names with a hyphen]] |

** Groovy Basic
| Name                           | Comment                                                   |
|--------------------------------+-----------------------------------------------------------|
| Get environment variables      | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/get-env.groovy][get-env.groovy]], =println env.WORKSPACE=                   |
| Groovy execute command         | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/execute-command.groovy][execute-command.groovy]]                                    |
| [[https://stackoverflow.com/questions/2060427/groovy-grails-how-to-determine-a-data-type][Get data type of a variable]]    | =myObject.getClass()=                                     |
| Print stdout                   | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/print.groovy][print.groovy]] echo 'Action is done', println "Hello World" |
| Use boolean parameter          | if (istrue == "false") {...}                              |
| Basic integer caculation       | def a = 3, b = 7; println "$a + $b = ${a + b}"            |
| Run groovy online              | [[https://groovyconsole.appspot.com][SaaS: Groovy Web console]]                                  |
| Run groovy script from Jenkins | [[https://wiki.jenkins.io/display/JENKINS/Jenkins+Script+Console][Link: Jenkins Script Console]]                              |
| Reference                      | [[http://groovy-lang.org][Link: Apache Groovy]]                                       |
#+BEGIN_HTML
<a href="https://cheatsheet.dennyzhang.com"><img align="right" width="185" height="37" src="https://raw.githubusercontent.com/dennyzhang/cheatsheet.dennyzhang.com/master/images/cheatsheet_dns.png"></a>
#+END_HTML
** Groovy String
| Name                           | Comment                                                        |
|--------------------------------+----------------------------------------------------------------|
| Check string startsWith        | =assert s.startsWith("\t")=                                    |
| Trim whitespaces               | s=s.trim()                                                     |
| Concat string                  | =first = 'Joe'; last = 'Smith'; println("Name: $first $last")= |
| [[http://groovy-lang.org/groovy-dev-kit.html#_list_literals][Convert list to string]]         | =l.join(";")=                                                  |
| Create string with multi-lines | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/multi-line-string.groovy][multi-line-string.groovy]]                                       |
| Convert string to list         | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/split-string.groovy][split-string.groovy]]                                            |
| [[http://groovy-lang.org/json.html][Convert string to json]]         | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/string-to-json.groovy][string-to-json.groovy]]                                          |
| Remove tags                    | =input.replaceAll("\\<.*?>","")=                               |
| Regex match                    | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/regexp-match.groovy][regexp-match.groovy]]                                            |
** Groovy Regexp
| Name                   | Comment                        |
|------------------------+--------------------------------|
| [[https://www.ngdc.noaa.gov/wiki/index.php/Regular_Expressions_in_Groovy][Regex case insensitive]] | (item.name == ~/(?i).*NSX.*/ ) |
| Reference              | [[https://www.ngdc.noaa.gov/wiki/index.php/Regular_Expressions_in_Groovy][Regular Expressions in Groovy]]  |
** Groovy Array
| Name                        | Comment                                  |
|-----------------------------+------------------------------------------|
| Iterate a list              | =for(item in [1,2,3,4]){ println item }= |
| Iterate a list              | =(1..3).each { println "Number ${it}"}=  |
| Add item to list            | =def alist = [10, 9, 8]; alist << 7=     |
| List size                   | =def alist = [10, 9, 8]; alist.size()=   |
| Split string with delimiter | ='1128-2'.tokenize('-')=                 |
** Groovy File
| Name                            | Comment                                                                 |
|---------------------------------+-------------------------------------------------------------------------|
| [[https://stackoverflow.com/questions/7729302/how-to-read-a-file-in-groovy-into-a-string][Read file into a string]]         | =String fileContents = new File('/tmp/test.txt).text=                   |
| Read file content as a variable | =def env = System.getenv()=, =def content = readFile("/tmp/test.txt")=  |
| [[https://jenkins.io/doc/pipeline/examples/][Write file in pipeline]]          | writeFile file: "output/my.txt", text: "This is a test"                 |
| [[https://jenkins.io/doc/pipeline/steps/pipeline-utility-steps/#code-readproperties-code-read-properties-from-files-in-the-workspace-or-text][Read a property file]]            | def conf = readProperties file: "${env.WORKSPACE}@script/my.properties" |
| Read and write json files       | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/json-file.groovy][json-file.groovy]]                                                        |
| Obtain a relative path          | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/json-file.groovy][relative-path.groovy]]                                                    |
** Groovy Shell Command
| Name                        | Comment                                             |
|-----------------------------+-----------------------------------------------------|
| Run shell and get output    | def out = sh script: command, returnStdout: true    |
| Run shell and get exit code | def status = sh script: command, returnStatus: true |
** Groovy Dictionary
| Name                | Comment                                        |
|---------------------+------------------------------------------------|
| Create a map        | =def m = ['fruit':'Apple', 'veggie':'Carrot']= |
| Add an item to map  | =m.put('denny','hello')=                       |
| Check if key exists | =m.containsKey('key1')=                        |
| Loop a map          | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/loop-map.groovy][loop-map.groovy]]                                |
** Groovy json
| Name                       | Comment               |
|----------------------------+-----------------------|
| [[http://groovy-lang.org/json.html][Convert string to json]]     | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/string-to-json.groovy][string-to-json.groovy]] |
| Convert dictionary to json | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/dict-to-json.groovy][dict-to-json.groovy]]   |
| Read and write json files  | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/json-file.groovy][json-file.groovy]]      |
#+BEGIN_HTML
<a href="https://cheatsheet.dennyzhang.com"><img align="right" width="185" height="37" src="https://raw.githubusercontent.com/dennyzhang/cheatsheet.dennyzhang.com/master/images/cheatsheet_dns.png"></a>
#+END_HTML
** Groovy Date
| Name           | Comment                                                                      |
|----------------+------------------------------------------------------------------------------|
| Date to string | =new Date().format("yyyy-MM-dd'T'HH:mm:ss'Z'", TimeZone.getTimeZone("UTC"))= |
| String to date | =Date.parse("yyyy-MM-dd'T'HH:mm:ss'Z'", "2001-01-01T00:00:00Z")=             |
| String to date | =Date.parse("yyyy-MM-dd'T'HH:mm:ssZ", "2001-01-01T00:00:00+0000")=           |
** Jenkins Agent
| Name                                | Comment                        |
|-------------------------------------+--------------------------------|
| Check jenkins slave jar version     | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/check-slave-jar-version.groovy][check-slave-jar-version.groovy]] |
| Find dead executors and remove them | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/find-dead-executors.groovy][find-dead-executors.groovy]]     |
| Set env for each agent              | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/set-agent-env.groovy][set-agent-env.groovy]]           |
** Jenkins Maintenance
| Name                            | Comment                                                 |
|---------------------------------+---------------------------------------------------------|
| Delete jenkins job by regexp    | [[https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4/blob/master/delete-job-by-regexp.groovy][delete-job-by-regexp.groovy]]                             |
| Deploy Jenkins via docker       | https://hub.docker.com/r/jenkins/jenkins/               |
| Clean up old builds             | [[https://support.cloudbees.com/hc/en-us/articles/215549798-Best-Strategy-for-Disk-Space-Management-Clean-Up-Old-Builds?mobile_site=true][Link: CloudBees Best Strategy for Disk Space Management]] |
** More Resources
http://groovy-lang.org/documentation.html#gettingstarted

https://github.com/fabric8io/jenkins-docker

License: Code is licensed under [[https://www.dennyzhang.com/wp-content/mit_license.txt][MIT License]].
#+BEGIN_HTML
<a href="https://cheatsheet.dennyzhang.com"><img align="right" width="201" height="268" src="https://raw.githubusercontent.com/USDevOps/mywechat-slack-group/master/images/denny_201706.png"></a>
<a href="https://cheatsheet.dennyzhang.com"><img align="right" src="https://raw.githubusercontent.com/dennyzhang/cheatsheet.dennyzhang.com/master/images/cheatsheet_dns.png"></a>

<a href="https://www.linkedin.com/in/dennyzhang001"><img align="bottom" src="https://www.dennyzhang.com/wp-content/uploads/sns/linkedin.png" alt="linkedin" /></a>
<a href="https://github.com/dennyzhang"><img align="bottom"src="https://www.dennyzhang.com/wp-content/uploads/sns/github.png" alt="github" /></a>
<a href="https://www.dennyzhang.com/slack" target="_blank" rel="nofollow"><img align="bottom" src="https://www.dennyzhang.com/wp-content/uploads/sns/slack.png" alt="slack"/></a>
#+END_HTML
* org-mode configuration                                           :noexport:
#+STARTUP: overview customtime noalign logdone showall
#+DESCRIPTION:
#+KEYWORDS:
#+LATEX_HEADER: \usepackage[margin=0.6in]{geometry}
#+LaTeX_CLASS_OPTIONS: [8pt]
#+LATEX_HEADER: \usepackage[english]{babel}
#+LATEX_HEADER: \usepackage{lastpage}
#+LATEX_HEADER: \usepackage{fancyhdr}
#+LATEX_HEADER: \pagestyle{fancy}
#+LATEX_HEADER: \fancyhf{}
#+LATEX_HEADER: \rhead{Updated: \today}
#+LATEX_HEADER: \rfoot{\thepage\ of \pageref{LastPage}}
#+LATEX_HEADER: \lfoot{\href{https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4}{GitHub: https://github.com/dennyzhang/cheatsheet-jenkins-groovy-A4}}
#+LATEX_HEADER: \lhead{\href{https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-A4}{Blog URL: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-A4}}
#+AUTHOR: Denny Zhang
#+EMAIL:  denny@dennyzhang.com
#+TAGS: noexport(n)
#+PRIORITIES: A D C
#+OPTIONS:   H:3 num:t toc:nil \n:nil @:t ::t |:t ^:t -:t f:t *:t <:t
#+OPTIONS:   TeX:t LaTeX:nil skip:nil d:nil todo:t pri:nil tags:not-in-toc
#+EXPORT_EXCLUDE_TAGS: exclude noexport
#+SEQ_TODO: TODO HALF ASSIGN | DONE BYPASS DELEGATE CANCELED DEFERRED
#+LINK_UP:
#+LINK_HOME:
* #  --8<-------------------------- separator ------------------------>8-- :noexport:
* TODO groovy challenges                                           :noexport:
** 101
Use groovy to add a test user in Jenkins
For better security, use groovy to only allow registered user login
Quiz:

Once I have enabled Jenkins security, how my chef update will work?
** 102
Define a Jenkins pipeline job automatically
Define a Jenkins job via Jenkinsfile script automatically
For automated backup, enable and configure ThinBackup plugin via Groovy
** 301
Define a dummy Jenkins pipeline job using Jenkinsfile
Define a Jenkins parameterized pipeline job using Jenkinsfile. It shall trigger another job.
Quiz:

Once I have enabled Jenkins security, how my chef update will work?
* TODO [#A] Blog: Jenkins pipeline: run multiple related jobs in a managed order :noexport:IMPORTANT:
** basic use
Jenkins Pipeline is a suite of plugins which supports implementing and
integrating continuous delivery pipelines into Jenkins.
** TODO jenkins pipeline show slack error message
** TODO why unecessary delay when running jobs via pipeline: http://injenkins.carol.ai:48080/view/Pipeline/job/PipelineMonitor/
** TODO Why pipeline scheduling takes serveral minutes
** TODO [#A] How to support testing different branch with scm: http://jenkins.shibgeek.com:48084/view/Pipeline/job/PipelineCodeCheck/
** TODO [#A] Jenkins pipeline doesn't set who initiate the deployment
jenkins APP [11:32 AM]
RefreshDemoEnvAll - #7 Started by upstream project "PipelineRefreshDemoEnvAll" build number 3 (Open)
** TODO [#A] kill in jenkins job doesn't stop the bash: curl
 root@bematech-do-es-2:~/elasticsearch-cli-tool# curl "http://${es_ip}:9200/_alias/staging-8a18aa800e5911e785f24a8136534b63"
 {"staging-index-8a18aa800e5911e785f24a8136534b63-new3":{"aliases":{"staging-8a18aa800e5911e785f24a8136534b63":{}}}}root@bematech-do-es-2:~/elasticsearch-cli-tool# curl "http://${es_ip}:9200/_alias/staging-8a18aa800e5911e785f24a8136534b63"
 {"staging-index-8a18aa800e5911e785f24a8136534b63-new3":{"aliases":{"staging-8a18aa800e5911e785f24a8136534b63":{}}}}root@bematech-do-es-2:~/elasticsearch-cli-tool# ps -ef | grep curl
 root     11085 11062  0 22:51 ?        00:00:00 curl -XPOST http://138.68.246.50:9200/_reindex?pretty -d       {        "conflicts": "proceed",        "source": {        "index": "master-index-8a18aa800e5911e785f24a8136534b63-new2",        "size": "500"     },        "dest": {        "index": "master-index-8a18aa800e5911e785f24a8136534b63-new3",        "op_type": "create"     }  }
 root     11109  9468  0 22:51 pts/2    00:00:00 grep --color=auto curl
 root     13367 13348  0 13:05 ?        00:00:04 curl -XPOST http://138.68.246.50:9200/_reindex?pretty -d       {        "conflicts": "proceed",        "source": {        "index": "master-index-321bb9606b2111e7b579a2f42be00f79-new2",        "size": "500"     },        "dest": {        "index": "master-index-321bb9606b2111e7b579a2f42be00f79-new3",        "op_type": "create"     }  }
 root@bematech-do-es-2:~/elasticsearch-cli-tool# date
** #  --8<-------------------------- separator ------------------------>8-- :noexport:
** TODO [#A] Jenkinsfile/Pipeline                                 :IMPORTANT:
 https://jenkins.io/doc/book/pipeline/jenkinsfile/

 Pipeline supports two syntaxes, Declarative (introduced in Pipeline 2.5) and Scripted Pipeline

 https://jenkins.io/pipeline/getting-started-pipelines/

 https://plugins.jenkins.io/workflow-aggregator

 https://github.com/jenkinsci/pipeline-examples/tree/master/jenkinsfile-examples/nodejs-build-test-deploy-docker-notify
*** Pipeline Vocabulary: Steps, Nodes, and Stages
 https://dzone.com/articles/jenkins-pipeline-plugin-tutorial
 - A step, also known as a "build step", is a single task that we want Jenkins to execute.

 - A "node", within the contexts of a pipeline, refers to a step that does two things.

   First, it schedules the defined steps so that it'll run as soon as
   an executor is available. Second, it creates a temporary workspace
   which is removed once all steps have completed.

 - And lastly, we have "Stages". Stages are for setting up logical
   divisions within pipelines. The Jenkins Pipeline visualization
   plugin will display each stage as a separate segment. Because of
   this, teams tend to name stages for each phase of the development
   process, such as "Dev, Test, Stage, and Production".
*** Jenkins pipeline is durable from Jenkins master restart
 https://dzone.com/articles/jenkins-pipeline-plugin-tutorial
 #+BEGIN_EXAMPLE
 - One huge benefit of using a pipeline is that the job itself is
   durable. A Pipeline job is able to survive planned or even unplanned
   restarts of the Jenkins master. If you need to survive slave
   failures as well, you'll have to use checkpoints.

 - Unfortunately, the checkpoints plugin is only available for the
   enterprise edition of Jenkins. Pipelines are also pausable.
 #+END_EXAMPLE
*** hello world: http://localhost:18083/job/jenkinsfile1/1/console
 https://serversforhackers.com/c/covering-a-simpler-jenkinsfile
 https://jenkins.io/doc/book/pipeline/getting-started/
** TODO Jenkins pipeline: Supporting APIs v2.10
 #+BEGIN_EXAMPLE
 INFO: Listed all plugins
 Nov 26, 2017 5:03:17 PM jenkins.InitReactorRunner$1 onTaskFailed
 SEVERE: Failed Loading plugin Pipeline: Nodes and Processes v2.8 (workflow-durable-task-step)
 java.io.IOException: Pipeline: Nodes and Processes v2.8 failed to load.
  - Pipeline: Supporting APIs v2.10 is older than required. To fix, install v2.12 or later.
	 at hudson.PluginWrapper.resolvePluginDependencies(PluginWrapper.java:626)
	 at hudson.PluginManager$2$1$1.run(PluginManager.java:516)
	 at org.jvnet.hudson.reactor.TaskGraphBuilder$TaskImpl.run(TaskGraphBuilder.java:169)
	 at org.jvnet.hudson.reactor.Reactor.runTask(Reactor.java:282)
	 at jenkins.model.Jenkins$7.runTask(Jenkins.java:1090)
	 at org.jvnet.hudson.reactor.Reactor$2.run(Reactor.java:210)
	 at org.jvnet.hudson.reactor.Reactor$Node.run(Reactor.java:117)
	 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	 at java.lang.Thread.run(Thread.java:748)
 #+END_EXAMPLE
** TODO jenkins pipeline agent
 https://www.digitalocean.com/community/tutorials/how-to-set-up-continuous-integration-pipelines-in-jenkins-on-ubuntu-16-04

 The pipeline contains the entire definition that Jenkins will
 evaluate. Inside, we have an agent section that specifies where the
 actions in the pipeline will execute. To isolate our environments from
 the host system, we will be testing in Docker containers, specified by
 the docker agent.

 #+BEGIN_EXAMPLE
 #!/usr/bin/env groovy

 pipeline {

     agent {
         docker {
             image 'node'
             args '-u root'
         }
     }

     stages {
         stage('Build') {
             steps {
                 echo 'Building...'
                 sh 'npm install'
             }
         }
         stage('Test') {
             steps {
                 echo 'Testing...'
                 sh 'npm test'
             }
         }
     }
 }
 #+END_EXAMPLE
** TODO Jenkins pipeline enable slack notificaiton
** TODO [#A] jenkins workflow: https://dzone.com/refcardz/continuous-delivery-with-jenkins-workflow
https://dzone.com/articles/top-10-best-practices-for-jenkins-pipeline
** TODO jenkins plugins: git, checkstyle, build-pipeline-plugin, clone-workspace-scm, deploy, Text-finder
https://github.com/ThoughtWorks-Chengdu-DevOps-Club/tw_devops_workshop/tree/master/season_1/workshop_2
** TODO verify whether local docker image is up-to-date
** TODO Why jenkins container use so much memory?
** TODO jenkins docker demo: https://hub.docker.com/u/jenkinsci/
docker run --rm -p 8080:8080 -v /var/run/docker.sock:/var/run/docker.sock --group-add=$(stat -c %g /var/run/docker.sock) jenkinsci/docker-workflow-demo
** TODO jenkins plugin: job plugin
根据前置job成功与否来执行当前job
插件链接 https://wiki.jenkins-ci.org/display/JENKINS/Join+Plugin

nice, 可以用于我们的CommonServerCheck的jenkins job依赖
** TODO jenkins job priority
** TODO jenkins plugin: HTML Publisher Plugin
https://wiki.jenkins-ci.org/display/JENKINS/HTML+Publisher+Plugin
https://wiki.jenkins-ci.org/display/JENKINS/DocLinks+Plugin
** #  --8<-------------------------- separator ------------------------>8--
** TODO [#A] jenkins get overview of scheduled jenkins jobs        :IMPORTANT:
** TODO Jenkins Warnings plugin: http://dustinrcollins.com/detecting-chef-upload-failures-with-jenkins
** TODO Jenkins Dependency-Check Plugin: https://wiki.jenkins-ci.org/display/JENKINS/OWASP+Dependency-Check+Plugin
** TODO jenkins restrict user running jobs on prod env
http://stackoverflow.com/questions/30397699/how-to-use-a-different-set-of-parameters-for-release-builds-in-jobs-triggered-vi
** TODO Jenkins job: stop/start container
docker pull sandbox image
** TODO Jenkins ssh key security: SSH Credentials Plugin; SSH Agent Plugin
https://wiki.jenkins-ci.org/display/JENKINS/SSH+Agent+Plugin
https://wiki.jenkins-ci.org/display/JENKINS/SSH+Credentials+Plugin
** TODO jenkins setting: only registered user can trigger, only admin can configure
** TODO [#A] Jenkinse use a cluster for testing; jenkins slave     :IMPORTANT:
http://blog.dataman-inc.com/20150623-jenkins-apache-mesos-marathon/
http://blog.alexellis.io/jenkins-2-0-first-impressions/
https://www.huangyunkun.com/2015/08/29/docker-with-jenkins/
** [#A] jenkins change enrinvonment variables for post-actions
http://stackoverflow.com/questions/23995648/jenkins-execute-shell-script-vars-needed-in-post-build-action-specifically-in
https://issues.jenkins-ci.org/browse/JENKINS-25355
** TODO [#A] jenkins docker plugin                                 :IMPORTANT:
** TODO [#A] QA jenkins job doesn't destroy the VMs

ImagesNetworkingMonitoringAPISupport
C

denny.zhang
denny.zhang@totvs.com
C
Carol
Settings
Notifications2
Logout
Create
kitchen-cluster-mdm-qa-4nodes-node4 4 GB Memory / 60 GB Disk / SFO2 - Ubuntu 14.04.5 x64
ipv4: 165.227.0.213 Copy ipv6:  Enable now Private IP:  Enable now Floating IP:  Enable now Console:
Graphs
Access
Power
Volumes
Resize
Networking
Backups
Snapshots
Kernel
History
Destroy
Tags
** TODO jenkins slave
U can attach ur nodes as a slaves to master Jenkins or if u want to to run a command from an endpoint, u can use pac software
** TODO Jenkins Blueocean
** TODO jenkins cancel job doesn't stop db backup
** TODO [#A] jenkins cancel job doesn't force-merge command        :IMPORTANT:
root@bematech-do-es-01:/var/log/elasticsearch# ps -ef | grep el
root        90     2  0 Aug11 ?        00:00:00 [khelper]
root      8097  8096  0 13:50 ?        00:00:00 python /opt/devops/bin/elasticsearch_force_merge.py --es_pattern_regexp staging-index-abae8b30ac9b11e692000401f8d88101-new3 --min_deleted_count 100000 --min_deleted_ratio 0
root     13315 13314  0 20:47 ?        00:00:00 python /opt/devops/bin/elasticsearch_force_merge.py --es_pattern_regexp staging-index-abae8b30ac9b11e692000401f8d88101-new3 --min_deleted_count 100000 --min_deleted_ratio 0
root     20846  1844  0 22:49 pts/1    00:00:00 grep --color=auto el
elastic+ 31034     1 99 Aug11 ?        36-14:05:03 /usr/lib/jvm/java-8-oracle-amd64/bin/java -Xms12288m -Xmx12288m -Djava.awt.headless=true -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -XX:+HeapDumpOnOutOfMemoryError -XX:+DisableExplicitGC -Dfile.encoding=UTF-8 -Djna.nosys=true -server -Djava.awt.headless=true -Djava.net.preferIPv4Stack=true -Xms12288m -Xmx12288m -Xss256k -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -XX:+HeapDumpOnOutOfMemoryError -XX:+DisableExplicitGC -Dfile.encoding=UTF-8 -Djna.nosys=true -Des.path.home=/usr/share/elasticsearch -cp /usr/share/elasticsearch/lib/elasticsearch-2.3.3.jar:/usr/share/elasticsearch/lib/* org.elasticsearch.bootstrap.Elasticsearch start -d -p /var/run/elasticsearch/elasticsearch.pid --default.path.home=/usr/share/elasticsearch --default.path.logs=/var/log/elasticsearch --default.path.data=/usr/share/elasticsearch --default.path.conf=/etc/elasticsearch
** TODO jenkins multi-stage build
** TODO jenkins multiple configuration
** TODO jenkins syntax generator
that means, constantly having to look up on plugin docs for pipeline steps


4 replies
Puneeth [41 minutes ago]
Use the pipeline syntax generator in your Jenkins installation


amrit [40 minutes ago]
Yea thats what I started using now :slightly_smiling_face: . Do people still use those?


amrit [< 1 minute ago]
@Denny Zhang (Github . Blogger) this can be handy for those situations


Denny Zhang (Github . Blogger) [< 1 minute ago]
thanks. I haven't used it. Will give it a try
** TODO How to force jenkins to reload a jenkinsfile?
** TODO Blog: Jenkins pipeline: reconfigure jenkins job and reload it
https://stackoverflow.com/questions/44422691/how-to-force-jenkins-to-reload-a-jenkinsfile
https://issues.jenkins-ci.org/browse/JENKINS-32984
https://issues.jenkins-ci.org/browse/JENKINS-33734
Question: How to use jenkins pipeline to reconfigure parameters of another jenkins job.

(Ideally I wish I could avoid reloading or restarting jenkins)

I remember this channel has similar discussion about this. Anyone remember the suggestion?
*** TODO Jenkins pipeline: Get current setting and add a new attribute
** TODO try Jenkins X
** TODO create a jenkins job to update markdown wiki
** TODO Why jenkins are up and running, after machine reboot. But couchbase, es are not
docker exec -it mdm-jenkins service jenkins status
docker exec -it mdm-all-in-one bash

service couchbase-server start && service elasticsearch start

service couchbase-server status && service elasticsearch status

service mdm start

service couchbase-server status && service elasticsearch status && service mdm status
** TODO Lessons learned: run one jenkins backup
** TODO jenkins load bundle
** HALF jenkins pipeline get job configuration
https://support.cloudbees.com/hc/en-us/articles/218353308-How-to-update-job-config-files-using-the-REST-API-and-cURL-

dennyzhang
lrpChangeMe1

curl -X GET http://dennyzhang:lrpChangeMe1@myjenkins:18080/job/dennytestRehearsal/config.xml -o mylocalconfig.xml

curl -X POST http://dennyzhang:lrpChangeMe1@myjenkins:18080/job/dennytestRehearsal/config.xml --data-binary "@mymodifiedlocalconfig.xml"
** TODO why has_error variable hasn't passed: http://myjenkins:18080/job/CheckDNSPropagation/14/console
** TODO jenkins docker image: why /var/jenkins_home/.bashrc folder is missing?
** TODO Use groovy to add a user
** TODO Use groovy to only allow register users use Jenkins
** TODO Use groovy script to restart jenkins
** TODO Use groovy to install a jenkins plugin
** #  --8<-------------------------- separator ------------------------>8-- :noexport:
** TODO jenkins pipeline job: add node
*** original one
node {
     // TODO: validate users input
     def ip_list = [];
     def ip_port_list = [];
     def ssh_port = '2702'
     for (entry in ip_hostname_list.split("\n")) {
         entry = entry.trim()
         ip_address = entry.split(" ")[0]
         ip_address = ip_address.trim()
         ip_list.add(ip_address)
         ip_port_list.add(ip_address + ":" + ssh_port)
     }

    stage('UpdateHAProxy') {
       build job: 'FixHostsFileBinding', parameters: [text(name: 'server_list', value: 'https://prodmgmt.carol.ai/querycluster/haproxy'), text(name: 'add_hosts', value: ip_hostname_list)]
       build job: 'UpdateHAProxyNodeListDOBematech'
       build job: 'CheckIPAddressInList',  parameters: [text(name: 'new_ip_list', value: ip_list.join("\n"))]
    }

    stage('FixConf') {
        parallel firstBranch: {
            def target_host_file='/tmp/hosts_target'
            retry(2) {
              build job: 'GetHostFileBinding',  parameters: [string(name: 'target_host_file', value: target_host_file)]
            }
            // update hosts file for existing nodes
            build job: 'FixHostsFileBinding', parameters: [text(name: 'add_hosts', value: ip_hostname_list)]
            // update hosts file for new nodes
            def host_binding_content=readFile(target_host_file)
            build job: 'FixHostsFileBinding', parameters: [text(name: 'server_list', value: ip_port_list.join("\n")), text(name: 'add_hosts', value: host_binding_content)]
            retry(2) {
                build 'FixHostsFileTemplateBematechDO'
            }
        }, secondBranch: {
            build job: 'UFWAddNodesBematechDO', parameters: [text(name: 'new_ip_list', value: ip_list.join("\n"))]
            retry(2) {
                build 'FixESYamlBematechDO'
            }
            retry(2) {
                build 'FixMDMYamlBematechDO'
            }
        },
        failFast: false
    }

    stage('Rehearsal') {
        if (skip_deployment_rehearsal == "false") {
           build job: 'DeploySystemRehearsalDOBematech', parameters: [text(name: 'server_list', value: ip_port_list.join("\n"))]
        }
    }
}
** TODO pipeline best practice
https://github.com/jenkinsci/pipeline-examples/blob/master/docs/BEST_PRACTICES.md
** TODO Jenkins CI Pipeline Scripts not permitted to use method groovy.lang.GroovyObject
** HALF groovy load a json file
http://groovy-lang.org/json.html
https://stackoverflow.com/questions/26230225/hashmap-getting-first-key-value
/usr/local/scripts/terraform_jenkins_digitalocean/bematech-do-es-39/terraform.tfstate
** HALF groovy send http request
https://stackoverflow.com/questions/25692515/groovy-built-in-rest-http-client
** TODO jenkins monitor
Denny Zhang [4:47 PM]
Nice, any screenshots? (Ignore, if it's against the policy)


Stefan Jansson
[4:49 PM]
the jenkins-plugin is called build monitor plugin: https://wiki.jenkins.io/display/JENKINS/Build+Monitor+Plugin


[4:50]
a competitor is radiator: https://wiki.jenkins.io/display/JENKINS/Radiator+View+Plugin
- i'd use radiator once getting over a certain amount of jobs to monitor, since it has an option to only display failing jobs


[4:54]
You could even call it "continuous testing in production" to make it an even stronger trend buzzword... "continuous testing" and "testing in production" are buzzwords that traditional testers do shrug from, but something I believe strongly in for the future, for devops teams, and teams running a continuous delivery process, and bigger organisations where you depend on other teams/products


Denny Zhang [4:54 PM]
Yes, we have Jenkins monitor plugin enabled


[4:55]
Don't quite understand its value though


Stefan Jansson [4:57 PM]
what is it that you don't understand?


Denny Zhang
[4:57 PM]
It gives me an overview. But what I can get from it?


new messages
Stefan Jansson [5:05 PM]
my example works like an extra layer of monitoring, to discover even faster if you got a problem in production, if your data-logging, alarms etc might not be as fast with, or as obvious.. it won't even catch everything, that a test can.

for example, my teams builds a booking-flow for the nordics biggest travel-company.. if you cannot book a seat on a plane, simply because an API somewhere doesn't respond, or are having slow timeouts so it doesn't even display the option for the customer... the error-code monitoring and larms might go up, but it takes a while until the larms sets off, or that the error count get's to a suspicious amount so that you take a look at it.. but the TEST that runs making a booking, will fail immidiatly and give you a RED-flag on the monitor
** TODO Jenkins SCM Sync configuration plugin
*** SCM Sync configuration plugin
https://wiki.jenkins.io/display/JENKINS/SCM+Sync+configuration+plugin
*** jenkinsfile: groovy script
*** Manage Jenkins Jobs with YAML
https://blogs.rdoproject.org/6006/manage-jenkins-jobs-with-yaml
** TODO configure pipeline status in a better way
** TODO jenkins pipeline: can't abort it
** TODO Jenkins group stage: 5 groups
Romain B. [12:21 AM]
@Denny Zhang (Github . Blogger): You should regroup your tests in less stages, you can still get a "test overview" in the `test result` webpage (append `testReport/` to your job)
Also, give BlueOcean a try, it doesn't do everything well but its pretty usefull to output pipeline status (especially to spot an error)

Dario Tranchitella [1:25 AM]
Some used Dependency Injection (with Inversion of Control) and Singleton patterns using Groovy shared library?
I noticed that documentation is really poor and I'm facing some scalability issues with a complex pipelines...

Denny Zhang (Github . Blogger) [8:07 AM]
@romainrbr, let me give it a try
** TODO Jenkins Features Controlled with System Properties: https://wiki.jenkins-ci.org/display/JENKINS/Features+controlled+by+system+properties
** TODO SCM Sync Configuration Plugin: http://www.scmtechblog.net/2014/12/14-must-have-jenkins-plugins-to.html
** TODO Explore env Jenkins update issue: updatejenkinsitself
cd /var/chef/cache/

java -jar ./jenkins-cli.jar -s http://localhost:18080/ login --username chefadmin --password "TOTVS123FD"
java -jar ./jenkins-cli.jar -s http://localhost:18080/ list-jobs
** TODO ip list as an inventory file provided by jenkins
** TODO Use Jenkins ssh plugin: http://davidsj.co.uk/blog/how-i-update-my-blog-with-jenkins/
** TODO jenkins powershell
seanturner83 [5:17 AM]
@dennyzhang you like powershell? https://github.com/poshbotio/PoshBot
GitHub
poshbotio/PoshBot
PoshBot - Powershell-based bot framework
** TODO improve bematech jenkins security: about tcp ports
** TODO [#A] secure sonarqube port forwarding jenkins
** TODO [#A] jenkins pipeline fail to be aborted
** TODO jenkins pipeline specify git credential
** TODO Blog: jenkins pipeline back to normal notification
** TODO [#A] Blog: jenkins piepline update job parameter
** TODO [#A] jenkins pipeline job to update existing job
** TODO jenkins create admin user from configure
** TODO [#A] How to keep jenkins in sync for two directions?       :IMPORTANT:
** TODO whenever I configure jenkins, it will crash
** TODO Candy Jenkins: https://github.com/david7482/caddy-jenkins-docker
https://caddyserver.com/
#+BEGIN_EXAMPLE
Also, the demo Jenkins you guys are running on docker?


3 replies
Denny Zhang (Github . Blogger) [3 minutes ago]
Jenkins is running on docker. Via AWS ECS (edited)


AnmolNagpal [1 minute ago]
Oke I have a suggestion try caddy with it  it's really nice and Jenkins will run on https


Denny Zhang (Github . Blogger) [< 1 minute ago]
This one?https://github.com/david7482/caddy-jenkins-docker
GitHub
david7482/caddy-jenkins-docker
caddy-jenkins-docker - Host Jenkins with Caddy as https proxy in Docker
#+END_EXAMPLE
** TODO jenkins SCM Sync configuration plugin
https://wiki.jenkins.io/display/JENKINS/SCM+Sync+configuration+plugin
** TODO [#A] Automatically generating Jenkins jobs
https://www.slalom.com/thinking/automatically-generating-jenkins-jobs
*** Jenkins Job Builder
Jenkins Job Builder is a command-line utility that will create Jenkins jobs based upon YAML configurations.
** TODO advanced jenkins customization
Hide port: Change http://XXX.XXX.XXX.XXX:8080 to http://XXX.XXX.XXX.XXX:18080
The whole process takes more than 10 minutes, I only acccept 5 minutes
Create a dedicated policy
Customize EC2 profile
Create Tags to manage the stack
When container restart/recreate, Jenkins configuration won't be lost
** TODO Blog: how to avoid Jenkins SPOF
#+BEGIN_EXAMPLE
Denny Zhang (Github . Blogger) [10:43 AM]
Let's say above 2 Jenkins instances serve the service.

As we know Jenkins have local $JENKINS_HOME folder.

So how these 2 instances work together to serve HA?

Any thoughts?
@Pradipta Dash @Stefan Jansson (QA in Continuous Delivery) @Jonathan.McAllister @Keef Baker


Jonathan McAllister [10:43 AM]
joined #jenkins by invitation from Denny Zhang (Github . Blogger).


Philip Schwartz [11:20 AM]
@Denny Zhang (Github . Blogger) are those suppose to be 2 jenkins masters running in ecs with a load balancer infront of them?


Denny Zhang (Github . Blogger)
[11:20 AM]
yes


Philip Schwartz [11:20 AM]
Jenkins doesn't work that way. You can't drop a load balance infront of masters as they don't cross communicate


[11:22]
If they are cloudbees instances you can use the HA plugin to allow promotion on single master failure. But it is still not the same and requires  shared file systems between them


Denny Zhang (Github . Blogger) [11:22 AM]
How we can avoid Jenkins SPOF, Philip?


new messages
Philip Schwartz [11:23 AM]
With jenkins OSS there is no way
#+END_EXAMPLE
*** TODO Jenkins HA
#+BEGIN_EXAMPLE
Puneeth [12:48 PM]
@Denny Zhang (Github . Blogger)  jenkins master HA is essentially jenkins master in an asg with efs volume for jenkins home


[12:49]
@Denny Zhang (Github . Blogger) there is a white paper from aws on jenkins HA


[12:49]
jenkins slaves ha is again via asg and spot fleet


[12:49]
at least that's our approach


Puneeth [12:54 PM]
@Denny Zhang (Github . Blogger) there can only be one master unless unless unless you move the main job queues from the jenkins master. and use an external job queue :) In this case there can be multi master jenkins confg spread across many regions or within the same region. this is a super advanced approach. this approach is used by openstack . we used it too in our previous company


[12:56]
https://wiki.jenkins.io/plugins/servlet/mobile?contentId=66846870#content/view/66846870
#+END_EXAMPLE
**** TODO Jenkins: https://jenkins.io/blog/2016/06/10/save-costs-with-ec2-spot-fleet/
**** TODO Jenkins Plugin: https://wiki.jenkins.io/display/JENKINS/Gearman+Plugin
**** TODO [#A] Jenkins HA: https://jenkins.io/doc/book/architecting-for-scale/
** TODO Why jenkins create user doesn't seem to work?
https://github.com/chef-cookbooks/jenkins/blob/master/test/fixtures/cookbooks/jenkins_credentials/recipes/create.rb
** TODO [#A] Blog: How chef keep as login user, even if jenkins restart
** TODO jenkins warning: Email notifications could be sent to people who are not users of Jenkins
#+BEGIN_EXAMPLE
Warnings have been published for the following currently installed components:
Mailer Plugin 1.18:
Email notifications could be sent to people who are not users of Jenkins
#+END_EXAMPLE
** TODO 4 Jenkins warning
#+BEGIN_EXAMPLE
You have data stored in an older format and/or unreadable data.
Manage
Dismiss
Disable CLI over Remoting
Dismiss
Allowing Jenkins CLI to work in -remoting mode is considered dangerous and usually unnecessary. You are advised to disable this mode. Please refer to the CLI documentation for details.
Warnings have been published for the following currently installed components:
Mailer Plugin 1.18:
Email notifications could be sent to people who are not users of Jenkins
Go to plugin manager
Configure which of these warnings are shown
Examine
Dismiss
Agent to master security subsystem is currently off. Please read the documentation and consider turning it on
#+END_EXAMPLE
** TODO [#A] jenkins Build Pipeline plugin                         :IMPORTANT:
https://jenkins.io/doc/pipeline/
https://dzone.com/articles/top-10-best-practices-for-jenkins-pipeline
https://github.com/ThoughtWorks-Chengdu-DevOps-Club/tw_devops_workshop/tree/master/season_1/workshop_2
https://jenkins.io/blog/2017/02/01/pipeline-scalability-best-practice/
** TODO Pipeline as Code with Jenkins
https://jenkins.io/solutions/pipeline/
https://www.cloudbees.com/blog/top-10-best-practices-jenkins-pipeline-plugin
** TODO try jenkinsfile-solution: backup Jenkins configuration
Stefan Jansson [12:33 PM]
For sure. We'll see


[12:33]
You feel your jenkins-backup solution works good for you?


Denny Zhang [12:33 PM]
Not very. But it's working


[12:33]
ThinBackup is good. But it will introduce some problem


Stefan Jansson [12:35 PM]
The jenkinsfile-solution seems pretty damn nice. I havent gone deepnintonit yet though.

You basicly points out a github-repo and its jenkinsfile. And it configures your jenkinsjob from scatch.


[12:35]
Sets up, and configures, if ive understoodnitncorrectlt


Denny Zhang [12:35 PM]
Yeah, I've heard of this part.

Let me give it a try.
** TODO [#A] Use Jenkinsfile instead of the UI
http://www.anniehedgie.com/jenkinsfile
https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_ci_jenkins_sample_walkthrough.htm
** TODO What's Jenkins JNLP worker?
** TODO Jenkins plugin: Build Monitor Plugin71 - Visual view of your builds status
** TODO Jenkins plugin: SSH Slaves64 - Manage workers through SSH
** TODO Jenkins plugin: Nested View Plugin70 - Groups jobs into multiple levels instead of a single big list of tabs
** TODO Jenkins plugin: Gearman
https://wiki.jenkins.io/plugins/servlet/mobile?contentId=66846870#content/view/66846870

https://plugins.jenkins.io/gearman-plugin

Jenkins core does not support multiple masters.
** TODO git jenkins depths issue
Ken Godoy [1:38 PM]
See my first screenshot


Denny Zhang (Github . Blogger) [1:38 PM]
Oh yes

Ken Godoy [1:38 PM]
The other options are to create a reference repo locally
Or to just create a new repo as you mentioned.

Denny Zhang (Github . Blogger) [1:39 PM]
hmm, the depth of 1 should be recognized. That looks weird indeed

Ken Godoy [1:39 PM]
But creating a new repo I still need history for at least one year. I have automation that uses history to generate SQL script packages.
I love Jenkins but sometimes it's a pain in the wazoo.

Denny Zhang (Github . Blogger) [1:40 PM]
Need to deep dive into the git jenkins plugin
Let me give it a try tonight as well.
** TODO When we cancel jenkins backup job, the python script won't die
** TODO try jenkins X: http://jenkins-x.io/
*** TODO [#A] why we need jenkins x
*** DONE jx help
   CLOSED: [2018-04-23 Mon 15:46]
➜  ~ jx help


Installing:
  install              Install Jenkins X in the current Kubernetes cluster
  uninstall            Uninstall the Jenkins X platform
  upgrade              Upgrades a resource
  create cluster       Create a new kubernetes cluster
  create jenkins token Adds a new username and api token for a Jenkins server
  init                 Init Jenkins X

Adding Projects to Jenkins X:
  import               Imports a local project or git repository into Jenkins
  create archetype     Create a new app from a Maven Archetype and import the generated code into git and Jenkins for CI/CD
  create spring        Create a new spring boot application and import the generated code into git and Jenkins for CI/CD
  create lile          Create a new lile based application and import the generated code into git and Jenkins for CI/CD
  create micro         Create a new micro based application and import the generated code into git and Jenkins for CI/CD
  create quickstart    Create a new app from a Quickstart and import the generated code into git and Jenkins for CI/CD

Addons:
  create addon         Creates an addon
  environment          View or change the current environment in the current kubernetes cluster
  namespace            View or change the current namespace context in the current kubernetes cluster
  prompt               Generate the command line prompt for the current team and environment
  shell                Create a sub shell so that changes to the kubernetes context, namespace or environment remain local to the shell
  status               status of the Kubernetes cluster or named node

Working with Applications:
  console              Opens the Jenkins console
  cdx                  Opens the CDX dashboard for visualising CI/CD and your environments
  logs                 Tails the log of the latest pod for a deployment
  open                 Open a service in a browser
  rsh                  Opens a terminal in a pod or runs a command in the pod

Working with Environments:
  preview              Creates or updates a Preview Environment for the current version of an application
  promote              Promotes a version of an application to an environment
  create environment   Create a new Environment which is used to promote your Team's Applications via Continuous Delivery
  delete environment   Deletes one or more environments
  edit environment     Edits an Environment which is used to promote your Team's Applications via Continuous Delivery
  get environments     Display one or many Environments

Working with Jenkins X resources:
  get                  Display one or many resources
  edit                 Edit a resource
  create               Create a new resource
  delete               Deletes one or many resources
  start                Starts a process such as a pipeline

Jenkins X Pipeline Commands:
  step                 pipeline steps

Other Commands:
  help                 Help about any command
  version              Print the version information
Usage:
  jx [flags] [options]
Use "jx <command> --help" for more information about a given command.
*** TODO easy how-to
github token: jenkins-x

fe67390d1be344bb48b6a4d524d9ebfa167030af
** TODO Github oauth on jenkins servers
** TODO [#A] avoid wrong input parameter issues
#+BEGIN_EXAMPLE
Denny Zhang (DevOps) [10:08 PM]
That's something I have done this morning.

Since we haven't update any other parts. Only the list is incorrect, so the impact is not big.

Thus I didn't mention that in the slack. But that's wrong indeed.

Robson Poffo [10:09 PM]
yes, it was low impact
Sandro got something wrong on some reportings
and he asked me that
:slightly_smiling_face:
all good


Denny Zhang (DevOps) [10:09 PM]
Inputing wrong parameters happens sometimes. But it could be very dangerous.

I definitely need to think how to prevent this misconfigure issue!
I have made a note. Will think more, and discuss with Carlos and Kung
#+END_EXAMPLE
** TODO when jenkins jobs take too long, abort it and send out alerts
** TODO How to add jenkins slave nodes in jenkins master server using Chef cookbook
 https://stackoverflow.com/questions/32219134/how-to-add-jenkins-slave-nodes-in-jenkins-master-server-using-chef-cookbook
** TODO Use a jenkins job to reconfigure the same chef_json for 3 jobs: DeploySystemDOBematech, DeploySystemRehearsalDOBematech, UpdateHAProxyNodeListDOBematech
** HALF copy json folder across nodes: http://myjenkins:18080/job/CopyFolderFromNode1ToNode2/
 > copy_folder_node1_to_node2.sh && vim copy_folder_node1_to_node2.sh

 bash -ex copy_folder_node1_to_node2.sh "138.197.206.101" "/data/staging/" "165.227.52.135" "/tmp/staging"
** HALF [#A] doc: why vm shutdown has failed: http://myjenkins:18080/job/RunCommandOnServers/187/
** TODO [#A] problem: Fail to shutdown couchbase nodes: http://myjenkins:18080/job/RunCommandOnServers/181/console
https://issues.couchbase.com/browse/MB-11765
159.65.76.92 (bematech-do-cb-008)

06:43:04
06:43:04  * couchbase-server is running
06:43:04

#+BEGIN_EXAMPLE
Denny Zhang (DevOps) [8:48 AM]
So far, haven't found major issues.

All ES/mdm/haproxy services have been shutdown.
All CB services have been shutdown, except one. `159.65.76.92 (bematech-do-cb-008)`

It has been 13 minutes since we have issued the service stop command.
Will watch another 2 minutes, then "stop again". If still doesn't work, use kill, then kill -9.
#+END_EXAMPLE

#+BEGIN_EXAMPLE
root@bematech-do-cb-008:/opt/couchbase/var/lib/couchbase/logs# service couchbase-server stop
{error_logger,{{2018,2,26},{14,48,36}},"Protocol: ~tp: the name executioner@executioner seems to be in use by another Erlang node",["inet_tcp"]}
{error_logger,{{2018,2,26},{14,48,36}},crash_report,[[{initial_call,{net_kernel,init,['Argument__1']}},{pid,<0.21.0>},{registered_name,[]},{error_info,{exit,{error,badarg},[{gen_server,init_it,6,[{file,"gen_server.erl"},{line,320}]},{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,239}]}]}},{ancestors,[net_sup,kernel_sup,<0.10.0>]},{messages,[]},{links,[#Port<0.53>,<0.18.0>]},{dictionary,[{longnames,true}]},{trap_exit,true},{status,running},{heap_size,610},{stack_size,27},{reductions,783}],[]]}
{error_logger,{{2018,2,26},{14,48,36}},supervisor_report,[{supervisor,{local,net_sup}},{errorContext,start_error},{reason,{'EXIT',nodistribution}},{offender,[{pid,undefined},{name,net_kernel},{mfargs,{net_kernel,start_link,[['executioner@executioner',longnames]]}},{restart_type,permanent},{shutdown,2000},{child_type,worker}]}]}
{error_logger,{{2018,2,26},{14,48,36}},supervisor_report,[{supervisor,{local,kernel_sup}},{errorContext,start_error},{reason,{shutdown,{failed_to_start_child,net_kernel,{'EXIT',nodistribution}}}},{offender,[{pid,undefined},{name,net_sup},{mfargs,{erl_distribution,start_link,[]}},{restart_type,permanent},{shutdown,infinity},{child_type,supervisor}]}]}
{error_logger,{{2018,2,26},{14,48,36}},crash_report,[[{initial_call,{application_master,init,['Argument__1','Argument__2','Argument__3','Argument__4']}},{pid,<0.9.0>},{registered_name,[]},{error_info,{exit,{{shutdown,{failed_to_start_child,net_sup,{shutdown,{failed_to_start_child,net_kernel,{'EXIT',nodistribution}}}}},{kernel,start,[normal,[]]}},[{application_master,init,4,[{file,"application_master.erl"},{line,133}]},{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,239}]}]}},{ancestors,[<0.8.0>]},{messages,[{'EXIT',<0.10.0>,normal}]},{links,[<0.8.0>,<0.7.0>]},{dictionary,[]},{trap_exit,true},{status,running},{heap_size,376},{stack_size,27},{reductions,117}],[]]}
{error_logger,{{2018,2,26},{14,48,36}},std_info,[{application,kernel},{exited,{{shutdown,{failed_to_start_child,net_sup,{shutdown,{failed_to_start_child,net_kernel,{'EXIT',nodistribution}}}}},{kernel,start,[normal,[]]}}},{type,permanent}]}
{"Kernel pid terminated",application_controller,"{application_start_failure,kernel,{{shutdown,{failed_to_start_child,net_sup,{shutdown,{failed_to_start_child,net_kernel,{'EXIT',nodistribution}}}}},{kernel,start,[normal,[]]}}}"}

Crash dump was written to: erl_crash.dump.1519656516.20531.babysitter
Kernel pid terminated (application_controller) ({application_start_failure,kernel,{{shutdown,{failed_to_start_child,net_sup,{shutdown,{failed_to_start_child,net_kernel,{'EXIT',nodistribution}}}}},{k
 * Failed to stop couchbase-server
#+END_EXAMPLE
** TODO jenkins: jenkins-job-builder plugin for job creation
** TODO https://jenkins.io/doc/book/managing/cli/#remoting-connection-mode
** TODO Jenkins: SCM Sync configuration plugin: https://wiki.jenkins.io/display/JENKINS/SCM+Sync+configuration+plugin
** TODO learn from other repo: aws jenkins: https://github.com/search?p=2&q=aws-jenkins&type=Repositories&utf8=✓
** TODO http://myjenkins:18080/job/CopyFolderFromNode1ToNode2/
** TODO mute the output of token: http://myjenkins:18080/job/CreateAndProvisionVMInCloud/176/console
** TODO restart es: console output is very slow to show: http://myjenkins:18080/job/RestartOneESSafely/5/console
** TODO https://medium.com/meedan-updates/github-jenkins-hubot-slack-1e61a466e388
** TODO Pull Request Validation Between Jenkins and Bitbucket: http://icarobichir.com.br/posts/pull-request-validation-between-jenkins-and-bitbucket/
** TODO beautify ansible output: http://jenkinscn.dennyzhang.com:18088/job/dennytest/3/console
** TODO jenkins: http://www.hugeinc.com/ideas/perspective/best-practices-for-jenkin-jobs
https://www.infoq.com/articles/orch-pipelines-jenkins
** HALF avoid jenkins: Jenkins is going to shut down
https://stackoverflow.com/questions/12182882/how-to-prevent-hudson-from-entering-shutdown-mode-automatically-or-when-idle
Solution: disable the thinBackup plugin

https://wiki.jenkins.io/display/JENKINS/thinBackup
https://issues.jenkins-ci.org/browse/JENKINS-13239

Have you installed any plugin called Thin backup? if yes  it might  configured to shut down after back up, then change the setting.
** #  --8<-------------------------- separator ------------------------>8-- :noexport:
** TODO Jenkins credential parameter
  http://steve-jansen.github.io/blog/2014/12/16/parsing-jenkins-secrets-in-a-shell-script/
https://stackoverflow.com/questions/34815482/accessing-credentials-in-jenkins-with-the-credentials-parameter-plugin
https://www.cloudbees.com/blog/injecting-secrets-jenkins-builds-using-credentials-plugin
** TODO Jenkins shell get credential secret text
** TODO Jenkins parse credential parameter
https://stackoverflow.com/questions/34815482/accessing-credentials-in-jenkins-with-the-credentials-parameter-plugin
https://wiki.jenkins-ci.org/display/JENKINS/Credentials+Binding+Plugin
** TODO Jenkins apache issue!
ls -lth /var/run/apache2/apache2.pid
** TODO bug: cancel backup from Jenkins won't kill the process
root@bematech-do-jenkins:/opt/couchbase/backup# ps -ef | grep cou
root     30800 30799  0 18:57 ?        00:00:00 python /opt/devops/bin/cb_backup.py --bucket_list=mdm-session --cbserver=http://138.68.225.199:8091 --cbbackup_bin=/opt/couchbase/mdmpublic/couchbase-cli/bin/cbbackup --backup_dir=/opt/couchbase/backup --username Administrator --password password1234 --backup_method full
root     30801 30800  0 18:57 ?        00:00:00 /bin/sh -c /opt/couchbase/mdmpublic/couchbase-cli/bin/cbbackup http://138.68.225.199:8091 /opt/couchbase/backup/mdm-session -u Administrator -p password1234 -b mdm-session -m full -t 4 >> /var/log/cb_backup.log
root     30802 30801 99 18:57 ?        00:00:43 python /opt/couchbase/mdmpublic/couchbase-cli/lib/python/cbbackup http://138.68.225.199:8091 /opt/couchbase/backup/mdm-session -u Administrator -p password1234 -b mdm-session -m full -t 4
root     31120 12741  0 18:58 pts/4    00:00:00 grep --color=auto cou
root@bematech-do-jenkins:/opt/couchbase/backup# kill 30800
** TODO Jenkins create a global variable: to avoid duplication configurations
** TODO Automate the thinbackup Jenkins restore
** TODO Jenkins agent and servers
** TODO automate Jenkins restore from thinbackup
** TODO High Jenkins CPU load: we can't run the jobs
** TODO Run Docker commands from Jenkins container
https://sreeninet.wordpress.com/2016/01/23/ci-cd-with-docker-jenkins-and-tutum/

https://stackoverflow.com/questions/38510952/jenkins-running-docker-commands-on-a-docker-slave
https://github.com/jenkinsci/docker-workflow-plugin/tree/master/demo
https://stackoverflow.com/questions/36088227/how-to-run-a-docker-command-in-jenkins-build-execute-shell
https://stackoverflow.com/questions/42859443/execute-docker-commands-in-jenkins-in-docker-container
** TODO Use AWS S3 for my critical backup: Jenkins configurations
* TODO [#A] try Jenkins X                                          :noexport:
* TODO jenkins pipeline run docker container                       :noexport:
* TODO jenkins enable github authentication                        :noexport:
https://jenkins.io/solutions/github/
* useful link                                                      :noexport:
http://tdongsi.github.io/blog/2017/12/30/groovy-hook-script-and-jenkins-configuration-as-code/
http://tdongsi.github.io/blog/2017/07/18/basic-jenkinsfile-cookbook/
http://tdongsi.github.io/blog/2017/06/16/troubleshooting-groovy-scripts-in-jenkinsfile/
http://tdongsi.github.io/blog/2017/04/18/groovy-code-in-jenkins-pipeline/
* #  --8<-------------------------- separator ------------------------>8-- :noexport:
* TODO Provision agent using Jenkins swarm plugin                  :noexport:
* TODO Automate agent provisioning and make them ephemeral         :noexport:
* TODO Jenkins pipeline: docker image as agent                     :noexport:
* TODO docker image as agent with persistent storage               :noexport:
* HALF Jenkins script approval                                     :noexport:
https://gist.github.com/dnozay/e7afcf7a7dd8f73a4e05
https://stackoverflow.com/questions/43476370/exporting-and-importing-jenkins-pipeline-script-approvals/43477258

#+BEGIN_EXAMPLE
// instance containing the approvals
// list of approved hashes: println instance.approvedScriptHashes
 
ScriptApproval instance = Jenkins.getInstance().getExtensionList(RootAction.class).get(ScriptApproval.class);
approvedScriptHashes = instance.approvedScriptHashes
#+END_EXAMPLE
* TODO groovy: Use a regular expression to include jobs into the view :noexport:
* #  --8<-------------------------- separator ------------------------>8-- :noexport:
* DONE [#A] Jenkins: send slack notification for job failures      :noexport:
  CLOSED: [2019-05-01 Wed 11:06]
* DONE [#A] jenkins kubo_ssh_passwd: jenkins secret text           :noexport:
  CLOSED: [2019-05-01 Wed 11:06]
https://support.cloudbees.com/hc/en-us/articles/204897020-Fetch-a-userid-and-password-from-a-Credential-object-in-a-Pipeline-job-
https://stackoverflow.com/questions/48330402/secret-text-git-credentials-not-showing-up-in-jenkins-project-source-code-mana#comment83676647_48336020
https://github.com/jenkinsci/slack-plugin/issues/270
https://fedidat.com/270-jenkinsfile-scripted-secret-text/
https://jenkins.io/doc/pipeline/steps/credentials-binding/
http://steve-jansen.github.io/blog/2014/12/16/parsing-jenkins-secrets-in-a-shell-script/
https://kb.novaordis.com/index.php/Injecting_Jenkins_Credentials_into_a_Build_Job

* DONE jenkins groovy get job                                      :noexport:
  CLOSED: [2019-04-25 Thu 22:13]
https://medium.com/@garimajdamani/how-to-get-jenkins-build-job-details-b8c918087030
import jenkins.model.Jenkins
name = "ProvisionPKSEnvRaw"
def job = Hudson.instance.getJob(name)
println job.getLastBuild().getLog(50)

* DONE doc: Jenkins pipeline: if ip not found, skip healthcheck    :noexport:
  CLOSED: [2019-04-26 Fri 19:16]
#+BEGIN_SRC groovy
void triggerHealthCheck() {
    if (!kuboIP.isEmpty()) {
        def child_job = build job: &apos;HealthCheckPKSEnv&apos;,
            propagate: false,
            parameters: [string(name: &apos;jumpbox_ip&apos;, value: kuboIP),
                         string(name: &apos;skip_kubectl_test&apos;, value: &apos;true&apos;)]
        loadAndParseJobLogs(child_job)
        updateBuild(child_job)
    } else {
        println(&quot;WARNING: kuboIP is not found from downstream job output. Skip health check&quot;)
    }
}
#+END_SRC

#+BEGIN_SRC groovy
        stage(&apos;Health check&apos;) {
            steps {
                echo &apos;===&gt; Start the health check of the provisioned nimbus testbed...&apos;
                timeout(time: 180, unit: &apos;MINUTES&apos;) {
                    script {
                        triggerHealthCheck()
                    }
                }
            }
#+END_SRC

* DONE Jenkins pipeline show user id                               :noexport:
  CLOSED: [2019-04-28 Sun 21:42]
https://stackoverflow.com/questions/49726409/jenkins-get-current-user-in-pipeline?answertab=votes#tab-top
node {
  wrap([$class: 'BuildUser']) {
       def user = env.BUILD_USER_ID
       println "user: " + user
     }
}
* DONE Jenkins pipeline if else not working                        :noexport:
  CLOSED: [2019-04-28 Sun 22:13]
https://stackoverflow.com/questions/43587964/jenkins-pipeline-if-else-not-working

- you can simplify this and potentially avoid the if statement (as long as you don't need the else) by using "when". 
- wrap it in a script step

#+BEGIN_SRC groovy
pipeline {
    agent any

    stages {
        stage('test') {
            steps {
                sh 'echo hello'
            }
        }
        stage('test1') {
            steps {
                sh 'echo $TEST'
            }
        }
        stage('test3') {
            steps {
                script {
                    if (env.BRANCH_NAME == 'master') {
                        echo 'I only execute on the master branch'
                    } else {
                        echo 'I execute elsewhere'
                    }
                }
            }
        }
    }
}
#+END_SRC
* DONE jenkins credentials                                         :noexport:
  CLOSED: [2019-04-29 Mon 14:45]
https://www.tikalk.com/posts/2017/03/07/how-to-mask-credentials-in-your-jenkins-jobs/

* DONE jenkins fails to send slack notification: check slack plugin version: slack:2.2 :noexport:
  CLOSED: [2019-03-06 Wed 16:59]
https://github.com/jenkinsci/slack-plugin/issues/323
* DONE Better Jenkins UI: ocean-blue                               :noexport:
  CLOSED: [2019-03-14 Thu 16:11]
https://jenkins.io/doc/book/blueocean/getting-started/#as-part-of-jenkins-in-docker
* DONE Dynamically create jenkins users                            :noexport:
  CLOSED: [2019-03-27 Wed 11:04]

* #  --8<-------------------------- separator ------------------------>8-- :noexport:
* TODO Jenkins credential scope: Global(jenkins, nodes, items, all child items, etc) and System (Jenkins and nodes only) :noexport:
* HALF Jenkins pipeline credentials for all stages                 :noexport:
https://stackoverflow.com/questions/49739933/jenkins-pipeline-credentials-for-all-stages
* TODO Configure jenkins slave Node                                :noexport:
* TODO Semantic Versioning class for Groovy                        :noexport:
https://gist.github.com/michaellihs/a6621376393821d6d206ccfc8dbf86ec
* TODO [#A] Run jenkins pipeline code inside docker image          :noexport:
https://akomljen.com/set-up-a-jenkins-ci-cd-pipeline-with-kubernetes/
https://gist.github.com/cyrille-leclerc/8cad9d1b35ea553820a1
* TODO [#A] jenkins wrap class                                     :noexport:
https://gist.github.com/cyrille-leclerc/552e3103139557e0196a
https://gist.github.com/HarshadRanganathan/97feed7f91b7ae542c994393447f3db4
* TODO Load groovy script as import, instead of                    :noexport:
pipelineUtils = load "${JENKINS_HOME}/init.groovy.d/pipeline-utils.groovy"

                    script {
                        pipelineUtils.sendSlackNotification(slack_target, jobLogs, downstreamJobResult)
                    }
* HALF Jenkins pipeline check website availability issue           :noexport:
https://stackoverflow.com/questions/40393557/jenkins-pipeline-script-to-check-the-website-is-up
https://jenkinsci.github.io/job-dsl-plugin/#method/javaposse.jobdsl.dsl.helpers.triggers.MultibranchWorkflowTriggerContext.urlTrigger
* #  --8<-------------------------- separator ------------------------>8-- :noexport:
* DONE Builds in Jenkins run as the virtual SYSTEM user with full permissions by default. :noexport:
  CLOSED: [2019-06-13 Thu 11:18]
https://wiki.jenkins.io/display/JENKINS/Authorize+Project+plugin
#+BEGIN_EXAMPLE
Builds in Jenkins run as the virtual SYSTEM user with full permissions by default. This can be a problem if some users have restricted or no access to some jobs, but can configure others. If that is the case, it is recommended to install a plugin implementing build authentication, and to override this default.
✅ An implementation of access control for builds is present.
❌ Access control for builds is possible, but not configured. Configure it in the global security configuration
#+END_EXAMPLE
* TODO Tried proxying jenkins.telemetry.Correlator to support a circular dependency, but it is not an interface. :noexport:
https://github.com/marcelbirkner/docker-ci-tool-stack/issues/70
* #  --8<-------------------------- separator ------------------------>8-- :noexport:
* Jenkins cheatshee: https://www.edureka.co/blog/cheatsheets/jenkins-cheat-sheet/ :noexport:
* TODO update doc                                                  :noexport:
https://wilsonmar.github.io/jenkins2-pipeline/
* Jenkins code coverage                                            :noexport:
** Cobertura coverage report
https://wiki.jenkins.io/display/JENKINS/Cobertura+Plugin

https://vmoperator.svc.eng.vmware.com/view/Auth%20Service/job/gcm-build/59/
* jenkins groovy timeout set the value                             :noexport:
https://stackoverflow.com/questions/38597006/input-step-with-timeout-which-continues-with-default-settings-using-jenkins-pipe?rq=1
* TODO Integrate GitLab MR with Jenkins Job in your CI Pipeline    :noexport:
https://confluence.eng.vmware.com/display/BUTLER/Jenkins+Troubleshooting#JenkinsTroubleshooting-Jenkinsgitlabplugin:Can'ttriggerbuildsonAcceptedMergeRequests

#+BEGIN_EXAMPLE

Create a Pipeline Job and configure Build Trigger as follows

Please Note that "Filter merge request by label" is optional. If you add any label, this job will be triggered only when the MR contains these labels
Generate Secret toke by clicking "Generate" button. (Please make note of the token, we need to enter same value in the GitLab hook in Step 3)
Configure your Pipeline job location. (Jenkins Job will scan the git-repo that you configure for "Jenkinsfile" file)

Credentials : You can use whoever have atleast "developer" permission on this project.
Branches to build: "${gitlabSourceRepoName}/${gitlabSourceBranch}"
Script path: This is the path to the Jenkinsfile in your repo.
Save your pipeline job.
Now, its time to configure the webhook in GitLab repo to trigger this job on MR.
Go to your repo in GitLab → Settings → Integrations

Enter the token that you generated in your Jenkins pipeline job and enable all appropriate checkboxes for your project.
Add GitLab logger in Jenkins
Go to Jenkins -> Manage Jenkins -> System Log
Add new log recorder
Enter 'Gitlab plugin' or whatever you want for the name
On the next page, enter 'com.dabsquared.gitlabjenkins' for Logger, set log level to FINEST, and save
Then click on your Gitlab plugin log, click 'Clear this log' if necessary, and then use GitLab to trigger some actions
Refresh the log page and you should see output
Go back to the Integration page in the GitLab, click on "Test" button to see if your webhook is triggering the Jenkins job. you can just see the log in the Jenkins under the logger you just created in previous step
Send a Dummy MR to the branch (Make sure you add the "labels" if you enabled any filtering in your job) and see if the pipeline is getting triggered, if not, check the logs in the Jenkins and Gitlab (by editing the hook, you can see the Recent Deliveries)
More info: https://github.com/jenkinsci/gitlab-plugin
More info on writing pipeline stages with GitLab: https://gitlab.eng.XXX.com/devtools/butler/butler-next/blob/butler-generic-workflow/api/Jenkinsfile
#+END_EXAMPLE
* TODO jenkins pipeline use array                                  :noexport:
* TODO jenkins groovy format string                                :noexport:
* groovy                                                           :noexport:
String fileContents = "zdenny-vdnet-esx-sb-30035046-1-poc-dev-denny-22 | 10.161.178.251 zdenny-vdnet-esx-sb-30035046-3-poc-dev-denny-22 | 10.161.164.134 zdenny-vdnet-esx-sb-30035046-2-poc-dev-denny-22 | 10.161.166.34 zdenny-vdnet-esx-sb-30035046-100-poc-dev-denny-22 | 10.161.181.6 zdenny-vdnet-vc-sb-30035088-1-poc-dev-denny-22 | 10.161.182.121 zdenny-vdnet-nsxmanager-14880419-1-poc-dev-denny-22 | 10.161.184.67 zdenny-wn-1-poc-dev-denny-22";

def digitPattern = ~/.*(vdnet-vc).*/;

def matcher = fileContents =~ digitPattern;
matcher.size();
matcher[0]
matcher[1]

// digitPattern.matcher(fileContents).find()

 [0-9]+\.[0-9]+\.[0-9]+121


================================================
FILE: addjobstoview-byregexp.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: addjobstoview-byregexp.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-05-23 14:37:35>
//-------------------------------------------------------------------
// imports
import jenkins.model.Jenkins
import hudson.model.ListView
import hudson.model.View

// get Jenkins instance
Jenkins jenkins = Jenkins.getInstance()

def viewName = 'MyTest'
jenkins.addView(new ListView(viewName))
myView = hudson.model.Hudson.instance.getView(viewName)
for (item in Jenkins.instance.projects.collect()) {
    if (item.name ==~ /.*Test.*/ ) {
        myView.doAddJobToView(item.name)
    }
}

// Add by regexp
viewName = 'Integration'
jenkins.addView(new ListView(viewName))
myView = hudson.model.Hudson.instance.getView(viewName)
myView.setIncludeRegex(".*Integration.*")


================================================
FILE: build-monitor-views.xml
================================================
  <views>
    <hudson.model.AllView>
      <owner class="hudson" reference="../../.."/>
      <name>all</name>
      <filterExecutors>false</filterExecutors>
      <filterQueue>false</filterQueue>
      <properties class="hudson.model.View$PropertyList"/>
    </hudson.model.AllView>
    <com.smartcodeltd.jenkinsci.plugins.buildmonitor.BuildMonitorView plugin="build-monitor-plugin@1.12+build.201809061734">
      <owner class="hudson" reference="../../.."/>
      <name>AutoReport</name>
      <filterExecutors>false</filterExecutors>
      <filterQueue>false</filterQueue>
      <properties class="hudson.model.View$PropertyList"/>
      <jobNames>
        <comparator class="hudson.util.CaseInsensitiveComparator"/>
        <string>DetectTestbedFormatChanges</string>
        <string>MonitorDownloadURLs</string>
        <string>NightlyProvisionBasicTest</string>
        <string>NightlyProvisionGear2Test</string>
        <string>NightlyProvisionIntegrationTest</string>
        <string>ProvisionPKSEnvNimbus</string>
        <string>ProvisionPKSEnvNimbusAdvancew</string>
      </jobNames>
      <jobFilters/>
      <columns/>
      <recurse>false</recurse>
      <title>AutoReport</title>
      <config>
        <displayCommitters>false</displayCommitters>
        <buildFailureAnalyzerDisplayedField>Name</buildFailureAnalyzerDisplayedField>
        <order class="com.smartcodeltd.jenkinsci.plugins.buildmonitor.order.ByName"/>
      </config>
    </com.smartcodeltd.jenkinsci.plugins.buildmonitor.BuildMonitorView>
  </views>


================================================
FILE: check-slave-jar-version.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: check-slave-jar-version.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-05-01 16:51:48>
//-------------------------------------------------------------------
// https://gist.github.com/ctran/8f82adedaa23ea924c52
import jenkins.model.*
import hudson.remoting.Launcher
import hudson.slaves.SlaveComputer

def expectedVersion = Launcher.VERSION
for (computer in Jenkins.instance.getComputers()) {
  if (! (computer instanceof SlaveComputer)) continue
  if (!computer.getChannel()) continue
	
  def version = computer.getSlaveVersion()
  if (!expectedVersion.equals(version)) {
    println "${computer.name} - expected ${expectedVersion} but got ${version}"
  }
}


================================================
FILE: config-pipeline-library.groovy
================================================
// https://github.com/thbkrkr/jks/blob/master/init.groovy.d/11-configure-pipeline-global-shared.groovy
/*
 * Configure pipeline shared libraries in the global Jenkins configuration.
 * This will safely compare configured libraries and only overwrite the global
 * shared library config if changes have been made.
 * workflow-cps-global-lib 2.9
 */
import jenkins.model.Jenkins
import jenkins.plugins.git.GitSCMSource
import jenkins.plugins.git.traits.BranchDiscoveryTrait
import org.jenkinsci.plugins.workflow.libs.GlobalLibraries
import org.jenkinsci.plugins.workflow.libs.LibraryConfiguration
import org.jenkinsci.plugins.workflow.libs.SCMSourceRetriever

List libraries = [] as ArrayList

def remote = System.getenv("PIPELINE_SHARED_LIB_REMOTE")
def credentialsId = System.getenv("PIPELINE_SHARED_LIB_CREDS_ID")

name = 'pipeline-lib'
defaultVersion = 'master'

if (remote != null) {

    def scm = new GitSCMSource(remote)
    if (credentialsId != null) {
        scm.credentialsId = credentialsId
    }

    scm.traits = [new BranchDiscoveryTrait()]
    def retriever = new SCMSourceRetriever(scm)

    def library = new LibraryConfiguration(name, retriever)
    library.defaultVersion = defaultVersion
    library.implicit = true
    library.allowVersionOverride = true
    library.includeInChangesets = true

    libraries << library

    def global_settings = Jenkins.instance.getExtensionList(GlobalLibraries.class)[0]
    global_settings.libraries = libraries
    global_settings.save()
    println 'Configured Pipeline Global Shared Libraries:\n    ' + global_settings.libraries.collect { it.name }.join('\n    ')
}


================================================
FILE: config-slack.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: slack_notification.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Description :
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-04-30 16:07:20>
//-------------------------------------------------------------------
// https://github.com/jenkinsci/slack-plugin/blob/master/src/main/java/jenkins/plugins/slack/SlackNotifier.java
import jenkins.model.Jenkins
import jenkins.plugins.slack.SlackNotifier.*

// def slack = Jenkins.instance.getDescriptorByType(jenkins.plugins.slack.SlackNotifier.DescriptorImpl)
def slack = Jenkins.instance.getExtensionList('jenkins.plugins.slack.SlackNotifier$DescriptorImpl')[0]

slack.tokenCredentialId = 'slack_token_passwd'
slack.baseUrl = 'https://vmware.slack.com/services/hooks/jenkins-ci'

slack.save()
println 'Slack global settings configured.'


================================================
FILE: create-jenkins-job.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: create-jenkins-job.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-05-01 13:47:38>
//-------------------------------------------------------------------
import jenkins.model.Jenkins;
import hudson.model.FreeStyleProject;
import hudson.tasks.Shell;

job = Jenkins.instance.createProject(FreeStyleProject, 'job-name')

job.buildersList.add(new Shell('echo hello world'))

job.save()

build = job.scheduleBuild2(5, new hudson.model.Cause.UserIdCause())

build.get()


================================================
FILE: create-jenkins-user.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: create-jenkins-user.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-05-01 16:51:53>
//-------------------------------------------------------------------
// https://gist.github.com/hayderimran7/50cb1244cc1e856873a4
import jenkins.model.*
import hudson.security.*

def instance = Jenkins.getInstance()

// Create a jenkins user
def hudsonRealm = new HudsonPrivateSecurityRealm(false)
hudsonRealm.createAccount("jenkinsadmin","password1234")
instance.setSecurityRealm(hudsonRealm)


================================================
FILE: create-secret-text.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: create-secret-text.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-05-01 16:51:58>
//-------------------------------------------------------------------
// https://gist.github.com/chrisvire/383a2c7b7cfb3f55df6a
import jenkins.model.*
import hudson.util.Secret
import com.cloudbees.plugins.credentials.*
import com.cloudbees.plugins.credentials.domains.*
import org.jenkinsci.plugins.plaincredentials.impl.*

domain = Domain.global()
store = Jenkins.instance.getExtensionList('com.cloudbees.plugins.credentials.SystemCredentialsProvider')[0].getStore()

secretText = new StringCredentialsImpl(
CredentialsScope.GLOBAL,
"secret-text",
"Secret Text Description",
Secret.fromString("some secret text goes here"))

store.addCredentials(domain, secretText)


================================================
FILE: delete-job-by-regexp.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: delete-job-by-regexp.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-05-01 16:52:03>
//-------------------------------------------------------------------
// https://gist.github.com/nextrevision/d11b2df4e8b229c6855b
import jenkins.model.*

def matchedJobs = Jenkins.instance.items.findAll { job ->
    job.name =~ /my_regex_here/
}
    
matchedJobs.each { job ->
    println job.name
    //job.delete()
}


================================================
FILE: dict-to-json.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: dict-to-json.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-05-01 16:51:19>
//-------------------------------------------------------------------
import static groovy.json.JsonOutput.*
def config = ['name': 'denny']
println prettyPrint(toJson(config))


================================================
FILE: docker-cleanup.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: docker-cleanup.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-05-01 16:52:13>
//-------------------------------------------------------------------
// https://gist.github.com/rcbop/4acabfb15db6b361698ebd76ce5646e2
node("${params.BUILD_AGENT}") {
    
    stage('Dangling Containers') {
      sh 'docker ps -q -f status=exited | xargs --no-run-if-empty docker rm'
    }

    stage('Dangling Images') {
      sh 'docker images -q -f dangling=true | xargs --no-run-if-empty docker rmi'
    }
    
    stage('Dangling Volumes') {
      sh 'docker volume ls -qf dangling=true | xargs -r docker volume rm'
    }
}



================================================
FILE: enable-ldap.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: enable-ldap.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-05-01 16:52:17>
//-------------------------------------------------------------------
import jenkins.model.*

import hudson.security.LDAPSecurityRealm
import hudson.security.HudsonPrivateSecurityRealm
import hudson.security.FullControlOnceLoggedInAuthorizationStrategy
import hudson.util.Secret
import jenkins.model.IdStrategy
import jenkins.security.plugins.ldap.LDAPConfiguration
import net.sf.json.JSONObject

// https://wiki.jenkins.io/display/JENKINS/LDAP+Plugin
if(!binding.hasVariable('ldap_settings')) {
   ldap_settings = [
      'server': 'ldaps://ldaps.mycompany.com:636',
      'rootDN': 'DC=mycompany,DC=com',
   ]
}
if(!(ldap_settings instanceof Map)) {
   throw new Exception('ldap_settings must be a Map.')
}

ldap_settings = ldap_settings as JSONObject

if(!(Jenkins.instance.securityRealm instanceof LDAPSecurityRealm)) {
   LDAPConfiguration conf = new LDAPConfiguration(
      ldap_settings.optString('server'),
      ldap_settings.optString('rootDN'),
      ldap_settings.optBoolean('inhibitInferRootDN'),
      ldap_settings.optString('managerDN'),
      Secret.fromString(ldap_settings.optString('managerPasswordSecret')))

   conf.userSearchBase = ldap_settings.optString('userSearchBase')
   conf.userSearch = ldap_settings.optString('userSearch', LDAPSecurityRealm.DescriptorImpl.DEFAULT_USER_SEARCH)
   conf.groupSearchBase = ldap_settings.optString('groupSearchBase')
   conf.groupSearchFilter = ldap_settings.optString('groupSearchFilter')
   conf.environmentProperties = (ldap_settings.opt('environmentProperties')?:[:]).collect { k, v ->
      new LDAPSecurityRealm.EnvironmentProperty(k.toString(), v.toString())
   } as LDAPSecurityRealm.EnvironmentProperty[]
   conf.displayNameAttributeName = ldap_settings.optString('displayNameAttributeName', LDAPSecurityRealm.DescriptorImpl.DEFAULT_DISPLAYNAME_ATTRIBUTE_NAME)
   conf.mailAddressAttributeName = ldap_settings.optString('mailAddressAttributeName', LDAPSecurityRealm.DescriptorImpl.DEFAULT_MAILADDRESS_ATTRIBUTE_NAME)

   List<LDAPConfiguration> configurations = [conf]
   Jenkins.instance.securityRealm = new LDAPSecurityRealm(
      configurations,
      ldap_settings.optBoolean('disableMailAddressResolver'),
      null,
      IdStrategy.CASE_INSENSITIVE,
      IdStrategy.CASE_INSENSITIVE)

   def strategy = new hudson.security.FullControlOnceLoggedInAuthorizationStrategy()
   strategy.setAllowAnonymousRead(true)
   Jenkins.instance.setAuthorizationStrategy(strategy)

   Jenkins.instance.save()
   println 'Security realm set to LDAP.'
}
else {
   println 'Nothing changed.  LDAP security realm already configured.'
}


================================================
FILE: execute-command.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: execute-command.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-05-01 16:52:22>
//-------------------------------------------------------------------
// https://gist.github.com/katta/5465317
def command = "date"
def proc = command.execute()
proc.waitFor()     

println "Process exit code: ${proc.exitValue()}"
println "Std Err: ${proc.err.text}"
println "Std Out: ${proc.in.text}" 


================================================
FILE: files-folder.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: files-folder.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-05-01 16:52:26>
//-------------------------------------------------------------------
import groovy.io.FileType

// Create folder if missing
def folderName = '/var/jenkins_home/jobs/backup'

def thinBackupDir = new File(folderName)
if (thinBackupDir.exists() == false) {
   // https://github.com/cloudbees/jenkins-scripts/blob/master/copy-move-diagnosis.groovy#L19
   thinBackupDir.mkdirs()
}

////////////////////////////////////////////////////////////////////////////////
// Create folders and files
// https://mrhaki.blogspot.com/2010/04/groovy-goodness-working-on-files-or.html
// First create sample dirs and files.
(1..3).each {
 new File("dir$it").mkdir()
}
(1..3).each {
 def file = new File("file$it")
 file << "Sample content for ${file.absolutePath}"
}

////////////////////////////////////////////////////////////////////////////////
// Create files with different methods
// https://mrhaki.blogspot.com/2009/08/groovy-goodness-working-with-files.html
// Normal way of creating file objects.
def file1 = new File('groovy1.txt')
def file2 = new File('groovy2.txt')
def file3 = new File('groovy3.txt')
 
// Writing to the files with the write method:
file1.write 'Working with files the Groovy way is easy.\n'
 
// Using the leftShift operator:
file1 << 'See how easy it is to add text to a file.\n'
 
// Using the text property:
file2.text = '''We can even use the text property of
a file to set a complete block of text at once.'''
 
// Or a writer object:
file3.withWriter('UTF-8') { writer ->
    writer.write('We can also use writers to add contents.')
}

////////////////////////////////////////////////////////////////////////////////
// Reading contents of files to an array:
def lines = file1.readLines()
assert 2 == lines.size()
assert 'Working with files the Groovy way is easy.' == lines[0]

// Or we read with the text property:
assert 'We can also use writers to add contents.' == file3.text

     
////////////////////////////////////////////////////////////////////////////////
// Delete all files:
// https://mrhaki.blogspot.com/2009/08/groovy-goodness-working-with-files.html
files.each { new File(it).delete() }

////////////////////////////////////////////////////////////////////////////////
/*
// https://mrhaki.blogspot.com/2009/12/groovy-goodness-delete-non-empty.html
def mainDir = new File('test')
def subDir = new File(mainDir, 'app')
def file = new File(subDir, 'test.txt')
 
subDir.mkdirs()  // Create directories.
file << 'sample'  // Create file and add contents.
 
assert mainDir.exists() && subDir.exists() && file.exists()
 
def result = mainDir.deleteDir()  // Returns true if all goes well, false otherwise.
assert result
assert !mainDir.exists() && !subDir.exists() && !file.exists()
*/    


================================================
FILE: find-dead-executors.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: find-dead-executors.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-05-01 14:09:37>
//-------------------------------------------------------------------
// https://gist.github.com/malonem/5045386
// get handle to build output
def config = new HashMap()
def bindings = getBinding()
config.putAll(bindings.getVariables())
def out = config['out']

for (aSlave in hudson.model.Hudson.instance.slaves) {
  // check if executor is dead
  execList = aSlave.getComputer().getExecutors()      
  for( exec in execList ) {
    if (exec.getCauseOfDeath()) {
      println("\tSlave ${aSlave.name} has a dead executor.")
      println("Error:")
      exec.getCauseOfDeath().printStackTrace(out) 
      println('\n')
      println("\tRemoving Dead Executor.")
      exec.doYank()
    }
  } 
}


================================================
FILE: get-env.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: get-env.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-04-30 15:27:12>
//-------------------------------------------------------------------
// http://www.mytechtoday.com/2009/01/read-environment-variables-with-groovy.html
def env = System.getenv()
// Print all the environment variables.

env.each{
println it
} 
// You can also access the specific variable, say 'username', as show below 
String user= env['USERNAME']

// https://stackoverflow.com/questions/31707667/how-to-access-jenkins-environment-variables-with-dsl

def envVars = Jenkins.instance.getGlobalNodeProperties()[0].getEnvVars()
println envVars['myVar']

/*
import hudson.model.*;
import jenkins.model.*;

Thread.start {
      sleep 10000
      println "--> setting agent port for jnlp"
      def env = System.getenv()
      int port = env['JENKINS_SLAVE_AGENT_PORT'].toInteger()
      Jenkins.instance.setSlaveAgentPort(port)
      println "--> setting agent port for jnlp... done"
}
*/


================================================
FILE: get-ip-by-hostname.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: get-ip-by-hostname.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// https://asoftwareguy.com/2014/04/17/get-the-ip-address-for-a-host-name-in-groovy/
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-04-29 15:42:37>
//-------------------------------------------------------------------
def hostname = 'google.com'
println InetAddress.getByName(hostname).address.collect { it & 0xFF }.join('.')


================================================
FILE: git-checkout.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: git-checkout.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-05-01 16:52:31>
//-------------------------------------------------------------------
// https://gist.github.com/lferro9000/471ae1a98267e20530d989f64f5290ee
#!/usr/bin/env groovy

node('php') {

    stage('Get code from SCM') {
        checkout(
                [$class: 'GitSCM', branches: [[name: '*/#your-dev-branch#']],
                 doGenerateSubmoduleConfigurations: false,
                 extensions: [],
                 submoduleCfg: [],
                 userRemoteConfigs: [[url: '#your-git-link#']]]
        )
    }

    stage('Composer Install') {
        sh 'composer install'
    }

    stage("PHPLint") {
        sh 'find app -name "*.php" -print0 | xargs -0 -n1 php -l'
    }
}


================================================
FILE: git-commits-before-fail.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: git-commits-before-fail.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-05-01 16:52:35>
//-------------------------------------------------------------------
// https://gist.github.com/ftclausen/8c46195ee56e48e4d01cbfab19c41fc0
// -*- mode: groovy -*-
// vim: set filetype=groovy :
node( 'some_node' ) {
  stage( "Phase 1" ) {
    sshagent( credentials: [ 'some_creds' ] ) {
      checkout scm
      def lastSuccessfulCommit = getLastSuccessfulCommit()
      def currentCommit = commitHashForBuild( currentBuild.rawBuild )
      if (lastSuccessfulCommit) {
        commits = sh(
          script: "git rev-list $currentCommit \"^$lastSuccessfulCommit\"",
          returnStdout: true
        ).split('\n')
        println "Commits are: $commits"
      }
    }
  }
}

def getLastSuccessfulCommit() {
  def lastSuccessfulHash = null
  def lastSuccessfulBuild = currentBuild.rawBuild.getPreviousSuccessfulBuild()
  if ( lastSuccessfulBuild ) {
    lastSuccessfulHash = commitHashForBuild( lastSuccessfulBuild )
  }
  return lastSuccessfulHash
}

/**
 * Gets the commit hash from a Jenkins build object, if any
 */
@NonCPS
def commitHashForBuild( build ) {
  def scmAction = build?.actions.find { action -> action instanceof jenkins.scm.api.SCMRevisionAction }
  return scmAction?.revision?.hash
}


================================================
FILE: git-list-tags-and-branches.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: git-list-tags-and-branches.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-05-01 16:47:01>
//-------------------------------------------------------------------
// https://gist.github.com/eeichinger/9761870
def gettags = ("git ls-remote -t -h ssh://jenkins@<mygitpath>/repo/some.git feature/*").execute()

return gettags.text.readLines()
         .collect { it.split()[1].replaceAll('refs/heads/', '')  }
         .unique()
         .findAll { it.startsWith('<some more pattern>') }


================================================
FILE: jenkins-kubernetes-cloud.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: jenkins-kubernetes-cloud.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-05-01 16:52:44>
//-------------------------------------------------------------------
// https://stackoverflow.com/questions/38273070/groovy-script-to-apply-kubernetes-cloud-config-in-jenkins
import org.csanchez.jenkins.plugins.kubernetes.*
import jenkins.model.*

def j = Jenkins.getInstance()

def k = new KubernetesCloud(
  'kubernetes',
  null,
  'https://192.168.150.100:8443',
  '',
  'http://40.0.4.3:8080',
  '10', 0, 0, 5
)
k.setSkipTlsVerify(true)

j.clouds.replace(k)
j.save()


================================================
FILE: jenkins-permission.groovy
================================================
import jenkins.model.Jenkins;
import hudson.security.GlobalMatrixAuthorizationStrategy;

if (hudson.model.User.getAll().size()==1 && hudson.model.User.getAll()[0].toString().equals('admin')) {
  List admins = [
    'admin1',
    'admin2'
  ]

  def strategy = new hudson.security.GlobalMatrixAuthorizationStrategy()
  admins.each {
    strategy.add(hudson.model.Hudson.ADMINISTER, it)
  }

  // Add read permission for all users
  strategy.add(hudson.model.Item.READ,'anonymous')
  strategy.add(hudson.model.Item.DISCOVER,'anonymous')
  strategy.add(hudson.model.Hudson.READ,'anonymous')
  strategy.add(hudson.model.Item.READ,'authenticated')
  strategy.add(hudson.model.Item.DISCOVER,'authenticated')
  strategy.add(hudson.model.Hudson.READ,'authenticated')
  Jenkins.instance.setAuthorizationStrategy(strategy)
}


================================================
FILE: jenkins-url.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: jenkins-url.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-05-09 11:43:15>
//-------------------------------------------------------------------
// https://gist.github.com/fishi0x01/7c2d29afbaa0f16126eb4d4b35942f76
/*
 * This script configures the Jenkins base URL.
 */

import jenkins.model.JenkinsLocationConfiguration

JenkinsLocationConfiguration location = Jenkins.instance.getExtensionList('jenkins.model.JenkinsLocationConfiguration')[0]
location.url = 'https://jenkins-as-code-poc.devtail.io/'
location.save()

// Solution 2
// https://github.com/docksal/service-jenkins/blob/master/groovy/default-config.groovy
import jenkins.model.*
import hudson.security.*

// Get environment variables.
def env = System.getenv()

// Change location configuration for admin address and Jenkins URL.
// Currently this will override settings changed via Jenkins UI.
def jenkinsLocationConfiguration = JenkinsLocationConfiguration.get()
jenkinsLocationConfiguration.setAdminAddress(env.JENKINS_EMAIL)
jenkinsLocationConfiguration.setUrl(env.JENKINS_URL)
jenkinsLocationConfiguration.save()


================================================
FILE: jenkins-views.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: jenkins-views.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-02-16 22:03:51>
//-------------------------------------------------------------------
// imports
import jenkins.model.Jenkins
import hudson.model.ListView
import hudson.model.View

// get Jenkins instance
Jenkins jenkins = Jenkins.getInstance()

def viewName = ''

viewName = 'CIAutoMaintain'
jenkins.addView(new ListView(viewName))
myView = hudson.model.Hudson.instance.getView(viewName)
for(item in ['CleanOldArtifact', 'CreateTestEnv']) {
    myView.doAddJobToView(item)
}

// save current Jenkins state to disk
jenkins.save()

// Set default view
View welcome_view = jenkins.getView('CIAutoMaintain')
View primary_view = jenkins.getPrimaryView()
jenkins.setPrimaryView(welcome_view)


================================================
FILE: jenkins.security.QueueItemAuthenticatorConfiguration.xml
================================================
<?xml version='1.1' encoding='UTF-8'?>
<jenkins.security.QueueItemAuthenticatorConfiguration>
  <authenticators>
    <org.jenkinsci.plugins.authorizeproject.GlobalQueueItemAuthenticator plugin="authorize-project@1.3.0">
      <strategy class="org.jenkinsci.plugins.authorizeproject.strategy.TriggeringUsersAuthorizationStrategy"/>
    </org.jenkinsci.plugins.authorizeproject.GlobalQueueItemAuthenticator>
  </authenticators>
</jenkins.security.QueueItemAuthenticatorConfiguration>


================================================
FILE: jenkinsfile-finally.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: jenkinsfile-finally.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-04-29 15:42:43>
//-------------------------------------------------------------------
node {
  try {
    def seconds = readFile("/tmp/test.txt")

      echo "seconds begin"
      echo seconds
      echo "seconds done"
      parallel firstBranch: {
      // do something
      build job: 'SleepAnHour', parameters: [string(name: 'sleep_seconds', value: seconds)]
    }, secondBranch: {
      // do something else
      build job: 'SleepTwoHours', parameters: [string(name: 'sleep_seconds', value: seconds)]
        },
         failFast: true
      }
  finally {
    echo "finally"
      }
}


================================================
FILE: jenkinsfile-parallelly.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: jenkinsfile-parallelly.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-04-29 15:42:45>
//-------------------------------------------------------------------
stage('stage1') {
    echo 'Hello World'
}

stage('stage2') {
    parallel firstBranch: {
        // do something
         build 'dennyjob1'
    }, secondBranch: {
        // do something else
        build job: 'dennyjob2', parameters: [string(name: 'env1', value: 'value3')]
    },
    failFast: true
}

stage('stage3') {
   build 'dennyjob3'
}


================================================
FILE: jenkinsfile-pass-parameter.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: jenkinsfile-pass-parameter.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-04-29 15:42:48>
//-------------------------------------------------------------------
node {
  def seconds = readFile("/tmp/test.txt")

    echo "seconds begin"
    echo seconds
    echo "seconds done"
    parallel firstBranch: {
    // do something
    build job: 'SleepAnHour', parameters: [string(name: 'sleep_seconds', value: seconds)]
  }, secondBranch: {
    // do something else
    build job: 'SleepTwoHours', parameters: [string(name: 'sleep_seconds', value: seconds)]
      },
       failFast: true
    }


================================================
FILE: jenkinsfile-sequentially.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: jenkinsfile-sequentially.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-04-29 15:42:50>
//-------------------------------------------------------------------
stage('stage1') {
    echo 'Hello World'
}


stage('stage2') {
   build 'dennyjob1'
}

stage('stage3') {
   build job: 'dennyjob2', parameters: [string(name: 'env1', value: 'value3')]
}


================================================
FILE: jenkinsfile-timeout-retry.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: jenkinsfile-timeout-retry.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-04-29 15:44:04>
//-------------------------------------------------------------------
// https://jenkins.io/doc/pipeline/tour/running-multiple-steps/
Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any
    stages {
        stage('Deploy') {
            steps {
                retry(3) {
                    sh './flakey-deploy.sh'
                }

                timeout(time: 3, unit: 'MINUTES') {
                    sh './health-check.sh'
                }
            }
        }
    }
}


================================================
FILE: json-file.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: json-file.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-05-01 16:52:56>
//-------------------------------------------------------------------
// https://gist.github.com/keyle/723181f3a9a59a3f7652

package utils

import groovy.json.JsonBuilder
import groovy.json.JsonSlurper

class HDD {

    static save(Object content, String filePath) {
        new File(filePath).write(new JsonBuilder(content).toPrettyString())
    }

    static Object load(String filePath) {
        return new JsonSlurper().parseText(new File(filePath).text)
    }
}


================================================
FILE: keep-going-with-errors.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: keep_going_with_errors.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Description :
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-04-29 15:44:11>
//-------------------------------------------------------------------
// https://stackoverflow.com/questions/36852310/show-a-jenkins-pipeline-stage-as-failed-without-failing-the-whole-job
// Stages with shell commands
def tc_list = testsuites.tokenize(',')
  tc_list.each {
  try {
    stage("${it}") {
      println "============ Test ${it}"
      sh "mvn com.smartbear.soapui:soapui-maven-plugin:5.1.2:test -Dmdm.test.suite=\"${it}\""
    }
  } catch (e) {
    result = "FAIL"
  }
}

////////////////////////////////////////////////////////////////////////////////
// Stages with jenkins jobs
try {
  stage('end-to-end-tests') {
    node {
      def e2e = build job:'end-to-end-tests', propagate: false
        result = e2e.result
        if (result.equals("SUCCESS")) {
        } else {
          sh "exit 1" // this fails the stage
        }
    }
  }
 } catch (e) {
  result = "FAIL" // make sure other exceptions are recorded as failure too
    }

stage('deploy') {
  if (result.equals("SUCCESS")) {
    build 'deploy'
    } else {
       echo "Cannot deploy without successful build" // it is important to have a deploy stage even here for the current visualization
    }
}


================================================
FILE: kill-queued-jenkins.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: kill-queued-jenkins.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-05-07 09:53:48>
//-------------------------------------------------------------------
// https://gist.github.com/realityforge/c57eb3d1854320d14252ac881fc6cedf
import hudson.model.*

def q = Jenkins.instance.queue

q.items.each {
  if (it =~ /deploy-to/) {
    q.cancel(it.task)
  }
}



================================================
FILE: list-all-jenkins-agent.sh
================================================
#!/usr/bin/env bash
##  @copyright 2019 DennyZhang.com
## Licensed under MIT 
##   https://www.dennyzhang.com/wp-content/mit_license.txt
##
## File: list-all-jenkins-agent.sh
## Author : Denny <https://www.dennyzhang.com/contact>
## Description : List all trouble shooting traces for each Jenkins agent
## --
## Created : <2019-08-30>
## Updated: Time-stamp: <2019-08-30 14:41:22>
##-------------------------------------------------------------------
#!/usr/bin/env bash
# set -o errexit
set -o pipefail
set -o nounset

jenkins_url=${1?}
jenkins_credential=${2?}
vm_user=${3?}
vm_pass=${4?}
for agent_name in $(curl "$jenkins_url/computer/api/json" | jq -r .computer[].displayName | grep -v master); do
    ip=$(curl -u "$jenkins_credential" -d "script=println InetAddress.localHost.hostAddress" \
              "$jenkins_url/computer/$agent_name/scriptText" 2>/dev/null | sed -e 's/^[ \t]*//' | sed -e '/^$/d')
    echo "agent_name: $agent_name, ip: $ip"
    for command in "cat /proc/loadavg" "docker version | grep '^ Version:'" "df -h /var/lib"; do
        sshpass -p "$vm_pass" ssh -o LogLevel=error -o StrictHostKeyChecking=no "$vm_user@$ip" "$command"
    done
done



================================================
FILE: list-all-jobs.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: list-all-jobs.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-05-07 14:14:04>
//-------------------------------------------------------------------
// http://paweloczadly.github.io/dev/2014/07/03/jenkins-groovy-script-list-all-jobs
import hudson.model.*

hudson.model.Hudson.instance.items.findAll{job -> job}.each {
    job -> println("Job: " + job.name)
}


================================================
FILE: logged-in-users.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: logged-in-users.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-05-01 16:53:03>
//-------------------------------------------------------------------
// https://gist.github.com/hayderimran7/50cb1244cc1e856873a4
import jenkins.model.*
import hudson.security.*

def instance = Jenkins.getInstance()

// logged-in users can do anything
def strategy = new hudson.security.FullControlOnceLoggedInAuthorizationStrategy()
strategy.setAllowAnonymousRead(false)
instance.setAuthorizationStrategy(strategy)

instance.save()


================================================
FILE: loop-map.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: loop-map.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-04-29 15:42:59>
//-------------------------------------------------------------------
def sampleMap = ['Key#1':'Value#1', 'Key#2':'Value#2']
println sampleMap['Key#1']
node{
    // itertate over stages
    for (key in sampleMap.keySet()){
        val = "${sampleMap[key]}"
        println key
        println val
        stage('Run Key'){
            println "Ran ${key}"
        }

        stage('Ran Value for that Key'){
            println "Ran ${val}"
        }

        stage('Clean Up'){
            println "Ran Some sort of Cleanup"
        }
    }
}


================================================
FILE: manage-jenkins-jobs.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: manage-jenkins-jobs.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-05-01 16:53:08>
//-------------------------------------------------------------------
// https://github.com/peterjenkins1/jenkins-scripts/blob/master/add-job.groovy
// Adds a pipeline job to jenkins
import jenkins.model.Jenkins
import org.jenkinsci.plugins.workflow.job.WorkflowJob
import org.jenkinsci.plugins.workflow.cps.CpsScmFlowDefinition
import org.jenkinsci.plugins.workflow.flow.FlowDefinition
import hudson.plugins.git.GitSCM
import hudson.plugins.git.UserRemoteConfig
import com.cloudbees.hudson.plugins.folder.*

// Bring some values in from ansible using the jenkins_script modules wierd "args" approach (these are not gstrings)
String folderName = "$folderName"
String jobName = "$jobName"
String jobScript = "$jobScript"
String gitRepo = "$gitRepo"
String gitRepoName = "$gitRepoName"
String credentialsId = "$credentialsId"

Jenkins jenkins = Jenkins.instance // saves some typing

// Get the folder where this job should be
def folder = jenkins.getItem(folderName)
// Create the folder if it doesn't exist
if (folder == null) {
  folder = jenkins.createProject(Folder.class, folderName)
}

// Create the git configuration
UserRemoteConfig userRemoteConfig = new UserRemoteConfig(gitRepo, gitRepoName, null, credentialsId)

branches = null
doGenerateSubmoduleConfigurations = false
submoduleCfg = null
browser = null
gitTool = null
extensions = []
GitSCM scm = new GitSCM([userRemoteConfig], branches, doGenerateSubmoduleConfigurations, submoduleCfg, browser, gitTool, extensions)

// Create the workflow
FlowDefinition flowDefinition = (FlowDefinition) new CpsScmFlowDefinition(scm, jobScript)

// Check if the job already exists
Object job = null
job = folder.getItem(jobName)
if (job == null) {
  oldJob = jenkins.getItem(jobName)
  if (oldJob.getClass() == WorkflowJob.class) {
    // Move any existing job into the folder
    Items.move(oldJob, folder)
  } else {
    // Create it if it doesn't
    job = folder.createProject(WorkflowJob, jobName)
  }
}
// Add the workflow to the job
job.setDefinition(flowDefinition)

// Set the branch somehow
job.save()


================================================
FILE: master-executors.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: master-executors.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-05-01 16:53:12>
//-------------------------------------------------------------------

import hudson.model.*;
import jenkins.model.*;

Jenkins.instance.setNumExecutors(6)


================================================
FILE: matrix-authorization-strategy.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: matrix-authorization-strategy.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-05-01 16:53:20>
//-------------------------------------------------------------------
// http://www.tothenew.com/blog/jenkins-implementing-project-based-matrix-authorization-strategy/
/*
   Configure matrix authorization strategy with permissions for users and
   groups.  This script is idempotent and will only change configuration if
   necessary.

   Example configuration:
       authz_strategy_config = [
           strategy: 'GlobalMatrixAuthorizationStrategy',
           user_permissions: [
               anonymous: ['Job Discover'],
               authenticated: ['Overall Read', 'Job Read', 'View Read'],
               admin: ['Overall Administer']
           ]
       ]

   Available Authorization Strategies:
       GlobalMatrixAuthorizationStrategy
       ProjectMatrixAuthorizationStrategy

   Available user permissions:
       Overall Administer
       Overall Read
       Agent Configure
       Agent Delete
       Agent Create
       Agent Disconnect
       Agent Connect
       Agent Build
       Agent Provision
       Run Delete
       Run Update
       Job Create
       Job Delete
       Job Configure
       Job Read
       Job Discover
       Job Build
       Job Workspace
       Job Cancel
       SCM Tag
       Credentials Create
       Credentials Update
       Credentials View
       Credentials Delete
       Credentials ManageDomains
       Job Move
       View Create
       View Delete
       View Configure
       View Read
       Run Replay

   "Job ViewStatus" permission becomes available after installing the
   embeddable build status plugin.
 */
import jenkins.model.*

import hudson.security.GlobalMatrixAuthorizationStrategy
import hudson.security.Permission
import hudson.security.ProjectMatrixAuthorizationStrategy
import jenkins.model.Jenkins

class Helper implements Serializable {
   static String shortName(Permission p) {
      p.id.tokenize('.')[-2..-1].join(' ')
	 .replace('Hudson','Overall')
	 .replace('Computer', 'Agent')
	 .replace('Item', 'Job')
	 .replace('CredentialsProvider', 'Credentials')
   }

   static Map getCurrentPermissions(Map config = [:]) {
      Map currentPermissions = [:].withDefault { [].toSet() }
      if(!('getGrantedPermissions' in Jenkins.instance.authorizationStrategy.metaClass.methods*.name.sort().unique())) {
	 return currentPermissions
      }
      Closure merger = { Map nmap, Map m ->
	 m.each { k, v ->
	    nmap[k] += v
	 }
      }
      Jenkins.instance.authorizationStrategy.grantedPermissions.collect { permission, userList ->
	 userList.collect { user ->
	    [ (user): shortName(permission) ]
	 }
      }.flatten().each merger.curry(currentPermissions)
      currentPermissions
   }

   static boolean isConfigurationEqual(Map config) {
      Map currentPermissions = getCurrentPermissions(config)
      Jenkins.instance.authorizationStrategy.class.name.endsWith(config['strategy']) &&
      !(false in config['user_permissions'].collect { k, v -> currentPermissions[k] == v.toSet() }) &&
      currentPermissions.keySet() == config['user_permissions'].keySet()
   }

   static boolean isValidConfig(def config, List<String> validPermissions) {
      Map currentPermissions = getCurrentPermissions()
      config instanceof Map &&
      config.keySet().containsAll(['strategy', 'user_permissions']) &&
      config['strategy'] &&
      config['strategy'] instanceof String &&
      config['strategy'] in ['GlobalMatrixAuthorizationStrategy', 'ProjectMatrixAuthorizationStrategy'] &&
      config['user_permissions'] &&
      !(false in config['user_permissions'].collect { k, v ->
	 k instanceof String &&
	 (v instanceof List || v instanceof Set) &&
	 !(false in v.collect {
	    validPermissions.contains(it)
	 })
      })
   }
}

Map<String, Permission> permissionIds = Permission.all.findAll { permission ->
   List<String> nonConfigurablePerms = ['RunScripts', 'UploadPlugins', 'ConfigureUpdateCenter']
   permission.enabled &&
      !permission.id.startsWith('hudson.security.Permission') &&
      !(true in nonConfigurablePerms.collect { permission.id.endsWith(it) })
}.collect { permission ->
   [ (Helper.shortName(permission)): permission ]
}.sum()

/**
 * MAIN EXECUTION
 */

if(!binding.hasVariable('authz_strategy_config')) {
   authz_strategy_config = [
      strategy: 'GlobalMatrixAuthorizationStrategy',
      user_permissions: [
	 'authenticated': ['Overall Read'],
	 'zdenny': ['Overall Administer']
      ]
   ]
}

if(!Helper.isValidConfig(authz_strategy_config, permissionIds.keySet().toList())) {
   println([
      'Skip configuring matrix authorization strategy because no valid config was provided.',
      'Available Authorization Strategies:\n    GlobalMatrixAuthorizationStrategy\n    ProjectMatrixAuthorizationStrategy',
      "Available Permissions:\n    ${permissionIds.keySet().join('\n    ')}"
   ].join('\n'))
   return
}

if(Helper.isConfigurationEqual(authz_strategy_config)) {
   println "Nothing changed.  ${authz_strategy_config['strategy']} authorization strategy already configured."
   return
}

println "Configuring authorization strategy ${authz_strategy_config['strategy']}"

def authz_strategy = Class.forName("hudson.security.${authz_strategy_config['strategy']}").newInstance()

// build the permissions in the strategy
authz_strategy_config['user_permissions'].each { user, permissions ->
   permissions.each { p ->
      authz_strategy.add(permissionIds[p], user)
      println "    For user ${user} grant permission ${p}."
   }
}

// configure global authorization
Jenkins.instance.authorizationStrategy = authz_strategy

// save settings to persist across restarts
Jenkins.instance.save()


================================================
FILE: multi-line-string.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: multi-line-string.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-04-29 15:43:06>
//-------------------------------------------------------------------
// http://grails.asia/groovy-multiline-string
def a = """test
test
test"""


================================================
FILE: print.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: print.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-04-29 15:43:08>
//-------------------------------------------------------------------
String message = 'Hello from Groovy'
println message


================================================
FILE: regexp-match.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: regexp-match.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-05-01 16:53:27>
//-------------------------------------------------------------------
// https://gist.github.com/EwanDawson/2407215
matcher = "Hello world v1.01" =~ /.* v(\S*)/
if (matcher.matches()) version = matcher[0][1]
assert version == "1.01"

// We can make this a little tidier using the 'with' method
version = ("Hello world v1.01" =~ /.* v(\S*)/).with { matches() ? it[0][1] : null }
assert version == "1.01"


================================================
FILE: relative-path.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: relative-path.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-05-01 13:55:52>
//-------------------------------------------------------------------
// https://gist.github.com/ysb33r/5804364
def root= new File('/usr/share')
def full= new File('/usr/share/docs/rpm-4.4')

// Print the relative path of 'full' in relation to 'root'
// Notice that the full path is passed as a parameter to the root.
def relPath= new File( root.toURI().relativize( full.toURI() ).toString() )


================================================
FILE: set-agent-env.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: set-agent-env.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-05-07 14:07:50>
//-------------------------------------------------------------------
// http://paweloczadly.github.io/dev/2014/07/03/jenkins-groovy-script-set-up-java_home-on-each-agent
import hudson.slaves.*

def javaHome = new EnvironmentVariablesNodeProperty(
    new EnvironmentVariablesNodeProperty.Entry('JAVA_HOME', '/usr/lib/jvm/java-7-oracle-amd64'))

hudson.model.Hudson.instance.slaves.each { it.nodeProperties.add(javaHome) }    


================================================
FILE: slack-notification.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: slack_notification.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Description :
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-04-29 15:44:34>
//-------------------------------------------------------------------
// https://stackoverflow.com/questions/39140191/how-to-send-slack-notification-after-jenkins-pipeline-build-failed
// https://jenkins.io/doc/pipeline/steps/slack/
// https://jenkins.io/blog/2016/07/18/pipeline-notifications/
node(agent_label) {
   
   //println testsuites
   stage('Preparation') {
      git (branch: 'master',
           credentialsId: 'github_key',
           url: 'git@github.com:DennyZhang/fake.git')
      if (run_deployment_before_test == "true") {
          build job:'DeploySandboxEnv', 
              parameters:[string(name:'initialize_system', value:initialize_system),
                          string(name:'whether_populatefakedata', value:whether_populatefakedata),
                          string(name:'whether_populaterealdata', value:whether_populaterealdata)]
      }
   }
   
   
  def tc_list = testsuites.tokenize(',')
     tc_list.each {
        try {
            stage("${it}") {
               println "============ Test ${it}"
               sh "mvn com.smartbear.soapui:soapui-maven-plugin:5.1.2:test -Dmdm.test.suite=\"${it}\""
            }
        } catch (e) {
            result = "FAIL"
        }
   }

  stage('CollectResult') {
      if (result == "FAIL") {
         buildStatus = result
         def subject = "${buildStatus}: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'"
         def summary = "${subject} (${env.BUILD_URL})"
         color = 'RED'
         colorCode = '#FF0000'
         slackSend (color: colorCode, message: summary)
         error("Job has failed")
      }
  }
}


================================================
FILE: split-string.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: split-string.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-04-29 15:43:13>
//-------------------------------------------------------------------
String ip_hostname_list = """ 138.197.192.172  myenv-do-jenkins
   138.68.254.56  myenv-do-lb-1
  138.68.254.215  myenv-do-lb-2
   165.227.8.194  myenv-do-cb-01
  138.197.215.93  myenv-do-cb-02   """;

def l = ip_hostname_list.split("\n")
print l.join("a")


================================================
FILE: string-to-json.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: string-to-json.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-04-29 15:43:15>
//-------------------------------------------------------------------
import groovy.json.JsonSlurper
def jsonSlurper = new JsonSlurper()
def object = jsonSlurper.parseText('{ "name": "John Doe" } /* some comment */')
assert object instanceof Map
assert object.name == 'John Doe'
print object.name


================================================
FILE: timezone.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: timezone.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-02-16 22:04:03>
//-------------------------------------------------------------------
// Configure Jenkins java options
// timezone: Asia/Shanghai, America/New_York, America/Los_Angeles
// https://www.epochconverter.com/timezones
// ENV JENKINS_TIMEZONE "UTC"

def env = System.getenv();
System.setProperty('org.apache.commons.jelly.tags.fmt.timeZone', env['JENKINS_TIMEZONE']);


================================================
FILE: validate-kubernetes-cloud.groovy
================================================
#!groovy
//-------------------------------------------------------------------
// @copyright 2018 DennyZhang.com
// Licensed under MIT
// https://www.dennyzhang.com/wp-content/mit_license.txt
//
// File: jenkins-kubernetes-cloud.groovy
// Author : Denny <https://www.dennyzhang.com/contact>
// Link: https://cheatsheet.dennyzhang.com/cheatsheet-jenkins-groovy-a4
// --
// Created : <2018-04-20>
// Updated: Time-stamp: <2019-05-23 22:30:46>
//-------------------------------------------------------------------
// https://github.com/carlossg/jenkins-kubernetes-plugin/blob/master/src/main/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesCloud.java
import org.csanchez.jenkins.plugins.kubernetes.*
import jenkins.model.*
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClientException;
try {
    def j = Jenkins.getInstance()
        def client = j.clouds[0].connect()
        client.pods().list();
} catch (KubernetesClientException e) {
    println("Error testing connection %s" + e.getMessage())
} catch (Exception e) {
    println("Error testing connection %s" + e.getMessage())
}
Download .txt
gitextract_5hxdtnyj/

├── .gitignore
├── 00-csrf.groovy
├── 00-disable-cli-remoting.groovy
├── 00-slave-to-master-access.groovy
├── README.org
├── addjobstoview-byregexp.groovy
├── build-monitor-views.xml
├── check-slave-jar-version.groovy
├── config-pipeline-library.groovy
├── config-slack.groovy
├── create-jenkins-job.groovy
├── create-jenkins-user.groovy
├── create-secret-text.groovy
├── delete-job-by-regexp.groovy
├── dict-to-json.groovy
├── docker-cleanup.groovy
├── enable-ldap.groovy
├── execute-command.groovy
├── files-folder.groovy
├── find-dead-executors.groovy
├── get-env.groovy
├── get-ip-by-hostname.groovy
├── git-checkout.groovy
├── git-commits-before-fail.groovy
├── git-list-tags-and-branches.groovy
├── jenkins-kubernetes-cloud.groovy
├── jenkins-permission.groovy
├── jenkins-url.groovy
├── jenkins-views.groovy
├── jenkins.security.QueueItemAuthenticatorConfiguration.xml
├── jenkinsfile-finally.groovy
├── jenkinsfile-parallelly.groovy
├── jenkinsfile-pass-parameter.groovy
├── jenkinsfile-sequentially.groovy
├── jenkinsfile-timeout-retry.groovy
├── json-file.groovy
├── keep-going-with-errors.groovy
├── kill-queued-jenkins.groovy
├── list-all-jenkins-agent.sh
├── list-all-jobs.groovy
├── logged-in-users.groovy
├── loop-map.groovy
├── manage-jenkins-jobs.groovy
├── master-executors.groovy
├── matrix-authorization-strategy.groovy
├── multi-line-string.groovy
├── print.groovy
├── regexp-match.groovy
├── relative-path.groovy
├── set-agent-env.groovy
├── slack-notification.groovy
├── split-string.groovy
├── string-to-json.groovy
├── timezone.groovy
└── validate-kubernetes-cloud.groovy
Condensed preview — 55 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (159K chars).
[
  {
    "path": ".gitignore",
    "chars": 27,
    "preview": "*.tex\n.DS_Store\nREADME.pdf\n"
  },
  {
    "path": "00-csrf.groovy",
    "chars": 239,
    "preview": "// https://wiki.jenkins.io/display/JENKINS/CSRF+Protection\nimport hudson.security.csrf.DefaultCrumbIssuer\nimport jenkins"
  },
  {
    "path": "00-disable-cli-remoting.groovy",
    "chars": 240,
    "preview": "// https://stackoverflow.com/questions/44501596/jenkins-disable-cli-over-remoting-via-a-groovy-script\nimport jenkins.mod"
  },
  {
    "path": "00-slave-to-master-access.groovy",
    "chars": 246,
    "preview": "// https://wiki.jenkins.io/display/JENKINS/Slave+To+Master+Access+Control\nimport jenkins.security.s2m.AdminWhitelistRule"
  },
  {
    "path": "README.org",
    "chars": 91565,
    "preview": "* CheatSheet: Jenkins & Groovy                                    :Languages:\n:PROPERTIES:\n:type:     language\n:export_f"
  },
  {
    "path": "addjobstoview-byregexp.groovy",
    "chars": 1108,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "build-monitor-views.xml",
    "chars": 1535,
    "preview": "  <views>\n    <hudson.model.AllView>\n      <owner class=\"hudson\" reference=\"../../..\"/>\n      <name>all</name>\n      <fi"
  },
  {
    "path": "check-slave-jar-version.groovy",
    "chars": 1012,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "config-pipeline-library.groovy",
    "chars": 1627,
    "preview": "// https://github.com/thbkrkr/jks/blob/master/init.groovy.d/11-configure-pipeline-global-shared.groovy\n/*\n * Configure p"
  },
  {
    "path": "config-slack.groovy",
    "chars": 1091,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "create-jenkins-job.groovy",
    "chars": 815,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "create-jenkins-user.groovy",
    "chars": 831,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "create-secret-text.groovy",
    "chars": 1103,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "delete-job-by-regexp.groovy",
    "chars": 757,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "dict-to-json.groovy",
    "chars": 605,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "docker-cleanup.groovy",
    "chars": 962,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "enable-ldap.groovy",
    "chars": 3026,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "execute-command.groovy",
    "chars": 735,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "files-folder.groovy",
    "chars": 3152,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "find-dead-executors.groovy",
    "chars": 1132,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "get-env.groovy",
    "chars": 1308,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "get-ip-by-hostname.groovy",
    "chars": 698,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "git-checkout.groovy",
    "chars": 1111,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "git-commits-before-fail.groovy",
    "chars": 1646,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "git-list-tags-and-branches.groovy",
    "chars": 835,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "jenkins-kubernetes-cloud.groovy",
    "chars": 913,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "jenkins-permission.groovy",
    "chars": 815,
    "preview": "import jenkins.model.Jenkins;\nimport hudson.security.GlobalMatrixAuthorizationStrategy;\n\nif (hudson.model.User.getAll()."
  },
  {
    "path": "jenkins-url.groovy",
    "chars": 1435,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "jenkins-views.groovy",
    "chars": 1101,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "jenkins.security.QueueItemAuthenticatorConfiguration.xml",
    "chars": 482,
    "preview": "<?xml version='1.1' encoding='UTF-8'?>\n<jenkins.security.QueueItemAuthenticatorConfiguration>\n  <authenticators>\n    <or"
  },
  {
    "path": "jenkinsfile-finally.groovy",
    "chars": 1010,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "jenkinsfile-parallelly.groovy",
    "chars": 856,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "jenkinsfile-pass-parameter.groovy",
    "chars": 942,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "jenkinsfile-sequentially.groovy",
    "chars": 697,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "jenkinsfile-timeout-retry.groovy",
    "chars": 930,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "json-file.groovy",
    "chars": 894,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "keep-going-with-errors.groovy",
    "chars": 1637,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "kill-queued-jenkins.groovy",
    "chars": 705,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "list-all-jenkins-agent.sh",
    "chars": 1174,
    "preview": "#!/usr/bin/env bash\n##  @copyright 2019 DennyZhang.com\n## Licensed under MIT \n##   https://www.dennyzhang.com/wp-content"
  },
  {
    "path": "list-all-jobs.groovy",
    "chars": 710,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "logged-in-users.groovy",
    "chars": 866,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "loop-map.groovy",
    "chars": 969,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "manage-jenkins-jobs.groovy",
    "chars": 2498,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "master-executors.groovy",
    "chars": 588,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "matrix-authorization-strategy.groovy",
    "chars": 6075,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "multi-line-string.groovy",
    "chars": 579,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "print.groovy",
    "chars": 545,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "regexp-match.groovy",
    "chars": 832,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "relative-path.groovy",
    "chars": 824,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "set-agent-env.groovy",
    "chars": 857,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "slack-notification.groovy",
    "chars": 2059,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "split-string.groovy",
    "chars": 756,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "string-to-json.groovy",
    "chars": 728,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "timezone.groovy",
    "chars": 788,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  },
  {
    "path": "validate-kubernetes-cloud.groovy",
    "chars": 1143,
    "preview": "#!groovy\n//-------------------------------------------------------------------\n// @copyright 2018 DennyZhang.com\n// Lice"
  }
]

About this extraction

This page contains the full source code of the dennyzhang/cheatsheet-jenkins-groovy-A4 GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 55 files (148.3 KB), approximately 38.6k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!