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/Dockerfile b/Dockerfile index 6f61ff1..5ea3840 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=3 CMD ["/opt/healthcheck.sh"] 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/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/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 9307ec9..a363870 100644 --- a/tests/test.bats +++ b/tests/test.bats @@ -9,22 +9,68 @@ teardown() { echo "================================================================" } -# Globals -DOCKSAL_IP=192.168.64.100 +# 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 +} # 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 } @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 +86,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