128 lines
4.4 KiB
Bash
Executable File
128 lines
4.4 KiB
Bash
Executable File
#!/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
|
|
exec 9>/run/lock/harbor-release.lock
|
|
if ! flock -n 9; then
|
|
printf '%s\n' "another release or rollback is in progress" >&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
|
|
tmp_release=$(mktemp -d "/opt/harbor/releases/.${release_id}.XXXXXX")
|
|
trap 'rm -rf "${tmp_release:-}"' EXIT
|
|
chown harbor:harbor "$tmp_release"
|
|
runuser -u harbor -- tar --no-same-owner --no-same-permissions -xzf "$archive" -C "$tmp_release"
|
|
runuser -u harbor -- sh -c 'cd "$1" && sha256sum -c manifest.sha256' sh "$tmp_release"
|
|
mv "$tmp_release" "$release_dir"
|
|
trap - EXIT
|
|
fi
|
|
test -x "$release_dir/bin/gateway"
|
|
test -x "$release_dir/bin/worker"
|
|
test -x "$release_dir/bin/seeder"
|
|
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/seeder" "$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"
|
|
runuser -u harbor -- "$release_dir/bin/migrate" -path "$release_dir/migrations" -database "$MONGO_URL" up
|
|
if [[ ! -f /etc/harbor/admin-seeded ]]; then
|
|
/opt/harbor/deploy/remote/seed-admin.sh "$release_dir/bin/seeder"
|
|
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
|
|
|
|
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
|
|
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 enable "harbor-gateway@$inactive.service" "harbor-worker@$inactive.service" >/dev/null
|
|
systemctl disable "harbor-gateway@$active.service" "harbor-worker@$active.service" >/dev/null 2>&1 || true
|
|
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)"
|