Improved module composition including renaming some functions for better self describtion.

This commit is contained in:
m8in
2026-06-19 21:38:20 +02:00
parent 7c8f9e1cfa
commit 478d298b16
2 changed files with 67 additions and 72 deletions
+61 -66
View File
@@ -3,15 +3,56 @@ source /cis/core/base.module.sh
# composition.isRunningOnThisHost COMPOSITION
# composition.printAll
#
# This function prints a list of all compositions, one per line.
function composition.printAll() {
local _COMPOSITIONS
_COMPOSITIONS="${CIS[COMPOSITIONS]:?"composition.printAll(): Missing CIS_COMPOSITIONS"}"
readonly _COMPOSITIONS
local _COMPOSITION_PATH
ls -d1 "${_COMPOSITIONS}"*/ | while read -r _COMPOSITION_PATH; do
# Like dirname: removes tailing '/'
local _COMPOSITION="${_COMPOSITION_PATH%/}"
# Like basename
echo "${_COMPOSITION##*/}"
done
}
# composition.printAllRunningOnThisHost
#
# This function prints a list of all compositions which run or should run on this host, one per line.
# see also: composition.shouldRunOnThisHost
function composition.printAllRunningOnThisHost() {
composition.printAll | while read -r _COMPOSITION; do
composition.shouldRunOnThisHost "${_COMPOSITION}" \
&& echo "${_COMPOSITION}"
done
}
# composition.printAllSyncedByThisHost
#
# This function prints a list of all compositions which should be synced to this host, one per line.
# see also: composition.shouldBeSyncedByThisHost
function composition.printAllSyncedByThisHost() {
composition.printAll | while read -r _COMPOSITION; do
composition.shouldBeSyncedByThisHost "${_COMPOSITION}" \
&& echo "${_COMPOSITION}"
done
}
# composition.shouldRunOnThisHost COMPOSITION
# - COMPOSITION mandatory: "uptime-kuma-prod"
#
# This function checks if the given composition runs or should run on this host.
# Therefore a file 'current-host' defines the the current host where the composition runs.
function composition.isRunningOnThisHost() {
function composition.shouldRunOnThisHost() {
local _COMPOSITION _CURRENTHOST_FILE
_COMPOSITION="${1:?"Missing first parameter COMPOSITION"}"
_CURRENTHOST_FILE="${CIS[COMPOSITIONS]:?"Missing CIS_COMPOSITIONS"}${_COMPOSITION}/current-host"
_COMPOSITION="${1:?"composition.shouldRunOnThisHost(): Missing first parameter COMPOSITION"}"
_CURRENTHOST_FILE="${CIS[COMPOSITIONS]:?"composition.shouldRunOnThisHost(): Missing CIS_COMPOSITIONS"}${_COMPOSITION}/current-host"
readonly _COMPOSITION _CURRENTHOST_FILE
! [ -f "${_CURRENTHOST_FILE}" ] \
@@ -25,16 +66,16 @@ function composition.isRunningOnThisHost() {
return 1
}
# composition.isSyncedByThisHost COMPOSITION
# composition.shouldBeSyncedByThisHost COMPOSITION
# - COMPOSITION mandatory: "uptime-kuma-prod"
#
# This function checks if the given composition is or should be synced to this host.
# Therefore a file 'composition-sync-hosts' defines a list of host, one per line, where the composition should be synced to.
# This host either runs the composition or syncs it.
function composition.isSyncedByThisHost() {
function composition.shouldBeSyncedByThisHost() {
local _COMPOSITION _COMPOSITION_PATH _CURRENTHOST_FILE _SYNCHOSTS_FILE
_COMPOSITION="${1:?"Missing first parameter COMPOSITION"}"
_COMPOSITION_PATH="${CIS[COMPOSITIONS]:?"Missing CIS_COMPOSITIONS"}${_COMPOSITION}/"
_COMPOSITION="${1:?"composition.shouldBeSyncedByThisHost(): Missing first parameter COMPOSITION"}"
_COMPOSITION_PATH="${CIS[COMPOSITIONS]:?"composition.shouldBeSyncedByThisHost(): Missing CIS_COMPOSITIONS"}${_COMPOSITION}/"
_CURRENTHOST_FILE="current-host"
_SYNCHOSTS_FILE="composition-sync-hosts"
readonly _COMPOSITION _COMPOSITION_PATH _CURRENTHOST_FILE _SYNCHOSTS_FILE
@@ -50,80 +91,34 @@ function composition.isSyncedByThisHost() {
return 1
}
# composition.printAll
#
# This function prints a list of all compositions, one per line.
function composition.printAll() {
local _COMPOSITIONS
_COMPOSITIONS="${CIS[COMPOSITIONS]:?"Missing CIS_COMPOSITIONS"}"
readonly _COMPOSITIONS
local _COMPOSITION_PATH
ls -d1 "${_COMPOSITIONS}"*/ | while read -r _COMPOSITION_PATH; do
# Like dirname: removes tailing '/'
local _COMPOSITION="${_COMPOSITION_PATH%/}"
# Like basename
echo "${_COMPOSITION##*/}"
done
}
# composition.printAllRunningOnThisHost
#
# This function prints a list of all compositions which run or should run on this host, one per line.
# see also: composition.isRunningOnThisHost
function composition.printAllRunningOnThisHost() {
composition.printAll | while read -r _COMPOSITION; do
composition.isRunningOnThisHost "${_COMPOSITION}" \
&& echo "${_COMPOSITION}"
done
}
# composition.printAllSyncedByThisHost
#
# This function prints a list of all compositions which should be synced to this host, one per line.
# see also: composition.isSyncedByThisHost
function composition.printAllSyncedByThisHost() {
composition.printAll | while read -r _COMPOSITION; do
composition.isSyncedByThisHost "${_COMPOSITION}" \
&& echo "${_COMPOSITION}"
done
}
# composition.start COMPOSITION
# - COMPOSITION mandatory: "uptime-kuma-prod"
#
# This function starts the given composition on this host, provided that this is the defined result.
function composition.start() {
local _COMPOSITION _COMPOSITION_FILE_BACKUP _COMPOSITION_HOME _COMPOSITION_HOME_FILE
local _COMPOSITION _COMPOSITION_HOME_FILE _COMPOSITION_HOME _COMPOSITION_FILE
_COMPOSITION="${1:?"composition.start(): Missing first parameter COMPOSITION"}"
_COMPOSITION_FILE_BACKUP="/persistent/${_COMPOSITION}/docker-compose.yml"
_COMPOSITION_HOME_FILE="${CIS[COMPOSITIONS]:?"Missing CIS_COMPOSITIONS"}${_COMPOSITION}/home"
_COMPOSITION_HOME_FILE="${CIS[COMPOSITIONS]:?"composition.start(): Missing CIS_COMPOSITIONS"}${_COMPOSITION}/home"
# The regex should ensure a path starts and ends with a '/' and it should limit the allowed set of characters
base.set _COMPOSITION_HOME "$(head -n 1 "${_COMPOSITION_HOME_FILE}" 2> /dev/null)" "${REGEX[DIRPATH]}" optional
readonly _COMPOSITION _COMPOSITION_FILE_BACKUP _COMPOSITION_HOME _COMPOSITION_HOME_FILE
_COMPOSITION_FILE="${_COMPOSITION_HOME}docker-compose.yml"
readonly _COMPOSITION _COMPOSITION_HOME_FILE _COMPOSITION_HOME _COMPOSITION_FILE
local _COMPOSITION_FILE
if [ -n "${_COMPOSITION_HOME}" ]; then
readonly _COMPOSITION_FILE="${_COMPOSITION_HOME}docker-compose.yml"
[ ! -f "${_COMPOSITION_FILE}" ] \
&& echo "FAILURE: No composition file found, using the information from file 'home': '${_COMPOSITION_FILE}'" >&2 \
! composition.shouldRunOnThisHost "${_COMPOSITION}" \
&& echo "SKIPPED: The composition '${_COMPOSITION}' should not run on this host." >&2 \
&& return 0
[ -z "${_COMPOSITION_HOME}" ] \
&& echo "FAILURE: there was no file 'home' defined." >&2 \
&& return 1
else
readonly _COMPOSITION_FILE="${_COMPOSITION_FILE_BACKUP}"
[ ! -f "${_COMPOSITION_FILE}" ] \
&& echo "FAILURE: No composition file found, falling back to convention: '${_COMPOSITION_FILE}'" >&2 \
&& echo "FAILURE: No composition file found: '${_COMPOSITION_FILE}'" >&2 \
&& return 1
fi
printf -- "Starting composition: '%s'\n" "${_COMPOSITION}" >&2
! composition.isRunningOnThisHost "${_COMPOSITION}" \
&& echo "SKIPPED: This composition does not run on this host" >&2 \
&& return 0
if [ "$(docker compose version 2> /dev/null)" ]; then
docker compose --file "${_COMPOSITION_FILE}" start \
&& echo "SUCCESS" >&2 \
+3 -3
View File
@@ -160,7 +160,7 @@ function receiveLoopSingle() {
_COMPOSITION="${1:?"receiveLoopSingle(): Missing first parameter COMPOSITION"}"
readonly _COMPOSITION
while composition.isSyncedByThisHost "${_COMPOSITION}"; do
while composition.shouldBeSyncedByThisHost "${_COMPOSITION}"; do
receive "${_COMPOSITION}" \
&& echo "Sleep for 5s" \
&& sleep 5 \
@@ -174,7 +174,7 @@ function receiveLoopSingle() {
return 1
done
! composition.isSyncedByThisHost "${_COMPOSITION}" \
! composition.shouldBeSyncedByThisHost "${_COMPOSITION}" \
&& echo "This host '${CIS[HOST]}' is no sync-host (anymore) for composition: '${_COMPOSITION}'"
}
@@ -193,7 +193,7 @@ function receiveOnceSingle() {
_COMPOSITION="${1:?"receiveOnceSingle(): Missing first parameter COMPOSITION"}"
readonly _COMPOSITION
! composition.isSyncedByThisHost "${_COMPOSITION}" \
! composition.shouldBeSyncedByThisHost "${_COMPOSITION}" \
&& echo "This host '${CIS[HOST]}' is no sync-host for composition: '${_COMPOSITION}'" \
&& return 1