Validates syntax, rsyncs code, copies compose files, fixes ownership, restarts containers. Supports --no-restart and per-host targeting.
168 lines
4.8 KiB
Bash
Executable File
168 lines
4.8 KiB
Bash
Executable File
#!/bin/bash
|
|
# ppf-deploy -- deploy PPF code to nodes
|
|
#
|
|
# Usage:
|
|
# ppf-deploy [--no-restart] [targets...]
|
|
#
|
|
# Targets:
|
|
# all odin + all workers (default)
|
|
# workers cassius, edge, sentinel
|
|
# master odin
|
|
# <hostname> specific host(s)
|
|
|
|
set -eu
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
# shellcheck disable=SC1091
|
|
. "$SCRIPT_DIR/lib/ppf-common.sh"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Usage
|
|
# ---------------------------------------------------------------------------
|
|
usage() {
|
|
cat <<EOF
|
|
Usage: ppf-deploy [--no-restart] [targets...]
|
|
|
|
Deploy PPF code to nodes.
|
|
|
|
Targets:
|
|
all odin + all workers (default)
|
|
workers cassius, edge, sentinel
|
|
master odin
|
|
<hostname> specific host(s)
|
|
|
|
Options:
|
|
--no-restart sync files only, skip container restart
|
|
--help show this help
|
|
--version show version
|
|
|
|
Steps:
|
|
1. Validate Python syntax locally
|
|
2. Rsync *.py + servers.txt to targets
|
|
3. Copy compose file per role
|
|
4. Fix ownership (podman:podman)
|
|
5. Restart containers (unless --no-restart)
|
|
6. Show container status
|
|
EOF
|
|
exit 0
|
|
}
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Parse args
|
|
# ---------------------------------------------------------------------------
|
|
DO_RESTART=1
|
|
TARGETS=""
|
|
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--help|-h) usage ;;
|
|
--version|-V) echo "ppf-deploy $PPF_TOOLS_VERSION"; exit 0 ;;
|
|
--no-restart) DO_RESTART=0 ;;
|
|
-*) die "Unknown option: $1" ;;
|
|
*) TARGETS="${TARGETS:+$TARGETS }$1" ;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
TARGETS="${TARGETS:-all}"
|
|
HOSTS=$(resolve_targets $TARGETS)
|
|
|
|
[ -z "$HOSTS" ] && die "No valid targets"
|
|
|
|
section "Deploy targets"
|
|
log_info "$HOSTS"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Step 1: Validate syntax
|
|
# ---------------------------------------------------------------------------
|
|
validate_syntax
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Step 2: Rsync code to targets
|
|
# ---------------------------------------------------------------------------
|
|
section "Syncing code"
|
|
|
|
for host in $HOSTS; do
|
|
if is_master "$host"; then
|
|
dest="/home/podman/ppf/"
|
|
else
|
|
dest="/home/podman/ppf/src/"
|
|
fi
|
|
|
|
log_info "${host} ${C_DIM}-> ${dest}${C_RST}"
|
|
|
|
ansible_cmd "$host" -m synchronize \
|
|
-a "src=$PPF_DIR/ dest=$dest rsync_opts='--include=*.py,--include=servers.txt,--include=Dockerfile,--exclude=*'" \
|
|
> /dev/null 2>&1 \
|
|
&& log_ok "$host synced" \
|
|
|| { log_err "$host sync failed"; continue; }
|
|
done
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Step 3: Copy compose file per role
|
|
# ---------------------------------------------------------------------------
|
|
section "Copying compose files"
|
|
|
|
for host in $HOSTS; do
|
|
if is_master "$host"; then
|
|
src="$PPF_DIR/compose.master.yml"
|
|
else
|
|
src="$PPF_DIR/compose.worker.yml"
|
|
fi
|
|
|
|
ansible_cmd "$host" -m copy \
|
|
-a "src=$src dest=/home/podman/ppf/compose.yml owner=podman group=podman" \
|
|
> /dev/null 2>&1 \
|
|
&& log_ok "$host compose file" \
|
|
|| log_err "$host compose copy failed"
|
|
done
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Step 4: Fix ownership
|
|
# ---------------------------------------------------------------------------
|
|
section "Fixing ownership"
|
|
|
|
csv=$(hosts_csv $HOSTS)
|
|
ansible_cmd "$csv" -m raw -a "chown -R podman:podman /home/podman/ppf/" \
|
|
> /dev/null 2>&1 \
|
|
&& log_ok "ownership fixed on all targets" \
|
|
|| log_err "ownership fix failed on some targets"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Step 5: Restart (unless --no-restart)
|
|
# ---------------------------------------------------------------------------
|
|
if [ "$DO_RESTART" -eq 1 ]; then
|
|
section "Restarting containers"
|
|
|
|
for host in $HOSTS; do
|
|
compose_cmd "$host" "restart" > /dev/null 2>&1 \
|
|
&& log_ok "$host restarted" \
|
|
|| log_err "$host restart failed"
|
|
done
|
|
|
|
# Brief pause for containers to settle
|
|
sleep 2
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Step 6: Show status
|
|
# ---------------------------------------------------------------------------
|
|
section "Container status"
|
|
|
|
for host in $HOSTS; do
|
|
local_output=$(compose_cmd "$host" "ps" 2>/dev/null) || true
|
|
if echo "$local_output" | grep -qi "up\|running"; then
|
|
log_ok "$host"
|
|
else
|
|
log_warn "$host"
|
|
fi
|
|
echo "$local_output" | grep -v '^\s*$' | while IFS= read -r line; do
|
|
log_dim "$line"
|
|
done
|
|
done
|
|
else
|
|
log_info "Restart skipped (--no-restart)"
|
|
fi
|
|
|
|
printf "\n"
|
|
log_ok "Deploy complete"
|