11#! /bin/bash
22set -e
3+
4+ # Configuration - matches spin defaults
5+ SPIN_ANSIBLE_IMAGE=" ${SPIN_ANSIBLE_IMAGE:- docker.io/ serversideup/ ansible-core: 2.18-alpine} "
6+ SPIN_USER_ID=" ${SPIN_USER_ID:- $(id -u)} "
7+ SPIN_GROUP_ID=" ${SPIN_GROUP_ID:- $(id -g)} "
8+ SPIN_RUN_AS_USER=" ${SPIN_RUN_AS_USER:- $(whoami)} "
9+
310show_help () {
411 cat << EOF
512Usage: ./dev.sh [OPTIONS] [-- ANSIBLE_ARGS]
613
714Development script to build, install, and run the Spin Ansible collection.
815
16+ By default, this script runs Ansible in Docker to match how "spin provision" works.
17+ Use --local-ansible to run with your system's Ansible instead.
18+
919Options:
1020 -h, --help Show this help message
21+ --local-ansible Use system Ansible instead of Docker (for debugging)
1122 --debug Enable debug output (ANSIBLE_STDOUT_CALLBACK=debug)
1223 --ask-vault-pass Prompt for vault password (for encrypted .spin.yml)
1324 --vault-password-file FILE Use FILE as the vault password file
@@ -16,9 +27,11 @@ Environment Variables:
1627 ANSIBLE_WORK_DIR Working directory (default: current directory)
1728 ANSIBLE_VARIABLE_FILE_NAME Variable file name (default: .spin.yml)
1829 ANSIBLE_VARIABLE_FILEPATH Full path to variable file
30+ SPIN_ANSIBLE_IMAGE Docker image to use (default: serversideup/ansible-core:2.18-alpine)
1931
2032Examples:
21- ./dev.sh # Run with defaults
33+ ./dev.sh # Run with Docker (default)
34+ ./dev.sh --local-ansible # Run with system Ansible
2235 ./dev.sh --debug # Run with debug output
2336 ./dev.sh --vault-password-file .vault-password # Use encrypted .spin.yml
2437 ./dev.sh --ask-vault-pass # Prompt for vault password
2841}
2942
3043# Initialize variables
44+ use_docker=true
3145vault_args=()
46+ docker_vault_args=()
3247extra_arguments=()
48+ debug_mode=false
3349
3450# Parse command line arguments
3551while [[ $# -gt 0 ]]; do
@@ -38,16 +54,23 @@ while [[ $# -gt 0 ]]; do
3854 show_help
3955 exit 0
4056 ;;
57+ --local-ansible)
58+ use_docker=false
59+ shift
60+ ;;
4161 --debug)
42- export ANSIBLE_STDOUT_CALLBACK=debug
62+ debug_mode=true
4363 shift
4464 ;;
4565 --ask-vault-pass)
4666 vault_args+=(" --ask-vault-pass" )
67+ docker_vault_args+=(" --ask-vault-pass" )
4768 shift
4869 ;;
4970 --vault-password-file)
5071 vault_args+=(" --vault-password-file" " $2 " )
72+ # For Docker, we'll handle this separately since the path needs to be inside the container
73+ docker_vault_args+=(" --vault-password-file" " /ansible/$( basename " $2 " ) " )
5174 shift 2
5275 ;;
5376 --)
@@ -63,22 +86,98 @@ while [[ $# -gt 0 ]]; do
6386done
6487
6588# Set environment variables
66- export ANSIBLE_WORK_DIR=" ${ANSIBLE_WORK_DIR:- $(pwd)} "
67- export ANSIBLE_VARIABLE_FILE_NAME=" ${ANSIBLE_VARIABLE_FILE_NAME:- " .spin.yml" } "
68- export ANSIBLE_VARIABLE_FILEPATH=" ${ANSIBLE_VARIABLE_FILEPATH:- " ${ANSIBLE_WORK_DIR} /${ANSIBLE_VARIABLE_FILE_NAME} " } "
89+ ANSIBLE_WORK_DIR=" ${ANSIBLE_WORK_DIR:- $(pwd)} "
90+ ANSIBLE_VARIABLE_FILE_NAME=" ${ANSIBLE_VARIABLE_FILE_NAME:- " .spin.yml" } "
91+ ANSIBLE_VARIABLE_FILEPATH=" ${ANSIBLE_VARIABLE_FILEPATH:- " ${ANSIBLE_WORK_DIR} /${ANSIBLE_VARIABLE_FILE_NAME} " } "
6992
70- variable_file_path=" ${ANSIBLE_VARIABLE_FILEPATH} "
93+ # Get the directory where this script lives (the collection source)
94+ SCRIPT_DIR=" $( cd " $( dirname " ${BASH_SOURCE[0]} " ) " && pwd) "
7195
72- # Build and install the collection
96+ # Build the collection
7397set -x
74- version=$( awk ' /version:/ {print $2; exit}' galaxy.yml)
75- ansible-galaxy collection build --force
76- ansible-galaxy collection install " serversideup-spin-${version} .tar.gz" --force
77-
78- # Run the playbook
79- ansible-playbook \
80- -i plugins/inventory/spin-dynamic-inventory.sh \
81- playbooks/provision.yml \
82- " ${vault_args[@]} " \
83- --extra-vars " @${variable_file_path} " \
84- " ${extra_arguments[@]} "
98+ version=$( awk ' /version:/ {print $2; exit}' " ${SCRIPT_DIR} /galaxy.yml" )
99+ ansible-galaxy collection build " ${SCRIPT_DIR} " --output-path " ${SCRIPT_DIR} " --force
100+
101+ if [[ " $use_docker " == true ]]; then
102+ # Create a temporary directory for the collection installation
103+ COLLECTIONS_PATH=$( mktemp -d)
104+ trap " rm -rf $COLLECTIONS_PATH " EXIT
105+
106+ # Install the collection AND its dependencies to the temporary directory
107+ # --force-with-deps ensures dependencies are installed even if they exist elsewhere
108+ ansible-galaxy collection install " ${SCRIPT_DIR} /serversideup-spin-${version} .tar.gz" \
109+ -p " $COLLECTIONS_PATH " --force --force-with-deps
110+
111+ # Build Docker arguments
112+ docker_args=(
113+ " --rm" " -it"
114+ " -e" " PUID=${SPIN_USER_ID} "
115+ " -e" " PGID=${SPIN_GROUP_ID} "
116+ " -e" " RUN_AS_USER=${SPIN_RUN_AS_USER} "
117+ " -e" " ANSIBLE_FORCE_COLOR=1"
118+ " -v" " ${COLLECTIONS_PATH} :/etc/ansible/collections"
119+ " -v" " ${ANSIBLE_WORK_DIR} :/ansible"
120+ " -w" " /ansible"
121+ )
122+
123+ # Add debug environment variable if requested
124+ if [[ " $debug_mode " == true ]]; then
125+ docker_args+=(" -e" " ANSIBLE_STDOUT_CALLBACK=debug" )
126+ fi
127+
128+ # Mount SSH directory if it exists
129+ if [[ -d " $HOME /.ssh" ]]; then
130+ docker_args+=(" -v" " $HOME /.ssh/:/ssh/:ro" )
131+ # Create known_hosts if it doesn't exist
132+ if [[ ! -f " $HOME /.ssh/known_hosts" ]]; then
133+ touch " $HOME /.ssh/known_hosts"
134+ fi
135+ docker_args+=(" -v" " $HOME /.ssh/known_hosts:/ssh/known_hosts:rw" )
136+ fi
137+
138+ # Mount SSH Agent based on OS
139+ if [[ -n " $SSH_AUTH_SOCK " ]]; then
140+ case " $( uname -s) " in
141+ Darwin)
142+ # macOS
143+ docker_args+=(
144+ " -v" " /run/host-services/ssh-auth.sock:/run/host-services/ssh-auth.sock"
145+ " -e" " SSH_AUTH_SOCK=/run/host-services/ssh-auth.sock"
146+ )
147+ ;;
148+ Linux)
149+ # Linux (including WSL2)
150+ docker_args+=(
151+ " -v" " $SSH_AUTH_SOCK :$SSH_AUTH_SOCK "
152+ " -e" " SSH_AUTH_SOCK=$SSH_AUTH_SOCK "
153+ )
154+ ;;
155+ esac
156+ fi
157+
158+ # Run Ansible in Docker
159+ docker run " ${docker_args[@]} " \
160+ " $SPIN_ANSIBLE_IMAGE " \
161+ ansible-playbook \
162+ serversideup.spin.provision \
163+ --inventory /etc/ansible/collections/ansible_collections/serversideup/spin/plugins/inventory/spin-dynamic-inventory.sh \
164+ " ${docker_vault_args[@]} " \
165+ --extra-vars " @./${ANSIBLE_VARIABLE_FILE_NAME} " \
166+ " ${extra_arguments[@]} "
167+ else
168+ # Local Ansible mode - original behavior
169+ ansible-galaxy collection install " ${SCRIPT_DIR} /serversideup-spin-${version} .tar.gz" --force
170+
171+ # Set debug mode for local Ansible
172+ if [[ " $debug_mode " == true ]]; then
173+ export ANSIBLE_STDOUT_CALLBACK=debug
174+ fi
175+
176+ # Run the playbook locally
177+ ansible-playbook \
178+ -i " ${SCRIPT_DIR} /plugins/inventory/spin-dynamic-inventory.sh" \
179+ " ${SCRIPT_DIR} /playbooks/provision.yml" \
180+ " ${vault_args[@]} " \
181+ --extra-vars " @${ANSIBLE_VARIABLE_FILEPATH} " \
182+ " ${extra_arguments[@]} "
183+ fi
0 commit comments