#!/usr/bin/env bash set -euo pipefail APP_DIR="/opt/containers/ansible-worker" APP_ROOT="${APP_DIR}/app" DATA_DIR="${APP_DIR}/data" SRC_DIR="${APP_DIR}/files" # <-- mounted from host ./files BIN_DIR="${APP_ROOT}/bin" VENV_DIR="${DATA_DIR}/ansible_venv" COLL_BASE="${DATA_DIR}/collections" COLL_NETBOX_DIR="${COLL_BASE}/ansible_collections/netbox/netbox" mkdir -p "$DATA_DIR" "$BIN_DIR" log() { echo "[entrypoint] $*"; } copy_nbplay() { local src="${SRC_DIR}/nbplay" local dst="${BIN_DIR}/nbplay" if [[ -f "$src" ]]; then log "Installing nbplay -> ${dst}" cp -f "$src" "$dst" chmod 0755 "$dst" else log "WARN: nbplay not found at ${src} (skipping)" fi } copy_rmq_client() { local src="${SRC_DIR}/rabbit-client.sh" local dst="${BIN_DIR}/rabbit-client.sh" if [[ -f "$src" ]]; then log "Installing rabbit-client.sh -> ${dst}" cp -f "$src" "$dst" chmod 0755 "$dst" else log "WARN: rabbit-client.sh not found at ${src} (skipping)" fi } copy_playbooks() { local src_dir="${SRC_DIR}/ansible-playbooks" if [[ -d "$src_dir" ]]; then log "Syncing playbooks from ${src_dir} -> ${APP_ROOT}" if command -v rsync >/dev/null 2>&1; then rsync -a --delete "${src_dir}/" "${APP_ROOT}/" else # clean only top-level *.yml in /app (playbooks), then copy find "${APP_ROOT}" -maxdepth 1 -type f -name '*.yml' -exec rm -f {} + cp -a "${src_dir}/." "${APP_ROOT}/" fi else log "WARN: ${src_dir} does not exist (skipping playbooks copy)" fi } provision_pwfile() { local src_yaml="${SRC_DIR}/ssh.yml" local src_txt="${SRC_DIR}/ssh.txt" local dst="${DATA_DIR}/ssh.yml" if [[ -f "$dst" ]]; then log "Found existing pwfile at ${dst} (leaving as-is)" return fi if [[ -f "$src_yaml" ]]; then log "Seeding password vars from ${src_yaml} -> ${dst}" install -m 600 "$src_yaml" "$dst" return fi if [[ -f "$src_txt" ]]; then log "Wrapping plain password ${src_txt} -> ${dst}" local pass pass="$(head -n1 "$src_txt" | tr -d '\r\n')" umask 177 { printf 'ansible_user: %s\n' "${NBPLAY_DEFAULT_USER:-root}" printf 'ansible_ssh_pass: %s\n' "$pass" } > "$dst" return fi log "WARN: no files/ssh.yml or files/ssh.txt found; skipping pwfile seed" } # ---- Copy from mounted files/ (if present) ---- if [[ -d "${SRC_DIR}" ]]; then log "Found source directory: ${SRC_DIR}" copy_nbplay copy_rmq_client copy_playbooks provision_pwfile else log "WARN: Source directory ${SRC_DIR} not present. Did you mount ./files? (see docker-compose.yml)" fi # ---- Venv bootstrap ---- if [[ ! -x "${VENV_DIR}/bin/ansible" ]]; then log "Creating venv in ${VENV_DIR} and installing packages..." python3 -m venv "${VENV_DIR}" "${VENV_DIR}/bin/python" -m pip install --upgrade pip setuptools wheel "${VENV_DIR}/bin/pip" install \ "ansible-core==2.16.*" \ "pytz" \ "pynetbox==7.*" log "venv bootstrap complete." fi # ---- Collections (persistent path) ---- if [[ ! -d "${COLL_NETBOX_DIR}" ]]; then log "Installing netbox.netbox collection into ${COLL_BASE} ..." mkdir -p "${COLL_BASE}" "${VENV_DIR}/bin/ansible-galaxy" collection install netbox.netbox -p "${COLL_BASE}" log "netbox.netbox installed." fi # Put venv first on PATH export PATH="${VENV_DIR}/bin:${PATH}" export TZ=${TZ:-Africa/Johannesburg} log "Startup complete. Executing: $*" exec "$@"