From 478d298b165edbe6c2072c6e442034d9e638eeb0 Mon Sep 17 00:00:00 2001 From: m8in Date: Fri, 19 Jun 2026 21:38:20 +0200 Subject: [PATCH] Improved module composition including renaming some functions for better self describtion. --- module/composition.module.sh | 133 +++++++++++------------ script/host/zfs/composition-sync/sync.sh | 6 +- 2 files changed, 67 insertions(+), 72 deletions(-) diff --git a/module/composition.module.sh b/module/composition.module.sh index 6122b50..3479427 100755 --- a/module/composition.module.sh +++ b/module/composition.module.sh @@ -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 \ - && 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 \ - && return 1 - fi + ! 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 + + [ ! -f "${_COMPOSITION_FILE}" ] \ + && echo "FAILURE: No composition file found: '${_COMPOSITION_FILE}'" >&2 \ + && return 1 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 \ diff --git a/script/host/zfs/composition-sync/sync.sh b/script/host/zfs/composition-sync/sync.sh index a9c31c8..1ae808c 100755 --- a/script/host/zfs/composition-sync/sync.sh +++ b/script/host/zfs/composition-sync/sync.sh @@ -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