cambios
This commit is contained in:
@@ -16,16 +16,19 @@ remote Docker daemon. No external registry is required.
|
|||||||
./scripts/build-and-push.sh --remote deploy@prod.example.com
|
./scripts/build-and-push.sh --remote deploy@prod.example.com
|
||||||
```
|
```
|
||||||
|
|
||||||
The script reads `artifactId` and `version` from `pom.xml` for the image name
|
The script reads `artifactId` and `version` from `pom.xml` for the local build tag
|
||||||
and version tag, builds for `linux/amd64`, and verifies the image is present on
|
and image name, builds for `linux/amd64`, and verifies the deploy on the remote.
|
||||||
the remote after pushing. On the remote (and locally) that push is tagged three
|
On the remote, durable tags are only:
|
||||||
ways, all pointing at the same image:
|
|
||||||
|
|
||||||
- `<name>:<version>` — the version from `pom.xml` or `--tag`
|
- `<name>:latest` — always the most recent successful push
|
||||||
- `<name>:latest` — moved to this push on every successful deploy
|
- `<name>:vYYYY.MM.DD-HH.MM` — UTC timestamp of that push (for rollback)
|
||||||
- `<name>:vYYYY.MM.DD-HH.MM` — UTC timestamp of the push (for rollback; list with `docker images`)
|
|
||||||
|
|
||||||
To roll back on the remote, pick an older `v…` tag from `docker images test-quarkus` and run that reference instead of `:latest`.
|
Older releases stay tagged by date only: the script keeps the current image (with
|
||||||
|
`latest` and its date tag) and the previous date tag, and removes other tags and
|
||||||
|
images (including old `1.0.x`, `sha256-*`, and third copies). Run
|
||||||
|
`--cleanup` on the remote to apply the same pruning without a new push.
|
||||||
|
|
||||||
|
To roll back on the remote, run a previous `v…` tag from `docker images` instead of `:latest`.
|
||||||
|
|
||||||
The temporary registry container and SSH tunnel are removed when the script
|
The temporary registry container and SSH tunnel are removed when the script
|
||||||
finishes. See `./scripts/build-and-push.sh --help` for all flags.
|
finishes. See `./scripts/build-and-push.sh --help` for all flags.
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>com.example</groupId>
|
<groupId>com.example</groupId>
|
||||||
<artifactId>test-quarkus</artifactId>
|
<artifactId>test-quarkus</artifactId>
|
||||||
<version>1.0.2</version>
|
<version>1.0.3</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>Test Quarkus</name>
|
<name>Test Quarkus</name>
|
||||||
|
|||||||
+57
-11
@@ -6,7 +6,7 @@
|
|||||||
# - Image name/tag default to pom.xml properties (artifactId and version)
|
# - Image name/tag default to pom.xml properties (artifactId and version)
|
||||||
# - Builds for linux/amd64 by default (cross-compile from arm64 hosts)
|
# - Builds for linux/amd64 by default (cross-compile from arm64 hosts)
|
||||||
# - Transfers layers over the tunnel (no external registry required)
|
# - Transfers layers over the tunnel (no external registry required)
|
||||||
# - On the remote, tags the image as <version>, latest, and vYYYY.MM.DD-HH.MM (UTC)
|
# - On the remote, durable tags are :latest and vYYYY.MM.DD-HH.MM (UTC) only
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
IFS=$'\n\t'
|
IFS=$'\n\t'
|
||||||
@@ -65,8 +65,8 @@ Required:
|
|||||||
|
|
||||||
Image identity (defaults read from pom.xml):
|
Image identity (defaults read from pom.xml):
|
||||||
--name NAME Image repository name
|
--name NAME Image repository name
|
||||||
--tag TAG Version tag. The remote also receives :latest
|
--tag TAG Local build tag (from pom.xml by default). On the
|
||||||
and a vYYYY.MM.DD-HH.MM release tag (UTC).
|
remote only :latest and vYYYY.MM.DD-HH.MM (UTC).
|
||||||
|
|
||||||
Working directory (defaults to the parent of the script's directory):
|
Working directory (defaults to the parent of the script's directory):
|
||||||
--project-dir PATH Project root containing pom.xml
|
--project-dir PATH Project root containing pom.xml
|
||||||
@@ -84,9 +84,9 @@ Post-push:
|
|||||||
--no-verify Skip the ssh/docker images verification step
|
--no-verify Skip the ssh/docker images verification step
|
||||||
|
|
||||||
Maintenance:
|
Maintenance:
|
||||||
--cleanup Remove leftover temporary registry containers and
|
--cleanup Remove temporary registry leftovers on the remote,
|
||||||
localhost:<port>/... image tags on the remote
|
drop stale tags (version, sha256-*, etc.), and keep
|
||||||
(no build, no push; Docker local not required)
|
at most two app images (current + previous release)
|
||||||
|
|
||||||
Other:
|
Other:
|
||||||
-h, --help Show this help
|
-h, --help Show this help
|
||||||
@@ -237,6 +237,46 @@ cleanup_remote_registry() {
|
|||||||
ok "Remote cleanup complete."
|
ok "Remote cleanup complete."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Keep :latest plus the two newest vYYYY.MM.DD-HH.MM releases; drop other tags/IDs.
|
||||||
|
prune_remote_image_history() {
|
||||||
|
local repo="${1:-$IMAGE_NAME}"
|
||||||
|
[[ -n "$repo" ]] || return 0
|
||||||
|
log "Pruning ${repo} on remote (keep latest and previous release)…"
|
||||||
|
run_remote "bash -s" <<EOS
|
||||||
|
set -euo pipefail
|
||||||
|
RD='${REMOTE_DOCKER}'
|
||||||
|
REPO='${repo}'
|
||||||
|
release_re='^v[0-9]{4}\\.[0-9]{2}\\.[0-9]{2}-[0-9]{2}\\.[0-9]{2}\$'
|
||||||
|
|
||||||
|
rmi_ref() {
|
||||||
|
\${RD} rmi "\$1" 2>/dev/null || true
|
||||||
|
}
|
||||||
|
|
||||||
|
while IFS= read -r ref; do
|
||||||
|
tag="\${ref#*:}"
|
||||||
|
[[ "\$tag" == latest ]] && continue
|
||||||
|
if [[ "\$tag" =~ \${release_re} ]]; then continue; fi
|
||||||
|
rmi_ref "\$ref"
|
||||||
|
done < <(\${RD} images --format '{{.Repository}}:{{.Tag}}' | grep -E "^\${REPO}:" || true)
|
||||||
|
|
||||||
|
mapfile -t release_refs < <(\${RD} images --format '{{.Repository}}:{{.Tag}}' | grep -E "^\${REPO}:v[0-9]{4}\\." | sort -t: -k2)
|
||||||
|
declare -A keep_ids=()
|
||||||
|
n=\${#release_refs[@]}
|
||||||
|
if (( n == 0 )); then exit 0; fi
|
||||||
|
for (( i=n-1; i>=0 && i>=n-2; i-- )); do
|
||||||
|
id=\$(\${RD} images --format '{{.ID}}' "\${release_refs[i]}" | head -1)
|
||||||
|
[[ -n "\$id" ]] && keep_ids["\$id"]=1
|
||||||
|
done
|
||||||
|
|
||||||
|
while IFS= read -r ref; do
|
||||||
|
id=\$(\${RD} images --format '{{.ID}}' "\$ref" | head -1)
|
||||||
|
[[ -n "\${keep_ids[\$id]:-}" ]] && continue
|
||||||
|
rmi_ref "\$ref"
|
||||||
|
done < <(\${RD} images --format '{{.Repository}}:{{.Tag}}' | grep -E "^\${REPO}:" || true)
|
||||||
|
EOS
|
||||||
|
ok "Remote ${repo} pruned."
|
||||||
|
}
|
||||||
|
|
||||||
REG_PUSH_CONTAINER=""
|
REG_PUSH_CONTAINER=""
|
||||||
REG_REMOTE_PORT=""
|
REG_REMOTE_PORT=""
|
||||||
REG_LOCAL_PORT=""
|
REG_LOCAL_PORT=""
|
||||||
@@ -324,13 +364,13 @@ push_via_registry_tunnel() {
|
|||||||
docker tag "$IMAGE_REF" "$latest_ref"
|
docker tag "$IMAGE_REF" "$latest_ref"
|
||||||
docker tag "$IMAGE_REF" "$RELEASE_REF"
|
docker tag "$IMAGE_REF" "$RELEASE_REF"
|
||||||
|
|
||||||
log "Pulling image on remote and tagging ${IMAGE_REF}, ${latest_ref}, ${RELEASE_REF}…"
|
log "Pulling image on remote and tagging ${latest_ref}, ${RELEASE_REF}…"
|
||||||
run_remote "${REMOTE_DOCKER} pull ${remote_registry_ref}"
|
run_remote "${REMOTE_DOCKER} pull ${remote_registry_ref}"
|
||||||
run_remote "${REMOTE_DOCKER} tag ${remote_registry_ref} ${IMAGE_REF}"
|
|
||||||
run_remote "${REMOTE_DOCKER} tag ${remote_registry_ref} ${latest_ref}"
|
run_remote "${REMOTE_DOCKER} tag ${remote_registry_ref} ${latest_ref}"
|
||||||
run_remote "${REMOTE_DOCKER} tag ${remote_registry_ref} ${RELEASE_REF}"
|
run_remote "${REMOTE_DOCKER} tag ${remote_registry_ref} ${RELEASE_REF}"
|
||||||
run_remote "${REMOTE_DOCKER} rmi ${remote_registry_ref}" >/dev/null || true
|
run_remote "${REMOTE_DOCKER} rmi ${remote_registry_ref}" >/dev/null || true
|
||||||
ok "Remote tags: ${IMAGE_REF}, ${latest_ref}, ${RELEASE_REF}."
|
prune_remote_image_history "${IMAGE_NAME}"
|
||||||
|
ok "Remote tags: ${latest_ref}, ${RELEASE_REF}."
|
||||||
}
|
}
|
||||||
|
|
||||||
# ---------- arg parsing ----------
|
# ---------- arg parsing ----------
|
||||||
@@ -368,10 +408,16 @@ fi
|
|||||||
if [[ "$CLEANUP" -eq 1 ]]; then
|
if [[ "$CLEANUP" -eq 1 ]]; then
|
||||||
log "Remote: ${REMOTE_TARGET}"
|
log "Remote: ${REMOTE_TARGET}"
|
||||||
require ssh
|
require ssh
|
||||||
|
if ! cd "${PROJECT_DIR}" 2>/dev/null; then
|
||||||
|
die "Invalid --project-dir: ${PROJECT_DIR}"
|
||||||
|
fi
|
||||||
|
[[ -z "$IMAGE_NAME" ]] \
|
||||||
|
&& IMAGE_NAME=$(read_pom "/*[local-name()='project']/*[local-name()='artifactId']" "test-quarkus" "artifactId")
|
||||||
parse_ssh_target
|
parse_ssh_target
|
||||||
build_ssh_args
|
build_ssh_args
|
||||||
detect_remote_docker
|
detect_remote_docker
|
||||||
cleanup_remote_registry
|
cleanup_remote_registry
|
||||||
|
prune_remote_image_history "${IMAGE_NAME}"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -441,14 +487,14 @@ else
|
|||||||
log "Verifying tags on ${REMOTE_TARGET}…"
|
log "Verifying tags on ${REMOTE_TARGET}…"
|
||||||
remote_images=$(run_remote "${REMOTE_DOCKER} images --format '{{.Repository}}:{{.Tag}}'")
|
remote_images=$(run_remote "${REMOTE_DOCKER} images --format '{{.Repository}}:{{.Tag}}'")
|
||||||
missing=0
|
missing=0
|
||||||
for ref in "${IMAGE_REF}" "${IMAGE_NAME}:latest" "${RELEASE_REF}"; do
|
for ref in "${IMAGE_NAME}:latest" "${RELEASE_REF}"; do
|
||||||
if ! printf '%s\n' "$remote_images" | grep -Fxq "$ref"; then
|
if ! printf '%s\n' "$remote_images" | grep -Fxq "$ref"; then
|
||||||
err "Missing on remote: ${ref}"
|
err "Missing on remote: ${ref}"
|
||||||
missing=1
|
missing=1
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
[[ "$missing" -eq 0 ]] || die "Expected tags were not found on ${REMOTE_TARGET} after push."
|
[[ "$missing" -eq 0 ]] || die "Expected tags were not found on ${REMOTE_TARGET} after push."
|
||||||
ok "Remote has ${IMAGE_REF}, ${IMAGE_NAME}:latest and ${RELEASE_REF}."
|
ok "Remote has ${IMAGE_NAME}:latest and ${RELEASE_REF}."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ---------- next step hint ----------
|
# ---------- next step hint ----------
|
||||||
|
|||||||
Reference in New Issue
Block a user