ci: support sudo docker on build node
This commit is contained in:
+35
-21
@@ -50,6 +50,20 @@ pipeline {
|
|||||||
env.SMOKE_NETWORK = "jizhi-smoke-net-${env.BUILD_NUMBER}"
|
env.SMOKE_NETWORK = "jizhi-smoke-net-${env.BUILD_NUMBER}"
|
||||||
env.SMOKE_MYSQL = "jizhi-smoke-mysql-${env.BUILD_NUMBER}"
|
env.SMOKE_MYSQL = "jizhi-smoke-mysql-${env.BUILD_NUMBER}"
|
||||||
env.SMOKE_APP = "jizhi-smoke-app-${env.BUILD_NUMBER}"
|
env.SMOKE_APP = "jizhi-smoke-app-${env.BUILD_NUMBER}"
|
||||||
|
env.DOCKER_CMD = sh(
|
||||||
|
script: '''
|
||||||
|
set +x
|
||||||
|
if docker version >/dev/null 2>&1; then
|
||||||
|
printf 'docker'
|
||||||
|
elif sudo -n docker version >/dev/null 2>&1; then
|
||||||
|
printf 'sudo -n docker'
|
||||||
|
else
|
||||||
|
echo 'Jenkins 用户无法访问 Docker;请加入 docker 组或配置免密 sudo docker。' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
''',
|
||||||
|
returnStdout: true,
|
||||||
|
).trim()
|
||||||
currentBuild.displayName = "#${env.BUILD_NUMBER} ${env.IMMUTABLE_TAG}"
|
currentBuild.displayName = "#${env.BUILD_NUMBER} ${env.IMMUTABLE_TAG}"
|
||||||
currentBuild.description = 'linux/amd64 · Admin Web + ASP.NET API'
|
currentBuild.description = 'linux/amd64 · Admin Web + ASP.NET API'
|
||||||
}
|
}
|
||||||
@@ -59,8 +73,8 @@ pipeline {
|
|||||||
for command_name in git docker curl gzip sha256sum python3; do
|
for command_name in git docker curl gzip sha256sum python3; do
|
||||||
command -v "$command_name" >/dev/null
|
command -v "$command_name" >/dev/null
|
||||||
done
|
done
|
||||||
docker version >/dev/null
|
$DOCKER_CMD version >/dev/null
|
||||||
docker buildx version
|
$DOCKER_CMD buildx version
|
||||||
test -f Dockerfile.backend
|
test -f Dockerfile.backend
|
||||||
test -f admin-web/package-lock.json
|
test -f admin-web/package-lock.json
|
||||||
mkdir -p artifacts
|
mkdir -p artifacts
|
||||||
@@ -75,7 +89,7 @@ pipeline {
|
|||||||
retry(2) {
|
retry(2) {
|
||||||
sh '''
|
sh '''
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
docker buildx build \
|
$DOCKER_CMD buildx build \
|
||||||
--platform linux/amd64 \
|
--platform linux/amd64 \
|
||||||
--load \
|
--load \
|
||||||
--file Dockerfile.backend \
|
--file Dockerfile.backend \
|
||||||
@@ -88,9 +102,9 @@ pipeline {
|
|||||||
}
|
}
|
||||||
sh '''
|
sh '''
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
test "$(docker image inspect "$IMAGE_REF" --format '{{.Os}}/{{.Architecture}}')" = 'linux/amd64'
|
test "$($DOCKER_CMD image inspect "$IMAGE_REF" --format '{{.Os}}/{{.Architecture}}')" = 'linux/amd64'
|
||||||
test "$(docker image inspect "$IMAGE_REF" --format '{{index .Config.Labels "org.opencontainers.image.revision"}}')" = "$FULL_SHA"
|
test "$($DOCKER_CMD image inspect "$IMAGE_REF" --format '{{index .Config.Labels "org.opencontainers.image.revision"}}')" = "$FULL_SHA"
|
||||||
docker run --rm --entrypoint /bin/sh "$IMAGE_REF" -c \
|
$DOCKER_CMD run --rm --entrypoint /bin/sh "$IMAGE_REF" -c \
|
||||||
'test -s /app/MiaoJiZhang.Api.dll && test -s /app/wwwroot/index.html'
|
'test -s /app/MiaoJiZhang.Api.dll && test -s /app/wwwroot/index.html'
|
||||||
'''
|
'''
|
||||||
}
|
}
|
||||||
@@ -100,8 +114,8 @@ pipeline {
|
|||||||
steps {
|
steps {
|
||||||
sh '''
|
sh '''
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
docker network create "$SMOKE_NETWORK" >/dev/null
|
$DOCKER_CMD network create "$SMOKE_NETWORK" >/dev/null
|
||||||
docker run --detach \
|
$DOCKER_CMD run --detach \
|
||||||
--name "$SMOKE_MYSQL" \
|
--name "$SMOKE_MYSQL" \
|
||||||
--network "$SMOKE_NETWORK" \
|
--network "$SMOKE_NETWORK" \
|
||||||
--env MYSQL_DATABASE=jizhi_smoke \
|
--env MYSQL_DATABASE=jizhi_smoke \
|
||||||
@@ -112,7 +126,7 @@ pipeline {
|
|||||||
|
|
||||||
mysql_ready=0
|
mysql_ready=0
|
||||||
for attempt in $(seq 1 60); do
|
for attempt in $(seq 1 60); do
|
||||||
if docker exec "$SMOKE_MYSQL" mysqladmin ping \
|
if $DOCKER_CMD exec "$SMOKE_MYSQL" mysqladmin ping \
|
||||||
--user=jizhi --password=jizhi-smoke-password --silent; then
|
--user=jizhi --password=jizhi-smoke-password --silent; then
|
||||||
mysql_ready=1
|
mysql_ready=1
|
||||||
break
|
break
|
||||||
@@ -120,11 +134,11 @@ pipeline {
|
|||||||
sleep 2
|
sleep 2
|
||||||
done
|
done
|
||||||
if [ "$mysql_ready" != 1 ]; then
|
if [ "$mysql_ready" != 1 ]; then
|
||||||
docker logs "$SMOKE_MYSQL" >&2
|
$DOCKER_CMD logs "$SMOKE_MYSQL" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
docker run --detach \
|
$DOCKER_CMD run --detach \
|
||||||
--name "$SMOKE_APP" \
|
--name "$SMOKE_APP" \
|
||||||
--network "$SMOKE_NETWORK" \
|
--network "$SMOKE_NETWORK" \
|
||||||
--publish 127.0.0.1::8080 \
|
--publish 127.0.0.1::8080 \
|
||||||
@@ -139,7 +153,7 @@ pipeline {
|
|||||||
--env "Build__Version=$IMMUTABLE_TAG" \
|
--env "Build__Version=$IMMUTABLE_TAG" \
|
||||||
"$IMAGE_REF" >/dev/null
|
"$IMAGE_REF" >/dev/null
|
||||||
|
|
||||||
host_port=$(docker port "$SMOKE_APP" 8080/tcp | sed -n 's/.*://p' | head -n 1)
|
host_port=$($DOCKER_CMD port "$SMOKE_APP" 8080/tcp | sed -n 's/.*://p' | head -n 1)
|
||||||
test -n "$host_port"
|
test -n "$host_port"
|
||||||
app_ready=0
|
app_ready=0
|
||||||
for attempt in $(seq 1 90); do
|
for attempt in $(seq 1 90); do
|
||||||
@@ -148,14 +162,14 @@ pipeline {
|
|||||||
app_ready=1
|
app_ready=1
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
if ! docker inspect "$SMOKE_APP" --format '{{.State.Running}}' | grep -qx true; then
|
if ! $DOCKER_CMD inspect "$SMOKE_APP" --format '{{.State.Running}}' | grep -qx true; then
|
||||||
docker logs "$SMOKE_APP" >&2
|
$DOCKER_CMD logs "$SMOKE_APP" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
sleep 2
|
sleep 2
|
||||||
done
|
done
|
||||||
if [ "$app_ready" != 1 ]; then
|
if [ "$app_ready" != 1 ]; then
|
||||||
docker logs "$SMOKE_APP" >&2
|
$DOCKER_CMD logs "$SMOKE_APP" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
grep -Fq "\"version\":\"$IMMUTABLE_TAG\"" artifacts/smoke-ping.json
|
grep -Fq "\"version\":\"$IMMUTABLE_TAG\"" artifacts/smoke-ping.json
|
||||||
@@ -169,11 +183,11 @@ pipeline {
|
|||||||
steps {
|
steps {
|
||||||
sh '''
|
sh '''
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
docker save "$IMAGE_REF" | gzip -1 >"$ARCHIVE_PATH"
|
$DOCKER_CMD save "$IMAGE_REF" | gzip -1 >"$ARCHIVE_PATH"
|
||||||
gzip -t "$ARCHIVE_PATH"
|
gzip -t "$ARCHIVE_PATH"
|
||||||
gzip -dc "$ARCHIVE_PATH" | tar -tf - | grep -q '^manifest.json$'
|
gzip -dc "$ARCHIVE_PATH" | tar -tf - | grep -q '^manifest.json$'
|
||||||
sha256sum "$ARCHIVE_PATH" >"$ARCHIVE_PATH.sha256"
|
sha256sum "$ARCHIVE_PATH" >"$ARCHIVE_PATH.sha256"
|
||||||
image_id=$(docker image inspect "$IMAGE_REF" --format '{{.Id}}')
|
image_id=$($DOCKER_CMD image inspect "$IMAGE_REF" --format '{{.Id}}')
|
||||||
archive_sha=$(awk '{print $1}' "$ARCHIVE_PATH.sha256")
|
archive_sha=$(awk '{print $1}' "$ARCHIVE_PATH.sha256")
|
||||||
export image_id archive_sha
|
export image_id archive_sha
|
||||||
python3 - <<'PY'
|
python3 - <<'PY'
|
||||||
@@ -221,12 +235,12 @@ PY
|
|||||||
post {
|
post {
|
||||||
always {
|
always {
|
||||||
script {
|
script {
|
||||||
if (env.NODE_NAME?.trim()) {
|
if (env.NODE_NAME?.trim() && env.DOCKER_CMD?.trim()) {
|
||||||
sh(
|
sh(
|
||||||
script: '''
|
script: '''
|
||||||
docker rm --force "$SMOKE_APP" "$SMOKE_MYSQL" >/dev/null 2>&1 || true
|
$DOCKER_CMD rm --force "$SMOKE_APP" "$SMOKE_MYSQL" >/dev/null 2>&1 || true
|
||||||
docker network rm "$SMOKE_NETWORK" >/dev/null 2>&1 || true
|
$DOCKER_CMD network rm "$SMOKE_NETWORK" >/dev/null 2>&1 || true
|
||||||
docker image rm "$IMAGE_REF" >/dev/null 2>&1 || true
|
$DOCKER_CMD image rm "$IMAGE_REF" >/dev/null 2>&1 || true
|
||||||
''',
|
''',
|
||||||
returnStatus: true,
|
returnStatus: true,
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user