You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
133 lines
4.1 KiB
133 lines
4.1 KiB
#!/usr/bin/env bash
|
|
set -Eeuo pipefail
|
|
|
|
TARGET="laic-backend-prod.srv"
|
|
REMOTE="root@jg-serv1"
|
|
REMOTE_DIR="/usr/local/laic-backend-prod"
|
|
SERVICE_NAME="laic-backend-prod"
|
|
SUPERVISOR_CONF_DIR="/etc/supervisor/conf.d"
|
|
WAIT_TIME=3
|
|
BACKUP_DIR="$REMOTE_DIR/backup"
|
|
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
|
LOCAL_CONF="$SCRIPT_DIR/config/$SERVICE_NAME.conf"
|
|
LOCAL_CONFIG="$SCRIPT_DIR/config-prod.yaml"
|
|
LOCAL_ARTIFACT="$SCRIPT_DIR/$TARGET"
|
|
|
|
cleanup() {
|
|
rm -f -- "$LOCAL_ARTIFACT"
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
remote_cmd() {
|
|
ssh "$REMOTE" "$@" </dev/null
|
|
}
|
|
|
|
require_command() {
|
|
command -v "$1" >/dev/null 2>&1 || {
|
|
printf 'Missing required command: %s\n' "$1" >&2
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
check_inputs() {
|
|
require_command go
|
|
require_command ssh
|
|
require_command scp
|
|
require_command diff
|
|
[[ -f "$LOCAL_CONF" ]] || { printf 'Missing Supervisor config: %s\n' "$LOCAL_CONF" >&2; exit 1; }
|
|
[[ -f "$LOCAL_CONFIG" ]] || { printf 'Missing production config: %s\n' "$LOCAL_CONFIG" >&2; exit 1; }
|
|
if [[ "$REMOTE" == *your-production-host* ]]; then
|
|
printf 'Set REMOTE in publish-prod.sh before deploying.\n' >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
build_local() {
|
|
printf 'Building Linux amd64 binary...\n'
|
|
(cd "$SCRIPT_DIR" && GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -trimpath -ldflags='-s -w' -o "$LOCAL_ARTIFACT" .)
|
|
}
|
|
|
|
ensure_remote_dirs() {
|
|
remote_cmd "mkdir -p '$REMOTE_DIR' '$REMOTE_DIR/config' '$REMOTE_DIR/log' '$BACKUP_DIR'"
|
|
}
|
|
|
|
check_remote_config() {
|
|
if ! remote_cmd "test -s '$REMOTE_DIR/config.yaml'"; then
|
|
printf 'Remote config.yaml is missing or empty: %s/config.yaml\n' "$REMOTE_DIR" >&2
|
|
printf 'Upload config.yaml with OBS credentials before deploying.\n' >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
backup_old() {
|
|
remote_cmd "
|
|
if [ -f '$REMOTE_DIR/$TARGET' ]; then
|
|
timestamp=\$(date +'%Y%m%d%H%M%S')
|
|
cp '$REMOTE_DIR/$TARGET' '$BACKUP_DIR/$TARGET.'\$timestamp
|
|
echo 'Previous binary backed up.'
|
|
fi
|
|
if [ -f '$REMOTE_DIR/config.yaml' ]; then
|
|
timestamp=\$(date +'%Y%m%d%H%M%S')
|
|
cp '$REMOTE_DIR/config.yaml' '$BACKUP_DIR/config.yaml.'\$timestamp
|
|
fi
|
|
"
|
|
}
|
|
|
|
upload_files() {
|
|
scp "$LOCAL_ARTIFACT" "$REMOTE:$REMOTE_DIR/$TARGET.new"
|
|
remote_cmd "mv -f '$REMOTE_DIR/$TARGET.new' '$REMOTE_DIR/$TARGET' && chmod 755 '$REMOTE_DIR/$TARGET'"
|
|
|
|
scp "$LOCAL_CONFIG" "$REMOTE:$REMOTE_DIR/config.yaml.new"
|
|
remote_cmd "mv -f '$REMOTE_DIR/config.yaml.new' '$REMOTE_DIR/config.yaml' && chmod 640 '$REMOTE_DIR/config.yaml'"
|
|
}
|
|
|
|
upload_supervisor_conf() {
|
|
local remote_conf="$SUPERVISOR_CONF_DIR/$SERVICE_NAME.conf"
|
|
if remote_cmd "test -f '$remote_conf'"; then
|
|
if diff -q "$LOCAL_CONF" <(ssh "$REMOTE" "cat '$remote_conf'") >/dev/null; then
|
|
printf 'Supervisor config unchanged.\n'
|
|
return
|
|
fi
|
|
fi
|
|
scp "$LOCAL_CONF" "$REMOTE:$remote_conf"
|
|
remote_cmd "supervisorctl reread && supervisorctl update"
|
|
}
|
|
|
|
restart_service() {
|
|
local status
|
|
status="$(remote_cmd "supervisorctl status '$SERVICE_NAME' 2>/dev/null | awk '{print \$2}'" || true)"
|
|
if [[ "$status" == RUNNING ]]; then
|
|
remote_cmd "supervisorctl restart '$SERVICE_NAME'"
|
|
else
|
|
remote_cmd "supervisorctl start '$SERVICE_NAME'"
|
|
fi
|
|
sleep "$WAIT_TIME"
|
|
if remote_cmd "supervisorctl status '$SERVICE_NAME' | grep -q RUNNING"; then
|
|
printf 'Service is running.\n'
|
|
remote_cmd "tail -n 20 '$REMOTE_DIR/log/info.log'" || true
|
|
return
|
|
fi
|
|
printf 'Service failed to start; rolling back binary.\n' >&2
|
|
rollback
|
|
exit 1
|
|
}
|
|
|
|
rollback() {
|
|
local latest_backup
|
|
latest_backup="$(remote_cmd "ls -t '$BACKUP_DIR/$TARGET.'* 2>/dev/null | head -n 1" || true)"
|
|
[[ -n "$latest_backup" ]] || { printf 'No binary backup available.\n' >&2; return 1; }
|
|
remote_cmd "cp '$latest_backup' '$REMOTE_DIR/$TARGET' && chmod 755 '$REMOTE_DIR/$TARGET' && supervisorctl restart '$SERVICE_NAME'"
|
|
}
|
|
|
|
main() {
|
|
check_inputs
|
|
build_local
|
|
ensure_remote_dirs
|
|
backup_old
|
|
upload_files
|
|
upload_supervisor_conf
|
|
restart_service
|
|
printf 'Deployment complete.\n'
|
|
}
|
|
|
|
main "$@"
|
|
|