Skip to content

Commit

Permalink
Merge pull request #730 from smerle33/dockerbake
Browse files Browse the repository at this point in the history
breaking!(buildDockerAndPublishImage): support multi-platform with Docker Bake for building Linux container images
  • Loading branch information
smerle33 authored Aug 31, 2023
2 parents 1bea2dc + fcc0873 commit d6d6908
Show file tree
Hide file tree
Showing 6 changed files with 464 additions and 115 deletions.
40 changes: 33 additions & 7 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -189,18 +189,45 @@ Supported parameters:
`imageName`::
Name of the docker image to build

`configs`::
(Optional) extra flags

registry: override the smart default of jenkinsciinfra/ or jenkins4eval/
dockerfile: override the default dockerfile of Dockerfile
`config`::
(Optional) map of extra flags

* agentLabels: String expression for the labels the agent must match
* automaticSemanticVersioning: Do not automagically increase semantic version by default
* includeImageNameInTag: Set to true for multiple semversioned images built in parallel, will include the image name in tag to avoid conflict
* dockerfile: override the default dockerfile of Dockerfile
* targetplatforms: defined the platforms to build as TARGET
* nextVersionCommand: Commmand line used to retrieve the next version (default 'jx-release-version')
* gitCredentials: override Credential ID for tagging and creating release
* imageDir: Relative path to the context directory for the Docker build
* registryNamespace: empty = autodiscover based on the current controller, but can override the smart default of jenkinsciinfra/ or jenkins4eval/
* unstash: Allow to unstash files if not empty
* dockerBakeFile: Allow to build from a bake file instead

==== Example
[source, groovy]
----
buildDockerImage_k8s('plugins-site-api')
buildDockerAndPublishImage('plugins-site-api')
buildDockerAndPublishImage('inbound-agent-maven:jdk8-nanoserver', [
dockerfile: 'maven/jdk8/Dockerfile.nanoserver',
agentLabels: 'docker-windows-2019 && amd64',
targetplatforms: 'windows/amd64',
imageDir: 'maven/jdk8',
])
----

is also called from `parallelDockerUpdatecli` with `config` within `buildDockerConfig` like this :
[source, groovy]
----
parallelDockerUpdatecli([
imageName: 'wiki',
rebuildImageOnPeriodicJob: false,
updatecliConfig: [containerMemory: '1G'],
buildDockerConfig : [targetplatforms: 'linux/amd64,linux/arm64,linux/s390x']
])
----


== Contribute

=== Requirements
Expand All @@ -213,4 +240,3 @@ buildDockerImage_k8s('plugins-site-api')
By adding `@Library('pipeline-library@pull/<your-pr-number>/head') _` at the top of a Jenkinsfile from a repository built on one of the *.ci.jenkins.io instances, you can test your pipeline library pull request on ci.jenkins.io.

A repository is dedicated for these kind of tests: https://github.com/jenkinsci/jenkins-infra-test-plugin/

21 changes: 19 additions & 2 deletions resources/io/jenkins/infra/docker/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ endif

IMAGE_NAME ?= helloworld
IMAGE_DEPLOY_NAME ?= "$(IMAGE_NAME)"
IMAGE_PLATFORM ?= linux/amd64
BUILD_TARGETPLATFORM ?= linux/amd64
# Paths
IMAGE_DOCKERFILE ?= "$(IMAGE_DIR)"/Dockerfile
HADOLINT_REPORT ?= "$(IMAGE_DIR)"/hadolint.json
TEST_HARNESS ?= "$(IMAGE_DIR)"/cst.yml
DOCKER_BAKE_FILE ?= "$(IMAGE_DIR)"/docker-bake.hcl

## Image metadatas
GIT_COMMIT_REV ?= $(shell git log -n 1 --pretty=format:'%h')
Expand Down Expand Up @@ -47,11 +48,16 @@ build: ## Build the Docker Image $(IMAGE_NAME) from $(IMAGE_DOCKERFILE)
--label "org.label-schema.vcs-ref=$(GIT_COMMIT_REV)" \
--label "org.opencontainers.image.created=$(BUILD_DATE)" \
--label "org.label-schema.build-date=$(BUILD_DATE)" \
--platform "$(IMAGE_PLATFORM)" \
--platform "$(BUILD_TARGETPLATFORM)" \
--file "$(call FixPath,$(IMAGE_DOCKERFILE))" \
"$(IMAGE_DIR)"
@echo "== Build succeeded"

