Finalize nx9-wg production release
This commit is contained in:
1 parent
4dfe42fe68
commit
d704c1e131
30 files changed
+2502
-370
No files matched your search
Executable
+216
@@ -0,0 +1,216 @@
|
||||
#!/usr/bin/env bash
|
||||
# ==============================================================================
|
||||
# nx9-wg Production Deployment Tool
|
||||
# ==============================================================================
|
||||
# PURPOSE:
|
||||
# Deploys the compiled release binary target/release/nx9-wg to the production
|
||||
# system path (/usr/local/bin/nx9-wg) with validated controlled replacement,
|
||||
# automatic backup of the previous binary, and controlled systemd service management.
|
||||
#
|
||||
# PREREQUISITES:
|
||||
# - Root privileges (or sudo)
|
||||
# - Pre-compiled release binary at target/release/nx9-wg
|
||||
# - Linux with systemd
|
||||
#
|
||||
# SAFETY INVARIANTS:
|
||||
# - Never overwrites the existing production binary without creating a timestamped backup.
|
||||
# - Never modifies or overwrites database files (/var/lib/nx9-wg/nx9-wg.db).
|
||||
# - Never deletes WireGuard interfaces or kills processes automatically on port conflict.
|
||||
# - Uses the standard 'install' command for controlled binary replacement and strict permissions.
|
||||
# - Returns non-zero exit code on failure.
|
||||
#
|
||||
# USAGE:
|
||||
# sudo bash scripts/deploy.sh [OPTIONS]
|
||||
#
|
||||
# OPTIONS:
|
||||
# --no-restart Install binary without restarting nx9-wg.service
|
||||
# --dry-run Simulate deployment actions without applying changes
|
||||
# -h, --help Show this help message
|
||||
# ==============================================================================
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ROOT_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
||||
|
||||
SOURCE_BIN="${ROOT_DIR}/target/release/nx9-wg"
|
||||
DEST_BIN="/usr/local/bin/nx9-wg"
|
||||
CONF_DIR="/etc/nx9-wg"
|
||||
DATA_DIR="/var/lib/nx9-wg"
|
||||
BACKUP_DIR="${DATA_DIR}/backups"
|
||||
LOG_DIR="/var/log/nx9-wg"
|
||||
SERVICE_DEST="/etc/systemd/system/nx9-wg.service"
|
||||
SERVICE_SRC="${ROOT_DIR}/nx9-wg.service"
|
||||
|
||||
DRY_RUN=0
|
||||
NO_RESTART=0
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
nx9-wg Production Deployment Tool
|
||||
|
||||
Usage:
|
||||
sudo bash scripts/deploy.sh [OPTIONS]
|
||||
|
||||
Options:
|
||||
--no-restart Install binary without restarting nx9-wg.service
|
||||
--dry-run Simulate deployment actions without applying changes
|
||||
-h, --help Show this help message
|
||||
EOF
|
||||
exit 0
|
||||
}
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--dry-run)
|
||||
DRY_RUN=1
|
||||
shift
|
||||
;;
|
||||
--no-restart)
|
||||
NO_RESTART=1
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1" >&2
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
log() {
|
||||
echo -e "\033[1;34m[DEPLOY]\033[0m \033[1;37m$*\033[0m"
|
||||
}
|
||||
|
||||
success() {
|
||||
echo -e "\033[1;32m[SUCCESS]\033[0m $*"
|
||||
}
|
||||
|
||||
warn() {
|
||||
echo -e "\033[1;33m[WARN]\033[0m $*"
|
||||
}
|
||||
|
||||
error() {
|
||||
echo -e "\033[1;31m[ERROR]\033[0m $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# 1. Privilege Verification
|
||||
if [[ "${EUID}" -ne 0 && "${DRY_RUN}" -eq 0 ]]; then
|
||||
error "Deployment must be run as root (or via sudo)."
|
||||
fi
|
||||
|
||||
# 2. Source Binary Verification
|
||||
if [[ ! -f "${SOURCE_BIN}" ]]; then
|
||||
error "Source binary not found at ${SOURCE_BIN}. Run 'bash scripts/build-release.sh' first."
|
||||
fi
|
||||
|
||||
if [[ ! -x "${SOURCE_BIN}" ]]; then
|
||||
error "Source binary at ${SOURCE_BIN} is not executable."
|
||||
fi
|
||||
|
||||
SOURCE_SIZE="$(du -h "${SOURCE_BIN}" | cut -f1)"
|
||||
SOURCE_SHA="$(sha256sum "${SOURCE_BIN}" | awk '{print $1}')"
|
||||
SOURCE_DATE="$(date -r "${SOURCE_BIN}" '+%Y-%m-%d %H:%M:%S')"
|
||||
|
||||
log "Source binary verified:"
|
||||
echo " Path: ${SOURCE_BIN}"
|
||||
echo " Size: ${SOURCE_SIZE}"
|
||||
echo " Timestamp: ${SOURCE_DATE}"
|
||||
echo " SHA-256: ${SOURCE_SHA}"
|
||||
|
||||
# 3. Create Filesystem Layout with Strict Permissions
|
||||
log "Ensuring directory permissions..."
|
||||
if [[ "${DRY_RUN}" -eq 0 ]]; then
|
||||
install -d -m 0750 "${CONF_DIR}"
|
||||
install -d -m 0700 "${DATA_DIR}"
|
||||
install -d -m 0700 "${BACKUP_DIR}"
|
||||
install -d -m 0750 "${LOG_DIR}"
|
||||
else
|
||||
echo " [DRY-RUN] install -d directories: ${CONF_DIR}, ${DATA_DIR}, ${BACKUP_DIR}, ${LOG_DIR}"
|
||||
fi
|
||||
|
||||
# 4. Backup Existing Production Binary
|
||||
if [[ -f "${DEST_BIN}" ]]; then
|
||||
TIMESTAMP="$(date +%Y%m%d_%H%M%S)"
|
||||
BACKUP_DEST="${DEST_BIN}.backup.${TIMESTAMP}"
|
||||
log "Backing up active binary to ${BACKUP_DEST}..."
|
||||
if [[ "${DRY_RUN}" -eq 0 ]]; then
|
||||
cp -p "${DEST_BIN}" "${BACKUP_DEST}"
|
||||
chmod 0755 "${BACKUP_DEST}"
|
||||
success "Backup created: ${BACKUP_DEST}"
|
||||
else
|
||||
echo " [DRY-RUN] cp -p ${DEST_BIN} ${BACKUP_DEST}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# 5. Controlled Installation of New Binary
|
||||
log "Installing new release binary to ${DEST_BIN}..."
|
||||
if [[ "${DRY_RUN}" -eq 0 ]]; then
|
||||
install -m 0755 "${SOURCE_BIN}" "${DEST_BIN}"
|
||||
success "Binary installed to ${DEST_BIN}"
|
||||
else
|
||||
echo " [DRY-RUN] install -m 0755 ${SOURCE_BIN} ${DEST_BIN}"
|
||||
fi
|
||||
|
||||
# 6. Install or Update systemd Service Unit
|
||||
if [[ -f "${SERVICE_SRC}" && -d "/etc/systemd/system" ]]; then
|
||||
log "Installing/updating systemd service unit..."
|
||||
if [[ "${DRY_RUN}" -eq 0 ]]; then
|
||||
install -m 0644 "${SERVICE_SRC}" "${SERVICE_DEST}"
|
||||
if command -v systemctl >/dev/null 2>&1; then
|
||||
systemctl daemon-reload
|
||||
fi
|
||||
success "systemd service unit updated at ${SERVICE_DEST}"
|
||||
else
|
||||
echo " [DRY-RUN] install -m 0644 ${SERVICE_SRC} ${SERVICE_DEST}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# 7. Safe Socket Inspection
|
||||
if command -v ss >/dev/null 2>&1; then
|
||||
log "Inspecting active UDP listen sockets without modifying the host..."
|
||||
ACTIVE_UDP_SOCKETS="$(ss -lunp 2>/dev/null | grep -v '^State' || true)"
|
||||
if [[ -n "${ACTIVE_UDP_SOCKETS}" ]]; then
|
||||
echo "${ACTIVE_UDP_SOCKETS}"
|
||||
else
|
||||
echo " No UDP listeners reported by ss."
|
||||
fi
|
||||
fi
|
||||
|
||||
# 8. Service Restart & Verification
|
||||
if [[ "${NO_RESTART}" -eq 0 && "${DRY_RUN}" -eq 0 ]]; then
|
||||
if command -v systemctl >/dev/null 2>&1; then
|
||||
log "Restarting nx9-wg.service..."
|
||||
systemctl restart nx9-wg || error "Failed to restart nx9-wg service."
|
||||
sleep 1
|
||||
|
||||
if systemctl is-active --quiet nx9-wg; then
|
||||
success "nx9-wg.service is active and running."
|
||||
else
|
||||
warn "nx9-wg.service is not in active state. Inspecting journal..."
|
||||
journalctl -u nx9-wg -n 20 --no-pager || true
|
||||
error "Service failed to start."
|
||||
fi
|
||||
fi
|
||||
elif [[ "${NO_RESTART}" -eq 1 ]]; then
|
||||
log "Skipping service restart as requested (--no-restart)."
|
||||
fi
|
||||
|
||||
# 9. Final Deployment Verification
|
||||
log "Verifying deployed binary version..."
|
||||
if [[ "${DRY_RUN}" -eq 0 ]]; then
|
||||
DEPLOYED_VER="$("${DEST_BIN}" version | head -n 1)"
|
||||
success "Deployed binary active: ${DEPLOYED_VER}"
|
||||
fi
|
||||
|
||||
echo -e "\n================================================================="
|
||||
echo -e "\033[1;32m DEPLOYMENT COMPLETED SUCCESSFULLY!\033[0m"
|
||||
echo -e "================================================================="
|
||||
echo " Installed Binary: ${DEST_BIN}"
|
||||
echo " Configuration: ${CONF_DIR}/config.toml"
|
||||
echo " Database: ${DATA_DIR}/nx9-wg.db"
|
||||
echo " Service Status: systemctl status nx9-wg"
|
||||
echo -e "=================================================================\n"
|
||||
Reference in new issue
Block a user