Skip to content

Commit 13db13d

Browse files
authored
Merge pull request #109 from cloudogu/feature/108_fix_healthcheck_in_multinode
#108 fix ready health check in multinode
2 parents d420fa1 + 65ca076 commit 13db13d

File tree

5 files changed

+44
-68
lines changed

5 files changed

+44
-68
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

77
## [Unreleased]
8+
### Fixed
9+
- Dogu state did not become `ready` in multinode [#108]
10+
- This is because Kubernetes ignores Dockerfile HEALTHCHECK statements
811

912
## [3.7.4-2] 2025-04-02
1013
### Added

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ EXPOSE 8080 2222
6868

6969
USER scm
7070

71-
HEALTHCHECK --start-period=30s --interval=20s CMD /healthcheck.sh
71+
HEALTHCHECK --interval=5s CMD doguctl healthy scm || exit 1
7272

7373
# start scm
7474
CMD ["/startup.sh"]

batsTests/healthcheck.bats

Lines changed: 5 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ load '/workspace/target/bats_libs/bats-assert/load.bash'
77
load '/workspace/target/bats_libs/bats-mock/load.bash'
88

99
setup() {
10-
export CES_TOKEN_CONFIGURATION_KEY=TestConfig
1110
export CES_TOKEN_HEADER=TestHeader
1211

1312
doguctl="$(mock_create)"
@@ -21,7 +20,7 @@ setup() {
2120
}
2221

2322
teardown() {
24-
unset CES_TOKEN_CONFIGURATION_KEY
23+
unset CES_TOKEN_HEADER
2524

2625
rm "${BATS_TMPDIR}/doguctl"
2726
rm "${BATS_TMPDIR}/curl"
@@ -30,66 +29,29 @@ teardown() {
3029
@test "health_check passes when everything is healthy" {
3130
source /workspace/resources/healthcheck.sh
3231

33-
# config --encrypted
34-
mock_set_status "${doguctl}" 0 1
35-
mock_set_output "${doguctl}" "fake_token" 1
36-
3732
# curl
3833
mock_set_status "${curl}" 0
3934
mock_set_output "${curl}" "200"
4035

41-
mock_set_status "${doguctl}" 0 2 # doguctl state ready
42-
mock_set_status "${doguctl}" 0 3 # doguctl healthy
43-
mock_set_status "${doguctl}" 0 4 # doguctl state ready
44-
45-
run runHealthCheck
36+
run runHealthCheck myApiToken
4637

4738
assert_success
4839
assert_equal "$(mock_get_call_num "${curl}")" "1"
49-
assert_equal "$(mock_get_call_num "${doguctl}")" "4"
50-
assert_equal "$(mock_get_call_args "${doguctl}" "4")" "state ready"
40+
assert_equal "$(mock_get_call_num "${doguctl}")" "0"
5141
}
5242

5343
@test "health_check fails when curl returns != 200" {
5444
source /workspace/resources/healthcheck.sh
5545

56-
# config --encrypted
57-
mock_set_status "${doguctl}" 0 1
58-
mock_set_output "${doguctl}" "fake_token" 1
59-
6046
# curl
6147
mock_set_status "${curl}" 0
6248
mock_set_output "${curl}" "401"
6349

64-
run runHealthCheck
50+
run runHealthCheck myApiToken
6551

6652
assert_failure
6753
assert_equal "$(mock_get_call_num "${curl}")" "1"
68-
assert_equal "$(mock_get_call_num "${doguctl}")" "2"
69-
assert_equal "$(mock_get_call_args "${doguctl}" "2")" "state unhealthy"
70-
}
71-
72-
@test "health_check fails when doguctl healthy returns failure (exit 1)" {
73-
source /workspace/resources/healthcheck.sh
74-
75-
# config --encrypted
76-
mock_set_status "${doguctl}" 0 1
77-
mock_set_output "${doguctl}" "fake_token" 1
78-
79-
# curl
80-
mock_set_status "${curl}" 0
81-
mock_set_output "${curl}" "200"
82-
83-
mock_set_status "${doguctl}" 0 2 # doguctl state ready
84-
mock_set_status "${doguctl}" 1 3 # doguctl healthy
85-
mock_set_status "${doguctl}" 0 4 # doguctl state ready
86-
87-
run runHealthCheck
88-
89-
assert_failure
90-
assert_equal "$(mock_get_call_num "${curl}")" "1"
91-
assert_equal "$(mock_get_call_num "${doguctl}")" "4"
92-
assert_equal "$(mock_get_call_args "${doguctl}" "4")" "state unhealthy"
54+
assert_equal "$(mock_get_call_num "${doguctl}")" "0"
9355
}
9456

9557

resources/healthcheck.sh

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,47 +5,54 @@ set -o pipefail
55

66
# Script to perform a health check
77
#
8-
# This script monitors the health of the SCM-Dogu. It uses `doguctl`
9-
# and a HTTP endpoint to perform the health checks. This is necessary as SCM-Dogu provides no dedicated health
10-
# endpoint at the moment.
8+
# This script monitors the health of the SCM-Dogu on startup.
119
#
1210
# Notes:
13-
# - Ensure that the script has execute permissions (`chmod +x health_check.sh`).
14-
# - Configure the script in the Docker container as a health check using Docker's `HEALTHCHECK` instruction.
11+
# - Ensure that the script has execute permissions (`chmod +x healthcheck.sh`).
1512
#
1613
# Example:
17-
# ./health_check.sh
14+
# ./healthcheck.sh
1815

1916
function runHealthCheck() {
20-
# connection token
21-
API_TOKEN=$(doguctl config --encrypted "${CES_TOKEN_CONFIGURATION_KEY}")
17+
local api_token=${1}
2218

2319
# Perform health check against scm endpoint
24-
HTTP_STATUS=$(curl --write-out "%{http_code}" --silent --output /dev/null --max-time 10 http://localhost:8080/scm/api/v2 -H "${CES_TOKEN_HEADER}: ${API_TOKEN}") || HTTP_STATUS=0
20+
HTTP_STATUS=$(curl --write-out "%{http_code}" --silent --output /dev/null --max-time 10 http://localhost:8080/scm/api/v2 -H "${CES_TOKEN_HEADER}: ${api_token}") || HTTP_STATUS=0
2521
if [[ "$HTTP_STATUS" -ne 200 ]]; then
2622
echo "scm is unhealthy, received http status code ${HTTP_STATUS}"
27-
doguctl state "unhealthy"
2823
return 1
2924
fi
3025

31-
32-
# Successful http check means tcp port is also available
33-
doguctl state "ready"
34-
35-
# Perform health check using doguctl
36-
if ! doguctl healthy -t 10 scm; then
37-
echo "doguctl is unhealthy"
38-
doguctl state "unhealthy"
39-
return 1
40-
fi
41-
42-
doguctl state "ready"
43-
4426
return 0
27+
}
4528

29+
waitForHealth () {
30+
doguctl state "starting"
31+
32+
local wait_timeout api_token
33+
wait_timeout=${1}
34+
api_token=${2}
35+
for i in $(seq 1 "${wait_timeout}"); do
36+
set +e
37+
local requestExitCode
38+
runHealthCheck "${api_token}"
39+
requestExitCode=$?
40+
set -e
41+
if [[ "${requestExitCode}" -eq 0 ]]; then
42+
echo "Reached SCM-Manager health endpoint successfully"
43+
doguctl state "ready"
44+
return 0
45+
fi
46+
if [[ "${i}" -eq ${wait_timeout} ]] ; then
47+
echo "SCM-Manager did not get healthy within ${wait_timeout} seconds. Dogu exits now"
48+
doguctl state "unhealthy"
49+
exit 1
50+
fi
51+
sleep 1
52+
done
4653
}
4754

4855
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
49-
runHealthCheck
56+
waitForHealth "${1}" "${2}"
5057
exit $?
5158
fi

resources/startup.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,17 @@ start_scm_server () {
6060
cp "${SCM_REQUIRED_PLUGINS_FOLDER}/${plugin}.smp" "${SCM_DATA}/plugins"
6161
fi
6262
done
63+
64+
/healthcheck.sh 600 "${API_TOKEN}" &
65+
6366
/opt/scm-server/bin/scm-server
6467
}
6568

6669
# Final startup and restart on exit code 42 (restart event)
6770

6871
while start_scm_server ; scm_exit_code=$? ; [ $scm_exit_code -eq 42 ] ; do
6972
echo Got exit code $scm_exit_code -- restarting SCM-Manager
73+
doguctl state restarting
7074
done
7175

7276
exit $scm_exit_code

0 commit comments

Comments
 (0)