1
0
mirror of https://github.com/certbot/certbot.git synced 2026-01-26 07:41:33 +03:00

Multiarch (#3)

* Add one Dockerfile for each supported architecture

* Update multi arch hooks

* Create multi arch scripts

* Update README.md

* WIP. Use build args instead of multiple Dockerfiles in build script

* WIP. Fix typo mistake

* Use build args instead of multiple Dockerfiles in build script

* WIP. Build all the architectures in one DockerHub build

* Add arm64v8 architecture

* WIP. Testing build all the architectures in one DockerHub build

* Revert "WIP. Testing build all the architectures in one DockerHub build"

This reverts commit 94a89398a4120b183d2851ac7cb9c93db0e3d187.

* Refactor tag docker images in hooks/post_push files

* Use variables instead of positional arguments

* Export externally used variables

* Use ${variable//search/replace} instead of echo $variable | sed.

* Update README.md

* Add Cleanup in build.sh script

* Fix tagging error in post_push hook

* Add "-ex" flags to bash script

* Test tagging images in build hook

* Tagging in hook/post_build instead of hook/post_push

* Push built architecture dependent image

* Use Dockerfile argument instead of fixed value

* Fix typo

* Use parameter instead of global variable

* Use custom "hook/push" to prevent duplicated push

* Make a short doctype for each function declared in common
This commit is contained in:
Oriol Teixidó
2019-10-11 17:07:45 +02:00
committed by Adrien Ferrand
parent 67fddae90d
commit e9a9a180bb
16 changed files with 273 additions and 48 deletions

View File

@@ -12,7 +12,7 @@ High-level behavior
When a new version tag (eg. v0.35.0) is pushed to this repository, it triggers a new build in each DockerHub project, to construct and publish the new version of the Docker,
containing the Certbot version corresponding to the pushed tag. With the example of the v0.35.0, the DockerHub projects will contain after few minutes a new tag v0.35.0,
whose the Docker contains Certbot v0.35.0.
whose the Docker contains Certbot v0.35.0.
Configuration
-------------
@@ -58,3 +58,14 @@ This script will trigger the publication on DockerHub of all Dockers for the giv
- commit locally the modifications,
- tag this commit with the given version,
- push this tag and the updated `master` branch.
Assuming the version to publish is `v0.35.0`, the following docker images will be created at DockerHub.
- certbot/certbot:v0.35.0 *(amd64 architecture)*
- certbot/certbot:amd64-v0.35.0
- certbot/certbot:arm32v6-v0.35.0
- certbot/certbot:arm64v8-v0.35.0
- certbot/certbot:latest *(amd64 architecture)*
- certbot/certbot:amd64-latest
- certbot/certbot:arm32v6-latest
- certbot/certbot:arm64v8-latest

View File

@@ -13,34 +13,32 @@ trap Cleanup 1 2 3 6
Cleanup() {
if [ ! -z "$WORK_DIR" ]; then
rm -rf "$WORK_DIR/plugin/certbot" || true
rm -rf "$WORK_DIR/core/certbot" || true
rm -rf "$WORK_DIR"/core/qemu-*-static || true
rm -rf "$WORK_DIR"/plugin/qemu-*-static || true
fi
popd 2> /dev/null || true
}
Build() {
DOCKER_REPO="$1"
CERTBOT_VERSION="$2"
CONTEXT_PATH="$3"
DOCKERFILE_PATH="$CONTEXT_PATH/Dockerfile"
DOCKER_TAG="$CERTBOT_VERSION"
pushd "$CONTEXT_PATH"
DOCKER_TAG="$DOCKER_TAG" DOCKER_REPO="$DOCKER_REPO" DOCKERFILE_PATH="$DOCKERFILE_PATH" bash hooks/pre_build
DOCKER_TAG="$DOCKER_TAG" DOCKER_REPO="$DOCKER_REPO" DOCKERFILE_PATH="$DOCKERFILE_PATH" bash hooks/build
popd
}
WORK_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
DOCKER_TAG="$1"
SOURCE_BRANCH="$DOCKER_TAG"
Cleanup
CERTBOT_VERSION="$1"
# Step 1: Certbot core Docker
DOCKER_REPO="certbot/certbot"
CONTEXT_PATH="$WORK_DIR/core"
DOCKERFILE_PATH="$CONTEXT_PATH/Dockerfile"
IMAGE_NAME="$DOCKER_REPO:$DOCKER_TAG"
pushd "$CONTEXT_PATH"
DOCKER_TAG="$DOCKER_TAG" DOCKER_REPO="$DOCKER_REPO" DOCKERFILE_PATH="$DOCKERFILE_PATH" IMAGE_NAME="$IMAGE_NAME" bash hooks/build
popd
Cleanup
Build "certbot/certbot" "$CERTBOT_VERSION" "$WORK_DIR/core"
# Step 2: Certbot dns plugins Dockers
CERTBOT_PLUGINS_DOCKER_REPOS=(
"certbot/dns-dnsmadeeasy"
"certbot/dns-dnsimple"
@@ -58,15 +56,8 @@ CERTBOT_PLUGINS_DOCKER_REPOS=(
"certbot/dns-sakuracloud"
)
for DOCKER_REPO in ${CERTBOT_PLUGINS_DOCKER_REPOS[@]}; do
CONTEXT_PATH="$WORK_DIR/plugin"
DOCKERFILE_PATH="$CONTEXT_PATH/Dockerfile"
IMAGE_NAME="$DOCKER_REPO:$DOCKER_TAG"
pushd "$CONTEXT_PATH"
DOCKER_TAG="$DOCKER_TAG" DOCKER_REPO="$DOCKER_REPO" DOCKERFILE_PATH="$DOCKERFILE_PATH" IMAGE_NAME="$IMAGE_NAME" bash hooks/pre_build
DOCKER_TAG="$DOCKER_TAG" DOCKER_REPO="$DOCKER_REPO" DOCKERFILE_PATH="$DOCKERFILE_PATH" IMAGE_NAME="$IMAGE_NAME" bash hooks/build
popd
Cleanup
for DOCKER_REPO in "${CERTBOT_PLUGINS_DOCKER_REPOS[@]}"; do
Build "${DOCKER_REPO}" "$CERTBOT_VERSION" "$WORK_DIR/plugin"
done
Cleanup

1
tools/docker/core/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
qemu-*-static

View File

@@ -1,4 +1,11 @@
FROM python:3.7-alpine3.10
# Docker Arch (amd64, arm32v6, ...)
ARG TARGET_ARCH
FROM ${TARGET_ARCH}/python:3.7-alpine3.10
# Qemu Arch (x86_64, arm, ...)
ARG QEMU_ARCH
ENV QEMU_ARCH=${QEMU_ARCH}
COPY qemu-${QEMU_ARCH}-static /usr/bin/
ARG CERTBOT_VERSION
ENV CERTBOT_VERSION=${CERTBOT_VERSION}

View File

@@ -1,5 +1,11 @@
#!/bin/bash
set -ex
CERTBOT_VERSION=${DOCKER_TAG//v/}
docker build --build-arg CERTBOT_VERSION=${CERTBOT_VERSION} -f ${DOCKERFILE_PATH} -t ${IMAGE_NAME} .
WORK_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
source "$WORK_DIR/../../lib/common"
CERTBOT_VERSION=$(GetCerbotVersionFromTag "$DOCKER_TAG")
for TARGET_ARCH in "${ALL_TARGET_ARCH[@]}"; do
BuildDockerCoreImage "${TARGET_ARCH}" "${CERTBOT_VERSION}"
done

View File

@@ -1,5 +1,12 @@
#!/bin/bash
set -ex
docker tag ${IMAGE_NAME} "${DOCKER_REPO}:latest"
docker push "${DOCKER_REPO}:latest"
WORK_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
source "$WORK_DIR/../../lib/common"
CERTBOT_VERSION=$(GetCerbotVersionFromTag "$DOCKER_TAG")
for TARGET_ARCH in "${ALL_TARGET_ARCH[@]}"; do
TagDockerImageAliases "${TARGET_ARCH}" "${CERTBOT_VERSION}"
PushDockerImageAliases "${TARGET_ARCH}" "${CERTBOT_VERSION}"
done

View File

@@ -0,0 +1,10 @@
#!/bin/bash
set -ex
WORK_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
source "$WORK_DIR/../../lib/common"
RegisterQemuHandlers
for TARGET_ARCH in "${ALL_TARGET_ARCH[@]}"; do
DownloadQemuStatic "${TARGET_ARCH}"
done

View File

@@ -0,0 +1,11 @@
#!/bin/bash
set -ex
WORK_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
source "$WORK_DIR/../../lib/common"
CERTBOT_VERSION=$(GetCerbotVersionFromTag "$DOCKER_TAG")
for TARGET_ARCH in "${ALL_TARGET_ARCH[@]}"; do
PushDockerImage "${TARGET_ARCH}" "${CERTBOT_VERSION}"
done

View File

@@ -18,14 +18,14 @@ Cleanup() {
WORK_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
CERTBOT_DOCKER_VERSION="$1" # Eg. v0.35.0 or v0.35.0-1
CERTBOT_VERSION=$(sed -E -e 's|(v[0-9+]\.[0-9]+\.[0-9]+).*|\1|g' <<< $CERTBOT_DOCKER_VERSION) # Eg. v0.35.0
BRANCH_NAME=$(sed -E -e 's|v(.*)\.[0-9]+|\1.x|g' <<< $CERTBOT_VERSION) # Eg. 0.35.x
CERTBOT_VERSION=$(sed -E -e 's|(v[0-9+]\.[0-9]+\.[0-9]+).*|\1|g' <<< "$CERTBOT_DOCKER_VERSION") # Eg. v0.35.0
BRANCH_NAME=$(sed -E -e 's|v(.*)\.[0-9]+|\1.x|g' <<< "$CERTBOT_VERSION") # Eg. 0.35.x
sed -i -e "s|current-.*-blue\.svg|current-$CERTBOT_VERSION-blue.svg|g" core/README.md
sed -i -e "s|branch=.*)\]|branch=$BRANCH_NAME)]|g" core/README.md
sed -i -e "s|current-.*-blue\\.svg|current-$CERTBOT_VERSION-blue.svg|g" core/README.md
sed -i -e "s|branch=.*)\\]|branch=$BRANCH_NAME)]|g" core/README.md
sed -i -e "s|current-.*-blue\.svg|current-$CERTBOT_VERSION-blue.svg|g" plugin/README.md
sed -i -e "s|branch=.*)\]|branch=$BRANCH_NAME)]|g" plugin/README.md
sed -i -e "s|current-.*-blue\\.svg|current-$CERTBOT_VERSION-blue.svg|g" plugin/README.md
sed -i -e "s|branch=.*)\\]|branch=$BRANCH_NAME)]|g" plugin/README.md
pushd "$WORK_DIR"
git commit -a -m "Release version $CERTBOT_DOCKER_VERSION" --allow-empty

142
tools/docker/lib/common Normal file
View File

@@ -0,0 +1,142 @@
#!/bin/bash
set -ex
# Current supported architectures
export ALL_TARGET_ARCH=(amd64 arm32v6 arm64v8)
# Architecture used in tags with no architecture especified (certbot/certbot:latest, certbot/cerbot:v0.35.0, ...)
export DEFAULT_ARCH=amd64
# Returns certbot version (ex. v0.35.0 returns 0.35.0)
# Usage: GetCerbotVersionFromTag <DOCKER_VERSION>
GetCerbotVersionFromTag() {
TAG=$1
echo "${TAG//v/}"
}
# Returns the translation from Docker to QEMU architecture
# Usage: GetQemuArch [amd64|arm32v6|arm64v8]
GetQemuArch() {
ARCH=$1
case "$ARCH" in
"amd64")
echo "x86_64"
;;
"arm32v6")
echo "arm"
;;
"arm64v8")
echo "aarch64"
;;
"*")
echo "Not supported build architecture '$1'." >&2
exit -1
esac
}
# Downloads QEMU static binary file for architecture
# Usage: DownloadQemuStatic [x86_64|arm|aarch64]
DownloadQemuStatic() {
ARCH=$1
QEMU_ARCH=$(GetQemuArch "$ARCH")
if [ ! -f "qemu-${QEMU_ARCH}-static" ]; then
QEMU_DOWNLOAD_URL="https://github.com/multiarch/qemu-user-static/releases/download"
QEMU_LATEST_TAG=$(curl -s https://api.github.com/repos/multiarch/qemu-user-static/tags \
| grep 'name.*v[0-9]' \
| head -n 1 \
| cut -d '"' -f 4)
curl -SL "${QEMU_DOWNLOAD_URL}/${QEMU_LATEST_TAG}/x86_64_qemu-$QEMU_ARCH-static.tar.gz" \
| tar xzv
fi
}
# Executes the QEMU register script
# Usage: RegisterQemuHandlers
RegisterQemuHandlers() {
docker run --rm --privileged multiarch/qemu-user-static:register --reset
}
# Builds docker certbot core image for a specific architecture and certbot version (ex. 0.35.0).
# Usage: BuildDockerCoreImage [amd64|arm32v6|arm64v8] <CERTBOT_VERSION>
BuildDockerCoreImage() {
ARCH=$1
VERSION=$2
QEMU=$(GetQemuArch "$ARCH")
docker build \
--build-arg CERTBOT_VERSION="${VERSION}" \
--build-arg TARGET_ARCH="${ARCH}" \
--build-arg QEMU_ARCH="${QEMU}" \
-f "${DOCKERFILE_PATH}" \
-t "${DOCKER_REPO}:${ARCH}-v${VERSION}" \
.
}
# Builds docker certbot plugin image for a specific architecture and certbot version (ex. 0.35.0).
# Usage: BuildDockerPluginImage [amd64|arm32v6|arm64v8] <CERTBOT_VERSION> <PLUGIN_NAME>
BuildDockerPluginImage() {
ARCH=$1
VERSION=$2
PLUGIN=$3
QEMU=$(GetQemuArch "$ARCH")
docker build \
--build-arg CERTBOT_VERSION="${VERSION}" \
--build-arg TARGET_ARCH="${ARCH}" \
--build-arg QEMU_ARCH="${QEMU}" \
--build-arg PLUGIN_NAME="${PLUGIN}" \
-f "${DOCKERFILE_PATH}" \
-t "${DOCKER_REPO}:${ARCH}-v${VERSION}" \
.
}
# Pushes docker image for a specific architecture and certbot version (ex. 0.35.0).
# Usage: BuildDockerCoreImage [amd64|arm32v6|arm64v8] <CERTBOT_VERSION>
PushDockerImage() {
ARCH=$1
VERSION=$2
docker push "${DOCKER_REPO}:${ARCH}-v${VERSION}"
}
# Creates docker image "latest" tag for a specific architecture and certbot version.
# In case of default architecture, it also creates tags without architecture part.
# As an example, for version 0.35.0 in amd64 (default arquitecture):
# - certbot/certbot:v0.35.0
# - certbot/certbot:latest
# - certbot/certbot:amd64-latest
# For version 0.35.0 in arm32v6:
# - certbot/certbot:arm32v6-latest
# Usage: TagDockerImageAliases [amd64|arm32v6|arm64v8] <CERTBOT_VERSION>
TagDockerImageAliases() {
ARCH=$1
VERSION=$2
docker tag "${DOCKER_REPO}:${ARCH}-v${VERSION}" "${DOCKER_REPO}:${ARCH}-latest"
if [ "${ARCH}" == "${DEFAULT_ARCH}" ]; then
docker tag "${DOCKER_REPO}:${ARCH}-v${VERSION}" "${DOCKER_REPO}:v${VERSION}"
docker tag "${DOCKER_REPO}:${ARCH}-v${VERSION}" "${DOCKER_REPO}:latest"
fi
}
# Pushes docker "latest" image for a specific architecture and certbot version.
# In case of default architecture, it also pushes image without architecture part.
# As an example, for version 0.35.0 in amd64 (default arquitecture):
# - certbot/certbot:v0.35.0
# - certbot/certbot:latest
# - certbot/certbot:amd64-latest
# For version 0.35.0 in arm32v6:
# - certbot/certbot:arm32v6-latest
# Usage: PushDockerImageAliases [amd64|arm32v6|arm64v8] <CERTBOT_VERSION>
PushDockerImageAliases() {
ARCH=$1
VERSION=$2
docker push "${DOCKER_REPO}:${ARCH}-latest"
if [ "${ARCH}" == "${DEFAULT_ARCH}" ]; then
docker push "${DOCKER_REPO}:v${VERSION}"
docker push "${DOCKER_REPO}:latest"
fi
}

1
tools/docker/plugin/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
qemu-*-static

View File

@@ -1,4 +1,12 @@
FROM certbot/certbot
# Docker Arch (amd64, arm32v6, ...)
ARG TARGET_ARCH
ARG CERTBOT_VERSION
FROM certbot/certbot:${TARGET_ARCH}-v${CERTBOT_VERSION}
# Qemu Arch (x86_64, arm, ...)
ARG QEMU_ARCH
ENV QEMU_ARCH=${QEMU_ARCH}
COPY qemu-${QEMU_ARCH}-static /usr/bin/
ARG PLUGIN_NAME
@@ -6,7 +14,7 @@ ARG PLUGIN_NAME
RUN wget -O certbot-${CERTBOT_VERSION}.tar.gz https://github.com/certbot/certbot/archive/v${CERTBOT_VERSION}.tar.gz \
&& tar xf certbot-${CERTBOT_VERSION}.tar.gz \
&& cp -r certbot-${CERTBOT_VERSION}/certbot-${PLUGIN_NAME} /opt/certbot/src/certbot-${PLUGIN_NAME} \
&& rm -rf certbot-${CERTBOT_VERSION}.tar.gz certbot-${CERTBOT_VERSION}
&& rm -rf certbot-${CERTBOT_VERSION}.tar.gz certbot-${CERTBOT_VERSION}
# Install the DNS plugin
RUN pip install --constraint /opt/certbot/docker_constraints.txt --no-cache-dir --editable /opt/certbot/src/certbot-${PLUGIN_NAME}

View File

@@ -1,5 +1,12 @@
#!/bin/bash
set -ex
WORK_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
source "$WORK_DIR/../../lib/common"
CERTBOT_VERSION=$(GetCerbotVersionFromTag "$DOCKER_TAG")
PLUGIN_NAME=${DOCKER_REPO//*\//}
docker build --build-arg PLUGIN_NAME=${PLUGIN_NAME} -f ${DOCKERFILE_PATH} -t ${IMAGE_NAME} .
for TARGET_ARCH in "${ALL_TARGET_ARCH[@]}"; do
BuildDockerPluginImage "${TARGET_ARCH}" "${CERTBOT_VERSION}" "${PLUGIN_NAME}"
done

View File

@@ -1,5 +1,12 @@
#!/bin/bash
set -ex
docker tag ${IMAGE_NAME} "${DOCKER_REPO}:latest"
docker push "${DOCKER_REPO}:latest"
WORK_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
source "$WORK_DIR/../../lib/common"
CERTBOT_VERSION=$(GetCerbotVersionFromTag "$DOCKER_TAG")
for TARGET_ARCH in "${ALL_TARGET_ARCH[@]}"; do
TagDockerImageAliases "${TARGET_ARCH}" "${CERTBOT_VERSION}"
PushDockerImageAliases "${TARGET_ARCH}" "${CERTBOT_VERSION}"
done

View File

@@ -1,5 +1,10 @@
#!/bin/bash
set -ex
CERTBOT_VERSION=${DOCKER_TAG//v/}
docker build --build-arg CERTBOT_VERSION=${CERTBOT_VERSION} -f ../core/Dockerfile -t certbot/certbot ../core
WORK_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
source "$WORK_DIR/../../lib/common"
RegisterQemuHandlers
for TARGET_ARCH in "${ALL_TARGET_ARCH[@]}"; do
DownloadQemuStatic "${TARGET_ARCH}"
done

View File

@@ -0,0 +1,11 @@
#!/bin/bash
set -ex
WORK_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
source "$WORK_DIR/../../lib/common"
CERTBOT_VERSION=$(GetCerbotVersionFromTag "$DOCKER_TAG")
for TARGET_ARCH in "${ALL_TARGET_ARCH[@]}"; do
PushDockerImage "${TARGET_ARCH}" "${CERTBOT_VERSION}"
done