From 752d83aeaa5d2500c81d375c5ea4f3acd7fd329a Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 4 Jun 2020 17:03:48 -0400 Subject: [PATCH] Introduce additional docker tags for the debian version. * Added new docker tag variations to specify the debian version ('stretch', and 'buster'). * Arch images are alway as specific as possible: pihole/pihole:master-amd64-stretch * Multiarch images have both the specific debian version tags as well as the generic non-debian tags: pihole/pihole:master-stretch & pihole/pihole:master * Currently, the non-specific tags point to the 'stretch' images. Eventaully it can be migrated to 'buster'. * Use GitHub actions to do the builds. Although the script names include 'gh-actions' to differentiate them from the 'circle' scripts, there is zero logic that is specific to Github (ie. no Github environment variables). * 'armhf:buster' & 'arm64:buster' has an issue with `ip route get`. I think the issue is related to 'qemu', but I'm not sure. Update the `validate_env` function to only use `ip route get` if `nc` reports something strange. Signed-off-by: Daniel --- .github/workflows/test-and-build.yaml | 62 +++++++++++++++++++++++ .github/workflows/test.yaml | 31 ------------ .gitignore | 1 + Dockerfile.py | 70 ++++++++++++------------- Dockerfile.sh | 11 ++-- Dockerfile_build | 7 +-- README.md | 17 ++++--- TESTING.md | 2 +- bash_functions.sh | 4 +- build.yml | 26 ++++------ gh-actions-deploy.sh | 73 +++++++++++++++++++++++++++ gh-actions-test.sh | 31 ++++++++++++ gh-actions-vars.sh | 53 +++++++++++++++++++ install.sh | 3 ++ test/conftest.py | 17 +++++-- test/test_volume_data.sh | 5 +- tox.ini | 2 +- 17 files changed, 302 insertions(+), 113 deletions(-) create mode 100644 .github/workflows/test-and-build.yaml delete mode 100644 .github/workflows/test.yaml create mode 100755 gh-actions-deploy.sh create mode 100755 gh-actions-test.sh create mode 100755 gh-actions-vars.sh diff --git a/.github/workflows/test-and-build.yaml b/.github/workflows/test-and-build.yaml new file mode 100644 index 0000000..f518e6a --- /dev/null +++ b/.github/workflows/test-and-build.yaml @@ -0,0 +1,62 @@ +name: Test & Build +on: + push: + branches: + - master + - dev + - v* + - beta-v* + pull_request: + +#env: +# DOCKER_HUB_REPO: pihole + +jobs: + test-and-build: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + ARCH: [amd64, armhf, arm64] + DEBIAN_VERSION: [stretch, buster] + env: + ARCH: ${{matrix.ARCH}} + DEBIAN_VERSION: ${{matrix.DEBIAN_VERSION}} + steps: + - name: Checkout Repo + uses: actions/checkout@v2 + - name: Run Tests + run: | + echo "Building ${ARCH}-${DEBIAN_VERSION}" + ./gh-actions-test.sh + - name: Push the ARCH image + if: github.event_name != 'pull_request' + run: | + . gh-actions-vars.sh + echo "${{ secrets.DOCKERHUB_PASS }}" | docker login --username="${{ secrets.DOCKERHUB_USER }}" --password-stdin + docker push "${ARCH_IMAGE}" + - name: Upload gh-workspace + if: github.event_name != 'pull_request' + uses: actions/upload-artifact@v1 + with: + name: gh-workspace + path: .gh-workspace + + publish: + if: github.event_name != 'pull_request' + runs-on: ubuntu-latest + needs: test-and-build + steps: + - name: Checkout Repo + uses: actions/checkout@v2 + - name: Download workspace files + uses: actions/download-artifact@v1 + with: + name: gh-workspace + path: .gh-workspace + - name: Tag and Publish multi-arch images + env: + DOCKERHUB_PASS: ${{ secrets.DOCKERHUB_PASS }} + DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }} + run: | + ./gh-actions-deploy.sh diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml deleted file mode 100644 index 102482d..0000000 --- a/.github/workflows/test.yaml +++ /dev/null @@ -1,31 +0,0 @@ -name: Tests -on: - push: - branches: - - master - - dev - - v* - - beta-v* - pull_request: - -jobs: - build: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - ARCH: - - amd64 - # https://github.com/pi-hole/docker-pi-hole/issues/587#issuecomment-617180631 - #- armel - - armhf - - arm64 - env: - ARCH: ${{matrix.ARCH}} - steps: - - name: Checkout Repo - uses: actions/checkout@v2 - - name: Run Circle Test - run: | - echo "Building ${ARCH}" - ./circle-test.sh diff --git a/.gitignore b/.gitignore index fd32835..4e7bc94 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ __pycache__ UNKNOWN.egg-info .env ci-workspace +.gh-workspace # WIP/test stuff doco.yml diff --git a/Dockerfile.py b/Dockerfile.py index 7fc1363..749db9a 100755 --- a/Dockerfile.py +++ b/Dockerfile.py @@ -2,15 +2,16 @@ """ Dockerfile.py - generates and build dockerfiles Usage: - Dockerfile.py [--hub_tag=] [--arch= ...] [-v] [-t] [--no-build] [--no-cache] + Dockerfile.py [--hub_tag=] [--arch= ...] [--debian= ...] [-v] [-t] [--no-build] [--no-cache] Options: - --no-build Skip building the docker images - --no-cache Build without using any cache data - --hub_tag= What the Docker Hub Image should be tagged as [default: None] - --arch= What Architecture(s) to build [default: amd64 armel armhf arm64] - -v Print docker's command output [default: False] - -t Print docker's build time [default: False] + --no-build Skip building the docker images + --no-cache Build without using any cache data + --hub_tag= What the Docker Hub Image should be tagged as [default: None] + --arch= What Architecture(s) to build [default: amd64 armel armhf arm64] + --debian= What debian version(s) to build [default: stretch buster] + -v Print docker's command output [default: False] + -t Print docker's build time [default: False] Examples: """ @@ -20,8 +21,6 @@ from docopt import docopt import os import subprocess -THIS_DIR = os.path.dirname(os.path.abspath(__file__)) - __version__ = None dot = os.path.abspath('.') with open('{}/VERSION'.format(dot), 'r') as v: @@ -30,21 +29,22 @@ with open('{}/VERSION'.format(dot), 'r') as v: def build_dockerfiles(args): + if args['-v']: + print(args) if args['--no-build']: print(" ::: Skipping Dockerfile building") return for arch in args['--arch']: - build('pihole', arch, args) + for debian_version in args['--debian']: + build('pihole', arch, debian_version, args['--hub_tag'], args['-t'], args['--no-cache'], args['-v']) -def run_and_stream_command_output(command, args): +def run_and_stream_command_output(command, environment_vars, verbose): print("Running", command) - build_env = os.environ.copy() - build_env['PIHOLE_VERSION'] = __version__ - build_result = subprocess.Popen(command.split(), env=build_env, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, - bufsize=1, universal_newlines=True) - if args['-v']: + build_result = subprocess.Popen(command.split(), env=environment_vars, stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, bufsize=1, universal_newlines=True) + if verbose: while build_result.poll() is None: for line in build_result.stdout: print(line, end='') @@ -54,31 +54,25 @@ def run_and_stream_command_output(command, args): print(build_result.stderr) -def build(docker_repo, arch, args): - repo_tag = '{}:{}-{}'.format(docker_repo, __version__, arch) - print(" ::: Building {}".format(repo_tag)) - time = '' - if args['-t']: - time = 'time ' - no_cache = '' - if args['--no-cache']: - no_cache = '--no-cache' - build_command = '{time}docker-compose -f build.yml build {no_cache} --pull {arch}'\ - .format(time=time, no_cache=no_cache, arch=arch) - print(" ::: Building {} into {}".format(arch, repo_tag)) - run_and_stream_command_output(build_command, args) - if args['-v']: +def build(docker_repo: str, arch: str, debian_version: str, hub_tag: str, show_time: bool, no_cache: bool, verbose: bool): + create_tag = f'{docker_repo}:{__version__}-{arch}-{debian_version}' + print(f' ::: Building {create_tag}') + time_arg = 'time' if show_time else '' + cache_arg = '--no-cache' if no_cache else '' + build_env = os.environ.copy() + build_env['PIHOLE_VERSION'] = __version__ + build_env['DEBIAN_VERSION'] = debian_version + build_command = f'{time_arg} docker-compose -f build.yml build {cache_arg} --pull {arch}' + print(f' ::: Building {arch} into {create_tag}') + run_and_stream_command_output(build_command, build_env, verbose) + if verbose: print(build_command, '\n') - if args['--hub_tag']: - hub_tag_command = "{time}docker tag {create_tag} {hub_tag}"\ - .format(time=time, create_tag=repo_tag, hub_tag=args['--hub_tag']) - print(" ::: Tagging {} into {}".format(repo_tag, args['--hub_tag'])) - run_and_stream_command_output(hub_tag_command, args) + if hub_tag: + hub_tag_command = f'{time_arg} docker tag {create_tag} {hub_tag}' + print(f' ::: Tagging {create_tag} into {hub_tag}') + run_and_stream_command_output(hub_tag_command, build_env, verbose) if __name__ == '__main__': args = docopt(__doc__, version='Dockerfile 1.1') - if args['-v']: - print(args) - build_dockerfiles(args) diff --git a/Dockerfile.sh b/Dockerfile.sh index 3338491..9f9d8d7 100755 --- a/Dockerfile.sh +++ b/Dockerfile.sh @@ -1,10 +1,13 @@ -#!/usr/bin/env sh -# alpine sh only +#!/usr/bin/env bash + +# @param ${ARCH} The architecture to build. Example: amd64 +# @param ${DEBIAN_VERSION} The debian version to build. Example: buster +# @param ${ARCH_IMAGE} What the Docker Hub Image should be tagged as [default: None] set -eux -./Dockerfile.py -v --arch="${ARCH}" --hub_tag="${ARCH_IMAGE}" +./Dockerfile.py -v --arch="${ARCH}" --debian="${DEBIAN_VERSION}" --hub_tag="${ARCH_IMAGE}" docker images -# TODO: Add junitxml output and have circleci consume it +# TODO: Add junitxml output and have something consume it # 2 parallel max b/c race condition with docker fixture (I think?) py.test -vv -n 2 -k "${ARCH}" ./test/ diff --git a/Dockerfile_build b/Dockerfile_build index 5327d8d..e40f551 100644 --- a/Dockerfile_build +++ b/Dockerfile_build @@ -3,16 +3,14 @@ FROM python:buster # Only works for docker CLIENT (bind mounted socket) COPY --from=docker:18.09.3 /usr/local/bin/docker /usr/local/bin/ -# Based on https://github.com/Ilhicas/alpine-pipenv -ARG packages RUN apt-get update && \ apt-get install -y python3-dev curl gcc make \ - libffi-dev libssl-dev ${packages} \ + libffi-dev libssl-dev \ && pip3 install -U pip pipenv + RUN curl -L https://github.com/docker/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose && \ chmod +x /usr/local/bin/docker-compose -# -v "$(pwd):/$(pwd)" -w "$(pwd)" to prevent nested docker path confusion COPY ./Dockerfile.sh /usr/local/bin/ COPY Pipfile* /root/ WORKDIR /root @@ -20,7 +18,6 @@ WORKDIR /root RUN pipenv install --system \ && sed -i 's|/bin/sh|/bin/bash|g' /usr/local/lib/python3.8/site-packages/testinfra/backend/docker.py - RUN echo "set -ex && Dockerfile.sh && \$@" > /usr/local/bin/entrypoint.sh RUN chmod +x /usr/local/bin/entrypoint.sh ENTRYPOINT entrypoint.sh diff --git a/README.md b/README.md index 1751c4a..9a05db6 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ A [Docker](https://www.docker.com/what-docker) project to make a lightweight x86 2) Use the above quick start example, customize if desired. 3) Enjoy! -[![Build Status](https://api.travis-ci.org/pi-hole/docker-pi-hole.svg?branch=master)](https://travis-ci.org/pi-hole/docker-pi-hole) [![Docker Stars](https://img.shields.io/docker/stars/pihole/pihole.svg?maxAge=604800)](https://store.docker.com/community/images/pihole/pihole) [![Docker Pulls](https://img.shields.io/docker/pulls/pihole/pihole.svg?maxAge=604800)](https://store.docker.com/community/images/pihole/pihole) +[![Build Status](https://github.com/pi-hole/docker-pi-hole/workflows/Test%20&%20Build/badge.svg)](https://github.com/pi-hole/docker-pi-hole/actions?query=workflow%3A%22Test+%26+Build%22) [![Docker Stars](https://img.shields.io/docker/stars/pihole/pihole.svg?maxAge=604800)](https://store.docker.com/community/images/pihole/pihole) [![Docker Pulls](https://img.shields.io/docker/pulls/pihole/pihole.svg?maxAge=604800)](https://store.docker.com/community/images/pihole/pihole) ## Running Pi-hole Docker @@ -176,14 +176,15 @@ Users of older Ubuntu releases (circa 17.04) will need to disable dnsmasq. ## Docker tags and versioning -The primary docker tags / versions are explained in the following table. [Click here to see the full list of tags](https://store.docker.com/community/images/pihole/pihole/tags) ([arm tags are here](https://store.docker.com/community/images/pihole/pihole/tags)), I also try to tag with the specific version of Pi-hole Core for version archival purposes, the web version that comes with the core releases should be in the [GitHub Release notes](https://github.com/pi-hole/docker-pi-hole/releases). +The primary docker tags / versions are explained in the following table. [Click here to see the full list of tags](https://store.docker.com/community/images/pihole/pihole/tags), I also try to tag with the specific version of Pi-hole Core for version archival purposes, the web version that comes with the core releases should be in the [GitHub Release notes](https://github.com/pi-hole/docker-pi-hole/releases). -| tag | architecture | description | Dockerfile | -| --- | ------------ | ----------- | ---------- | -| `latest` | auto detect | x86, arm, or arm64 container, docker auto detects your architecture. | [Dockerfile](https://github.com/pi-hole/docker-pi-hole/blob/master/Dockerfile) | -| `v4.0.0-1` | auto detect | Versioned tags, if you want to pin against a specific version, use one of these | | -| `v4.0.0-1_` | based on tag | Specific architectures tags | | -| `dev` | auto detect | like latest tag, but for the development branch (pushed occasionally) | | +| tag | architecture | description | Dockerfile | +| --- | ------------ | ----------- | ---------- | +| `latest` | auto detect | x86, arm, or arm64 container, docker auto detects your architecture. | [Dockerfile](https://github.com/pi-hole/docker-pi-hole/blob/master/Dockerfile) | +| `v5.0` | auto detect | Versioned tags, if you want to pin against a specific Pi-hole version, use one of these | | +| `v5.0-stretch` | auto detect | Versioned tags, if you want to pin against a specific Pi-hole and Debian version, use one of these | | +| `v5.0--stretch` | based on tag | Specific architectures and Debian version tags | | +| `dev` | auto detect | like latest tag, but for the development branch (pushed occasionally) | | ### `pihole/pihole:latest` [![](https://images.microbadger.com/badges/image/pihole/pihole:latest.svg)](https://microbadger.com/images/pihole/pihole "Get your own image badge on microbadger.com") [![](https://images.microbadger.com/badges/version/pihole/pihole:latest.svg)](https://microbadger.com/images/pihole/pihole "Get your own version badge on microbadger.com") [![](https://images.microbadger.com/badges/version/pihole/pihole:latest.svg)](https://microbadger.com/images/pihole/pihole "Get your own version badge on microbadger.com") diff --git a/TESTING.md b/TESTING.md index 88d10cc..75e8090 100644 --- a/TESTING.md +++ b/TESTING.md @@ -4,7 +4,7 @@ Make sure you have bash, docker. Python and some test hacks are crammed into th # Running tests locally -`ARCH=amd64 ./circle-test.sh` +`ARCH=amd64 ./gh-actions-test.sh` Should result in : diff --git a/bash_functions.sh b/bash_functions.sh index 32a0d32..025f845 100644 --- a/bash_functions.sh +++ b/bash_functions.sh @@ -46,7 +46,7 @@ validate_env() { # Optional ServerIP is a valid IP # nc won't throw any text based errors when it times out connecting to a valid IP, otherwise it complains about the DNS name being garbage # if nc doesn't behave as we expect on a valid IP the routing table should be able to look it up and return a 0 retcode - if [[ "$(nc -4 -w1 -z "$ServerIP" 53 2>&1)" != "" ]] || ! ip route get "$ServerIP" > /dev/null ; then + if [[ "$(nc -4 -w1 -z "$ServerIP" 53 2>&1)" != "" ]] && ! ip route get "$ServerIP" > /dev/null ; then echo "ERROR: ServerIP Environment variable ($ServerIP) doesn't appear to be a valid IPv4 address" exit 1 fi @@ -58,7 +58,7 @@ validate_env() { unset ServerIPv6 exit 1 fi - if [[ "$(nc -6 -w1 -z "$ServerIPv6" 53 2>&1)" != "" ]] || ! ip route get "$ServerIPv6" > /dev/null ; then + if [[ "$(nc -6 -w1 -z "$ServerIPv6" 53 2>&1)" != "" ]] && ! ip route get "$ServerIPv6" > /dev/null ; then echo "ERROR: ServerIPv6 Environment variable ($ServerIPv6) doesn't appear to be a valid IPv6 address" echo " TIP: If your server is not IPv6 enabled just remove '-e ServerIPv6' from your docker container" exit 1 diff --git a/build.yml b/build.yml index ab78653..0a33a7c 100644 --- a/build.yml +++ b/build.yml @@ -12,46 +12,38 @@ x-common-args: &common-args services: amd64: - image: pihole:${PIHOLE_VERSION}-amd64 + image: pihole:${PIHOLE_VERSION}-amd64-${DEBIAN_VERSION:-stretch} build: context: . - cache_from: - - pihole/pihole:${PIHOLE_VERSION}-amd64 args: <<: *common-args - PIHOLE_BASE: pihole/debian-base:latest + PIHOLE_BASE: pihole/debian-base:${DEBIAN_VERSION:-stretch} PIHOLE_ARCH: amd64 S6_ARCH: amd64 armel: - image: pihole:${PIHOLE_VERSION}-armel + image: pihole:${PIHOLE_VERSION}-armel-${DEBIAN_VERSION:-stretch} build: context: . - cache_from: - - pihole/pihole:${PIHOLE_VERSION}-armel args: <<: *common-args - PIHOLE_BASE: multiarch/debian-debootstrap:armel-stretch-slim + PIHOLE_BASE: multiarch/debian-debootstrap:armel-${DEBIAN_VERSION:-stretch}-slim PIHOLE_ARCH: armel S6_ARCH: arm armhf: - image: pihole:${PIHOLE_VERSION}-armhf + image: pihole:${PIHOLE_VERSION}-armhf-${DEBIAN_VERSION:-stretch} build: context: . - cache_from: - - pihole/pihole:${PIHOLE_VERSION}-armhf args: <<: *common-args - PIHOLE_BASE: multiarch/debian-debootstrap:armhf-stretch-slim + PIHOLE_BASE: multiarch/debian-debootstrap:armhf-${DEBIAN_VERSION:-stretch}-slim PIHOLE_ARCH: arm S6_ARCH: arm arm64: - image: pihole:${PIHOLE_VERSION}-arm64 + image: pihole:${PIHOLE_VERSION}-arm64-${DEBIAN_VERSION:-stretch} build: context: . - cache_from: - - pihole/pihole:${PIHOLE_VERSION}-arm64 args: <<: *common-args - PIHOLE_BASE: multiarch/debian-debootstrap:arm64-stretch-slim + PIHOLE_BASE: multiarch/debian-debootstrap:arm64-${DEBIAN_VERSION:-stretch}-slim PIHOLE_ARCH: arm64 - S6_ARCH: aarch64 \ No newline at end of file + S6_ARCH: aarch64 diff --git a/gh-actions-deploy.sh b/gh-actions-deploy.sh new file mode 100755 index 0000000..66f0d01 --- /dev/null +++ b/gh-actions-deploy.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash +set -ex +# Github Actions Job for merging/deploying all architectures (post-test passing) +. gh-actions-vars.sh + +function annotate() { + local base=$1 + local image=$2 + local arch=$3 + local annotate_flags="${annotate_map[$arch]}" + + $dry docker manifest annotate ${base} ${image} --os linux ${annotate_flags} +} + +function create_manifest() { + local debian_version=$1 + cd "${debian_version}" + + for arch in *; do + arch_image=$(cat "${arch}") + docker pull "${arch_image}" + images+=("${arch_image}") + done + + multiarch_images=$(get_multiarch_images) + for docker_tag in ${multiarch_images}; do + docker manifest create ${docker_tag} ${images[*]} + for arch in *; do + arch_image=$(cat "${arch}") + annotate "${docker_tag}" "${arch_image}" "${arch}" + done + + docker manifest inspect "${docker_tag}" + docker manifest push --purge "${docker_tag}" + done + cd ../ +} + +function get_multiarch_images() { + multiarch_images="${MULTIARCH_IMAGE}-${debian_version}" + if [[ "${debian_version}" == "${DEFAULT_DEBIAN_VERSION}" ]] ; then + # default debian version gets a non-debian tag as well as latest tag + multiarch_images="${multiarch_images} ${MULTIARCH_IMAGE} ${LATEST_IMAGE}" + fi + echo "${multiarch_images}" +} + + +# Keep in sync with build.yml names +declare -A annotate_map=( + ["amd64"]="--arch amd64" + ["armel"]="--arch arm --variant v6" + ["armhf"]="--arch arm --variant v7" + ["arm64"]="--arch arm64 --variant v8" +) + +mkdir -p ~/.docker +export DOCKER_CLI_EXPERIMENTAL='enabled' +echo "{}" | jq '.experimental="enabled"' | tee ~/.docker/config.json +# I tried to keep this login command outside of this script +# but for some reason auth would always fail in Github Actions. +# I think setting up a cred store would fix it +# https://docs.docker.com/engine/reference/commandline/login/#credentials-store +echo "${DOCKERHUB_PASS}" | docker login --username="${DOCKERHUB_USER}" --password-stdin +docker info + +images=() +ls -lat ./.gh-workspace/ +cd .gh-workspace + +for debian_version in *; do + create_manifest "${debian_version}" +done diff --git a/gh-actions-test.sh b/gh-actions-test.sh new file mode 100755 index 0000000..691ab16 --- /dev/null +++ b/gh-actions-test.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +set -ex + +# Script ran by Github actions for tests +# +# @environment ${ARCH} The architecture to build. Example: amd64. +# @environment ${DEBIAN_VERSION} Debian version to build. ('buster' or 'stretch'). +# @environment ${ARCH_IMAGE} What the Docker Hub Image should be tagged as. Example: pihole/pihole:master-amd64-stretch + +# setup qemu/variables +docker run --rm --privileged multiarch/qemu-user-static:register --reset > /dev/null +. gh-actions-vars.sh + +if [[ "$1" == "enter" ]]; then + enter="-it --entrypoint=sh" +fi + +# generate and build dockerfile +docker build --tag image_pipenv --file Dockerfile_build . +docker run --rm \ + --volume /var/run/docker.sock:/var/run/docker.sock \ + --volume "$(pwd):/$(pwd)" \ + --workdir "$(pwd)" \ + --env PIPENV_CACHE_DIR="$(pwd)/.pipenv" \ + --env ARCH="${ARCH}" \ + --env ARCH_IMAGE="${ARCH_IMAGE}" \ + --env DEBIAN_VERSION="${DEBIAN_VERSION}" \ + ${enter} image_pipenv + +mkdir -p ".gh-workspace/${DEBIAN_VERSION}/" +echo "${ARCH_IMAGE}" | tee "./.gh-workspace/${DEBIAN_VERSION}/${ARCH}" diff --git a/gh-actions-vars.sh b/gh-actions-vars.sh new file mode 100755 index 0000000..6361698 --- /dev/null +++ b/gh-actions-vars.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash +set -a + +# @environment ${ARCH} The architecture to build. Defaults to 'amd64'. +# @environment ${DEBIAN_VERSION} Debian version to build. Defaults to 'stretch'. +# @environment ${DOCKER_HUB_REPO} The docker hub repo to tag images for. Defaults to 'pihole'. +# @environment ${DOCKER_HUB_IMAGE_NAME} The name of the resulting image. Defaults to 'pihole'. + +GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD | sed "s/\//-/g") +GIT_TAG=$(git describe --tags --exact-match 2> /dev/null || true) + +DEFAULT_DEBIAN_VERSION="stretch" + +if [[ -z "${ARCH}" ]]; then + ARCH="amd64" + echo "Defaulting arch to ${ARCH}" +fi + +if [[ -z "${DEBIAN_VERSION}" ]]; then + DEBIAN_VERSION="${DEFAULT_DEBIAN_VERSION}" + echo "Defaulting DEBIAN_VERSION to ${DEBIAN_VERSION}" +fi + +if [[ -z "${DOCKER_HUB_REPO}" ]]; then + DOCKER_HUB_REPO="pihole" + echo "Defaulting DOCKER_HUB_REPO to ${DOCKER_HUB_REPO}" +fi + +if [[ -z "${DOCKER_HUB_IMAGE_NAME}" ]]; then + DOCKER_HUB_IMAGE_NAME="pihole" + echo "Defaulting DOCKER_HUB_IMAGE_NAME to ${DOCKER_HUB_IMAGE_NAME}" +fi + +BASE_IMAGE="${DOCKER_HUB_REPO}/${DOCKER_HUB_IMAGE_NAME}" + +GIT_TAG="${GIT_TAG:-$GIT_BRANCH}" +ARCH_IMAGE="${BASE_IMAGE}:${GIT_TAG}-${ARCH}-${DEBIAN_VERSION}" +MULTIARCH_IMAGE="${BASE_IMAGE}:${GIT_TAG}" + + + +# To get latest released, cut a release on https://github.com/pi-hole/docker-pi-hole/releases (manually gated for quality control) +latest_tag='UNKNOWN' +if ! latest_tag=$(curl -sI https://github.com/pi-hole/docker-pi-hole/releases/latest | grep --color=never -i Location | awk -F / '{print $NF}' | tr -d '[:cntrl:]'); then + print "Failed to retrieve latest docker-pi-hole release metadata" +else + if [[ "${GIT_TAG}" == "${latest_tag}" ]] ; then + LATEST_IMAGE="${BASE_IMAGE}:latest" + fi +fi + + +set +a diff --git a/install.sh b/install.sh index 2df2275..8b8f40f 100644 --- a/install.sh +++ b/install.sh @@ -15,6 +15,9 @@ fi apt-get update apt-get install --no-install-recommends -y curl procps ca-certificates +# curl in armhf-buster's image has SSL issues. Running c_rehash fixes it. +# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=923479 +c_rehash curl -L -s $S6OVERLAY_RELEASE | tar xvzf - -C / mv /init /s6-init diff --git a/test/conftest.py b/test/conftest.py index bb82273..61d68fd 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -9,6 +9,7 @@ import types local_host = testinfra.get_host('local://') check_output = local_host.check_output +DEBIAN_VERSION = os.environ.get('DEBIAN_VERSION', 'stretch') __version__ = None dotdot = os.path.abspath(os.path.join(os.path.abspath(__file__), os.pardir, os.pardir)) with open('{}/VERSION'.format(dotdot), 'r') as v: @@ -99,8 +100,12 @@ def version(): return __version__ @pytest.fixture() -def tag(version, arch): - return '{}-{}'.format(version, arch) +def debian_version(): + return DEBIAN_VERSION + +@pytest.fixture() +def tag(version, arch, debian_version): + return '{}-{}-{}'.format(version, arch, debian_version) @pytest.fixture def webserver(tag): @@ -125,6 +130,10 @@ def persist_arch(): def persist_version(): return __version__ +@pytest.fixture(scope='module') +def persist_debian_version(): + return DEBIAN_VERSION + @pytest.fixture(scope='module') def persist_args_dns(): return '--dns 127.0.0.1 --dns 1.1.1.1' @@ -147,8 +156,8 @@ def persist_test_args(): return '' @pytest.fixture(scope='module') -def persist_tag(persist_version, persist_arch): - return '{}_{}'.format(persist_version, persist_arch) +def persist_tag(persist_version, persist_arch, persist_debian_version): + return '{}_{}_{}'.format(persist_version, persist_arch, persist_debian_version) @pytest.fixture(scope='module') def persist_webserver(persist_tag): diff --git a/test/test_volume_data.sh b/test/test_volume_data.sh index 2c87a63..0acf9b2 100755 --- a/test/test_volume_data.sh +++ b/test/test_volume_data.sh @@ -33,8 +33,9 @@ trap "cleanup" INT TERM EXIT # VOLUME TESTS # Given... -IMAGE="${1:-pihole:v5.0-amd64}" # Default is latest build test image (generic, non release/branch tag) -VOLUMES="$(mktemp -d)" # A fresh volume directory +DEBIAN_VERSION="$(DEBIAN_VERSION:-stretch)" +IMAGE="${1:-pihole:v5.0-amd64}-${DEBIAN_VERSION}" # Default is latest build test image (generic, non release/branch tag) +VOLUMES="$(mktemp -d)" # A fresh volume directory VOL_PH="$VOLUMES/pihole" VOL_DM="$VOLUMES/dnsmasq.d" tty -s && TTY='-t' || TTY='' diff --git a/tox.ini b/tox.ini index 9d3164d..9342d6b 100644 --- a/tox.ini +++ b/tox.ini @@ -2,7 +2,7 @@ envlist = py38 [testenv] -commands = echo "Use ./circle-test.sh instead for now" +commands = echo "Use ./gh-actions-test.sh instead for now" # Currently out of comission post-python3 upgrade due to failed monkey patch of testinfra sh -> bash #[testenv]