#!/bin/bash # Purpose: detect modified files in config tree and execute # any defined service modifications ################################################################################ set -e set -u # support testsuite FUNCTIONS="${FUNCTIONS:-/usr/share/ngcp-ngcpcfg/functions/}" if ! [ -r "${FUNCTIONS}"/main ] ; then printf "Error: %s/main could not be read. Exiting.\n" "${FUNCTIONS}">&2 exit 1 fi . "${FUNCTIONS}"/main # main script DRYRUN='false' if [[ "${1:-}" == "test" ]] || [[ "${1:-}" == "--dry-run" ]]; then DRYRUN='true' elif [[ -n "${1:-}" ]] ; then log_error "Unsupported option(s) given: $*" log_info "Did you mean '--dry-run'?" exit 1 fi log_debug "DRYRUN = $DRYRUN" TMPFILE="$(mktemp)" log_debug "TMPFILE = $TMPFILE" # unify service calls unifyer() { file="$1" # make sure services are listed just once to # avoid re-execution of services (which will # happen if /etc/foo/ngcpcfg.services exists # and several file inside /etc/foo are modified) if ! grep -q "^${file}$" "$TMPFILE" ; then echo "$file" >> "$TMPFILE" fi } for dir in ${CONFIG_POOL} ; do #shellcheck disable=SC2106 ( if ! [[ "${dir}" =~ ^/ ]] ; then log_error "${dir} is not an absolute path" continue fi cd "${dir}" if [ ! -d .git ] ; then log_info "$dir has no support of .services" continue fi for file in $(git status --porcelain | sed 's/^...//') ; do if [ -r "$file" ] && [ -r "${SERVICES_POOL_BASE}/${dir}/${file}".services ] ; then log_debug "unifyer ${SERVICES_POOL_BASE}/${dir}/${file}.services" unifyer "${SERVICES_POOL_BASE}/${dir}/${file}".services elif [ -r "$file" ] && [ -r "${SERVICES_POOL_BASE}/${dir}/$(dirname "$file")"/ngcpcfg.services ] ; then log_debug "unifyer ${SERVICES_POOL_BASE}/${dir}/$(dirname "$file")/ngcpcfg.services" unifyer "${SERVICES_POOL_BASE}/${dir}/$(dirname "$file")/ngcpcfg.services" fi done ) done exec_wrapper() { if $DRYRUN ; then log_info "TEST MODE: Would execute action for ${line}" return 0 fi log_info "Executing action for $line" if [ -x "$line" ] ; then log_debug "$line" if ! "$line" ; then log_warn "$line returned with error code, continuing anyway." fi elif [ -r "$line" ] ; then log_debug "bash $line" if ! bash "$line" ; then log_warn "$line returned with error code, continuing anyway." fi else log_error "Error: $line could not be read." exit 1 fi } if ! [ -s "$TMPFILE" ] ; then log_debug "No services file(s) reported - nothing to do." exit 0 fi # get rid of "./" and "//" in file names normalize_files() { NORMALIZED_FILES="$(mktemp)" log_debug "NORMALIZED_FILES = $NORMALIZED_FILES" while read line ; do # shellcheck disable=SC2001 echo "$line" | sed -e 's_\./_/_g ; s_//_/_g' >> "${NORMALIZED_FILES}" done < "$TMPFILE" } # restart monit services before the rest (see MT#9971) # restart HA just after monit (see MT#17163) sort_service_list() { SORTED_LIST="$(mktemp)" log_debug "SORTED_LIST = $SORTED_LIST" grep "${SERVICES_POOL_BASE}"/etc/monit/'.*services' "${NORMALIZED_FILES}" > \ "${SORTED_LIST}" || true grep "${SERVICES_POOL_BASE}"/etc/ha.d/'.*services' "${NORMALIZED_FILES}" >> \ "${SORTED_LIST}" || true grep -v "${SERVICES_POOL_BASE}"/etc/monit/'.*services' "${NORMALIZED_FILES}"| \ grep -v "${SERVICES_POOL_BASE}"/etc/ha.d/'.*services' >> \ "${SORTED_LIST}" || true } execute() { while read line ; do exec_wrapper "$line" done < "${SORTED_LIST}" } if [ -d "/run/systemd/system" ]; then log_debug "systemd needs daemon-reload so the unit files loaded are in sync" log_debug "Running: systemctl daemon-reload 2>&1 || true" systemctl daemon-reload 2>&1 || true fi log_debug "normalize_files function" normalize_files log_debug "sort_service_list function" sort_service_list log_debug "execute function" execute if [ -n "${DEBUG:-}" ] ; then log_debug "Not removing temporary files" else rm -f "$TMPFILE" "$NORMALIZED_FILES" "$SORTED_LIST" fi ## END OF FILE #################################################################