thread-master/deploy/prod/remote/activate-release.sh

115 lines
3.6 KiB
Bash
Raw Normal View History

2026-07-14 08:54:31 +00:00
#!/usr/bin/env bash
set -euo pipefail
if [[ ${EUID} -ne 0 ]]; then
printf '%s\n' "activate-release must run as root" >&2
exit 1
fi
archive=${1:-}
checksum=${2:-}
if [[ -z "$archive" || -z "$checksum" || ! -f "$archive" ]]; then
printf '%s\n' "usage: activate-release.sh <archive> <sha256>" >&2
exit 1
fi
if [[ "$archive" != /opt/harbor/incoming/* ]]; then
printf '%s\n' "archive must be under /opt/harbor/incoming" >&2
exit 1
fi
actual=$(sha256sum "$archive" | cut -d' ' -f1)
if [[ "$actual" != "$checksum" ]]; then
printf '%s\n' "release checksum mismatch" >&2
exit 1
fi
release_id=$(basename "$archive" .tar.gz)
if [[ ! "$release_id" =~ ^harbor-[0-9]{8}T[0-9]{6}Z-[a-zA-Z0-9._-]+$ ]]; then
printf '%s\n' "invalid release archive name" >&2
exit 1
fi
release_dir=/opt/harbor/releases/$release_id
if [[ ! -d "$release_dir" ]]; then
install -d -m 0755 "$release_dir"
tar -xzf "$archive" -C "$release_dir"
fi
test -x "$release_dir/bin/gateway"
test -x "$release_dir/bin/worker"
test -x "$release_dir/bin/migrate"
test -f "$release_dir/web/index.html"
chown -R root:harbor "$release_dir"
find "$release_dir" -type d -exec chmod 0755 {} +
find "$release_dir" -type f -exec chmod 0644 {} +
chmod 0755 "$release_dir/bin/gateway" "$release_dir/bin/worker" "$release_dir/bin/migrate"
active=blue
if [[ -f /etc/harbor/active-slot ]]; then
active=$(cat /etc/harbor/active-slot)
fi
if [[ "$active" == blue ]]; then
inactive=green
inactive_port=8889
else
inactive=blue
inactive_port=8888
fi
if systemctl is-active --quiet "harbor-gateway@$inactive.service"; then
connections=$(ss -Htn state established "( sport = :$inactive_port )" | wc -l)
if (( connections > 0 )); then
printf '%s\n' "inactive slot still has $connections established connection(s); retry later" >&2
exit 1
fi
systemctl stop "harbor-gateway@$inactive.service"
fi
systemctl stop "harbor-worker@$inactive.service" 2>/dev/null || true
set -a
source /etc/harbor/harbor.env
set +a
printf '%s\n' "running forward migrations"
"$release_dir/bin/migrate" -path "$release_dir/migrations" -database "$MONGO_URL" up || status=$?
if [[ ${status:-0} -ne 0 && ${status:-0} -ne 2 ]]; then
exit "$status"
fi
ln -sfn "$release_dir" "/opt/harbor/slots/$inactive"
chown -h harbor:harbor "/opt/harbor/slots/$inactive"
systemctl start "harbor-gateway@$inactive.service"
for _ in $(seq 1 60); do
if curl -fsS "http://127.0.0.1:$inactive_port/api/v1/health" >/dev/null; then
break
fi
sleep 1
done
if ! curl -fsS "http://127.0.0.1:$inactive_port/api/v1/health" >/dev/null; then
journalctl -u "harbor-gateway@$inactive.service" -n 80 --no-pager >&2
systemctl stop "harbor-gateway@$inactive.service"
exit 1
fi
if [[ -L /opt/harbor/current ]]; then
readlink -f /opt/harbor/current > /etc/harbor/previous-release
printf '%s\n' "$active" > /etc/harbor/previous-slot
fi
ln -sfn "$release_dir" /opt/harbor/current.new
mv -Tf /opt/harbor/current.new /opt/harbor/current
printf 'server 127.0.0.1:%s;\n' "$inactive_port" > /etc/nginx/harbor-active-server.conf.new
mv -f /etc/nginx/harbor-active-server.conf.new /etc/nginx/harbor-active-server.conf
nginx -t
systemctl reload nginx
printf '%s\n' "$inactive" > /etc/harbor/active-slot
systemctl start "harbor-worker@$inactive.service"
sleep 3
if ! systemctl is-active --quiet "harbor-worker@$inactive.service"; then
journalctl -u "harbor-worker@$inactive.service" -n 80 --no-pager >&2
/opt/harbor/deploy/remote/rollback.sh || true
exit 1
fi
systemctl stop --no-block "harbor-worker@$active.service" 2>/dev/null || true
curl -fsS http://127.0.0.1/health >/dev/null
rm -f "$archive"
printf '%s\n' "activated $release_id on $inactive ($inactive_port)"