| #!groovy | 
 |  | 
 | def main(String cacheHome = 'output/cache') { | 
 |     String gitUrl = "${env.GERRIT_SCHEME}://${env.GERRIT_HOST}:${env.GERRIT_PORT}/${env.GERRIT_PROJECT}" | 
 |     String gitRef = env.GERRIT_BRANCH ?: env.GERRIT_REFNAME | 
 |     String artInfraNamespace = 'binary-dev-local/infra' | 
 |     String artCacheFile = "${env.CI_NAME}.jjb.zip" | 
 |     String artCacheUrl = "${env.ARTIFACTORY_URL}/artifactory/${artInfraNamespace}/${artCacheFile}" | 
 |     String artCredential = env.ART_CREDENTIALS_ID | 
 |     String jenkinsCredential = env.JENKINS_CREDENTIALS_ID | 
 |     def response | 
 |  | 
 |     def jenkinsJobs | 
 |     def jjbJobs | 
 |     def jobsToRemove | 
 |  | 
 |     currentBuild.description = '' | 
 |  | 
 |     // Set current build description | 
 |     if (env.GERRIT_CHANGE_URL) { | 
 |         currentBuild.description = """ | 
 |         <p> | 
 |           Triggered by change: <a href="${env.GERRIT_CHANGE_URL}">${env.GERRIT_CHANGE_NUMBER},${env.GERRIT_PATCHSET_NUMBER}</a><br/> | 
 |           Project: <b>${env.GERRIT_PROJECT}</b><br/> | 
 |           Branch: <b>${env.GERRIT_BRANCH}</b><br/> | 
 |           Subject: <b>${env.GERRIT_CHANGE_SUBJECT}</b><br/> | 
 |         </p> | 
 |         """ | 
 |     } | 
 |  | 
 |     stage('SCM checkout') { | 
 |         if (env.MAINTAIN_MODE.toLowerCase() == 'false') { | 
 |             checkout([ | 
 |                 $class: 'GitSCM', | 
 |                 branches: [[ | 
 |                     name: 'FETCH_HEAD' | 
 |                 ]], | 
 |                 userRemoteConfigs: [[ | 
 |                     url: gitUrl, | 
 |                     refspec: gitRef, | 
 |                     credentialsId: env.GIT_CREDENTIALS_ID | 
 |                 ]], | 
 |                 extensions: [[ | 
 |                     $class: 'WipeWorkspace' | 
 |                 ]], | 
 |             ]) | 
 |         } | 
 |     } | 
 |  | 
 |     /*stage('Get JJB cache') { | 
 |         dir(cacheHome) { | 
 |             response = httpRequest \ | 
 |                 url: artCacheUrl, | 
 |                 authentication: artCredential, | 
 |                 httpMode: 'GET', | 
 |                 outputFile: artCacheFile, | 
 |                 validResponseCodes: '100:399,404' | 
 |             if (response.status != 404) { | 
 |                unzip \ | 
 |                    zipFile: artCacheFile, | 
 |                    dir: '.cache' | 
 |             } | 
 |         } | 
 |     }*/ | 
 |  | 
 |     stage('Update JJB jobs') { | 
 |         if (env.MAINTAIN_MODE.toLowerCase() == 'false') { | 
 |             withCredentials([ | 
 |                 usernamePassword( | 
 |                     credentialsId: env.JENKINS_CREDENTIALS_ID, | 
 |                     usernameVariable: 'JJB_USER', | 
 |                     passwordVariable: 'JJB_PASSWORD') | 
 |                 ]) { | 
 |                     withEnv([ | 
 |                         "HOME=${cacheHome}" | 
 |                     ]) { | 
 |                         sh 'tox -v -e update $JOBS_LIST' | 
 |                 } | 
 |             } | 
 |         } else { | 
 |             input \ | 
 |                 message: 'Sleeping for maintainance' | 
 |         } | 
 |     } | 
 |  | 
 |     stage('Get deployed jobs list') { | 
 |         response = httpRequest \ | 
 |             url: "${JENKINS_URL}/crumbIssuer/api/json", | 
 |             authentication: jenkinsCredential | 
 |         def crumb = readJSON text: response.getContent() | 
 |  | 
 |         response = httpRequest \ | 
 |             url: "${JENKINS_URL}/api/json?tree=jobs[name,description]", | 
 |             authentication: jenkinsCredential, | 
 |             customHeaders: [[ | 
 |                 name: crumb.crumbRequestField, | 
 |                 value: crumb.crumb, | 
 |                 maskValue: true | 
 |             ]] | 
 |         def jobs = readJSON text: response.getContent() | 
 |  | 
 |         jenkinsJobs = jobs.jobs.findAll { | 
 |                 // Filter jenkins jobs deployed by JJB | 
 |                 it.description.toString().contains('Managed by Jenkins Job Builder') | 
 |             }.collect{ it.name } | 
 |     } | 
 |  | 
 |     stage('Get JJB jobs list') { | 
 |         withEnv([ | 
 |             "HOME=${cacheHome}" | 
 |         ]) { | 
 |             sh 'tox -v -e jobs' | 
 |         } | 
 |         dir("output/${env.CI_NAME}") { | 
 |             jjbJobs = sh( | 
 |                 script: "grep -rl actions | sed 's|/config.xml\$||g'", | 
 |                 returnStdout: true | 
 |             ).trim().readLines() | 
 |         } | 
 |  | 
 |         if (jjbJobs.size() == 0) { | 
 |             error 'ERROR: Unexpected JJB output. No generated jobs found' | 
 |         } | 
 |     } | 
 |  | 
 |     stage('Remove undefined jobs') { | 
 |         jobsToRemove = jenkinsJobs.findAll { ! jjbJobs.contains(it) } | 
 |  | 
 |         if (jobsToRemove.size() > 0) { | 
 |             withCredentials([ | 
 |                 usernamePassword( | 
 |                     credentialsId: jenkinsCredential, | 
 |                     usernameVariable: 'JJB_USER', | 
 |                     passwordVariable: 'JJB_PASSWORD') | 
 |             ]) { | 
 |                 withEnv([ | 
 |                     "HOME=${cacheHome}" | 
 |                 ]) { | 
 |                     sh "tox -v -e delete ${jobsToRemove.join(' ')}" | 
 |                 } | 
 |             } | 
 |  | 
 |             String description = '<b>DELETED</b><ul>' | 
 |             jobsToRemove.each { description += "<li>${it}</li>" } | 
 |             description += '</ul>' | 
 |             currentBuild.description += description | 
 |         } else { | 
 |             currentBuild.description += 'No jobs to remove' | 
 |         } | 
 |     } | 
 |  | 
 |     /*stage('Save JJB cache') { | 
 |         dir(cacheHome) { | 
 |             sh "rm -f ${artCacheFile}" | 
 |             zip \ | 
 |                 zipFile: artCacheFile, | 
 |                 dir: '.cache', | 
 |                 glob: 'jenkins_jobs/**' | 
 |             response = httpRequest \ | 
 |                 url: artCacheUrl, | 
 |                 authentication: artCredential, | 
 |                 httpMode: 'PUT', | 
 |                 multipartName: 'file', | 
 |                 uploadFile: artCacheFile | 
 |         } | 
 |     }*/ | 
 | } | 
 |  | 
 | String podTpl = """ | 
 |     apiVersion: "v1" | 
 |     kind: "Pod" | 
 |     spec: | 
 |       securityContext: | 
 |           runAsUser: 1000 | 
 |       containers: | 
 |       - name: "tox" | 
 |         image: "${env.DOCKER_IMAGE}" | 
 |         command: | 
 |         - "cat" | 
 |         securityContext: | 
 |           privileged: false | 
 |         tty: true | 
 | """ | 
 |  | 
 | if (env.K8S_CLUSTER == 'unset') { | 
 |     node(env.SLAVE_LABEL ?: 'docker') { | 
 |         main(env.WORKSPACE) | 
 |     } | 
 | } else { | 
 |     podTemplate( | 
 |             cloud: env.K8S_CLUSTER, | 
 |             yaml: podTpl, | 
 |             showRawYaml: false | 
 |     ) { | 
 |         node(POD_LABEL) { | 
 |             container('tox') { | 
 |                 main() | 
 |             } | 
 |         } | 
 |     } | 
 | } | 
 |  |