Skip to content

Commit

Permalink
Switch to docker bake (#81)
Browse files Browse the repository at this point in the history
  • Loading branch information
timja authored Sep 8, 2021
1 parent d527cae commit a823a18
Show file tree
Hide file tree
Showing 11 changed files with 307 additions and 193 deletions.
10 changes: 6 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
.DS_Store
bats-core/
bats/
11/*/setup-sshd*
8/*/setup-sshd*
*/CreateProfile.psm1

/*/**/CreateProfile.psm1
/.vscode/
/*/**/setup-sshd
target/

/*/**/CreateProfile.psm1
/.vscode/
/*/**/setup-sshd
6 changes: 6 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[submodule "tests/test_helper/bats-support"]
path = tests/test_helper/bats-support
url = https://github.com/bats-core/bats-support.git
[submodule "tests/test_helper/bats-assert"]
path = tests/test_helper/bats-assert
url = https://github.com/bats-core/bats-assert.git
File renamed without changes.
File renamed without changes.
5 changes: 5 additions & 0 deletions Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ pipeline {
}
}
}
post {
always {
junit('target/*.xml')
}
}
}
}
}
Expand Down
102 changes: 76 additions & 26 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,38 +1,88 @@
ROOT:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))

IMAGE_NAME:=jenkins4eval/ssh-slave
IMAGE_ALPINE:=${IMAGE_NAME}:alpine
IMAGE_BULLSEYE:=${IMAGE_NAME}:test
IMAGE_JDK11:=${IMAGE_NAME}:jdk11
## For Docker <=20.04
export DOCKER_BUILDKIT=1
## For Docker <=20.04
export DOCKER_CLI_EXPERIMENTAL=enabled
## Required to have docker build output always printed on stdout
export BUILDKIT_PROGRESS=plain

build: build-alpine build-bullseye build-jdk11
current_arch := $(shell uname -m)
export ARCH ?= $(shell case $(current_arch) in (x86_64) echo "amd64" ;; (i386) echo "386";; (aarch64|arm64) echo "arm64" ;; (armv6*) echo "arm/v6";; (armv7*) echo "arm/v7";; (ppc64*|s390*|riscv*) echo $(current_arch);; (*) echo "UNKNOWN-CPU";; esac)

build-alpine:
cp -f setup-sshd 8/alpine/
docker build -t ${IMAGE_ALPINE} 8/alpine
IMAGE_NAME:=jenkins4eval/ssh-agent

build-bullseye:
cp -f setup-sshd 8/debian/bullseye/
docker build -t ${IMAGE_BULLSEYE} 8/debian/bullseye
# Set to the path of a specific test suite to restrict execution only to this
# default is "all test suites in the "tests/" directory
TEST_SUITES ?= $(CURDIR)/tests

build-jdk11:
cp -f setup-sshd 11/debian/bullseye/
docker build -t ${IMAGE_JDK11} 11/debian/bullseye
##### Macros
## Check the presence of a CLI in the current PATH
check_cli = type "$(1)" >/dev/null 2>&1 || { echo "Error: command '$(1)' required but not found. Exiting." ; exit 1 ; }
## Check if a given image exists in the current manifest docker-bake.hcl
check_image = make --silent list | grep -w '$(1)' >/dev/null 2>&1 || { echo "Error: the image '$(1)' does not exist in manifest for the platform 'linux/$(ARCH)'. Please check the output of 'make list'. Exiting." ; exit 1 ; }
## Base "docker buildx base" command to be reused everywhere
bake_base_cli := docker buildx bake -f docker-bake.hcl --load

.PHONY: build
.PHONY: test test-alpine test-archlinux test-debian test-jdk11 test-jdk11-alpine

bats:
# The lastest version is v1.1.0
@if [ ! -d bats-core ]; then git clone https://github.com/bats-core/bats-core.git; fi
@git -C bats-core reset --hard c706d1470dd1376687776bbe985ac22d09780327
check-reqs:
## Build requirements
@$(call check_cli,bash)
@$(call check_cli,git)
@$(call check_cli,docker)
@docker info | grep 'buildx:' >/dev/null 2>&1 || { echo "Error: Docker BuildX plugin required but not found. Exiting." ; exit 1 ; }
## Test requirements
@$(call check_cli,curl)
@$(call check_cli,jq)

