#!groovy /** * Deploy components to the D4Science Infrastructure (dev-only) * * Roberto Cirillo (ISTI-CNR) */ // related jenkins job: https://jenkins.d4science.org/job/gCubeDeployer/ def agent_root_folder = '/var/lib/jenkins' def agent_deploy_filename = 'deploy.csv' def agent_deploy_backup_filename = 'deploy.bck' def deployList def backupList if (params.deployFile) { println "Using custom deploy file" deployList = params.deployFile } else { println "Using local deploy file" //load the report from local deployList = agent_root_folder+'/'+agent_deploy_filename; println "Load from local file ${deployList}" } backupList = agent_root_folder+'/'+agent_deploy_backup_filename; pipeline { agent { label 'CD' } triggers { // every fifteen minutes (perhaps at :07, :22, :37, :52) cron('H/15 * * * *') // once a day on the 1st and 15th of every month // cron ('H H 1,15 * *') // once every two hours at 45 minutes past the hour starting at 9:45 AM and finishing at 3:45 PM every weekday. // cron('45 9-20/2 * * 1-5') } //once in every two hours slot between 9 AM and 5 PM every weekday (perhaps at 10:38 AM, 12:38 PM, 2:38 PM, 4:38 PM) // cron('H H(9-16)/2 * * 1-5') environment { AGENT_ROOT_FOLDER = "${agent_root_folder}" DEPLOY_FILE = "${agent_root_folder}/${agent_deploy_filename}" BACKUP_FILE = "${agent_root_folder}/${agent_deploy_backup_filename}" TRIGGER_JOB= "${params.TRIGGER_JOB}" TRIGGER_VERSION= "${params.TRIGGER_VERSION}" // maybe here define another param used to identify the target host. In this way the developer can change it from the job } stages { stage('initialize environment') { steps { sh ''' date=`date`; ''' } } stage('Deploy from system') { when{ allOf{ triggeredBy 'TimerTrigger' // maybe we can add a new condition in order to consider the manual execution of this pipeline environment name: 'IS_CRON', value: 'True' } } steps { echo 'Cron build enabled. Deploy from system ongoing' script { // parse the report and extract the data def components = parseCSVList(deployList) if (components.size() > 0) { for (component in components) { stage(component){ println "Deploy on going of component: $component" catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') { sh "exit 0" } } }else{ println "No components found" } } sh ''' echo "cleanup $DEPLOY_FILE"; if [ -f ${DEPLOY_FILE} ]; then if [ -f ${BACKUP_FILE} ]; then echo "backup found: ${BACKUP_FILE} going to replace it"; rm ${BACKUP_FILE}; fi mv ${DEPLOY_FILE} ${BACKUP_FILE}; rm ${DEPLOY_FILE}; else echo "deploy file empty" fi ''' } } stage('Nothing to do by System ') { when{ allOf{ triggeredBy 'TimerTrigger' environment name: 'IS_CRON', value: 'False' } } steps { echo 'Do Nothing: cron build disabled' } } stage('Add new pending deploy ') { when{ environment name: 'IS_CRON', value: 'True' anyOf{ triggeredBy 'BuildUpstreamCause' triggeredBy 'UpstreamCause' } } steps { sh ''' echo "Cron build enabled. New deploy of ${TRIGGER_JOB} - ${TRIGGER_VERSION} will be added to the deploy file" touch $DEPLOY_FILE; if grep -q \"\${TRIGGER_JOB}\" \${DEPLOY_FILE}; then echo "component ${TRIGGER_JOB} already added. Nothing to add." else echo "${TRIGGER_JOB},${TRIGGER_VERSION}" >> ${DEPLOY_FILE} fi ''' } } stage('Deploy from job ') { when{ environment name: 'IS_CRON', value: 'False' anyOf{ triggeredBy 'BuildUpstreamCause' triggeredBy 'UpstreamCause' } } steps { echo "Cron build disabled. New deploy of ${params.TRIGGER_JOB} - ${params.TRIGGER_VERSION} ongoing" catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') { sh "exit 0" } } } } post { always { script { sh ''' echo ' jobs currently appended:' ''' //cat ./${ACTION_DEPLOY_FILE}.csv } } success { echo 'The deploy pipeline worked!' emailext attachLog: true,//attachmentsPattern: "**/${ACTION_DEPLOY_FILE}.csv", to: 'roberto.cirillo@isti.cnr.it', subject: "Deploy report", body: "${currentBuild.fullDisplayName}. Build time: ${currentBuild.durationString}. See ${env.BUILD_URL}. " } failure { echo 'The deploy pipeline has failed' emailext attachLog: true, to: 'roberto.cirillo@isti.cnr.it', subject: "[Jenkins deploy D4S] deploy ${currentBuild.fullDisplayName} failed", body: "Something is wrong with ${env.BUILD_URL}" } } } //parse a csv file formatted in this way: ComponentName,ComponentVersion def parseCSVList(def deployList) { def components = [] if (fileExists("${deployList}")) { echo 'file found' readFile("${deployList}").split('\n').each { line, count-> if (line.startsWith('#')) return def fields = line.split(',') components.add([ name : fields[0], version : fields[1] ] ) } } else { echo ' File Not found. Failing.' } return components } //Alternative way to append a text in a small file (not used) def appendToFile(String fileName, String line) { def current = "" if (fileExists(fileName)) { current = readFile fileName } writeFile file: fileName, text: current + "\n" + line } /** * Appends the footer to the deploy file. */ def appendFooter( def File) { def now = new Date() sh(""" echo "#---" >> $File echo "#generated by the gCubeDeploy pipeline >> $File echo "#last update $now*" >> $File """) }