/** * Harbor ???? + ACK ??????? Jenkins ???? * ????produ//Jenkinsfile * ??/???produ/whole/Jenkinsfile ? produ/promote-image/Jenkinsfile */ /** ???? tag */ def resolveTargetTag(def script, String targetTagParam) { def t = (targetTagParam ?: '').trim() return t ?: "produ-${script.env.BUILD_NUMBER}" } /** * ?????????? Harbor ???pull ? tag ? tag ?? tag ? push? * cfg: harborRegistry, harborProject, sourceTag, targetTag, harborCredentialsId, dryRun * services: List ? prodDir */ def promoteHarborImages(def script, List services, Map cfg) { def regHost = cfg.harborRegistry.trim() def proj = cfg.harborProject.trim() def srcTag = (cfg.sourceTag ?: 'uat-latest').trim() def tgtTag = cfg.targetTag def dryRun = cfg.dryRun == true services.each { s -> def src = "${regHost}/${proj}/${s.prodDir}:${srcTag}" def tgt = "${regHost}/${proj}/${s.prodDir}:${tgtTag}" echo ">>> ???? ${s.prodDir}: ${src} ? ${tgt}" if (dryRun) { return } } if (dryRun) { return } script.withCredentials([script.usernamePassword( credentialsId: cfg.harborCredentialsId, usernameVariable: 'HARBOR_USER', passwordVariable: 'HARBOR_PASS', )]) { script.sh "echo \${HARBOR_PASS} | docker login ${regHost} -u \${HARBOR_USER} --password-stdin" services.each { s -> def src = "${regHost}/${proj}/${s.prodDir}:${srcTag}" def tgt = "${regHost}/${proj}/${s.prodDir}:${tgtTag}" script.sh """ set -e docker pull ${src} docker tag ${src} ${tgt} docker push ${tgt} """ } } } def deployToAck(def script, Map cfg) { def ns = cfg.k8sNamespace def imageRef = cfg.imageRef def strategy = cfg.deployStrategy def targetDeploy = strategy == 'canary' ? cfg.deploymentCanary : cfg.deploymentStable def canaryWeight = cfg.canaryWeight def ingressCanary = cfg.ingressCanary def kubeCreds = cfg.kubeCredentialsId script.withCredentials([script.file(credentialsId: kubeCreds, variable: 'KUBECONFIG')]) { script.sh """ set -e kubectl config current-context kubectl -n ${ns} set image deployment/${targetDeploy} app=${imageRef} --record kubectl -n ${ns} rollout status deployment/${targetDeploy} --timeout=300s """ if (strategy == 'canary') { script.sh """ set -e kubectl -n ${ns} annotate ingress ${ingressCanary} \\ nginx.ingress.kubernetes.io/canary=true \\ nginx.ingress.kubernetes.io/canary-weight=${canaryWeight} \\ --overwrite """ } } } /** ?????? + ?? ACK */ def promoteOneServiceToAck(def script, Map svc, Map params, Map env) { def regHost = params.HARBOR_REGISTRY.trim() def proj = params.HARBOR_PROJECT.trim() def srcTag = (params.SOURCE_TAG ?: 'uat-latest').trim() def tgtTag = resolveTargetTag(script, params.TARGET_TAG) def dryRun = params.DRY_RUN == true def strategy = params.DEPLOY_STRATEGY ?: 'rolling' env.TARGET_TAG_RESOLVED = tgtTag env.IMAGE_REF = "${regHost}/${proj}/${svc.prodDir}:${tgtTag}" promoteHarborImages(script, [svc], [ harborRegistry: regHost, harborProject: proj, sourceTag: srcTag, targetTag: tgtTag, harborCredentialsId: env.HARBOR_CREDENTIALS, dryRun: dryRun, ]) if (dryRun || strategy == 'skip') { return } deployToAck(script, [ k8sNamespace: params.K8S_NAMESPACE, imageRef: env.IMAGE_REF, deployStrategy: strategy == 'canary' ? 'canary' : 'rolling', deploymentStable: svc.deployName, deploymentCanary: "${svc.deployName}-canary", ingressCanary: "${svc.deployName}-canary", canaryWeight: (params.CANARY_WEIGHT ?: '10').trim(), kubeCredentialsId: env.KUBECONFIG_CREDENTIALS, ]) } return this