build: check-reqs
@set -x; $(bake_base_cli) --set '*.platform=linux/$(ARCH)' $(shell make --silent list)

build-%:
@$(call check_image,$*)
@set -x; $(bake_base_cli) --set '*.platform=linux/$(ARCH)' '$*'

.PHONY: test test-alpine test-jdk11 test-bullseye
test: bats test-alpine test-jdk11 test-bullseye
show:
@$(bake_base_cli) linux --print

list: check-reqs
@set -x; make --silent show | jq -r '.target | path(.. | select(.platforms[] | contains("linux/$(ARCH)"))?) | add'

bats:
git clone https://github.com/bats-core/bats-core bats ;\
cd bats ;\
git checkout v1.4.1

test-alpine:
@FOLDER="8/alpine" bats-core/bin/bats tests/tests.bats
prepare-test: bats check-reqs
git submodule update --init --recursive
mkdir -p target

test-jdk11:
@FOLDER="11/debian/bullseye" bats-core/bin/bats tests/tests.bats
## Define bats options based on environment
# common flags for all tests
bats_flags := $(TEST_SUITES)
# if DISABLE_PARALLEL_TESTS true, then disable parallel execution
ifneq (true,$(DISABLE_PARALLEL_TESTS))
# If the GNU 'parallel' command line is absent, then disable parallel execution
parallel_cli := $(shell command -v parallel 2>/dev/null)
ifneq (,$(parallel_cli))
# If parallel execution is enabled, then set 2 tests per core available for the Docker Engine
test-%: PARALLEL_JOBS ?= $(shell echo $$(( $(shell docker run --rm alpine grep -c processor /proc/cpuinfo) * 2)))
test-%: bats_flags += --jobs $(PARALLEL_JOBS)
endif
endif
test-%: prepare-test
# Check that the image exists in the manifest
@$(call check_image,$*)
# Ensure that the image is built
@make --silent build-$*
# Execute the test harness and write result to a TAP file
set -x
IMAGE=$* bats/bin/bats $(bats_flags) | tee target/results-$*.tap
# convert TAP to JUNIT
docker run --rm -v "$(CURDIR)":/usr/src/app -w /usr/src/app node:16-alpine \
sh -c "npm install tap-xunit -g && cat target/results-$*.tap | tap-xunit --package='jenkinsci.docker.$*' > target/junit-results-$*.xml"

test-bullseye:
@FOLDER="8/debian/bullseye" bats-core/bin/bats tests/tests.bats
test: prepare-test
@make --silent list | while read image; do make --silent "test-$${image}"; done
78 changes: 78 additions & 0 deletions docker-bake.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
group "linux" {
targets = [
"alpine_jdk8",
"debian_jdk8",
"debian_jdk11",
]
}

group "linux-arm64" {
targets = [
"debian_jdk11",
]
}

group "linux-s390x" {
targets = [
"debian_jdk11",
]
}

group "linux-ppc64le" {
targets = []
}

variable "REGISTRY" {
default = "docker.io"
}

variable "JENKINS_REPO" {
default = "jenkins/ssh-agent"
}

variable "ON_TAG" {
default = "false"
}

variable "VERSION" {
default = ""
}

target "alpine_jdk8" {
dockerfile = "8/alpine/Dockerfile"
context = "."
tags = [
equal(ON_TAG, "true") ? "${REGISTRY}/${JENKINS_REPO}:${VERSION}-alpine-jdk8": "",
"${REGISTRY}/${JENKINS_REPO}:alpine-jdk8",
"${REGISTRY}/${JENKINS_REPO}:latest-alpine-jdk8",
]
platforms = ["linux/amd64"]
}

