LocalAuthority / scripts / deploy_to_jumper.sh
c80a9aa 18 hours ago History
1 contributor
121 lines | 3.328kb
#!/usr/bin/env bash
# Deploy Madagascar Local Authority application code to jumper.

set -euo pipefail

TARGET_HOST="${TARGET_HOST:-jumper.madagascar.xdev.ro}"
TARGET_DIR="${TARGET_DIR:-/usr/local/xdev-host-manager}"
RESTART=1
ALLOW_DIRTY=0
DRY_RUN=0
INCLUDE_CONFIG=0

usage() {
    cat <<EOF
Usage: $0 [--target host] [--target-dir path] [--no-restart] [--allow-dirty] [--dry-run] [--include-config]

Deploys application code/docs to jumper. Runtime registry data in config/ is not
deployed unless --include-config is explicit.

Environment:
  TARGET_HOST   Default: jumper.madagascar.xdev.ro
  TARGET_DIR    Default: /usr/local/xdev-host-manager
EOF
}

while [[ $# -gt 0 ]]; do
    case "$1" in
        --target)
            TARGET_HOST="$2"
            shift 2
            ;;
        --target-dir)
            TARGET_DIR="$2"
            shift 2
            ;;
        --no-restart)
            RESTART=0
            shift
            ;;
        --allow-dirty)
            ALLOW_DIRTY=1
            shift
            ;;
        --dry-run)
            DRY_RUN=1
            shift
            ;;
        --include-config)
            INCLUDE_CONFIG=1
            shift
            ;;
        --help|-h)
            usage
            exit 0
            ;;
        *)
            echo "Unknown option: $1" >&2
            usage >&2
            exit 2
            ;;
    esac
done

cd "$(dirname "$0")/.."

if [[ "$ALLOW_DIRTY" -ne 1 ]] && [[ -n "$(git status --porcelain)" ]]; then
    echo "Working tree is dirty; commit first or pass --allow-dirty." >&2
    git status --short >&2
    exit 1
fi

command -v rsync >/dev/null 2>&1 || {
    echo "rsync is required for deployment." >&2
    exit 1
}
ssh "$TARGET_HOST" "command -v rsync >/dev/null 2>&1" || {
    echo "rsync is required on $TARGET_HOST." >&2
    exit 1
}

perl -c scripts/host_manager.pl >/dev/null
BUILD_REVISION="$(git rev-parse --short=12 HEAD)"
BUILD_BRANCH="$(git rev-parse --abbrev-ref HEAD)"
BUILD_DIRTY=0
if [[ -n "$(git status --porcelain)" ]]; then
    BUILD_DIRTY=1
fi
BUILD_DEPLOYED_AT="$(date -u '+%Y-%m-%dT%H:%M:%SZ')"

rsync_args=(-az --delete)
if [[ "$DRY_RUN" -eq 1 ]]; then
    rsync_args+=(--dry-run --itemize-changes)
fi

ssh "$TARGET_HOST" "mkdir -p '$TARGET_DIR/scripts' '$TARGET_DIR/deploy' '$TARGET_DIR/.doc'"
rsync "${rsync_args[@]}" scripts/ "$TARGET_HOST:$TARGET_DIR/scripts/"
rsync "${rsync_args[@]}" deploy/ "$TARGET_HOST:$TARGET_DIR/deploy/"
rsync "${rsync_args[@]}" .doc/ "$TARGET_HOST:$TARGET_DIR/.doc/"
rsync "${rsync_args[@]}" README.md "$TARGET_HOST:$TARGET_DIR/README.md"

if [[ "$INCLUDE_CONFIG" -eq 1 ]]; then
    ssh "$TARGET_HOST" "mkdir -p '$TARGET_DIR/config'"
    rsync "${rsync_args[@]}" config/ "$TARGET_HOST:$TARGET_DIR/config/"
fi

if [[ "$DRY_RUN" -eq 1 ]]; then
    exit 0
fi

printf 'revision=%s\nbranch=%s\ndirty=%s\ndeployed_at=%s\n' \
    "$BUILD_REVISION" "$BUILD_BRANCH" "$BUILD_DIRTY" "$BUILD_DEPLOYED_AT" |
    ssh "$TARGET_HOST" "cat > '$TARGET_DIR/BUILD'"

ssh "$TARGET_HOST" "cd '$TARGET_DIR' && perl -c scripts/host_manager.pl >/dev/null"

if [[ "$RESTART" -eq 1 ]]; then
    ssh "$TARGET_HOST" "sudo -n systemctl restart host-manager && systemctl is-active host-manager >/dev/null"
fi

ssh "$TARGET_HOST" "curl -fsS http://127.0.0.1:8088/healthz >/dev/null"
echo "Deployed to $TARGET_HOST:$TARGET_DIR"