diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 7ef1f32..0000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,98 +0,0 @@ -version: 2 - -.job_template: &job_template - machine: - enabled: true - steps: - - checkout - - run: - command: ./circle-test.sh - - persist_to_workspace: - root: . - paths: [ 'ci-workspace' ] - -jobs: - amd64: - <<: *job_template - arm64: - <<: *job_template - armhf: - <<: *job_template - armel: - <<: *job_template - deploy: - docker: - - image: circleci/python:latest - steps: - - setup_remote_docker: - version: 18.06.0-ce - - checkout - - attach_workspace: - at: . - - run: - command: ./circle-deploy.sh - - - -workflows: - version: 2 - build: - jobs: - - amd64: - filters: - tags: - only: /^v.*/ - - arm64: - filters: - tags: - only: /^v.*/ - - armhf: - filters: - tags: - only: /^v.*/ - #- armel: - # filters: - # tags: - # only: /^v.*/ - - deploy: - requires: - - amd64 - - arm64 - - armhf - #- armel - filters: - tags: - only: /^v.*/ - nightly_build: - triggers: - - schedule: - cron: "0 0 * * *" - filters: - branches: - only: 'beta-v5.0' - jobs: - - amd64: - filters: - tags: - only: /^v.*/ - - arm64: - filters: - tags: - only: /^v.*/ - - armhf: - filters: - tags: - only: /^v.*/ - #- armel: - # filters: - # tags: - # only: /^v.*/ - - deploy: - requires: - - amd64 - - arm64 - - armhf - #- armel - filters: - tags: - only: /^v.*/ diff --git a/Dockerfile.py b/Dockerfile.py index 749db9a..44efac4 100755 --- a/Dockerfile.py +++ b/Dockerfile.py @@ -2,11 +2,12 @@ """ Dockerfile.py - generates and build dockerfiles Usage: - Dockerfile.py [--hub_tag=] [--arch= ...] [--debian= ...] [-v] [-t] [--no-build] [--no-cache] + Dockerfile.py [--hub_tag=] [--arch= ...] [--debian= ...] [-v] [-t] [--no-build] [--no-cache] [--fail-fast] Options: --no-build Skip building the docker images --no-cache Build without using any cache data + --fail-fast Exit on first build error --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] @@ -15,10 +16,9 @@ Options: Examples: """ - - from docopt import docopt import os +import sys import subprocess __version__ = None @@ -28,19 +28,23 @@ with open('{}/VERSION'.format(dot), 'r') as v: __version__ = raw_version.replace('release/', 'release-') -def build_dockerfiles(args): +def build_dockerfiles(args) -> bool: + all_success = True if args['-v']: print(args) if args['--no-build']: print(" ::: Skipping Dockerfile building") - return + return all_success for arch in args['--arch']: for debian_version in args['--debian']: - build('pihole', arch, debian_version, args['--hub_tag'], args['-t'], args['--no-cache'], args['-v']) + all_success = build('pihole', arch, debian_version, args['--hub_tag'], args['-t'], args['--no-cache'], args['-v']) and all_success + if not all_success and args['--fail-fast']: + return False + return all_success -def run_and_stream_command_output(command, environment_vars, verbose): +def run_and_stream_command_output(command, environment_vars, verbose) -> bool: print("Running", command) build_result = subprocess.Popen(command.split(), env=environment_vars, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=1, universal_newlines=True) @@ -52,9 +56,10 @@ def run_and_stream_command_output(command, environment_vars, verbose): if build_result.returncode != 0: print(" ::: Error running".format(command)) print(build_result.stderr) + return build_result.returncode == 0 -def build(docker_repo: str, arch: str, debian_version: str, hub_tag: str, show_time: bool, no_cache: bool, verbose: bool): +def build(docker_repo: str, arch: str, debian_version: str, hub_tag: str, show_time: bool, no_cache: bool, verbose: bool) -> bool: create_tag = f'{docker_repo}:{__version__}-{arch}-{debian_version}' print(f' ::: Building {create_tag}') time_arg = 'time' if show_time else '' @@ -64,15 +69,18 @@ def build(docker_repo: str, arch: str, debian_version: str, hub_tag: str, show_t 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) + success = run_and_stream_command_output(build_command, build_env, verbose) if verbose: print(build_command, '\n') - if hub_tag: + if success and 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) + success = run_and_stream_command_output(hub_tag_command, build_env, verbose) + return success if __name__ == '__main__': args = docopt(__doc__, version='Dockerfile 1.1') - build_dockerfiles(args) + success = build_dockerfiles(args) + exit_code = 0 if success else 1 + sys.exit(exit_code) diff --git a/Dockerfile.sh b/Dockerfile.sh index 9f9d8d7..76ae6e0 100755 --- a/Dockerfile.sh +++ b/Dockerfile.sh @@ -5,7 +5,7 @@ # @param ${ARCH_IMAGE} What the Docker Hub Image should be tagged as [default: None] set -eux -./Dockerfile.py -v --arch="${ARCH}" --debian="${DEBIAN_VERSION}" --hub_tag="${ARCH_IMAGE}" +./Dockerfile.py -v --no-cache --arch="${ARCH}" --debian="${DEBIAN_VERSION}" --hub_tag="${ARCH_IMAGE}" docker images # TODO: Add junitxml output and have something consume it diff --git a/Dockerfile_build b/Dockerfile_build index e40f551..70e5a28 100644 --- a/Dockerfile_build +++ b/Dockerfile_build @@ -3,9 +3,10 @@ FROM python:buster # Only works for docker CLIENT (bind mounted socket) COPY --from=docker:18.09.3 /usr/local/bin/docker /usr/local/bin/ +ARG packages RUN apt-get update && \ apt-get install -y python3-dev curl gcc make \ - libffi-dev libssl-dev \ + libffi-dev libssl-dev ${packages} \ && 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 && \ diff --git a/VERSION b/VERSION index 5e0a0f1..346d9ca 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v5.0 +v5.1.1 diff --git a/circle-deploy.sh b/circle-deploy.sh deleted file mode 100755 index 884383a..0000000 --- a/circle-deploy.sh +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env bash -set -ex -# Circle CI Job for merging/deploying all architectures (post-test passing) -. circle-vars.sh - -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} -} - -# Keep in sync with circle-ci job names -declare -A annotate_map=( - ["amd64"]="--arch amd64" - ["armel"]="--arch arm --variant v6" - ["armhf"]="--arch arm --variant v7" - ["arm64"]="--arch arm64 --variant v8" -) - -# push image when not running a PR -mkdir -p ~/.docker -export DOCKER_CLI_EXPERIMENTAL='enabled' -echo "{}" | jq '.experimental="enabled"' | tee ~/.docker/config.json -docker info -if [[ "$CIRCLE_PR_NUMBER" == "" ]]; then - images=() - echo $DOCKERHUB_PASS | docker login --username=$DOCKERHUB_USER --password-stdin - ls -lat ./ci-workspace/ - cd ci-workspace - - for arch in *; do - arch_image=$(cat $arch) - docker pull $arch_image - images+=($arch_image) - done - - for docker_tag in $MULTIARCH_IMAGE $LATEST_IMAGE; do - docker manifest create $docker_tag ${images[*]} - for arch in *; do - arch_image=$(cat $arch) - docker pull $arch_image - annotate "$docker_tag" "$arch_image" "$arch" - done - - docker manifest inspect "$docker_tag" - docker manifest push --purge "$docker_tag" - done; -fi diff --git a/circle-test.sh b/circle-test.sh deleted file mode 100755 index 38ff736..0000000 --- a/circle-test.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env bash -set -ex - -# Circle CI Job for single architecture - -# setup qemu/variables -docker run --rm --privileged multiarch/qemu-user-static:register --reset > /dev/null -. circle-vars.sh - -if [[ "$1" == "enter" ]]; then - enter="-it --entrypoint=sh" -fi - -# generate and build dockerfile -docker build -t image_pipenv -f Dockerfile_build . -env > /tmp/env -docker run --rm \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v "$(pwd):/$(pwd)" \ - -w "$(pwd)" \ - -e PIPENV_CACHE_DIR="$(pwd)/.pipenv" \ - --env-file /tmp/env \ - $enter image_pipenv - -test -z "${CIRCLE_PROJECT_REPONAME}" && exit 0 -# The rest is circle-ci only -echo $DOCKERHUB_PASS | docker login --username=$DOCKERHUB_USER --password-stdin -docker push $ARCH_IMAGE -mkdir -p ci-workspace -echo "$ARCH_IMAGE" | tee ./ci-workspace/$ARCH diff --git a/circle-vars.sh b/circle-vars.sh deleted file mode 100755 index fbe4db1..0000000 --- a/circle-vars.sh +++ /dev/null @@ -1,48 +0,0 @@ -set -a - -CIRCLE_JOB="${CIRCLE_JOB:-}" -ARCH="${ARCH:-$CIRCLE_JOB}" -if [[ -z "$ARCH" ]] ; then - echo "Defaulting arch to amd64" - ARCH="amd64" -fi -BASE_IMAGE="${BASE_IMAGE:-${CIRCLE_PROJECT_REPONAME}}" -if [[ -z "$BASE_IMAGE" ]] ; then - echo "Defaulting image name to pihole" - BASE_IMAGE="pihole" -fi - -# The docker image will match the github repo path by default but is overrideable with CircleCI environment -# BASE_IMAGE Overridable by Circle environment, including namespace (e.g. BASE_IMAGE=bobsmith/test-img:latest) -CIRCLE_PROJECT_USERNAME="${CIRCLE_PROJECT_USERNAME:-unset}" -HUB_NAMESPACE="${HUB_NAMESPACE:-$CIRCLE_PROJECT_USERNAME}" -[[ $CIRCLE_PROJECT_USERNAME == "pi-hole" ]] && HUB_NAMESPACE="pihole" # Custom mapping for namespace -[[ $BASE_IMAGE != *"/"* ]] && BASE_IMAGE="${HUB_NAMESPACE}/${BASE_IMAGE}" # If missing namespace, add one - -# Secondary docker tag info (origin github branch/tag) will get prepended also -ARCH_IMAGE="$BASE_IMAGE" -[[ $ARCH_IMAGE != *":"* ]] && ARCH_IMAGE="${BASE_IMAGE}:$ARCH" # If tag missing, add circle job name as a tag (architecture here) - -DOCKER_TAG="${CIRCLE_TAG:-$CIRCLE_BRANCH}" -if [[ -n "$DOCKER_TAG" ]]; then - # remove latest tag if used (as part of a user provided image variable) - ARCH_IMAGE="${ARCH_IMAGE/:latest/:}" - # Prepend the github tag(version) or branch. image:arch = image:v1.0-arch - ARCH_IMAGE="${ARCH_IMAGE/:/:${DOCKER_TAG}-}" - # latest- sometimes has a trailing slash, remove it - ARCH_IMAGE="${ARCH_IMAGE/%-/}" -fi - -# To get latest released, cut a release on https://github.com/pi-hole/docker-pi-hole/releases (manually gated for quality control) -latest_tag='' -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 [[ "$DOCKER_TAG" == "$latest_tag" ]] ; then - LATEST_IMAGE="$BASE_IMAGE:latest" - fi -fi - -MULTIARCH_IMAGE="$BASE_IMAGE:$DOCKER_TAG" - -set +a diff --git a/install.sh b/install.sh index 8b8f40f..11fe442 100644 --- a/install.sh +++ b/install.sh @@ -4,7 +4,7 @@ mkdir -p /etc/pihole/ mkdir -p /var/run/pihole # Production tags with valid web footers export CORE_VERSION="$(cat /etc/docker-pi-hole-version)" -export WEB_VERSION="${CORE_VERSION}" +export WEB_VERSION="v5.1" # Only use for pre-production / testing export CHECKOUT_BRANCHES=false @@ -18,6 +18,7 @@ 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 +ln -s `which echo` /usr/local/bin/whiptail curl -L -s $S6OVERLAY_RELEASE | tar xvzf - -C / mv /init /s6-init