target "debian_jdk8" {
dockerfile = "8/bullseye/Dockerfile"
context = "."
tags = [
equal(ON_TAG, "true") ? "${REGISTRY}/${JENKINS_REPO}:${VERSION}-jdk8": "",
"${REGISTRY}/${JENKINS_REPO}:bullseye-jdk8",
"${REGISTRY}/${JENKINS_REPO}:jdk8",
"${REGISTRY}/${JENKINS_REPO}:latest-bullseye-jdk8",
"${REGISTRY}/${JENKINS_REPO}:latest-jdk8",
]
platforms = ["linux/amd64"]
}

target "debian_jdk11" {
dockerfile = "11/bullseye/Dockerfile"
context = "."
tags = [
equal(ON_TAG, "true") ? "${REGISTRY}/${JENKINS_REPO}:${VERSION}": "",
equal(ON_TAG, "true") ? "${REGISTRY}/${JENKINS_REPO}:${VERSION}-jdk11": "",
"${REGISTRY}/${JENKINS_REPO}:bullseye-jdk11",
"${REGISTRY}/${JENKINS_REPO}:jdk11",
"${REGISTRY}/${JENKINS_REPO}:latest",
"${REGISTRY}/${JENKINS_REPO}:latest-bullseye-jdk11",
"${REGISTRY}/${JENKINS_REPO}:latest-jdk11",
]
platforms = ["linux/amd64", "linux/arm64", "linux/s390x"]
}
1 change: 1 addition & 0 deletions tests/test_helper/bats-assert
Submodule bats-assert added at 672ad1
1 change: 1 addition & 0 deletions tests/test_helper/bats-support
Submodule bats-support added at d140a6
27 changes: 21 additions & 6 deletions tests/test_helpers.bash
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@ function assert {
fi
}

function get_sut_image {
test -n "${IMAGE:?"[sut_image] Please set the variable 'IMAGE' to the name of the image to test in 'docker-bake.hcl'."}"
## Retrieve the SUT image name from buildx
# Option --print for 'docker buildx bake' prints the JSON configuration on the stdout
# Option --silent for 'make' suppresses the echoing of command so the output is valid JSON
# The image name is the 1st of the "tags" array, on the first "image" found
make --silent show | jq -r ".target.${IMAGE}.tags[0]"
}

# Retry a command $1 times until it succeeds. Wait $2 seconds between retries.
function retry {
local attempts
Expand All @@ -51,13 +60,17 @@ function retry {

# return the published port for given container port $1
function get_port {
docker port "${AGENT_CONTAINER}" "${1}" | cut -d: -f2
local agent_container_name="${1}"
local port="${2}"
docker port "${agent_container_name}" "${port}" | cut -d: -f2
}

# run a given command through ssh on the test container.
# Use the $status, $output and $lines variables to make assertions
function run_through_ssh {
SSH_PORT=$(get_port 22)
local agent_container_name="${1}"
shift 1
SSH_PORT=$(get_port "${agent_container_name}" 22)
if [[ "${SSH_PORT}" = "" ]]; then
printMessage "failed to get SSH port"
false
Expand All @@ -71,7 +84,7 @@ function run_through_ssh {
-o UserKnownHostsFile=/dev/null \
-o StrictHostKeyChecking=no \
-l jenkins \
localhost \
127.0.0.1 \
-p "${SSH_PORT}" \
"${@}"

Expand All @@ -80,11 +93,13 @@ function run_through_ssh {
}

function clean_test_container {
docker kill "${AGENT_CONTAINER}" &>/dev/null ||:
docker rm -fv "${AGENT_CONTAINER}" &>/dev/null ||:
local agent_container=$1
docker kill "${agent_container}" &>/dev/null ||:
docker rm -fv "${agent_container}" &>/dev/null ||:
}

function is_agent_container_running {
local agent_container=$1
sleep 1 # give time to sshd to eventually fail to initialize
retry 3 1 assert "true" docker inspect -f '{{.State.Running}}' "${AGENT_CONTAINER}"
retry 3 1 assert "true" docker inspect -f '{{.State.Running}}' "${agent_container}"
}
Loading

0 comments on commit a823a18

Please sign in to comment.