#!/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 # specific host(s) set -eu SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" # shellcheck disable=SC1091 . "$SCRIPT_DIR/lib/ppf-common.sh" # --------------------------------------------------------------------------- # Usage # --------------------------------------------------------------------------- usage() { cat < 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"