From bca3d5d1fcacd58a785fcd1c5bcfa3a3fba5dae8 Mon Sep 17 00:00:00 2001 From: Zachary Lentz Date: Tue, 26 Mar 2024 17:56:02 -0700 Subject: [PATCH 1/8] ENH: start script to help check when we need to activate an env --- scripts/ensure_python.sh | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100755 scripts/ensure_python.sh diff --git a/scripts/ensure_python.sh b/scripts/ensure_python.sh new file mode 100755 index 0000000..ace2501 --- /dev/null +++ b/scripts/ensure_python.sh @@ -0,0 +1,38 @@ +#!/bin/bash +# This is meant to be sourced. +# Helper script for ensuring we have a suitable python environment loaded. +# Needs to make sure the following binaries are available: +# - ansible-playbook +# Needs to make sure the following ansible modules are available: +# - community.general.xml +# - community.general.sysrc +# Needs to make sure the following libraries are importable: +# - lxml +# - ruamel.yaml +# If any of these are missing, try to load the prepared python env. + +ISSUES=() + +if [ ! -x "$(command -v ansible-playbook)" ]; then + ISSUES+=( "Missing ansible-playbook" ) +elif [ ! -x "$(command -v ansible-doc)" ]; then + ISSUES+=( "Missing ansible-doc" ) +else + for module in community.general.xml community.general.sysrc; do + if [ "$(ansible-doc -j "${module}")" = "{}" ]; then + ISSUES+=( "Missing ${module} ansible module" ) + fi + done +fi +if [ ! -x "$(command -v python)" ]; then + ISSUES+=( "Missing Python!" ) +else + for module in lxml ruamel.yaml; do + if ! python -c "import ${module}"; then + ISSUES+=( "Missing ${module} python module" ) + fi + done +fi +for iss in "${ISSUES[@]}"; do + echo "${iss}" +done From 4d45111f31bb3c5cb3afdf1abab4b55040ffc52e Mon Sep 17 00:00:00 2001 From: Zachary Lentz Date: Wed, 27 Mar 2024 09:55:27 -0700 Subject: [PATCH 2/8] MAINT: simplify the python env script, checking is too slow --- scripts/ensure_python.sh | 37 ++----------------------------------- 1 file changed, 2 insertions(+), 35 deletions(-) diff --git a/scripts/ensure_python.sh b/scripts/ensure_python.sh index ace2501..0edc6da 100755 --- a/scripts/ensure_python.sh +++ b/scripts/ensure_python.sh @@ -1,38 +1,5 @@ #!/bin/bash # This is meant to be sourced. -# Helper script for ensuring we have a suitable python environment loaded. -# Needs to make sure the following binaries are available: -# - ansible-playbook -# Needs to make sure the following ansible modules are available: -# - community.general.xml -# - community.general.sysrc -# Needs to make sure the following libraries are importable: -# - lxml -# - ruamel.yaml -# If any of these are missing, try to load the prepared python env. +# Helper script for activating the correct python environment. -ISSUES=() - -if [ ! -x "$(command -v ansible-playbook)" ]; then - ISSUES+=( "Missing ansible-playbook" ) -elif [ ! -x "$(command -v ansible-doc)" ]; then - ISSUES+=( "Missing ansible-doc" ) -else - for module in community.general.xml community.general.sysrc; do - if [ "$(ansible-doc -j "${module}")" = "{}" ]; then - ISSUES+=( "Missing ${module} ansible module" ) - fi - done -fi -if [ ! -x "$(command -v python)" ]; then - ISSUES+=( "Missing Python!" ) -else - for module in lxml ruamel.yaml; do - if ! python -c "import ${module}"; then - ISSUES+=( "Missing ${module} python module" ) - fi - done -fi -for iss in "${ISSUES[@]}"; do - echo "${iss}" -done +source /cds/group/pcds/pyps/conda/venvs/ansible/bin/activate From 2be255907cfb70b06ba1343e570cc55af2aed8cc Mon Sep 17 00:00:00 2001 From: Zachary Lentz Date: Wed, 27 Mar 2024 09:56:00 -0700 Subject: [PATCH 3/8] ENH: rename python activation script --- scripts/{ensure_python.sh => activate_python.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename scripts/{ensure_python.sh => activate_python.sh} (100%) diff --git a/scripts/ensure_python.sh b/scripts/activate_python.sh similarity index 100% rename from scripts/ensure_python.sh rename to scripts/activate_python.sh From 60d6e57d1ec59c14d5317421f1c2c3e98265b1eb Mon Sep 17 00:00:00 2001 From: Zachary Lentz Date: Wed, 27 Mar 2024 09:58:47 -0700 Subject: [PATCH 4/8] ENH: always activate the python env --- scripts/bootstrap_plc.sh | 8 +++----- scripts/provision_plc.sh | 6 ++---- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/scripts/bootstrap_plc.sh b/scripts/bootstrap_plc.sh index 0d5bd7b..fcc2afb 100755 --- a/scripts/bootstrap_plc.sh +++ b/scripts/bootstrap_plc.sh @@ -22,11 +22,6 @@ fi HOSTNAME="${1}" shift -# Activate python env if we don't have ansible on the path -if [ ! -x ansible-playbook ]; then - source /cds/group/pcds/pyps/conda/venvs/ansible/bin/activate -fi - USERNAME="${PLC_USERNAME:=Administrator}" THIS_SCRIPT="$(realpath "${0}")" THIS_DIR="$(dirname "${THIS_SCRIPT}")" @@ -34,6 +29,9 @@ ANSIBLE_ROOT="$(realpath "${THIS_DIR}/..")" INVENTORY_PATH="${ANSIBLE_ROOT}/inventory/plcs.yaml" SSH_CONFIG="${ANSIBLE_ROOT}/ssh_config" +# Use the correct python env +source "${THIS_DIR}"/activate_python.sh + # Check the inventory for your plc if grep -q "${HOSTNAME}:" "${INVENTORY_PATH}"; then echo "Found ${HOSTNAME} in ${INVENTORY_PATH}." diff --git a/scripts/provision_plc.sh b/scripts/provision_plc.sh index bce4699..6834d1d 100755 --- a/scripts/provision_plc.sh +++ b/scripts/provision_plc.sh @@ -22,10 +22,8 @@ THIS_SCRIPT="$(realpath "${0}")" THIS_DIR="$(dirname "${THIS_SCRIPT}")" ANSIBLE_ROOT="$(realpath "${THIS_DIR}/..")" -# Activate python env if we don't have ansible on the path -if [ ! -x ansible-playbook ]; then - source /cds/group/pcds/pyps/conda/venvs/ansible/bin/activate -fi +# Use the correct python env +source "${THIS_DIR}"/activate_python.sh # Register the ssh key with the ssh agent if needed source "${THIS_DIR}/ssh_agent_helper.sh" From 4dbdf4984485949ea9ae35dddd2c60f73a7159b8 Mon Sep 17 00:00:00 2001 From: Zachary Lentz Date: Wed, 27 Mar 2024 10:08:30 -0700 Subject: [PATCH 5/8] ENH: add failure state and override for python env --- scripts/activate_python.sh | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) mode change 100755 => 100644 scripts/activate_python.sh diff --git a/scripts/activate_python.sh b/scripts/activate_python.sh old mode 100755 new mode 100644 index 0edc6da..33883a4 --- a/scripts/activate_python.sh +++ b/scripts/activate_python.sh @@ -1,5 +1,13 @@ #!/bin/bash # This is meant to be sourced. # Helper script for activating the correct python environment. +# Sets a default env or you can provide your own activate path for testing -source /cds/group/pcds/pyps/conda/venvs/ansible/bin/activate +DEFAULT_ENV=/cds/group/pcds/pyps/conda/venvs/ansible/bin/activate + +if [ -f "${ANSIBLE_PYTHON_ACTIVATE:=${DEFAULT_ENV}}" ]; then + source "${ANSIBLE_PYTHON_ACTIVATE}" +else + echo "No Python activation script found at ${ANSIBLE_PYTHON_ACTIVATE}" + return 1 +fi From abb38a5a0608343c25706095f4070af6df77103d Mon Sep 17 00:00:00 2001 From: Zachary Lentz Date: Wed, 27 Mar 2024 10:08:53 -0700 Subject: [PATCH 6/8] MAINT: sourceable script does not need to be executable --- scripts/ssh_agent_helper.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 scripts/ssh_agent_helper.sh diff --git a/scripts/ssh_agent_helper.sh b/scripts/ssh_agent_helper.sh old mode 100755 new mode 100644 From b03718cf7dea8ec188be84932aee4f13aa048c98 Mon Sep 17 00:00:00 2001 From: Zachary Lentz Date: Wed, 27 Mar 2024 10:31:03 -0700 Subject: [PATCH 7/8] ENH/MAINT: rework the error handling to avoid bad states --- scripts/bootstrap_plc.sh | 5 ++--- scripts/dry_run.sh | 2 ++ scripts/provision_plc.sh | 7 ++++--- scripts/setup_new_plc.sh | 5 ++--- scripts/ssh_agent_helper.sh | 3 +++ scripts/update_admin_pass.sh | 5 ++--- 6 files changed, 15 insertions(+), 12 deletions(-) diff --git a/scripts/bootstrap_plc.sh b/scripts/bootstrap_plc.sh index fcc2afb..289fa81 100755 --- a/scripts/bootstrap_plc.sh +++ b/scripts/bootstrap_plc.sh @@ -50,6 +50,8 @@ fi # Register the ssh key with the ssh agent if needed source "${THIS_DIR}/ssh_agent_helper.sh" +# Stop the ssh agent at exit if we started it here +trap ssh_agent_helper_cleanup EXIT # Send the public key to the plc, if it has not already been done ssh-copy-id -i "${SSH_KEY_FILENAME}" -o PreferredAuthentications=keyboard-interactive "${USERNAME}@${HOSTNAME}" @@ -91,6 +93,3 @@ scp -F "${SSH_CONFIG}" -i "${SSH_KEY_FILENAME}" -r "${SOURCE_DIR}" "${USERNAME}@ # Run the local install version of the bootstrap playbook ansible-playbook "${ANSIBLE_ROOT}/tcbsd-bootstrap-from-local-playbook.yaml" --extra-vars "target=${HOSTNAME} ansible_ssh_private_key_file=${SSH_KEY_FILENAME}" --ask-become-pass "$@" - -# Stop the ssh agent if we started it here -ssh_agent_helper_cleanup diff --git a/scripts/dry_run.sh b/scripts/dry_run.sh index 56dab27..d5257ed 100755 --- a/scripts/dry_run.sh +++ b/scripts/dry_run.sh @@ -10,6 +10,8 @@ # $ ./dry_run.sh tst_all # # Groups are defined in the inventory file. +set -e + if [ -z "${1}" ]; then echo "Ansible target required" exit 1 diff --git a/scripts/provision_plc.sh b/scripts/provision_plc.sh index 6834d1d..2590515 100755 --- a/scripts/provision_plc.sh +++ b/scripts/provision_plc.sh @@ -10,6 +10,8 @@ # $ ./provision_plc.sh tst_all # # Groups are defined in the inventory file. +set -e + if [ -z "${1}" ]; then echo "Ansible target required" exit 1 @@ -27,12 +29,11 @@ source "${THIS_DIR}"/activate_python.sh # Register the ssh key with the ssh agent if needed source "${THIS_DIR}/ssh_agent_helper.sh" +# Stop the ssh agent at exit if we started it here +trap ssh_agent_helper_cleanup EXIT # Run the provision playbook ansible-playbook "${ANSIBLE_ROOT}/tcbsd-provision-playbook.yaml" --extra-vars "target=${TARGET} ansible_ssh_private_key_file=${SSH_KEY_FILENAME}" --ask-become-pass "$@" -# Stop the ssh agent if we started it here -ssh_agent_helper_cleanup - # Prompt to update deployment docs "${THIS_DIR}"/docs_prompt.sh diff --git a/scripts/setup_new_plc.sh b/scripts/setup_new_plc.sh index d8774f1..74e007f 100755 --- a/scripts/setup_new_plc.sh +++ b/scripts/setup_new_plc.sh @@ -18,10 +18,9 @@ THIS_DIR="$(dirname "${THIS_SCRIPT}")" # Register the ssh key with the ssh agent if needed source "${THIS_DIR}/ssh_agent_helper.sh" +# Stop the ssh agent at exit if we started it here +trap ssh_agent_helper_cleanup EXIT # Run both playbooks and one-time pre-playbook setup "${THIS_DIR}"/bootstrap_plc.sh "${1}" "${THIS_DIR}"/provision_plc.sh "${1}" - -# Stop the ssh agent if we started it here -ssh_agent_helper_cleanup diff --git a/scripts/ssh_agent_helper.sh b/scripts/ssh_agent_helper.sh index 8c4ff29..f904fa9 100644 --- a/scripts/ssh_agent_helper.sh +++ b/scripts/ssh_agent_helper.sh @@ -7,6 +7,7 @@ # Expected usage: # # source ssh_agent_helper.sh +set -e SSH_KEY_FILENAME="${HOME}/.ssh/tcbsd_key_rsa" export SSH_KEY_FILENAME @@ -28,6 +29,8 @@ ssh_agent_helper_cleanup() { fi } export ssh_agent_helper_cleanup +# Clean up immediately if something in this script fails +trap ssh_agent_helper_cleanup ERR # Create an ssh key, if it does not already exist if [ ! -f "${SSH_KEY_FILENAME}" ]; then diff --git a/scripts/update_admin_pass.sh b/scripts/update_admin_pass.sh index 1b2eb63..356b881 100755 --- a/scripts/update_admin_pass.sh +++ b/scripts/update_admin_pass.sh @@ -26,11 +26,10 @@ SSH_CONFIG="${ANSIBLE_ROOT}/ssh_config" # Register the ssh key with the ssh agent if needed source "${THIS_DIR}/ssh_agent_helper.sh" +# Stop the ssh agent at exit if we started it here +trap ssh_agent_helper_cleanup EXIT for HOSTNAME in "$@"; do echo "Logging into ${HOSTNAME}" ssh -F "${SSH_CONFIG}" -i "${SSH_KEY_FILENAME}" -t "${USERNAME}@${HOSTNAME}" passwd done - -# Stop the ssh agent if we started it here -ssh_agent_helper_cleanup From f0305a61534ebeb4ba87c2ff90ae73cbc7719b05 Mon Sep 17 00:00:00 2001 From: Zachary Lentz Date: Wed, 27 Mar 2024 11:14:46 -0700 Subject: [PATCH 8/8] ENH: bring paths into sourceable script, always cd to appease ansible --- scripts/bootstrap_plc.sh | 5 ++--- scripts/paths.sh | 18 ++++++++++++++++++ scripts/provision_plc.sh | 2 +- scripts/update_admin_pass.sh | 3 +-- 4 files changed, 22 insertions(+), 6 deletions(-) create mode 100644 scripts/paths.sh diff --git a/scripts/bootstrap_plc.sh b/scripts/bootstrap_plc.sh index 289fa81..9231b91 100755 --- a/scripts/bootstrap_plc.sh +++ b/scripts/bootstrap_plc.sh @@ -23,11 +23,10 @@ HOSTNAME="${1}" shift USERNAME="${PLC_USERNAME:=Administrator}" + THIS_SCRIPT="$(realpath "${0}")" THIS_DIR="$(dirname "${THIS_SCRIPT}")" -ANSIBLE_ROOT="$(realpath "${THIS_DIR}/..")" -INVENTORY_PATH="${ANSIBLE_ROOT}/inventory/plcs.yaml" -SSH_CONFIG="${ANSIBLE_ROOT}/ssh_config" +source "${THIS_DIR}"/paths.sh # Use the correct python env source "${THIS_DIR}"/activate_python.sh diff --git a/scripts/paths.sh b/scripts/paths.sh new file mode 100644 index 0000000..46fd047 --- /dev/null +++ b/scripts/paths.sh @@ -0,0 +1,18 @@ +#!/bin/bash +# Sourceable script to set common vars for the various scripts. +# This sets a bunch of environment variables related to known paths +# and puts us into the ansible directory for the duration of the +# encapsulating script. +set -e + +THIS_SCRIPT="$(realpath "${BASH_SOURCE[0]}")" +THIS_DIR="$(dirname "${THIS_SCRIPT}")" + +ANSIBLE_ROOT="$(realpath "${THIS_DIR}/..")" +export ANSIBLE_ROOT +INVENTORY_PATH="${ANSIBLE_ROOT}/inventory/plcs.yaml" +export INVENTORY_PATH +SSH_CONFIG="${ANSIBLE_ROOT}/ssh_config" +export SSH_CONFIG + +cd "${ANSIBLE_ROOT}" diff --git a/scripts/provision_plc.sh b/scripts/provision_plc.sh index 2590515..2cf1669 100755 --- a/scripts/provision_plc.sh +++ b/scripts/provision_plc.sh @@ -22,7 +22,7 @@ shift THIS_SCRIPT="$(realpath "${0}")" THIS_DIR="$(dirname "${THIS_SCRIPT}")" -ANSIBLE_ROOT="$(realpath "${THIS_DIR}/..")" +source "${THIS_DIR}"/paths.sh # Use the correct python env source "${THIS_DIR}"/activate_python.sh diff --git a/scripts/update_admin_pass.sh b/scripts/update_admin_pass.sh index 356b881..09203ff 100755 --- a/scripts/update_admin_pass.sh +++ b/scripts/update_admin_pass.sh @@ -21,8 +21,7 @@ fi USERNAME="${PLC_USERNAME:=Administrator}" THIS_SCRIPT="$(realpath "${0}")" THIS_DIR="$(dirname "${THIS_SCRIPT}")" -ANSIBLE_ROOT="$(realpath "${THIS_DIR}/..")" -SSH_CONFIG="${ANSIBLE_ROOT}/ssh_config" +source "${THIS_DIR}"/paths.sh # Register the ssh key with the ssh agent if needed source "${THIS_DIR}/ssh_agent_helper.sh"