Skip to content

Commit

Permalink
tests & tweaks
Browse files Browse the repository at this point in the history
  • Loading branch information
SaswatPadhi committed Oct 1, 2024
1 parent 61861cc commit 84f00ac
Show file tree
Hide file tree
Showing 16 changed files with 123 additions and 44 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: "Docker Compose Test (docker.sock)"
name: "Docker Compose Test (docker_sock)"

on:
pull_request:
Expand All @@ -9,7 +9,7 @@ on:
- cron: "0 8 * * *"

env:
TARGET_SERVICE: docker.sock
TARGET_SERVICE: docker_sock
TARGET_TIMEOUT: 15

jobs:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: "Docker Compose Test (Kodi.DB)"
name: "Docker Compose Test (Kodi_DB)"

on:
pull_request:
Expand All @@ -9,7 +9,7 @@ on:
- cron: "0 8 * * *"

env:
TARGET_SERVICE: kodi.db
TARGET_SERVICE: kodi_db
TARGET_TIMEOUT: 60

jobs:
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@ Options: { yes | no }
ignores options*.conf and uses all 'docker-compose.*.{sh,yml}' files.

Compositions Found (18):
airdcpp certbot docker.sock gitea hass indexarr
influxdb kodi.db monitarr navidrome nextcloud pihole
airdcpp certbot docker_sock gitea hass indexarr
influxdb kodi_db monitarr navidrome nextcloud pihole
qbittorrent tang telegraf teslamate traefik unifi
```
</details>
Expand Down Expand Up @@ -229,11 +229,11 @@ Compositions Found (18):
</tr>
<tr>
<th>
<a href='https://docs.docker.com/engine/security/protect-access/'>docker.sock</a>
<a href='https://docs.docker.com/engine/security/protect-access/'>docker_sock</a>
<br>
<sub>-</sub>
<hr>
<a href='https://github.com/padhi-homelab/services/actions?query=workflow%3A%22Docker+Compose+Test+%28docker.sock%29%22'><img src='https://img.shields.io/github/actions/workflow/status/padhi-homelab/services/compose-test_docker.sock.yml?branch=master&logo=github&logoWidth=24&style=flat-square&label=tests'></img></a>
<a href='https://github.com/padhi-homelab/services/actions?query=workflow%3A%22Docker+Compose+Test+%28docker_sock%29%22'><img src='https://img.shields.io/github/actions/workflow/status/padhi-homelab/services/compose-test_docker_sock.yml?branch=master&logo=github&logoWidth=24&style=flat-square&label=tests'></img></a>
</th>
<th>
A
Expand Down Expand Up @@ -466,7 +466,7 @@ Compositions Found (18):
<br>
<sub>:3306</sub>
<hr>
<a href='https://github.com/padhi-homelab/services/actions?query=workflow%3A%22Docker+Compose+Test+%28Kodi.DB%29%22'><img src='https://img.shields.io/github/actions/workflow/status/padhi-homelab/services/compose-test_kodi.db.yml?branch=master&logo=github&logoWidth=24&style=flat-square&label=tests'></img></a>
<a href='https://github.com/padhi-homelab/services/actions?query=workflow%3A%22Docker+Compose+Test+%28Kodi.DB%29%22'><img src='https://img.shields.io/github/actions/workflow/status/padhi-homelab/services/compose-test_kodi_db.yml?branch=master&logo=github&logoWidth=24&style=flat-square&label=tests'></img></a>
</th>
<th>
B
Expand Down
5 changes: 5 additions & 0 deletions _scripts/colors.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
#!/usr/bin/env bash

set -Eumo pipefail

DISABLE_COLORS=${DISABLE_COLORS:-}

function P () {
[ -z "$DISABLE_COLORS" ] || return 0
tput "$@" 2>/dev/null
}

Expand Down
69 changes: 61 additions & 8 deletions _scripts/test_comp.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ mkdir -p "$TEST_COMP_TMP_PATH"

# SETUP <test description> <comp arguments> <stdin content>
function SETUP () {
echo -e "\n${_fg_white_}${_bg_black_}${_bold_}[#]${_normal_} Test $1: "
echo -e "\n${_fg_white_}${_bg_black_}${_bold_} T ${_normal_} Test $1: "

local io_path_prefix="$TEST_COMP_TMP_PATH/$1"
COMP_ERR_PATH="$io_path_prefix.err"
Expand All @@ -30,7 +30,7 @@ function SETUP () {
echo "INPUT: $3"
fi

./comp $2 >"$COMP_OUT_PATH" 2>"$COMP_ERR_PATH" <<<"$3"
DISABLE_COLORS=1 ./comp $2 >"$COMP_OUT_PATH" 2>"$COMP_ERR_PATH" <<<"$3"
COMP_EXIT_CODE=$?
if [ -n "$DEBUG" ]; then
echo "\$COMP_ERR_PATH contents:"
Expand All @@ -52,8 +52,6 @@ function CHECK {
fi
}

./comp status tang &> /dev/null

SETUP "invocation without args" \
"" \
""
Expand All @@ -63,29 +61,84 @@ CHECK $'[ $COMP_EXIT_CODE -eq $EXIT_CODE_USAGE_ERROR ]' \
SETUP "status of non-existent composition" \
"status unknown_comp" \
""
CHECK $'grep -sq "Executing status on unknown_comp" "$COMP_OUT_PATH"' \
"Expected info message at beginning of execution"
CHECK $'[ $COMP_EXIT_CODE -eq $EXIT_CODE_COMPOSITION_NOT_FOUND ]'\
"Expected EXIT_CODE_COMPOSITION_NOT_FOUND"
CHECK $'grep -sq "is not a base directory" "$COMP_ERR_PATH"' \
"Expected a helpful error message"

SETUP "deny deleting data" \
SETUP "that 'tang' is not running" \
"status -P tang" \
""
CHECK $'grep -sq "Executing status on tang" "$COMP_OUT_PATH"' \
"Expected info message at beginning of execution"
CHECK $'grep -sq "Unhealthy service: tang" "$COMP_ERR_PATH"' \
"Expected error message for unhealthy service"
CHECK $'[ $COMP_EXIT_CODE -eq $EXIT_CODE_SIMPLE_VERB_FAILURE ]' \
"Expected EXIT_CODE_SIMPLE_VERB_FAILURE"

SETUP "starting 'tang' service without prerequisites" \
"up -P tang" \
"n"
CHECK $'grep -sq "Executing up on tang" "$COMP_OUT_PATH"' \
"Expected info message at beginning of execution"
CHECK $'[ $COMP_EXIT_CODE -eq 0 ]' \
"Expected EXIT_CODE = 0"

SETUP "cleaning 'tang' service before stopping" \
"clean tang" \
""
CHECK $'grep -sq "Executing clean on tang" "$COMP_OUT_PATH"' \
"Expected info message at beginning of execution"
CHECK $'grep -sq "Cannot clean while tang is running" "$COMP_ERR_PATH"' \
"Expected error message for running composition"
CHECK $'[ $COMP_EXIT_CODE -eq $EXIT_CODE_SIMPLE_VERB_FAILURE ]' \
"Expected EXIT_CODE_SIMPLE_VERB_FAILURE"

# Wait for tang to start and record health status
sleep 15s

SETUP "that 'tang' is still running" \
"status -P tang" \
""
CHECK $'grep -sq "Executing status on tang" "$COMP_OUT_PATH"' \
"Expected info message at beginning of execution"
CHECK $'grep -sq "tang is healthy" "$COMP_OUT_PATH"' \
"Expected info message for healthy composition"
CHECK $'[ $COMP_EXIT_CODE -eq 0 ]' \
"Expected EXIT_CODE = 0"

SETUP "stopping 'tang' service" \
"down tang" \
""
CHECK $'grep -sq "Executing down on tang" "$COMP_OUT_PATH"' \
"Expected info message at beginning of execution"
CHECK $'[ $COMP_EXIT_CODE -eq 0 ]' \
"Expected EXIT_CODE = 0"

SETUP "cleaning, but deny deleting data" \
"clean tang" \
"n"
CHECK $'grep -sq "Executing clean on tang" "$COMP_OUT_PATH"' \
"Expected info message at beginning of execution"
CHECK $'[ $COMP_EXIT_CODE -eq 0 ]' \
"Expected EXIT_CODE = 0"
CHECK $'grep -sq "Remove \'tang/data\' (y/N)?" "$COMP_OUT_PATH"' \
"Expected confirmation prompt before deletion"
CHECK $'[ -f tang/.env ]' \
CHECK $'[ -d tang/data ]' \
"Expected data is not deleted"

SETUP "allow deleting data" \
SETUP "cleaning, and allow deleting data" \
"clean tang" \
"y"
CHECK $'grep -sq "Executing clean on tang" "$COMP_OUT_PATH"' \
"Expected info message at beginning of execution"
CHECK $'[ $COMP_EXIT_CODE -eq 0 ]' \
"Expected EXIT_CODE = 0"
CHECK $'grep -sq "Remove \'tang/data\' (y/N)?" "$COMP_OUT_PATH"' \
"Expected confirmation prompt before deletion"
CHECK $'! [ -f tang/.env ]' \
CHECK $'! [ -d tang/data ]' \
"Expected data is deleted"

exit "$FINAL_EXIT_CODE"
67 changes: 44 additions & 23 deletions comp
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,15 @@ __gen_templates () {
done < <(find ./extra -name '*.template.*')
}

__grab_ps () {
# FIXME: `podman` doesn't print health status!
local _ps_res="$( $DOCKER_CMD ps \
--format '{{.Label "com.docker.compose.service"}}\t{{.Status}}' \
--filter label=com.docker.compose.project=$comp \
)"
eval "$1"='$_ps_res'
}

__maybe_fail_fast () {
[ "$FLAG_FAIL_FAST" != "yes" ] || exit "$1"

Expand Down Expand Up @@ -216,20 +225,25 @@ __verify_volumes () {
}

__will_invoke_compose () {
[ "$1" = "down" ] || [ "$1" = "pull" ] || [ "$1" = "status" ] || [ "$1" = "up" ]
[ "$1" = "down" ] || [ "$1" = "pull" ] || [ "$1" = "up" ]
}

# # # # # # # # # # # # # # # # # # # TOP-LEVEL VERBS # # # # # # # # # # # # # # # # # # #

do_validate () {
[ "$1" = "shallow" ] || __do_prereqs validate || return 1
[ "${1:-}" = "shallow" ] || __do_prereqs validate || return 1

if echo "$comp" | grep -q '\.'; then
__error "$DOCKER_COMPOSE_CMD will use '${comp//.}' as project name."
return 1
fi

printf '[~] Validating service:'
for svc in $("$YQ_CMD" -M '.services | keys | .[]' docker-compose.yml) ; do
local attrs=( $("$YQ_CMD" -M ".services.\"$svc\" | keys | .[]" docker-compose.yml) )
echo -n " $svc"
for bad_attr in devices labels logging ports ; do
if printf '%s\0' "${attrs[@]}" | grep -Fxqz -- $bad_attr; then
if printf '%s\0' "${attrs[@]}" | grep -Fxqz -- $bad_attr ; then
echo ; __error "'$bad_attr' for '$svc' should be in docker_compose.$bad_attr.yml."
return 1
fi
Expand All @@ -239,12 +253,18 @@ do_validate () {
}

do_clean () {
do_down || return 1

echo -n "Remove '$comp/data' (y/N)? " ; read -rn1 2>&1 ; echo
[[ $REPLY =~ ^[Yy]$ ]] || return 0
__grab_ps __ps_before_clean
if [ -n "$__ps_before_clean" ] ; then
__error "Cannot clean while ${_bold_}$comp${_normal_} is running!"
return 1
fi

rm -rfv data generated .env
rm -rfv generated .env
if [ -d data ] ; then
echo -n "Remove '$comp/data' (y/N)? " ; read -rn1 2>&1
[[ $REPLY =~ ^[Yy]$ ]] && echo || return 0
fi
rm -rfv data
}

do_down () {
Expand Down Expand Up @@ -277,11 +297,12 @@ do_pull () {
do_status () {
__do_prereqs status || return 1

__grab_ps __ps_before_status
printf '[?] Querying service:'
for svc in $( "$YQ_CMD" -M '.services | keys | .[]' docker-compose.yml ) ; do
echo -n " $svc"
if ! ( $DOCKER_COMPOSE_CMD ps "$svc" 2> /dev/null | grep -q healthy ) ; then
echo ; __error "'$svc' is not healthy."
if ! ( echo "$__ps_before_status" | grep "$svc" | grep -q healthy ) ; then
echo ; __error "Unhealthy service: ${_fg_red_}$svc${_normal_}"
return 1
fi
done
Expand All @@ -303,14 +324,14 @@ usage () {
Usage:
$0 <verb>[,<verb>,...] [flags] <comp_dir> [<comp_dir> ...]
Verbs: (short forms within [])
[c]lean Delete '<comp_dir>/data'
[d]own Stop a composition
[o]verrides List all override files in a composition
[p]ull Pull all images for a composition
[s]tatus Display health / status of a composition
[u]p Start a composition
[v]alidate Validate a composition
Verbs: (short forms within <>)
<c>lean Delete '<comp_dir>/data'
<d>own Stop a composition
<o>verrides List all override files in a composition
<p>ull Pull all images for a composition
<s>tatus Display health / status of a composition
<u>p Start a composition
<v>alidate Validate a composition
Flags:
[-P | --skip-prereqs] Ignore verifying/starting prerequisite compositions
Expand Down Expand Up @@ -475,15 +496,15 @@ perform () {
local SIMPLE_VERB="$1"
for comp in "${COMPOSITIONS[@]}" ; do
comp="${comp%/}"
echo -ne "\n${_fg_white_}${_bg_black_}${_bold_}[${SIMPLE_VERB:0:1}]${_normal_} Executing ${_bold_}$SIMPLE_VERB${_normal_} on "
echo -ne "\n${_fg_white_}${_bg_black_}${_bold_} ${SIMPLE_VERB:0:1} ${_normal_} Executing ${_bold_}$SIMPLE_VERB${_normal_} on "
[ -z "$COMP_INTERNAL_CALL" ] || printf 'pre-req '
echo "${_bold_}$comp${_normal_} ... "
if ! { [ "$comp" = "$(basename "$comp")" ] && [ -d "$SELF_DIR/$comp" ]; } ; then
__error "'$comp' is not a base directory at '$SELF_DIR'!"
__error "${_bold_}$comp${_normal_} is not a base directory at '$SELF_DIR'!"
__maybe_fail_fast $EXIT_CODE_COMPOSITION_NOT_FOUND || continue
fi
if ! [ -f "$SELF_DIR/$comp/docker-compose.yml" ] ; then
__error "No 'docker-compose.yml' found under '$comp'!"
__error "No 'docker-compose.yml' found under ${_bold_}$comp${_normal_}!"
__maybe_fail_fast $EXIT_CODE_COMPOSITION_NOT_FOUND || continue
fi

Expand Down Expand Up @@ -526,8 +547,8 @@ perform () {
local verb_exit=0
"do_${SIMPLE_VERB}" ; verb_exit=$?

[ "$SIMPLE_VERB" != "validate" ] || [ $verb_exit -ne 0 ] || echo "[=] '$comp' is valid!"
[ "$SIMPLE_VERB" != "status" ] || [ $verb_exit -ne 0 ] || echo "[=] '$comp' is healthy!"
[ "$SIMPLE_VERB" != "validate" ] || [ $verb_exit -ne 0 ] || echo "[=] ${_bold_}$comp${_normal_} is valid!"
[ "$SIMPLE_VERB" != "status" ] || [ $verb_exit -ne 0 ] || echo "[=] ${_bold_}$comp${_normal_} is healthy!"

[ $verb_exit -eq 0 ] \
|| __maybe_fail_fast $EXIT_CODE_SIMPLE_VERB_FAILURE || continue
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ services:
labels:
traefik.enable: true
traefik.docker.network: shared
traefik.http.routers.docker_sock.rule: PathPrefix(`/docker.sock`)
traefik.http.routers.docker_sock.rule: PathPrefix(`/docker_sock`)
traefik.http.services.docker_sock.loadBalancer.server.port: 9000
traefik.http.routers.docker_sock.entryPoints: lan-https
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion kodi.db/docker-compose.yml → kodi_db/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ services:
- ./data/mariadb/var/lib/mysql:/var/lib/mysql

environment:
MARIADB_ROOT_PASSWORD: 'kodi.db_mariadb_root_password'
MARIADB_ROOT_PASSWORD: 'kodi_db_mariadb_root_password'

healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
Expand Down
2 changes: 1 addition & 1 deletion telegraf/pre.reqs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
docker.sock
docker_sock
2 changes: 1 addition & 1 deletion traefik/pre.reqs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
docker.sock
docker_sock

0 comments on commit 84f00ac

Please sign in to comment.