node ("swarm") { stage("Clear Work Space") { try { deleteDir() } catch(err) { throw err } } withEnv([ "git_url=https://git.sdsys.ru/iru/promo.git", "jenkins_ssh_key=/run/secrets/provision-ssh-key", "docker_image=promo", "service_name=info_promo", "docker_registry=dev-registry.infoclinica.ru:5000", "cluster_name=dev-iru-swarm", "domain_name=infoclinica.lan", "mailfrom=jenkins.dev@sdsys.ru", "mailto=tomishinets.v@sdsys.ru", "swarm_git_mail=jenkins.dev@sdsys.ru", "swarm_git_user=provision", "swarm_git_url=ssh://git@git.sdsys.ru:8022/iru/stack-deploy.git", ]) { stage("Pull") { try { git url: "${git_url}" } catch(err) { currentBuild.result = "FAILURE" String error = "${err}"; mail charset: 'UTF-8', from: "${mailfrom}", mimeType: 'text/html', subject: "Ошибка Jenkins CI/CD: Имя проекта -> ${env.JOB_NAME}", to: "${mailto}", body: "Внимание!!!
\n\nСообщение об ошибке:
${error} Pull promo failed\n\n
Project Name:
${env.JOB_NAME}
\nBuild Number:
${env.BUILD_NUMBER}
\nStage Name:
Pull
\nURL Build:
${env.BUILD_URL}" deleteDir() throw err } } stage("Build") { try { sh ('''docker build -t ${docker_registry}/${docker_image}:${BUILD_NUMBER} ${WORKSPACE}/ if [ $? -eq 1 ]; then echo "Can not build a ${docker_registry}/${docker_image}:${BUILD_NUMBER}"; exit 1; fi ''') } catch(err) { currentBuild.result = "FAILURE" String error = "${err}"; mail charset: 'UTF-8', from: "${mailfrom}", mimeType: 'text/html', subject: "Ошибка Jenkins CI/CD: Имя проекта -> ${env.JOB_NAME}", to: "${mailto}", body: "Внимание!!!
\n\nСообщение об ошибке:
${error}\n\n
Project Name:
${env.JOB_NAME}
\nBuild Number:
${env.BUILD_NUMBER}
\nStage Name:
Build
\nURL Build:
${env.BUILD_URL}" deleteDir() throw err } } stage("Publish") { try { sh ('''docker push ${docker_registry}/${docker_image}:${BUILD_NUMBER} if [ $? -eq 1 ]; then echo "Can not push a ${docker_registry}/${docker_image}:${BUILD_NUMBER}"; exit 1; fi ''') } catch (err) { currentBuild.result = "FAILURE" String error = "${err}"; mail charset: 'UTF-8', from: "${mailfrom}", mimeType: 'text/html', subject: "Ошибка Jenkins CI/CD: Имя проекта -> ${env.JOB_NAME}", to: "${mailto}", body: "Внимание!!!
\n\nСообщение об ошибке:
${error}\n\n
Project Name:
${env.JOB_NAME}
\nBuild Number:
${env.BUILD_NUMBER}
\nStage Name:
Publish
\nURL Build:
${env.BUILD_URL}" deleteDir() throw err } } stage("Prod-like") { try { sh ('''export DOCKER_CERT_PATH=/run/secrets/swarm export DOCKER_HOST=tcp://${cluster_name}1.${domain_name}:2376 DOCKER_TLS_VERIFY=1 docker node ls --format "{{.Hostname}} {{.TLSStatus}}" | while read host status do if [ $status != Ready ]; then echo "Cluster ${cluster_name}.${domain_name} state is inconsistent"; exit 1 else echo "HOST: $host STATUS: $status" fi done ''') } catch(err) { currentBuild.result = "FAILURE" String error = "${err}"; mail charset: 'UTF-8', from: "${mailfrom}", mimeType: 'text/html', subject: "Ошибка Jenkins CI/CD: Имя проекта -> ${env.JOB_NAME}", to: "${mailto}", body: "Внимание!!!
\n\nСообщение об ошибке:
${error}\n\n
Project Name:
${env.JOB_NAME}
\nBuild Number:
${env.BUILD_NUMBER}
\nStage Name:
Prod-like
\nURL Build:
${env.BUILD_URL}" deleteDir() throw err } try { sh ('''export DOCKER_CERT_PATH=/run/secrets/swarm export DOCKER_HOST=tcp://${cluster_name}1.${domain_name}:2376 DOCKER_TLS_VERIFY=1 docker service update --image ${docker_registry}/${docker_image}:${BUILD_NUMBER} ${service_name} sleep 60 if [ `docker service inspect ${service_name} --format='{{.UpdateStatus.State}}'` != "completed" ] then echo ${service_name} is not updated! Do rollback! docker service update --image ${docker_registry}/${docker_image}:latest ${service_name} exit 1 else docker service ps ${service_name} --filter desired-state=Running --format='{{.ID}} {{.Node}}' | while read id node do export DOCKER_HOST=tcp://${node}:2376 DOCKER_TLS_VERIFY=1 container_id=`docker inspect ${id} --format='{{.Status.ContainerStatus.ContainerID}}'` if [ `docker inspect ${container_id} --format='{{..State.Health.Status}}'` != "healthy" ] then echo ${service_name} on ${node} with ${container_id} is not healthy! Do rollback! docker service update --image ${docker_registry}/${docker_image}:latest ${service_name} exit 1 else echo all is well fi done fi ''') } catch(err) { currentBuild.result = "FAILURE" String error = "${err}"; mail charset: 'UTF-8', from: "${mailfrom}", mimeType: 'text/html', subject: "Ошибка Jenkins CI/CD: Имя проекта -> ${env.JOB_NAME}", to: "${mailto}", body: "Внимание!!!
\n\nСообщение об ошибке:
${error}\n\n
Project Name:
${env.JOB_NAME}
\nBuild Number:
${env.BUILD_NUMBER}
\nStage Name:
Prod-like
\nURL Build:
${env.BUILD_URL}" deleteDir() throw err } } stage("Tag image to latest") { try { sh ('''docker tag ${docker_registry}/${docker_image}:${BUILD_NUMBER} ${docker_registry}/${docker_image}:latest docker push ${docker_registry}/${docker_image}:latest if [ $? -eq 1 ]; then echo "Can not push a ${docker_registry}/${docker_image}:latest"; exit 1; fi GIT_SSH_COMMAND='ssh -i ${jenkins_ssh_key} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' \ git clone ${swarm_git_url} cd ${WORKSPACE}/stack-deploy echo ${BUILD_NUMBER} > tags/promo.version git config --global user.email "${swarm_git_mail}" git config --global user.name "${swarm_git_user}" git add --all git commit -m "Update version of promo" GIT_SSH_COMMAND='ssh -i ${jenkins_ssh_key} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' \ git push origin master rm -rf ~/.gitconfig ''') } catch(err) { currentBuild.result = "FAILURE" String error = "${err}"; mail charset: 'UTF-8', from: "${mailfrom}", mimeType: 'text/html', subject: "Ошибка Jenkins CI/CD: Имя проекта -> ${env.JOB_NAME}", to: "${mailto}", body: "Внимание!!!
\n\nСообщение об ошибке:
${error}\n\n Ошибка обновления тэга версии!!!
Project Name:
${env.JOB_NAME}
\nBuild Number:
${env.BUILD_NUMBER}
\nStage Name:
Tag image to latest
\nURL Build:
${env.BUILD_URL}" deleteDir() throw err } } stage("Send E-mail") { try { currentBuild.result = "SUCCESS" mail charset: 'UTF-8', from: "${mailfrom}", mimeType: 'text/html', subject: "Сборка успешно завешена! Имя проекта -> ${env.JOB_NAME}", to: "${mailto}", body: "Внимание!!!
\n\nСборка успешно завешена!
Project Name:
${env.JOB_NAME}
\nBuild Number:
${env.BUILD_NUMBER}
\nStage Name:
Send E-mail
\nURL Build:
${env.BUILD_URL}" deleteDir() } catch(err) { throw err } } } }