Refactor to multistage builds
This commit introduces a huge change in the build process. What changed: - Dockerfile.ldap was integrated into Dockerfile as a seperate [build stage][multistage-build]. - All the build scripts were refactored according to this. - The `docker-compose.yml` file was adjusted likewise. - The main build script, `/build.sh`, now always builds all targets (formerly called variants). - The minimal requirements for Docker and docker-compose have increased. - The build on hub.docker.com must be adjusted. This change should also fix #156 permanently. [multistage-build]: https://docs.docker.com/develop/develop-images/multistage-build/
This commit is contained in:
parent
c148d3ceb9
commit
d0ebb34432
@ -12,28 +12,16 @@ Repository Links: Enable for Base Image
|
||||
Build Rules:
|
||||
- Source Type: Branch
|
||||
Source: master
|
||||
Docker Tag: branches-main
|
||||
Docker Tag: branches
|
||||
Dockerfile location: Dockerfile
|
||||
- Source Type: Branch
|
||||
Source: master
|
||||
Docker Tag: branches-ldap
|
||||
Dockerfile location: Dockerfile.ldap
|
||||
- Source Type: Branch
|
||||
Source: master
|
||||
Docker Tag: prerelease-main
|
||||
Docker Tag: prerelease
|
||||
Dockerfile location: Dockerfile
|
||||
- Source Type: Branch
|
||||
Source: master
|
||||
Docker Tag: prerelease-ldap
|
||||
Dockerfile location: Dockerfile.ldap
|
||||
- Source Type: Branch
|
||||
Source: master
|
||||
Docker Tag: release-main
|
||||
Docker Tag: release
|
||||
Dockerfile location: Dockerfile
|
||||
- Source Type: Branch
|
||||
Source: master
|
||||
Docker Tag: release-ldap
|
||||
Dockerfile location: Dockerfile.ldap
|
||||
Build Environment Variables:
|
||||
# Create an app on Github and use it's OATH credentials here
|
||||
- Key: GITHUB_OAUTH_CLIENT_ID
|
||||
@ -51,16 +39,15 @@ The build system of cloud.docker.com is not made for this kind of project.
|
||||
But we found a way to make it work, and this is how:
|
||||
|
||||
1. The docker hub build system [allows to overwrite the scripts that get executed
|
||||
for `build`, `test` and `push`](overwrite). See `hooks/*`.
|
||||
2. Shared functionality of the scripts `build`, `test` and `push` is extracted to `hooks/common`.
|
||||
3. The `build` script runs `run_build()` from `hooks/common`.
|
||||
This triggers either `build-branches.sh`, `build-latest.sh` or directly `build.sh`.
|
||||
for `build`, `test` and `push`](overwrite). See `/hooks/*`.
|
||||
2. Shared functionality of the scripts `build`, `test` and `push` is extracted to `/hooks/common`.
|
||||
3. The `build` script runs `run_build()` from `/hooks/common`.
|
||||
This triggers either `/build-branches.sh`, `/build-latest.sh` or directly `/build.sh`.
|
||||
4. The `test` script just invokes `docker-compose` commands.
|
||||
5. The `push` script runs `run_build()` from `hooks/common` with a `--push-only` flag.
|
||||
This causes the `build.sh` script to not re-build the Docker image, but just the just built image.
|
||||
|
||||
The _Docker Tag_ configuration setting is misused to select the type (_release_, _prerelease_, _branches_) of the build as well as the variant (_main_, _ldap_).
|
||||
|
||||
The _Dockerfile location_ configuration setting is completely ignored by the build scripts.
|
||||
The _Docker Tag_ configuration setting (`$DOCKER_TAG`) is only used to select the type (_release_, _prerelease_, _branches_) of the build in `hooks/common`.
|
||||
Because it has a different meaning in all the other build scripts, it is `unset` after it has served it's purpose.
|
||||
|
||||
[overwrite]: https://docs.docker.com/docker-hub/builds/advanced/#override-build-test-or-push-commands
|
||||
|
14
Dockerfile
14
Dockerfile
@ -1,4 +1,5 @@
|
||||
FROM python:3.7-alpine3.10
|
||||
ARG FROM=python:3.7-alpine
|
||||
FROM ${FROM} as main
|
||||
|
||||
RUN apk add --no-cache \
|
||||
bash \
|
||||
@ -71,3 +72,14 @@ LABEL SRC_URL="$URL"
|
||||
|
||||
ARG NETBOX_DOCKER_PROJECT_VERSION=snapshot
|
||||
LABEL NETBOX_DOCKER_PROJECT_VERSION="$NETBOX_DOCKER_PROJECT_VERSION"
|
||||
|
||||
#####
|
||||
## LDAP specific tasks
|
||||
#####
|
||||
|
||||
FROM main as ldap
|
||||
|
||||
RUN pip install django_auth_ldap
|
||||
|
||||
COPY docker/ldap_config.docker.py /opt/netbox/netbox/netbox/ldap_config.py
|
||||
COPY configuration/ldap_config.py /etc/netbox/config/ldap_config.py
|
||||
|
@ -1,9 +0,0 @@
|
||||
ARG DOCKER_ORG=netboxcommunity
|
||||
ARG DOCKER_REPO=netbox
|
||||
ARG FROM_TAG=latest
|
||||
FROM $DOCKER_ORG/$DOCKER_REPO:$FROM_TAG
|
||||
|
||||
RUN pip install django_auth_ldap
|
||||
|
||||
COPY docker/ldap_config.docker.py /opt/netbox/netbox/netbox/ldap_config.py
|
||||
COPY configuration/ldap_config.py /etc/netbox/config/ldap_config.py
|
@ -49,8 +49,8 @@ Default credentials:
|
||||
|
||||
This project relies only on *Docker* and *docker-compose* meeting this requirements:
|
||||
|
||||
* The *Docker version* must be at least `1.13.0`.
|
||||
* The *docker-compose version* must be at least `1.10.0`.
|
||||
* The *Docker version* must be at least `17.05`.
|
||||
* The *docker-compose version* must be at least `1.17.0`.
|
||||
|
||||
To ensure this, compare the output of `docker --version` and `docker-compose --version` with the requirements above.
|
||||
|
||||
|
78
build-all.sh
78
build-all.sh
@ -12,8 +12,6 @@ BUILDS=("${BUILD:-"${ALL_BUILDS[@]}"}")
|
||||
|
||||
echo "⚙️ Configured builds: ${BUILDS[*]}"
|
||||
|
||||
VARIANTS=("main" "ldap")
|
||||
|
||||
if [ -n "${DEBUG}" ]; then
|
||||
export DEBUG
|
||||
fi
|
||||
@ -22,63 +20,35 @@ ERROR=0
|
||||
|
||||
# Don't build if not on `master` and don't build if on a pull request,
|
||||
# but build when DEBUG is not empty
|
||||
for VARIANT in "${VARIANTS[@]}"; do
|
||||
export VARIANT
|
||||
|
||||
# Checking which VARIANT to build
|
||||
if [ "${VARIANT}" == "main" ]; then
|
||||
DOCKERFILE="${DOCKERFILE_PATH-Dockerfile}"
|
||||
else
|
||||
DOCKERFILE="${DOCKERFILE_PATH-Dockerfile}.${VARIANT}"
|
||||
|
||||
# Fail fast
|
||||
if [ ! -f "${DOCKERFILE}" ]; then
|
||||
echo "🚨 The Dockerfile '${DOCKERFILE}' for variant '${VARIANT}' doesn't exist."
|
||||
ERROR=1
|
||||
for BUILD in "${BUILDS[@]}"; do
|
||||
echo "🛠 Building '$BUILD' from '$DOCKERFILE'"
|
||||
case $BUILD in
|
||||
release)
|
||||
# build the latest release
|
||||
# shellcheck disable=SC2068
|
||||
./build-latest.sh $@ || ERROR=1
|
||||
;;
|
||||
prerelease)
|
||||
# build the latest pre-release
|
||||
# shellcheck disable=SC2068
|
||||
PRERELEASE=true ./build-latest.sh $@ || ERROR=1
|
||||
;;
|
||||
branches)
|
||||
# build all branches
|
||||
# shellcheck disable=SC2068
|
||||
./build-branches.sh $@ || ERROR=1
|
||||
;;
|
||||
*)
|
||||
echo "🚨 Unrecognized build '$BUILD'."
|
||||
|
||||
if [ -z "$DEBUG" ]; then
|
||||
continue
|
||||
exit 1
|
||||
else
|
||||
echo "⚠️ Would skip this, but DEBUG is enabled."
|
||||
echo "⚠️ Would exit here with code '1', but DEBUG is enabled."
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
for BUILD in "${BUILDS[@]}"; do
|
||||
echo "🛠 Building '$BUILD' from '$DOCKERFILE'"
|
||||
case $BUILD in
|
||||
release)
|
||||
# build the latest release
|
||||
# shellcheck disable=SC2068
|
||||
./build-latest.sh $@ || ERROR=1
|
||||
;;
|
||||
prerelease)
|
||||
# build the latest pre-release
|
||||
# shellcheck disable=SC2068
|
||||
PRERELEASE=true ./build-latest.sh $@ || ERROR=1
|
||||
;;
|
||||
branches)
|
||||
# build all branches
|
||||
# shellcheck disable=SC2068
|
||||
./build-branches.sh $@ || ERROR=1
|
||||
;;
|
||||
special)
|
||||
# special build
|
||||
# shellcheck disable=SC2068
|
||||
#SRC_ORG=lampwins TAG=webhooks-backend ./build.sh "feature/webhooks-backend" $@ || ERROR=1
|
||||
echo "✅ No special builds today."
|
||||
;;
|
||||
*)
|
||||
echo "🚨 Unrecognized build '$BUILD'."
|
||||
|
||||
if [ -z "$DEBUG" ]; then
|
||||
exit 1
|
||||
else
|
||||
echo "⚠️ Would exit here with code '1', but DEBUG is enabled."
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
exit $ERROR
|
||||
|
@ -3,6 +3,10 @@
|
||||
|
||||
echo "▶️ $0 $*"
|
||||
|
||||
###
|
||||
# Checking for the presence of GITHUB_OAUTH_CLIENT_ID
|
||||
# and GITHUB_OAUTH_CLIENT_SECRET
|
||||
###
|
||||
if [ -n "${GITHUB_OAUTH_CLIENT_ID}" ] && [ -n "${GITHUB_OAUTH_CLIENT_SECRET}" ]; then
|
||||
echo "🗝 Performing authenticated Github API calls."
|
||||
GITHUB_OAUTH_PARAMS="client_id=${GITHUB_OAUTH_CLIENT_ID}&client_secret=${GITHUB_OAUTH_CLIENT_SECRET}"
|
||||
@ -11,18 +15,33 @@ else
|
||||
GITHUB_OAUTH_PARAMS=""
|
||||
fi
|
||||
|
||||
###
|
||||
# Calling Github to get the all branches
|
||||
###
|
||||
ORIGINAL_GITHUB_REPO="${SRC_ORG-netbox-community}/${SRC_REPO-netbox}"
|
||||
GITHUB_REPO="${GITHUB_REPO-$ORIGINAL_GITHUB_REPO}"
|
||||
URL_RELEASES="https://api.github.com/repos/${GITHUB_REPO}/branches?${GITHUB_OAUTH_PARAMS}"
|
||||
|
||||
# Composing the JQ commans to extract the most recent version number
|
||||
JQ_BRANCHES='map(.name) | .[] | scan("^[^v].+") | match("^(master|develop).*") | .string'
|
||||
|
||||
CURL="curl -sS"
|
||||
|
||||
BRANCHES=$($CURL "${URL_RELEASES}" | jq -r 'map(.name) | .[] | scan("^[^v].+") | match("^(master|develop).*") | .string')
|
||||
# Querying the Github API to fetch all branches
|
||||
BRANCHES=$($CURL "${URL_RELEASES}" | jq -r "$JQ_BRANCHES")
|
||||
|
||||
###
|
||||
# Building each branch
|
||||
###
|
||||
|
||||
# keeping track whether an error occured
|
||||
ERROR=0
|
||||
|
||||
# calling build.sh for each branch
|
||||
for BRANCH in $BRANCHES; do
|
||||
# shellcheck disable=SC2068
|
||||
./build.sh "${BRANCH}" $@ || ERROR=1
|
||||
done
|
||||
|
||||
# returning whether an error occured
|
||||
exit $ERROR
|
||||
|
@ -3,6 +3,10 @@
|
||||
|
||||
echo "▶️ $0 $*"
|
||||
|
||||
###
|
||||
# Checking for the presence of GITHUB_OAUTH_CLIENT_ID
|
||||
# and GITHUB_OAUTH_CLIENT_SECRET
|
||||
###
|
||||
if [ -n "${GITHUB_OAUTH_CLIENT_ID}" ] && [ -n "${GITHUB_OAUTH_CLIENT_SECRET}" ]; then
|
||||
echo "🗝 Performing authenticated Github API calls."
|
||||
GITHUB_OAUTH_PARAMS="client_id=${GITHUB_OAUTH_CLIENT_ID}&client_secret=${GITHUB_OAUTH_CLIENT_SECRET}"
|
||||
@ -11,17 +15,38 @@ else
|
||||
GITHUB_OAUTH_PARAMS=""
|
||||
fi
|
||||
|
||||
###
|
||||
# Checking if PRERELEASE is either unset, 'true' or 'false'
|
||||
###
|
||||
if [ -n "$PRERELEASE" ] &&
|
||||
{ [ "$PRERELEASE" != "true" ] && [ "$PRERELEASE" != "false" ]; }; then
|
||||
|
||||
if [ -z "$DEBUG" ]; then
|
||||
echo "⚠️ PRERELEASE must be either unset, 'true' or 'false', but was \"$PRERELEASE\"!"
|
||||
exit 1
|
||||
else
|
||||
echo "⚠️ Would exit here with code '0', but DEBUG is enabled."
|
||||
fi
|
||||
fi
|
||||
|
||||
###
|
||||
# Calling Github to get the latest version
|
||||
###
|
||||
ORIGINAL_GITHUB_REPO="netbox-community/netbox"
|
||||
GITHUB_REPO="${GITHUB_REPO-$ORIGINAL_GITHUB_REPO}"
|
||||
URL_RELEASES="https://api.github.com/repos/${GITHUB_REPO}/releases?${GITHUB_OAUTH_PARAMS}"
|
||||
|
||||
# Composing the JQ commans to extract the most recent version number
|
||||
JQ_LATEST="group_by(.prerelease) | .[] | sort_by(.published_at) | reverse | .[0] | select(.prerelease==${PRERELEASE-false}) | .tag_name"
|
||||
|
||||
CURL="curl -sS"
|
||||
|
||||
# Querying the Github API to fetch the most recent version number
|
||||
VERSION=$($CURL "${URL_RELEASES}" | jq -r "${JQ_LATEST}")
|
||||
|
||||
###
|
||||
# Check if the prerelease version is actually higher than stable version
|
||||
###
|
||||
if [ "${PRERELEASE}" == "true" ]; then
|
||||
JQ_STABLE="group_by(.prerelease) | .[] | sort_by(.published_at) | reverse | .[0] | select(.prerelease==false) | .tag_name"
|
||||
STABLE_VERSION=$($CURL "${URL_RELEASES}" | jq -r "${JQ_STABLE}")
|
||||
@ -35,8 +60,9 @@ if [ "${PRERELEASE}" == "true" ]; then
|
||||
# shellcheck disable=SC2003
|
||||
MINOR_UNSTABLE=$(expr match "${VERSION}" 'v[0-9]\+\.\([0-9]\+\)')
|
||||
|
||||
if ( [ "$MAJOR_STABLE" -eq "$MAJOR_UNSTABLE" ] && [ "$MINOR_STABLE" -ge "$MINOR_UNSTABLE" ] ) \
|
||||
if { [ "$MAJOR_STABLE" -eq "$MAJOR_UNSTABLE" ] && [ "$MINOR_STABLE" -ge "$MINOR_UNSTABLE" ]; } \
|
||||
|| [ "$MAJOR_STABLE" -gt "$MAJOR_UNSTABLE" ]; then
|
||||
|
||||
echo "❎ Latest unstable version ('$VERSION') is not higher than the latest stable version ('$STABLE_VERSION')."
|
||||
if [ -z "$DEBUG" ]; then
|
||||
exit 0
|
||||
@ -46,23 +72,33 @@ if [ "${PRERELEASE}" == "true" ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check if that version is not already available on docker hub:
|
||||
###
|
||||
# Compose DOCKER_TAG to build
|
||||
###
|
||||
if [ -z "$DOCKER_TARGET" ] || [ "$DOCKER_TARGET" == "main" ]; then
|
||||
DOCKER_TAG="${VERSION}"
|
||||
else
|
||||
DOCKER_TAG="${VERSION}-${DOCKER_TARGET}"
|
||||
fi
|
||||
|
||||
###
|
||||
# Check if the version received is not already available on Docker Hub:
|
||||
###
|
||||
ORIGINAL_DOCKERHUB_REPO="${DOCKER_ORG-netboxcommunity}/${DOCKER_REPO-netbox}"
|
||||
DOCKERHUB_REPO="${DOCKERHUB_REPO-$ORIGINAL_DOCKERHUB_REPO}"
|
||||
|
||||
# Bearer Token
|
||||
URL_DOCKERHUB_TOKEN="https://auth.docker.io/token?service=registry.docker.io&scope=repository:${DOCKERHUB_REPO}:pull"
|
||||
BEARER_TOKEN="$($CURL "${URL_DOCKERHUB_TOKEN}" | jq -r .token)"
|
||||
|
||||
# Actual API call
|
||||
URL_DOCKERHUB_TAG="https://registry.hub.docker.com/v2/${DOCKERHUB_REPO}/tags/list"
|
||||
AUTHORIZATION_HEADER="Authorization: Bearer ${BEARER_TOKEN}"
|
||||
|
||||
if [ -z "$VARIANT" ] || [ "$VARIANT" == "main" ]; then
|
||||
DOCKER_TAG="${VERSION}"
|
||||
else
|
||||
DOCKER_TAG="${VERSION}-${VARIANT}"
|
||||
fi
|
||||
|
||||
ALREADY_BUILT="$($CURL -H "${AUTHORIZATION_HEADER}" "${URL_DOCKERHUB_TAG}" | jq -e ".tags | any(.==\"${DOCKER_TAG}\")")"
|
||||
|
||||
###
|
||||
# Only build the image if it's not already been built before
|
||||
###
|
||||
if [ -n "$DEBUG" ] || [ "$ALREADY_BUILT" == "false" ]; then
|
||||
if [ -n "$DEBUG" ]; then
|
||||
echo "⚠️ Would not build, because ${DOCKER_TAG} already exists on https://hub.docker.com/r/${DOCKERHUB_REPO}, but DEBUG is enabled."
|
||||
|
231
build.sh
231
build.sh
@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
# Builds the Dockerfile[.variant] and injects tgz'ed Netbox code from Github
|
||||
# Builds the Dockerfile and injects tgz'ed Netbox code from Github
|
||||
|
||||
echo "▶️ $0 $*"
|
||||
|
||||
@ -12,12 +12,6 @@ if [ "${1}x" == "x" ] || [ "${1}" == "--help" ] || [ "${1}" == "-h" ]; then
|
||||
echo " --push-only Does not build. Only pushes the Docker image to the registry."
|
||||
echo ""
|
||||
echo "You can use the following ENV variables to customize the build:"
|
||||
echo " DEBUG If defined, the script does not stop when certain checks are unsatisfied."
|
||||
echo " DRY_RUN Prints all build statements instead of running them."
|
||||
echo " DOCKER_OPTS Add parameters to Docker."
|
||||
echo " Default:"
|
||||
echo " When <TAG> starts with 'v': \"\""
|
||||
echo " Else: \"--no-cache\""
|
||||
echo " BRANCH The branch to build."
|
||||
echo " Also used for tagging the image."
|
||||
echo " TAG The version part of the docker tag."
|
||||
@ -25,18 +19,27 @@ if [ "${1}x" == "x" ] || [ "${1}" == "--help" ] || [ "${1}" == "-h" ]; then
|
||||
echo " When <BRANCH>=master: latest"
|
||||
echo " When <BRANCH>=develop: snapshot"
|
||||
echo " Else: same as <BRANCH>"
|
||||
echo " DOCKER_ORG The Docker registry (i.e. hub.docker.com/r/<DOCKER_ORG>/<DOCKER_REPO>) "
|
||||
echo " DOCKER_OPTS Add parameters to Docker."
|
||||
echo " Default:"
|
||||
echo " When <TAG> starts with 'v': \"\""
|
||||
echo " Else: \"--no-cache\""
|
||||
echo " DOCKER_ORG The Docker registry (i.e. hub.docker.com/r/<DOCKER_ORG>/<DOCKER_REPO>)"
|
||||
echo " Also used for tagging the image."
|
||||
echo " Default: netboxcommunity"
|
||||
echo " DOCKER_REPO The Docker registry (i.e. hub.docker.com/r/<DOCKER_ORG>/<DOCKER_REPO>) "
|
||||
echo " DOCKER_REPO The Docker registry (i.e. hub.docker.com/r/<DOCKER_ORG>/<DOCKER_REPO>)"
|
||||
echo " Also used for tagging the image."
|
||||
echo " Default: netbox"
|
||||
echo " DOCKER_FROM The base image to use."
|
||||
echo " Default: Whatever is defined as default in the Dockerfile."
|
||||
echo " DOCKER_TAG The name of the tag which is applied to the image."
|
||||
echo " Useful for pushing into another registry than hub.docker.com."
|
||||
echo " Default: <DOCKER_ORG>/<DOCKER_REPO>:<BRANCH>"
|
||||
echo " DOCKER_SHORT_TAG The name of the short tag which is applied to the image."
|
||||
echo " This is used to tag all patch releases to their containing version e.g. v2.5.1 -> v2.5"
|
||||
echo " DOCKER_SHORT_TAG The name of the short tag which is applied to the"
|
||||
echo " image. This is used to tag all patch releases to their"
|
||||
echo " containing version e.g. v2.5.1 -> v2.5"
|
||||
echo " Default: <DOCKER_ORG>/<DOCKER_REPO>:\$MAJOR.\$MINOR"
|
||||
echo " DOCKERFILE The name of Dockerfile to use."
|
||||
echo " Default: Dockerfile"
|
||||
echo " SRC_ORG Which fork of netbox to use (i.e. github.com/<SRC_ORG>/<SRC_REPO>)."
|
||||
echo " Default: netbox-community"
|
||||
echo " SRC_REPO The name of the netbox for to use (i.e. github.com/<SRC_ORG>/<SRC_REPO>)."
|
||||
@ -44,18 +47,6 @@ if [ "${1}x" == "x" ] || [ "${1}" == "--help" ] || [ "${1}" == "-h" ]; then
|
||||
echo " URL Where to fetch the package from."
|
||||
echo " Must be a tar.gz file of the source code."
|
||||
echo " Default: https://github.com/<SRC_ORG>/<SRC_REPO>/archive/\$BRANCH.tar.gz"
|
||||
echo " VARIANT The variant to build."
|
||||
echo " The value will be used as a suffix to the \$TAG and for the Dockerfile"
|
||||
echo " selection. The TAG being build must exist for the base variant and"
|
||||
echo " corresponding Dockerfile must start with the following lines:"
|
||||
echo " ARG DOCKER_ORG=netboxcommunity"
|
||||
echo " ARG DOCKER_REPO=netbox"
|
||||
echo " ARG FROM_TAG=latest"
|
||||
echo " FROM \$DOCKER_ORG/\$DOCKER_REPO:\$FROM_TAG"
|
||||
echo " Example: VARIANT=ldap will result in the tag 'latest-ldap' and the"
|
||||
echo " Dockerfile './Dockerfile.ldap' being used."
|
||||
echo " Exception: VARIANT=main will use the './Dockerfile' Dockerfile"
|
||||
echo " Default: main"
|
||||
echo " HTTP_PROXY The proxy to use for http requests."
|
||||
echo " Example: http://proxy.domain.tld:3128"
|
||||
echo " Default: empty"
|
||||
@ -68,6 +59,8 @@ if [ "${1}x" == "x" ] || [ "${1}" == "--help" ] || [ "${1}" == "-h" ]; then
|
||||
echo " NO_PROXY Comma-separated list of domain extensions proxy should not be used for."
|
||||
echo " Example: .domain1.tld,.domain2.tld"
|
||||
echo " Default: empty"
|
||||
echo " DEBUG If defined, the script does not stop when certain checks are unsatisfied."
|
||||
echo " DRY_RUN Prints all build statements instead of running them."
|
||||
|
||||
if [ "${1}x" == "x" ]; then
|
||||
exit 1
|
||||
@ -76,27 +69,27 @@ if [ "${1}x" == "x" ] || [ "${1}" == "--help" ] || [ "${1}" == "-h" ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
# read the project version and trim it
|
||||
###
|
||||
# read the project version from the `VERSION` file and trim it
|
||||
# see https://stackoverflow.com/a/3232433/172132
|
||||
###
|
||||
NETBOX_DOCKER_PROJECT_VERSION="${NETBOX_DOCKER_PROJECT_VERSION-$(sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' VERSION)}"
|
||||
|
||||
###
|
||||
# variables for fetching the source
|
||||
###
|
||||
SRC_ORG="${SRC_ORG-netbox-community}"
|
||||
SRC_REPO="${SRC_REPO-netbox}"
|
||||
BRANCH="${1}"
|
||||
URL="${URL-https://github.com/${SRC_ORG}/${SRC_REPO}/archive/$BRANCH.tar.gz}"
|
||||
|
||||
# Checking which VARIANT to build
|
||||
VARIANT="${VARIANT-main}"
|
||||
if [ "$VARIANT" == "main" ]; then
|
||||
DOCKERFILE="Dockerfile"
|
||||
else
|
||||
DOCKERFILE="Dockerfile.${VARIANT}"
|
||||
fi
|
||||
|
||||
# Fail fast
|
||||
###
|
||||
# Determining the value for DOCKERFILE
|
||||
# and checking whether it exists
|
||||
###
|
||||
DOCKERFILE="${DOCKERFILE-Dockerfile}"
|
||||
if [ ! -f "${DOCKERFILE}" ]; then
|
||||
echo "🚨 The Dockerfile ${DOCKERFILE} for variant '${VARIANT}' doesn't exist."
|
||||
echo "🚨 The Dockerfile ${DOCKERFILE} doesn't exist."
|
||||
|
||||
if [ -z "$DEBUG" ]; then
|
||||
exit 1
|
||||
@ -105,7 +98,9 @@ if [ ! -f "${DOCKERFILE}" ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
###
|
||||
# variables for tagging the docker image
|
||||
###
|
||||
DOCKER_ORG="${DOCKER_ORG-netboxcommunity}"
|
||||
DOCKER_REPO="${DOCKER_REPO-netbox}"
|
||||
case "${BRANCH}" in
|
||||
@ -117,81 +112,109 @@ case "${BRANCH}" in
|
||||
TAG="${TAG-$BRANCH}";;
|
||||
esac
|
||||
|
||||
DOCKER_TAG="${DOCKER_TAG-${DOCKER_ORG}/${DOCKER_REPO}:${TAG}}"
|
||||
if [ "$VARIANT" != "main" ]; then
|
||||
DOCKER_TAG="${DOCKER_TAG}-${VARIANT}"
|
||||
fi
|
||||
|
||||
if [[ "${TAG}" =~ ^v([0-9]+)\.([0-9]+)\.[0-9]+$ ]]; then
|
||||
MAJOR=${BASH_REMATCH[1]}
|
||||
MINOR=${BASH_REMATCH[2]}
|
||||
|
||||
DOCKER_SHORT_TAG="${DOCKER_SHORT_TAG-${DOCKER_ORG}/${DOCKER_REPO}:v${MAJOR}.${MINOR}}"
|
||||
|
||||
if [ "$VARIANT" != "main" ]; then
|
||||
DOCKER_SHORT_TAG="${DOCKER_SHORT_TAG}-${VARIANT}"
|
||||
DOCKER_TARGETS=("main" "ldap")
|
||||
for DOCKER_TARGET in "${DOCKER_TARGETS[@]}"; do
|
||||
###
|
||||
# composing the final DOCKER_TAG
|
||||
###
|
||||
DOCKER_TAG="${DOCKER_TAG-${DOCKER_ORG}/${DOCKER_REPO}:${TAG}}"
|
||||
if [ "$DOCKER_TARGET" != "main" ]; then
|
||||
DOCKER_TAG="${DOCKER_TAG}-${DOCKER_TARGET}"
|
||||
fi
|
||||
fi
|
||||
|
||||
DOCKER_OPTS=("${DOCKER_OPTS[@]}")
|
||||
###
|
||||
# composing the additional DOCKER_SHORT_TAG,
|
||||
# i.e. "v2.6.1" becomes "v2.6",
|
||||
# which is only relevant for version tags
|
||||
###
|
||||
if [[ "${TAG}" =~ ^v([0-9]+)\.([0-9]+)\.[0-9]+$ ]]; then
|
||||
MAJOR=${BASH_REMATCH[1]}
|
||||
MINOR=${BASH_REMATCH[2]}
|
||||
|
||||
# caching is only ok for version tags
|
||||
case "${TAG}" in
|
||||
v*) ;;
|
||||
*) DOCKER_OPTS+=( "--no-cache" ) ;;
|
||||
esac
|
||||
DOCKER_SHORT_TAG="${DOCKER_SHORT_TAG-${DOCKER_ORG}/${DOCKER_REPO}:v${MAJOR}.${MINOR}}"
|
||||
|
||||
DOCKER_OPTS+=( "--pull" )
|
||||
|
||||
# Build args
|
||||
DOCKER_BUILD_ARGS=(
|
||||
--build-arg "NETBOX_DOCKER_PROJECT_VERSION=${NETBOX_DOCKER_PROJECT_VERSION}"
|
||||
--build-arg "FROM_TAG=${TAG}"
|
||||
--build-arg "BRANCH=${BRANCH}"
|
||||
--build-arg "URL=${URL}"
|
||||
--build-arg "DOCKER_ORG=${DOCKER_ORG}"
|
||||
--build-arg "DOCKER_REPO=${DOCKER_REPO}"
|
||||
)
|
||||
if [ -n "$HTTP_PROXY" ]; then
|
||||
DOCKER_BUILD_ARGS+=( --build-arg "http_proxy=${HTTP_PROXY}" )
|
||||
fi
|
||||
if [ -n "$HTTPS_PROXY" ]; then
|
||||
DOCKER_BUILD_ARGS+=( --build-arg "https_proxy=${HTTPS_PROXY}" )
|
||||
fi
|
||||
if [ -n "$FTP_PROXY" ]; then
|
||||
DOCKER_BUILD_ARGS+=( --build-arg "ftp_proxy=${FTP_PROXY}" )
|
||||
fi
|
||||
if [ -n "$NO_PROXY" ]; then
|
||||
DOCKER_BUILD_ARGS+=( --build-arg "no_proxy=${NO_PROXY}" )
|
||||
fi
|
||||
|
||||
if [ -z "$DRY_RUN" ]; then
|
||||
DOCKER_CMD="docker"
|
||||
else
|
||||
echo "⚠️ DRY_RUN MODE ON ⚠️"
|
||||
DOCKER_CMD="echo docker"
|
||||
fi
|
||||
|
||||
if [ "${2}" != "--push-only" ] ; then
|
||||
echo "🐳 Building the Docker image '${DOCKER_TAG}' from the url '${URL}'."
|
||||
$DOCKER_CMD build -t "${DOCKER_TAG}" "${DOCKER_BUILD_ARGS[@]}" "${DOCKER_OPTS[@]}" -f "${DOCKERFILE}" .
|
||||
echo "✅ Finished building the Docker images '${DOCKER_TAG}'"
|
||||
|
||||
if [ -n "$DOCKER_SHORT_TAG" ]; then
|
||||
echo "🐳 Tagging image '${DOCKER_SHORT_TAG}'."
|
||||
$DOCKER_CMD tag "${DOCKER_TAG}" "${DOCKER_SHORT_TAG}"
|
||||
echo "✅ Tagged image '${DOCKER_SHORT_TAG}'"
|
||||
if [ "$DOCKER_TARGET" != "main" ]; then
|
||||
DOCKER_SHORT_TAG="${DOCKER_SHORT_TAG}-${DOCKER_TARGET}"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "${2}" == "--push" ] || [ "${2}" == "--push-only" ] ; then
|
||||
echo "⏫ Pushing '${DOCKER_TAG}"
|
||||
$DOCKER_CMD push "${DOCKER_TAG}"
|
||||
echo "✅ Finished pushing the Docker image '${DOCKER_TAG}'."
|
||||
###
|
||||
# Composing global Docker CLI arguments
|
||||
###
|
||||
DOCKER_OPTS=("${DOCKER_OPTS[@]}")
|
||||
|
||||
if [ -n "$DOCKER_SHORT_TAG" ]; then
|
||||
echo "⏫ Pushing '${DOCKER_SHORT_TAG}'"
|
||||
$DOCKER_CMD push "${DOCKER_SHORT_TAG}"
|
||||
echo "✅ Finished pushing the Docker image '${DOCKER_SHORT_TAG}'."
|
||||
# caching is only ok for version tags
|
||||
case "${TAG}" in
|
||||
v*) ;;
|
||||
*) DOCKER_OPTS+=( --no-cache ) ;;
|
||||
esac
|
||||
|
||||
DOCKER_OPTS+=( --pull )
|
||||
DOCKER_OPTS+=( --target "$DOCKER_TARGET" )
|
||||
|
||||
###
|
||||
# Composing arguments for `docker build` CLI
|
||||
###
|
||||
DOCKER_BUILD_ARGS=(
|
||||
--build-arg "NETBOX_DOCKER_PROJECT_VERSION=${NETBOX_DOCKER_PROJECT_VERSION}"
|
||||
--build-arg "BRANCH=${BRANCH}"
|
||||
--build-arg "URL=${URL}"
|
||||
--build-arg "DOCKER_ORG=${DOCKER_ORG}"
|
||||
--build-arg "DOCKER_REPO=${DOCKER_REPO}"
|
||||
)
|
||||
if [ -n "$DOCKER_FROM" ]; then
|
||||
DOCKER_BUILD_ARGS+=( --build-arg "FROM=${DOCKER_FROM}" )
|
||||
fi
|
||||
fi
|
||||
if [ -n "$HTTP_PROXY" ]; then
|
||||
DOCKER_BUILD_ARGS+=( --build-arg "http_proxy=${HTTP_PROXY}" )
|
||||
fi
|
||||
if [ -n "$HTTPS_PROXY" ]; then
|
||||
DOCKER_BUILD_ARGS+=( --build-arg "https_proxy=${HTTPS_PROXY}" )
|
||||
fi
|
||||
if [ -n "$FTP_PROXY" ]; then
|
||||
DOCKER_BUILD_ARGS+=( --build-arg "ftp_proxy=${FTP_PROXY}" )
|
||||
fi
|
||||
if [ -n "$NO_PROXY" ]; then
|
||||
DOCKER_BUILD_ARGS+=( --build-arg "no_proxy=${NO_PROXY}" )
|
||||
fi
|
||||
|
||||
###
|
||||
# Determining the build command to use
|
||||
###
|
||||
if [ -z "$DRY_RUN" ]; then
|
||||
DOCKER_CMD="docker"
|
||||
else
|
||||
echo "⚠️ DRY_RUN MODE ON ⚠️"
|
||||
DOCKER_CMD="echo docker"
|
||||
fi
|
||||
|
||||
###
|
||||
# Building the docker images, except if `--push-only` is passed
|
||||
###
|
||||
if [ "${2}" != "--push-only" ] ; then
|
||||
echo "🐳 Building the Docker image '${DOCKER_TAG}' from the url '${URL}'."
|
||||
$DOCKER_CMD build -t "${DOCKER_TAG}" "${DOCKER_BUILD_ARGS[@]}" "${DOCKER_OPTS[@]}" -f "${DOCKERFILE}" .
|
||||
echo "✅ Finished building the Docker images '${DOCKER_TAG}'"
|
||||
|
||||
if [ -n "$DOCKER_SHORT_TAG" ]; then
|
||||
echo "🐳 Tagging image '${DOCKER_SHORT_TAG}'."
|
||||
$DOCKER_CMD tag "${DOCKER_TAG}" "${DOCKER_SHORT_TAG}"
|
||||
echo "✅ Tagged image '${DOCKER_SHORT_TAG}'"
|
||||
fi
|
||||
fi
|
||||
|
||||
###
|
||||
# Pushing the docker images if either `--push` or `--push-only` are passed
|
||||
###
|
||||
if [ "${2}" == "--push" ] || [ "${2}" == "--push-only" ] ; then
|
||||
echo "⏫ Pushing '${DOCKER_TAG}"
|
||||
$DOCKER_CMD push "${DOCKER_TAG}"
|
||||
echo "✅ Finished pushing the Docker image '${DOCKER_TAG}'."
|
||||
|
||||
if [ -n "$DOCKER_SHORT_TAG" ]; then
|
||||
echo "⏫ Pushing '${DOCKER_SHORT_TAG}'"
|
||||
$DOCKER_CMD push "${DOCKER_SHORT_TAG}"
|
||||
echo "✅ Finished pushing the Docker image '${DOCKER_SHORT_TAG}'."
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
@ -1,10 +1,11 @@
|
||||
version: '3'
|
||||
version: '3.4'
|
||||
services:
|
||||
netbox: &netbox
|
||||
build:
|
||||
context: .
|
||||
args:
|
||||
- BRANCH=${VERSION-master}
|
||||
context: .
|
||||
target: ${DOCKER_TARGET-main}
|
||||
args:
|
||||
- BRANCH=${VERSION-master}
|
||||
image: netboxcommunity/netbox:${VERSION-latest}
|
||||
depends_on:
|
||||
- postgres
|
||||
|
46
hooks/common
46
hooks/common
@ -1,37 +1,19 @@
|
||||
#!/bin/bash
|
||||
|
||||
ensure_jq() {
|
||||
echo "🛠🛠🛠 Installing JQ via apt-get"
|
||||
[ -x "$(command -v jq)" ] || ( apt-get update && apt-get install -y jq )
|
||||
}
|
||||
|
||||
ensure_dockerfile_present() {
|
||||
if [ "${VARIANT}" == "main" ]; then
|
||||
DOCKERFILE="Dockerfile"
|
||||
else
|
||||
DOCKERFILE="Dockerfile.${VARIANT}"
|
||||
|
||||
# Fail fast
|
||||
if [ ! -f "${DOCKERFILE}" ]; then
|
||||
echo "🚨 The Dockerfile '${DOCKERFILE}' for variant '${VARIANT}' doesn't exist."
|
||||
|
||||
if [ -z "$DEBUG" ]; then
|
||||
exit 1
|
||||
else
|
||||
echo "⚠️ Would skip this, but DEBUG is enabled."
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "${DOCKERFILE}" != "${DOCKERFILE_PATH}" ]; then
|
||||
echo "⚠️ The specified Dockerfile '${DOCKERFILE_PATH}' does not match the expected Dockerfile '${DOCKERFILE}'."
|
||||
echo " This script will use '${DOCKERFILE}' and ignore '${DOCKERFILE_PATH}'."
|
||||
if [ ! -x "$(command -v jq)" ]; then
|
||||
if [ ! -x "$(command -v apt-get)" ]; then
|
||||
echo "🛠🛠🛠 Installing 'jq' via 'apt-get'"
|
||||
apt-get update && apt-get install -y jq
|
||||
else
|
||||
echo "⚠️⚠️⚠️ apt-get not found, unable to automatically install 'jq'."
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Passes args to the scripts
|
||||
run_build() {
|
||||
echo "🐳🐳🐳 Building '${BUILD}' images, the '${VARIANT:-main}' variant"
|
||||
echo "🐳🐳🐳 Building '${BUILD}' images"
|
||||
case $BUILD in
|
||||
release)
|
||||
# build the latest release
|
||||
@ -48,12 +30,6 @@ run_build() {
|
||||
# shellcheck disable=SC2068
|
||||
./build-branches.sh $@
|
||||
;;
|
||||
special)
|
||||
# special build
|
||||
# shellcheck disable=SC2068
|
||||
#SRC_ORG=lampwins TAG=webhooks-backend ./build.sh "feature/webhooks-backend" $@
|
||||
echo "✅ No special builds today."
|
||||
;;
|
||||
*)
|
||||
echo "🚨 Unrecognized build '$BUILD'."
|
||||
|
||||
@ -70,13 +46,9 @@ echo "🤖🤖🤖 Preparing build"
|
||||
export DOCKER_ORG="index.docker.io/netboxcommunity"
|
||||
export DOCKER_REPO=netbox
|
||||
export DOCKERHUB_REPO=netboxcommunity/netbox
|
||||
|
||||
# mis-using the "${DOCKER_TAG}" variable as "branch to build"
|
||||
export BUILD="${DOCKER_TAG%-*}"
|
||||
export VARIANT="${DOCKER_TAG#*-}"
|
||||
# shellcheck disable=SC2153
|
||||
export BUILD="$DOCKER_TAG"
|
||||
|
||||
unset DOCKER_TAG
|
||||
|
||||
ensure_dockerfile_present
|
||||
|
||||
ensure_jq
|
||||
|
@ -2,11 +2,13 @@
|
||||
|
||||
. hooks/common
|
||||
|
||||
if [ "${VARIANT}" == "main" ] && [ "${BUILD}" == "BRANCHES" ]; then
|
||||
if [ "${BUILD}" == "BRANCHES" ]; then
|
||||
echo "🐳🐳🐳 Testing"
|
||||
export DOCKER_TARGET="main"
|
||||
|
||||
docker-compose pull --parallel
|
||||
docker-compose build
|
||||
docker-compose run netbox ./manage.py test
|
||||
else
|
||||
echo "🐳🐳🐳 No tests are implemented for build '${BUILD}' with variant '${VARIANT}'."
|
||||
echo "🐳🐳🐳 No tests are implemented for build '${BUILD}'."
|
||||
fi
|
||||
|
Loading…
Reference in New Issue
Block a user