低空智控平台 后端go
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

#!/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 "$@"