bake-build: ## Build the Docker Image(s) with dockerbake file
@echo "== Building from DockerBake file"
@docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))"


clean: ## Delete any file generated during the build steps
@echo "== Cleaning working directory $(IMAGE_DIR) from generated artefacts:"
rm -f "$(call FixPath,$(IMAGE_DIR)/*.tar)" "$(HADOLINT_REPORT)"
Expand All @@ -62,11 +68,22 @@ test: ## Execute the test harness on the Docker Image
container-structure-test test --driver=docker --image="$(IMAGE_NAME)" --config="$(call FixPath,$(TEST_HARNESS))"
@echo "== Test succeeded"

bake-test: ## Execute the test harness on the Docker Image with load
@echo "== Load $(IMAGE_NAME) within docker engine from docker bake buildx engine"
@docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --set "*.platform=linux/$(shell dpkg --print-architecture)" --load
@echo "== Test $(IMAGE_NAME) with $(call FixPath,$(TEST_HARNESS)) from $(IMAGE_NAME) with container-structure-test:"
container-structure-test test --driver=docker --image="$(IMAGE_NAME)" --config="$(call FixPath,$(TEST_HARNESS))"
@echo "== Test succeeded"

## This steps expects that you are logged to the Docker registry to push image into
deploy: ## Tag and push the built image as specified by $(IMAGE_DEPLOY).
@echo "== Deploying $(IMAGE_NAME) to $(IMAGE_DEPLOY_NAME) with docker:"
docker image tag "$(IMAGE_NAME)" "$(IMAGE_DEPLOY_NAME)"
docker image push "$(IMAGE_DEPLOY_NAME)"
@echo "== Deploy succeeded"

bake-deploy: ## Tag and push the built image as specified by docker bake file
@echo "== Deploying with docker bake file"
@docker buildx bake -f "$(call FixPath,$(DOCKER_BAKE_FILE))" --push

.PHONY: all clean lint build test deploy
52 changes: 52 additions & 0 deletions resources/io/jenkins/infra/docker/jenkinsinfrabakefile.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
variable "IMAGE_DEPLOY_NAME" {}

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

variable "TAG_NAME" {
default = ""
}

variable "BAKE_TARGETPLATFORMS" {
default = "linux/arm64"
}

variable "IMAGE_DOCKERFILE" {
default = "Dockerfile"
}

variable "IMAGE_DIR" {
default = "."
}

# return the full image name
function "full_image_name" {
params = [tag]
result = notequal("", tag) ? "${REGISTRY}/${IMAGE_DEPLOY_NAME}:${tag}" : "${REGISTRY}/${IMAGE_DEPLOY_NAME}:latest"
}

target "default" {
dockerfile = IMAGE_DOCKERFILE
context = IMAGE_DIR
tags = [
full_image_name("latest"),
full_image_name(TAG_NAME)
]
platforms = [BAKE_TARGETPLATFORMS]
args = {
GIT_COMMIT_REV="$(GIT_COMMIT_REV)",
GIT_SCM_URL="$(GIT_SCM_URL)",
BUILD_DATE="$(BUILD_DATE)",
}
labels = {
"org.opencontainers.image.source"="$(GIT_SCM_URL)",
"org.label-schema.vcs-url"="$(GIT_SCM_URL)",
"org.opencontainers.image.url"="$(SCM_URI)",
"org.label-schema.url"="$(SCM_URI)",
"org.opencontainers.image.revision"="$(GIT_COMMIT_REV)",
"org.label-schema.vcs-ref"="$(GIT_COMMIT_REV)",
"org.opencontainers.image.created"="$(BUILD_DATE)",
"org.label-schema.build-date"="$(BUILD_DATE)",
}
}
Loading

0 comments on commit d6d6908

Please sign in to comment.