added the script deboco which is able to create multiple standalone debops controllers
- it automates the creation of standalone debops controllers. A standalone debops controller is a directory that embeds: - its own ansible.debops tree (which contains ipr debops configuration, but also its secret directory) - its own virtualenv - its own reports on debops runs when perfoming operations with this controller - it simplifies some operations like applying a configuration to a new machine work related to https://bugzilla.ipr.univ-rennes.fr/show_bug.cgi?id=3713
This commit is contained in:
parent
e83998ef51
commit
c629be803f
|
@ -0,0 +1,313 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# set -o errexit
|
||||||
|
|
||||||
|
|
||||||
|
## Colors
|
||||||
|
readonly COLOR_RED='\033[0;31m'
|
||||||
|
readonly COLOR_GREEN='\033[0;32m'
|
||||||
|
readonly COLOR_YELLOW='\033[0;33m'
|
||||||
|
readonly COLOR_BLUE='\033[0;34m'
|
||||||
|
readonly COLOR_PURPLE='\033[1;35m'
|
||||||
|
readonly COLOR_RESET='\033[0m'
|
||||||
|
|
||||||
|
|
||||||
|
RETURNCODE_SUCCESS=0
|
||||||
|
RETURNCODE_ERROR=1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
log()
|
||||||
|
{
|
||||||
|
local log_type="$1" # 'debug', 'info', 'warning' or 'error'
|
||||||
|
local message="$2"
|
||||||
|
local message_color=''
|
||||||
|
case "$log_type" in
|
||||||
|
'error')
|
||||||
|
message_color="$COLOR_RED"
|
||||||
|
;;
|
||||||
|
'warning')
|
||||||
|
message_color="$COLOR_YELLOW"
|
||||||
|
;;
|
||||||
|
'info')
|
||||||
|
message_color="$COLOR_BLUE"
|
||||||
|
;;
|
||||||
|
'debug')
|
||||||
|
message_color="$COLOR_PURPLE"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "unexpected log type $log_type"
|
||||||
|
exit "$RETURNCODE_ERROR"
|
||||||
|
esac
|
||||||
|
|
||||||
|
printf "%b : %s\n" "${message_color}${log_type}${COLOR_RESET}" "$message"
|
||||||
|
}
|
||||||
|
|
||||||
|
replace_in_file()
|
||||||
|
{
|
||||||
|
local file_path="$1"
|
||||||
|
local searched_string="$2"
|
||||||
|
local replacement_string="$3"
|
||||||
|
|
||||||
|
log 'debug' "replacing ${searched_string} with ${replacement_string} in $file_path"
|
||||||
|
|
||||||
|
|
||||||
|
local safe_searched_string=$(echo "$searched_string" | tr '"' '\"' | tr '$' '\$')
|
||||||
|
local safe_replacement_string=$(echo "$replacement_string" | tr '"' '\"' | tr '$' '\$')
|
||||||
|
# log 'debug' "safe_searched_string : $safe_searched_string"
|
||||||
|
|
||||||
|
printf 'safe_searched_string: %b\n' "$safe_searched_string"
|
||||||
|
|
||||||
|
grep -q "$safe_searched_string" "$file_path"
|
||||||
|
if [ $? != "$RETURNCODE_SUCCESS" ]
|
||||||
|
then
|
||||||
|
log 'error' "failed to find $safe_searched_string in $file_path"
|
||||||
|
return $RETURNCODE_ERROR
|
||||||
|
fi
|
||||||
|
|
||||||
|
# log 'debug' "searching a separator"
|
||||||
|
|
||||||
|
local sep=''
|
||||||
|
for sep in '/' '|' '@'
|
||||||
|
do
|
||||||
|
if $(echo "$safe_searched_string" | grep -q "$sep") || $(echo "$safe_replacement_string" | grep -q "$sep")
|
||||||
|
then
|
||||||
|
sep=''
|
||||||
|
else
|
||||||
|
# found a suitable separator for use in sed
|
||||||
|
log 'debug' "found separator: $sep"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
if [ "$sep" = '' ]
|
||||||
|
then
|
||||||
|
log 'error' "failed to find a sed separator suitable for $safe_searched_string and $safe_replacement_string"
|
||||||
|
fi
|
||||||
|
sed -i "s${sep}${safe_searched_string}${sep}${safe_replacement_string}${sep}" "$file_path"
|
||||||
|
|
||||||
|
grep -q "$safe_replacement_string" "$file_path"
|
||||||
|
if [ $? != "$RETURNCODE_SUCCESS" ]
|
||||||
|
then
|
||||||
|
log 'error' "failed to find $safe_replacement_string in $file_path"
|
||||||
|
return $RETURNCODE_ERROR
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
controller__get_local_repos_path()
|
||||||
|
{
|
||||||
|
local debops_controller_path="$1"
|
||||||
|
echo "${debops_controller_path}/ansible.debops.git"
|
||||||
|
}
|
||||||
|
|
||||||
|
controller__get_reports_path()
|
||||||
|
{
|
||||||
|
local debops_controller_path="$1"
|
||||||
|
echo "${debops_controller_path}/reports"
|
||||||
|
}
|
||||||
|
|
||||||
|
controller__get_virtualenv_path()
|
||||||
|
{
|
||||||
|
local debops_controller_path="$1"
|
||||||
|
echo "${debops_controller_path}/debops.venv"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
controller__get_debops_env_path()
|
||||||
|
{
|
||||||
|
local debops_controller_path="$1"
|
||||||
|
echo "${debops_controller_path}/debops-environment"
|
||||||
|
}
|
||||||
|
|
||||||
|
deboco__init()
|
||||||
|
{
|
||||||
|
local debops_controller_path="$1"
|
||||||
|
log 'info' "creating debobs controller in $debops_controller_path"
|
||||||
|
if [ "$debops_controller_path" = '' ]
|
||||||
|
then
|
||||||
|
log 'error' "wrong debops controller path: $debops_controller_path"
|
||||||
|
return "$RETURNCODE_ERROR"
|
||||||
|
fi
|
||||||
|
if [ -d "$debops_controller_path" ]
|
||||||
|
then
|
||||||
|
log 'error' "$debops_controller_path already exists"
|
||||||
|
return "$RETURNCODE_ERROR"
|
||||||
|
fi
|
||||||
|
local local_repos_path=$(controller__get_local_repos_path "$debops_controller_path")
|
||||||
|
local ipr_debops_url='https://git.ipr.univ-rennes.fr/cellinfo/ansible.debops'
|
||||||
|
log 'info' "cloning $ipr_debops_url into $local_repos_path"
|
||||||
|
git clone https://git.ipr.univ-rennes.fr/cellinfo/ansible.debops "$local_repos_path"
|
||||||
|
|
||||||
|
local debops_env_path=$(controller__get_debops_env_path "$debops_controller_path")
|
||||||
|
|
||||||
|
local debops_update_script_path="$local_repos_path/bin/update-debops.sh"
|
||||||
|
|
||||||
|
local from_line='readonly DEBOPS_ENVIRONMENT_FILE="${HOME}/.config/debops/environment"'
|
||||||
|
# local from_line='readonly DEBOPS_ENVIRONMENT_FILE'
|
||||||
|
local to_line="readonly DEBOPS_ENVIRONMENT_FILE=${debops_env_path}"
|
||||||
|
log 'info' "replacing $from_line with $to_line in $debops_update_script_path so that the script uses a debops environment specific to this controller"
|
||||||
|
replace_in_file "$debops_update_script_path" "$from_line" "$to_line"
|
||||||
|
if [ $? != "$RETURNCODE_SUCCESS" ]
|
||||||
|
then
|
||||||
|
return $RETURNCODE_ERROR
|
||||||
|
fi
|
||||||
|
|
||||||
|
local bug_3678_is_fixed='false'
|
||||||
|
if [ "$bug_3678_is_fixed" = 'false' ]
|
||||||
|
then
|
||||||
|
log 'warning' "disabling pip update in $debops_update_script_path because of https://bugzilla.ipr.univ-rennes.fr/show_bug.cgi?id=3678"
|
||||||
|
replace_in_file "$debops_update_script_path" \
|
||||||
|
'python -m pip install --quiet --requirement "${PIP_PKG_LIST}" --upgrade' \
|
||||||
|
'# python -m pip install --quiet --requirement "${PIP_PKG_LIST}" --upgrade'
|
||||||
|
if [ $? != "$RETURNCODE_SUCCESS" ]
|
||||||
|
then
|
||||||
|
return $RETURNCODE_ERROR
|
||||||
|
fi
|
||||||
|
|
||||||
|
replace_in_file "$debops_update_script_path" \
|
||||||
|
'|| error_message "Error with pip packages upgrade ' \
|
||||||
|
'# || error_message "Error with pip packages upgrade '
|
||||||
|
if [ $? != "$RETURNCODE_SUCCESS" ]
|
||||||
|
then
|
||||||
|
return $RETURNCODE_ERROR
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
local virtual_env_path=$(controller__get_virtualenv_path "$debops_controller_path")
|
||||||
|
# no need to call update-debops.sh since update-dev.sh does it
|
||||||
|
DEBOPS_VENV="$virtual_env_path" "$local_repos_path/bin/update-dev.sh"
|
||||||
|
}
|
||||||
|
|
||||||
|
deboco__update()
|
||||||
|
{
|
||||||
|
local debops_controller_path="$1"
|
||||||
|
log 'info' "updating debobs controller in $debops_controller_path"
|
||||||
|
|
||||||
|
reports_path="$(controller__get_reports_path "$debops_controller_path")"
|
||||||
|
mkdir -p "${reports_path}"
|
||||||
|
report_file_path=${reports_path}/$(date --iso=seconds)-init-${target_host_fqdn}
|
||||||
|
|
||||||
|
local local_repos_path=$(controller__get_local_repos_path "$debops_controller_path")
|
||||||
|
local virtual_env_path=$(controller__get_virtualenv_path "$debops_controller_path")
|
||||||
|
|
||||||
|
log info "updating repository $local_repos_path"
|
||||||
|
pushd "$local_repos_path"
|
||||||
|
git pull | tee --append ${report_file_path}
|
||||||
|
popd
|
||||||
|
|
||||||
|
log info "updating debops itself in $virtual_env_path"
|
||||||
|
DEBOPS_VENV="$virtual_env_path" "$local_repos_path/bin/update-dev.sh" | tee --append ${report_file_path}
|
||||||
|
}
|
||||||
|
|
||||||
|
deboco__configure_machine()
|
||||||
|
{
|
||||||
|
local debops_controller_path="$1"
|
||||||
|
local target_host_fqdn="$2" # the machine on which we want to install debops bootstrap, eg alambix-108.ipr.univ-rennes.fr
|
||||||
|
log 'info' "configuring $machine_fqdn using debobs controller $debops_controller_path"
|
||||||
|
|
||||||
|
local error_code=$RETURNCODE_SUCCESS
|
||||||
|
|
||||||
|
reports_path="$(controller__get_reports_path "$debops_controller_path")"
|
||||||
|
mkdir -p "${reports_path}"
|
||||||
|
report_file_path=${reports_path}/$(date --iso=seconds)-init-${target_host_fqdn}
|
||||||
|
echo "installing debops bootstrap on ${target_host_fqdn} (report stored in ${report_file_path})"
|
||||||
|
|
||||||
|
local local_repos_path=$(controller__get_local_repos_path "$debops_controller_path")
|
||||||
|
local virtual_env_path=$(controller__get_virtualenv_path "$debops_controller_path")
|
||||||
|
|
||||||
|
pushd "$local_repos_path"
|
||||||
|
source "$virtual_env_path/bin/activate"
|
||||||
|
ANS_HOST=$(echo ${target_host_fqdn} | sed -E 's/\.univ-rennes[1]?\.fr$//')
|
||||||
|
log 'debug' "ANS_HOST=${ANS_HOST}"
|
||||||
|
debops run bootstrap-ldap -l "${ANS_HOST:-/dev/null}" | tee --append ${report_file_path}
|
||||||
|
if [ $? = "$RETURNCODE_SUCCESS" ]
|
||||||
|
then
|
||||||
|
log 'info' "debops bootstrap installed successfully. Now applying the configuration on ${target_host_fqdn}"
|
||||||
|
debops run site --limit "${ANS_HOST:-/dev/null}" | tee --append ${report_file_path}
|
||||||
|
if [ $? != "$RETURNCODE_SUCCESS" ]
|
||||||
|
then
|
||||||
|
log 'error' 'debops run site failed'
|
||||||
|
error_code="$RETURNCODE_ERROR"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log 'error' 'debops run bootstrap-ldap failed'
|
||||||
|
error_code="$RETURNCODE_ERROR"
|
||||||
|
fi
|
||||||
|
deactivate
|
||||||
|
popd
|
||||||
|
return "$error_code"
|
||||||
|
}
|
||||||
|
|
||||||
|
deboco__update_machine()
|
||||||
|
{
|
||||||
|
local debops_controller_path="$1"
|
||||||
|
local machine_fqdn="$2" # eg alambix-108.ipr.univ-rennes.fr
|
||||||
|
log 'info' "updating $machine_fqdn using debobs controller $debops_controller_path"
|
||||||
|
|
||||||
|
local error_code=$RETURNCODE_SUCCESS
|
||||||
|
|
||||||
|
reports_path="$(controller__get_reports_path "$debops_controller_path")"
|
||||||
|
mkdir -p "${reports_path}"
|
||||||
|
report_file_path=${reports_path}/$(date --iso=seconds)-init-${target_host_fqdn}
|
||||||
|
echo "installing debops bootstrap on ${target_host_fqdn} (report stored in ${report_file_path})"
|
||||||
|
|
||||||
|
local local_repos_path=$(controller__get_local_repos_path "$debops_controller_path")
|
||||||
|
local virtual_env_path=$(controller__get_virtualenv_path "$debops_controller_path")
|
||||||
|
|
||||||
|
pushd "$local_repos_path"
|
||||||
|
source "$virtual_env_path/bin/activate"
|
||||||
|
ANS_HOST=$(echo ${target_host_fqdn} | sed -E 's/\.univ-rennes[1]?\.fr$//')
|
||||||
|
log 'debug' "ANS_HOST=${ANS_HOST}"
|
||||||
|
debops run site --limit "${ANS_HOST:-/dev/null}" | tee --append ${report_file_path}
|
||||||
|
if [ $? != "$RETURNCODE_SUCCESS" ]
|
||||||
|
then
|
||||||
|
log 'error' 'debops run site failed'
|
||||||
|
error_code="$RETURNCODE_ERROR"
|
||||||
|
fi
|
||||||
|
deactivate
|
||||||
|
popd
|
||||||
|
return "$error_code"
|
||||||
|
}
|
||||||
|
|
||||||
|
deboco_print_usage()
|
||||||
|
{
|
||||||
|
echo "$0 performs a debops controller operation"
|
||||||
|
echo
|
||||||
|
echo "usage:"
|
||||||
|
echo " $0 <command>"
|
||||||
|
echo
|
||||||
|
echo "where:"
|
||||||
|
echo " <command> is one of:"
|
||||||
|
echo " init <debobs-controller-path>"
|
||||||
|
echo " creates a debops controller in <debobs-controller-path>"
|
||||||
|
echo
|
||||||
|
echo " update <debobs-controller-path>"
|
||||||
|
echo " updates the debops controller in <debobs-controller-path>"
|
||||||
|
echo
|
||||||
|
echo " configure-machine <debobs-controller-path> <machine-fqdn>"
|
||||||
|
echo " configures the machine <machine-fqdn> using the debops controller in <debobs-controller-path>"
|
||||||
|
echo
|
||||||
|
echo " update-machine <debobs-controller-path> <machine-fqdn>"
|
||||||
|
echo " updates the machine <machine-fqdn> using the debops controller in <debobs-controller-path>"
|
||||||
|
}
|
||||||
|
|
||||||
|
deboco()
|
||||||
|
{
|
||||||
|
local command_name="$1"
|
||||||
|
shift
|
||||||
|
if type "deboco__${command_name}" >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
"deboco__${command_name}" "$@"
|
||||||
|
return $?
|
||||||
|
else
|
||||||
|
log 'error' "unknown command: ${command_name}"
|
||||||
|
deboco_print_usage
|
||||||
|
return "$RETURNCODE_ERROR"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
deboco $@
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue