From bad28c57eafb5499772206062cd28e6ce4320309 Mon Sep 17 00:00:00 2001 From: Sergey Zabolotny Date: Thu, 25 Oct 2018 12:50:38 +0300 Subject: [PATCH 1/5] Added healthcheck support --- Dockerfile | 4 ++++ healthcheck.sh | 6 ++++++ tests/test.bats | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+) create mode 100755 healthcheck.sh diff --git a/Dockerfile b/Dockerfile index 6f61ff1..e6ff8a5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,6 +10,7 @@ RUN set -xe; \ RUN sed -i '/strict-order/s/^#//g' /etc/dnsmasq.conf COPY docker-entrypoint.sh /usr/local/bin +COPY healthcheck.sh /opt/healthcheck.sh # Default domain and IP for wildcard query resolution ENV DNS_DOMAIN 'docksal' @@ -21,3 +22,6 @@ EXPOSE 53/udp ENTRYPOINT ["docker-entrypoint.sh"] CMD ["dnsmasq"] + +# Health check script +HEALTHCHECK --interval=5s --timeout=1s --retries=12 CMD ["/opt/healthcheck.sh"] diff --git a/healthcheck.sh b/healthcheck.sh new file mode 100755 index 0000000..58cc297 --- /dev/null +++ b/healthcheck.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env sh + +netstat -nlp | grep -E 'tcp.*53.*LISTEN.*dnsmasq' >/dev/null || exit 1 +netstat -nlp | grep -E 'udp.*53.*dnsmasq' >/dev/null || exit 1 + +exit 0 diff --git a/tests/test.bats b/tests/test.bats index 9307ec9..a78c916 100644 --- a/tests/test.bats +++ b/tests/test.bats @@ -9,6 +9,53 @@ teardown() { echo "================================================================" } +# Checks container health status (if available) +# @param $1 container id/name +_healthcheck () +{ + local health_status + health_status=$(docker inspect --format='{{json .State.Health.Status}}' "$1" 2>/dev/null) + + # Wait for 5s then exit with 0 if a container does not have a health status property + # Necessary for backward compatibility with images that do not support health checks + if [[ $? != 0 ]]; then + echo "Waiting 10s for container to start..." + sleep 10 + return 0 + fi + + # If it does, check the status + echo $health_status | grep '"healthy"' >/dev/null 2>&1 +} + +# Waits for containers to become healthy +# For reasoning why we are not using `depends_on` `condition` see here: +# https://github.com/docksal/docksal/issues/225#issuecomment-306604063 +_healthcheck_wait () +{ + # Wait for cli to become ready by watching its health status + local container_name="${NAME}" + local delay=5 + local timeout=30 + local elapsed=0 + + until _healthcheck "$container_name"; do + echo "Waiting for $container_name to become ready..." + sleep "$delay"; + + # Give the container 30s to become ready + elapsed=$((elapsed + delay)) + if ((elapsed > timeout)); then + echo-error "$container_name heathcheck failed" \ + "Container did not enter a healthy state within the expected amount of time." \ + "Try ${yellow}fin restart${NC}" + exit 1 + fi + done + + return 0 +} + # Globals DOCKSAL_IP=192.168.64.100 @@ -17,6 +64,7 @@ DOCKSAL_IP=192.168.64.100 @test "DNS container is up and using the \"${IMAGE}\" image" { [[ ${SKIP} == 1 ]] && skip + _healthcheck_wait run docker ps --filter "name=docksal-dns" --format "{{ .Image }}" [[ "$output" =~ "$IMAGE" ]] @@ -25,6 +73,7 @@ DOCKSAL_IP=192.168.64.100 @test ".docksal name resolution" { [[ $SKIP == 1 ]] && skip + _healthcheck_wait # Check .docksal domain resolution via ping run ping -c 1 -t 1 anything.docksal @@ -40,6 +89,7 @@ DOCKSAL_IP=192.168.64.100 @test "External name resolution" { [[ $SKIP == 1 ]] && skip + _healthcheck_wait # Real domain run ping -c 1 -t 1 www.google.com From 703e1d36773df3691ebd2efc4ce73ff45d64dabb Mon Sep 17 00:00:00 2001 From: Leonid Makarov Date: Mon, 12 Nov 2018 11:01:46 -0800 Subject: [PATCH 2/5] Minor cleanup in build and CI --- .travis.yml | 6 ++---- Makefile | 3 ++- docker-entrypoint.sh | 3 +++ scripts/release.sh | 2 +- tests/test.bats | 9 +++------ 5 files changed, 11 insertions(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5c1f43a..295bf82 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,17 +3,15 @@ sudo: required language: generic env: - REPO: docksal/dns - IMAGE_DNS: ${REPO}:dev DOCKSAL_VERSION: develop services: - docker install: - - sudo sudo curl -L https://raw.githubusercontent.com/docksal/docksal/${DOCKSAL_VERSION}/bin/fin -o /usr/local/bin/fin && sudo chmod +x /usr/local/bin/fin + # Install Docksal to have a matching versions of Docker on the build host + - curl -fsSL https://get.docksal.io | bash - fin version - - fin update - fin sysinfo script: diff --git a/Makefile b/Makefile index 09160c8..b5aadc9 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,7 @@ VERSION ?= dev REPO = docksal/dns NAME = docksal-dns +DOCKSAL_IP=192.168.64.100 .EXPORT_ALL_VARIABLES: @@ -29,7 +30,7 @@ shell: @make exec-it -e CMD=sh run: clean - docker run --rm -it -e DNS_DOMAIN=docksal -e DNS_IP=192.168.64.100 ${REPO}:${VERSION} sh + docker run --rm -it -e DNS_DOMAIN=docksal -e DNS_IP=${DOCKSAL_IP} ${REPO}:${VERSION} sh # This is the only place where fin is used/necessary start: diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index f3b804a..7d5183e 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -3,6 +3,9 @@ DEBUG=${DEBUG:-0} # Turn debugging ON when cli is started in the service mode if [ "$1" == "dnsmasq" ]; then DEBUG=1; fi + +# Print a debug message if debug mode is on +# @param message echo_debug () { [[ "$DEBUG" != 0 ]] && echo "$(date +"%F %H:%M:%S") | $@" diff --git a/scripts/release.sh b/scripts/release.sh index 423f795..9482077 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -10,7 +10,7 @@ if [[ "${TRAVIS_PULL_REQUEST}" == "false" ]]; then if [[ "$TAG" != "" ]]; then docker login -u "${DOCKER_USER}" -p "${DOCKER_PASS}" - docker tag ${IMAGE_DNS} ${REPO}:${TAG} + docker tag ${REPO}:dev ${REPO}:${TAG} docker push ${REPO}:${TAG} fi; fi; diff --git a/tests/test.bats b/tests/test.bats index a78c916..fe5f0d8 100644 --- a/tests/test.bats +++ b/tests/test.bats @@ -56,18 +56,15 @@ _healthcheck_wait () return 0 } -# Globals -DOCKSAL_IP=192.168.64.100 - # To work on a specific test: # run `export SKIP=1` locally, then comment skip in the test you want to debug -@test "DNS container is up and using the \"${IMAGE}\" image" { +@test "${NAME} container is up and using the \"${IMAGE}\" image" { [[ ${SKIP} == 1 ]] && skip _healthcheck_wait - run docker ps --filter "name=docksal-dns" --format "{{ .Image }}" - [[ "$output" =~ "$IMAGE" ]] + run docker ps --filter "name=${NAME}" --format "{{ .Image }}" + [[ "$output" =~ "${IMAGE}" ]] unset output } From fca44207467664cc0be2b62f2172069caeddebba Mon Sep 17 00:00:00 2001 From: Leonid Makarov Date: Mon, 12 Nov 2018 13:35:08 -0800 Subject: [PATCH 3/5] Convert indents to tabs in test.bats --- tests/test.bats | 68 ++++++++++++++++++++++++------------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/tests/test.bats b/tests/test.bats index fe5f0d8..3f32beb 100644 --- a/tests/test.bats +++ b/tests/test.bats @@ -13,19 +13,19 @@ teardown() { # @param $1 container id/name _healthcheck () { - local health_status - health_status=$(docker inspect --format='{{json .State.Health.Status}}' "$1" 2>/dev/null) - - # Wait for 5s then exit with 0 if a container does not have a health status property - # Necessary for backward compatibility with images that do not support health checks - if [[ $? != 0 ]]; then - echo "Waiting 10s for container to start..." - sleep 10 - return 0 - fi - - # If it does, check the status - echo $health_status | grep '"healthy"' >/dev/null 2>&1 + local health_status + health_status=$(docker inspect --format='{{json .State.Health.Status}}' "$1" 2>/dev/null) + + # Wait for 5s then exit with 0 if a container does not have a health status property + # Necessary for backward compatibility with images that do not support health checks + if [[ $? != 0 ]]; then + echo "Waiting 10s for container to start..." + sleep 10 + return 0 + fi + + # If it does, check the status + echo $health_status | grep '"healthy"' >/dev/null 2>&1 } # Waits for containers to become healthy @@ -33,27 +33,27 @@ _healthcheck () # https://github.com/docksal/docksal/issues/225#issuecomment-306604063 _healthcheck_wait () { - # Wait for cli to become ready by watching its health status - local container_name="${NAME}" - local delay=5 - local timeout=30 - local elapsed=0 - - until _healthcheck "$container_name"; do - echo "Waiting for $container_name to become ready..." - sleep "$delay"; - - # Give the container 30s to become ready - elapsed=$((elapsed + delay)) - if ((elapsed > timeout)); then - echo-error "$container_name heathcheck failed" \ - "Container did not enter a healthy state within the expected amount of time." \ - "Try ${yellow}fin restart${NC}" - exit 1 - fi - done - - return 0 + # Wait for cli to become ready by watching its health status + local container_name="${NAME}" + local delay=5 + local timeout=30 + local elapsed=0 + + until _healthcheck "$container_name"; do + echo "Waiting for $container_name to become ready..." + sleep "$delay"; + + # Give the container 30s to become ready + elapsed=$((elapsed + delay)) + if ((elapsed > timeout)); then + echo-error "$container_name heathcheck failed" \ + "Container did not enter a healthy state within the expected amount of time." \ + "Try ${yellow}fin restart${NC}" + exit 1 + fi + done + + return 0 } # To work on a specific test: From 9672969c5461a5666c4c1766a93b724079d75961 Mon Sep 17 00:00:00 2001 From: Leonid Makarov Date: Mon, 12 Nov 2018 16:13:05 -0800 Subject: [PATCH 4/5] Some more cleanup in test.bats --- tests/test.bats | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test.bats b/tests/test.bats index 3f32beb..a363870 100644 --- a/tests/test.bats +++ b/tests/test.bats @@ -47,8 +47,8 @@ _healthcheck_wait () elapsed=$((elapsed + delay)) if ((elapsed > timeout)); then echo-error "$container_name heathcheck failed" \ - "Container did not enter a healthy state within the expected amount of time." \ - "Try ${yellow}fin restart${NC}" + "Container did not enter a healthy state within the expected amount of time." \ + "Try ${yellow}fin restart${NC}" exit 1 fi done From 2707e3327a8ca8bc8212a018dba495e9ce416222 Mon Sep 17 00:00:00 2001 From: Leonid Makarov Date: Tue, 13 Nov 2018 21:50:39 -0800 Subject: [PATCH 5/5] Lower heathcheck retries to 3 This gives container 15s total to start before it would be considered unhealthy --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index e6ff8a5..5ea3840 100644 --- a/Dockerfile +++ b/Dockerfile @@ -24,4 +24,4 @@ ENTRYPOINT ["docker-entrypoint.sh"] CMD ["dnsmasq"] # Health check script -HEALTHCHECK --interval=5s --timeout=1s --retries=12 CMD ["/opt/healthcheck.sh"] +HEALTHCHECK --interval=5s --timeout=1s --retries=3 CMD ["/opt/healthcheck.sh"]