|
|
@@ -1,4 +1,4 @@
|
|
|
-/**
|
|
|
+/**
|
|
|
* UAT: Checkout -> Maven -> (optional) push images to Harbor -> deploy jar + docker restart.
|
|
|
*
|
|
|
* Jenkins Job: Pipeline script from SCM
|
|
|
@@ -6,8 +6,8 @@
|
|
|
*
|
|
|
* Harbor (153.68): when PUSH_TO_HARBOR=true, push e.g.
|
|
|
* 39.105.153.68/alien_cloud/gateway:uat-latest
|
|
|
- * Before push: existing uat-latest is archived as uat-build-<BUILD_NUMBER> via Harbor API
|
|
|
- * (same digest, no docker pull/tag/push). New image is pushed only as uat-latest.
|
|
|
+ * Before push: existing uat-latest is archived as uat-build-<BUILD_NUMBER> (Harbor API tag when
|
|
|
+ * permitted; on 403 falls back to docker pull/tag/push). New image is pushed only as uat-latest.
|
|
|
* Prod promote: SOURCE_TAG=uat-latest.
|
|
|
*/
|
|
|
|
|
|
@@ -43,8 +43,14 @@ def filterHarborPushScope(List allServices, String scope) {
|
|
|
error("Unknown HARBOR_PUSH_SCOPE: ${scope}")
|
|
|
}
|
|
|
|
|
|
+/** Marker file: docker pull/tag/push archive needed when Harbor API tag is forbidden. */
|
|
|
+def harborArchiveDockerFallbackMarker(String repo) {
|
|
|
+ return "/tmp/harbor_archive_docker_fallback_${repo}"
|
|
|
+}
|
|
|
+
|
|
|
/** Archive current uat-latest as uat-build-N via Harbor API (same digest, no layer re-upload). */
|
|
|
def archiveHarborLatestViaApi(def script, String reg, String proj, String repo, String latestTag, String buildTag) {
|
|
|
+ def fallbackMarker = harborArchiveDockerFallbackMarker(repo)
|
|
|
script.sh """
|
|
|
set -e
|
|
|
REG='${reg}'
|
|
|
@@ -52,8 +58,11 @@ def archiveHarborLatestViaApi(def script, String reg, String proj, String repo,
|
|
|
REPO='${repo}'
|
|
|
LATEST='${latestTag}'
|
|
|
BUILD_TAG='${buildTag}'
|
|
|
+ FALLBACK_MARKER='${fallbackMarker}'
|
|
|
+ rm -f "\${FALLBACK_MARKER}"
|
|
|
if ! command -v jq >/dev/null 2>&1; then
|
|
|
- echo '>>> WARN: jq missing, skip Harbor API archive for '\${REPO}
|
|
|
+ echo ">>> WARN: jq missing, will docker-fallback archive for \${REPO}"
|
|
|
+ touch "\${FALLBACK_MARKER}"
|
|
|
exit 0
|
|
|
fi
|
|
|
enc_repo=\$(printf '%s' "\${REPO}" | jq -sRr @uri)
|
|
|
@@ -75,6 +84,11 @@ def archiveHarborLatestViaApi(def script, String reg, String proj, String repo,
|
|
|
409)
|
|
|
echo ">>> WARN: \${REPO}:\${BUILD_TAG} already exists, continue"
|
|
|
;;
|
|
|
+ 403)
|
|
|
+ echo ">>> WARN: Harbor API archive forbidden (403) for \${REPO}, will docker-fallback"
|
|
|
+ cat /tmp/harbor_archive_\${REPO}.json 2>/dev/null || true
|
|
|
+ touch "\${FALLBACK_MARKER}"
|
|
|
+ ;;
|
|
|
*)
|
|
|
echo ">>> ERROR: Harbor archive \${REPO} HTTP \${archive_code}"
|
|
|
cat /tmp/harbor_archive_\${REPO}.json 2>/dev/null || true
|
|
|
@@ -88,6 +102,8 @@ def pushOneHarborImage(def script, Map svc, String reg, String proj, String late
|
|
|
String baseImage, String dockerfile, String workspace) {
|
|
|
def jarName = "${svc.module}-1.0.0.jar"
|
|
|
def imageLatest = "${reg}/${proj}/${svc.repo}:${latestTag}"
|
|
|
+ def imageBuild = "${reg}/${proj}/${svc.repo}:${buildTag}"
|
|
|
+ def fallbackMarker = harborArchiveDockerFallbackMarker(svc.repo)
|
|
|
def withLibFlag = svc.withLib ? 'true' : 'false'
|
|
|
script.sh """
|
|
|
set -e
|
|
|
@@ -109,6 +125,19 @@ def pushOneHarborImage(def script, Map svc, String reg, String proj, String late
|
|
|
DOCKER_LOCK=/tmp/jenkins-alien-cloud-docker.lock
|
|
|
flock "\${DOCKER_LOCK}" sh -c '
|
|
|
set -e
|
|
|
+ FALLBACK_MARKER="${fallbackMarker}"
|
|
|
+ if [ -f "\${FALLBACK_MARKER}" ]; then
|
|
|
+ echo ">>> docker-fallback archive ${svc.repo}:${buildTag} from ${latestTag}"
|
|
|
+ if docker pull ${imageLatest}; then
|
|
|
+ docker tag ${imageLatest} ${imageBuild}
|
|
|
+ docker push ${imageBuild}
|
|
|
+ docker rmi ${imageBuild} 2>/dev/null || true
|
|
|
+ echo ">>> archived ${imageBuild} via docker"
|
|
|
+ else
|
|
|
+ echo ">>> WARN: docker pull ${imageLatest} failed, skip archive"
|
|
|
+ fi
|
|
|
+ rm -f "\${FALLBACK_MARKER}"
|
|
|
+ fi
|
|
|
cd ${workspace}/${svc.module}/.jenkins_docker_ctx
|
|
|
build_ok=0
|
|
|
for attempt in 1 2 3; do
|
|
|
@@ -288,7 +317,7 @@ pipeline {
|
|
|
stage('Checkout') {
|
|
|
steps {
|
|
|
script {
|
|
|
- // Do not use env.GIT_BRANCH — Jenkins SCM plugin injects origin/<branch> and overwrites it.
|
|
|
+ // Do not use env.GIT_BRANCH 鈥?Jenkins SCM plugin injects origin/<branch> and overwrites it.
|
|
|
def branch = normalizeGitBranch(params.GIT_BRANCH)
|
|
|
if (!branch) {
|
|
|
error('GIT_BRANCH is required')
|