Skip to content

Commit

Permalink
Merge pull request #827 from lemeurherve/align-with-docker-ssh-agent-…
Browse files Browse the repository at this point in the history
…process

chore: align with docker-ssh-agent build process
  • Loading branch information
dduportal committed Sep 24, 2024
2 parents 350499f + ffed12e commit 5b26913
Show file tree
Hide file tree
Showing 16 changed files with 580 additions and 305 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
bats-core/
bats/
target/
build-windows-current.yaml
build-windows_*.yaml
41 changes: 19 additions & 22 deletions Jenkinsfile
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
def agentSelector(String imageType) {
// Image type running on a Linux agent
// Linux agent
if (imageType == 'linux') {
// Need Docker and a LOT of memory for faster builds (due to multi archs) or fallback to linux (trusted.ci)
return 'docker-highmem || linux'
}
// Image types running on a Windows Server Core 2022 agent
// Windows Server Core 2022 agent
if (imageType.contains('2022')) {
return 'windows-2022'
}
// Remaining image types running on a Windows Server Core 2019 agent: (nanoserver|windowservercore)-(1809|2019)
// Windows Server Core 2019 agent (for nanoserver 1809 & ltsc2019 and for windowservercore ltsc2019)
return 'windows-2019'
}

Expand Down Expand Up @@ -37,18 +37,15 @@ pipeline {
timeout(time: 60, unit: 'MINUTES')
}
environment {
DOCKERHUB_ORGANISATION = "${infra.isTrusted() ? 'jenkins' : 'jenkins4eval'}"
REGISTRY_ORG = "${infra.isTrusted() ? 'jenkins' : 'jenkins4eval'}"
}
stages {
stage('Prepare Docker') {
when {
environment name: 'IMAGE_TYPE', value: 'linux'
}
steps {
sh '''
docker buildx create --use
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
'''
sh 'make docker-init'
}
}
stage('Build and Test') {
Expand All @@ -58,18 +55,19 @@ pipeline {
}
steps {
script {
if(isUnix()) {
if (isUnix()) {
sh './build.sh'
sh './build.sh test'
// If the tests are passing for Linux AMD64, then we can build all the CPU architectures
sh 'docker buildx bake --file docker-bake.hcl linux'
sh 'make every-build'
} else {
powershell '& ./build.ps1 test'
}
}
}
post {
always {
archiveArtifacts artifacts: 'build-windows_*.yaml', allowEmptyArchive: true
junit(allowEmptyResults: true, keepLongStdio: true, testResults: 'target/**/junit-results*.xml')
}
}
Expand All @@ -83,18 +81,17 @@ pipeline {
script {
def tagItems = env.TAG_NAME.split('-')
if(tagItems.length == 2) {
def remotingVersion = tagItems[0]
def buildNumber = tagItems[1]
// This function is defined in the jenkins-infra/pipeline-library
infra.withDockerCredentials {
if (isUnix()) {
sh """
docker buildx create --use
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
./build.sh -r ${remotingVersion} -b ${buildNumber} -d publish
"""
} else {
powershell "& ./build.ps1 -RemotingVersion $remotingVersion -BuildNumber $buildNumber -DisableEnvProps publish"
withEnv(
["REMOTING_VERSION=${tagItems[0]}"],
["BUILD_NUMBER=${tagItems[1]}"]
) {
// This function is defined in the jenkins-infra/pipeline-library
infra.withDockerCredentials {
if (isUnix()) {
sh 'make publish'
} else {
powershell '& ./build.ps1 publish'
}
}
}
} else {
Expand Down
25 changes: 17 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ check_cli = type "$(1)" >/dev/null 2>&1 || { echo "Error: command '$(1)' require
## 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
bake_base_cli := docker buildx bake --file docker-bake.hcl
bake_cli := $(bake_base_cli) --load

.PHONY: build
.PHONY: test test-alpine test-archlinux test-debian test-jdk11 test-jdk11-alpine
Expand All @@ -31,16 +32,24 @@ check-reqs:
@$(call check_cli,curl)
@$(call check_cli,jq)

## This function is specific to Jenkins infrastructure and isn't required in other contexts
docker-init: check-reqs
@set -x; docker buildx create --use
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes

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

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

every-build: check-reqs
@set -x; $(bake_base_cli) linux

show:
@$(bake_base_cli) linux --print
@$(bake_cli) linux --print

list: check-reqs
@set -x; make --silent show | jq -r '.target | path(.. | select(.platforms[] | contains("linux/$(ARCH)"))?) | add'
Expand All @@ -52,6 +61,9 @@ prepare-test: bats check-reqs
git submodule update --init --recursive
mkdir -p target

publish:
@set -x; $(bake_base_cli) linux --push

## Define bats options based on environment
# common flags for all tests
bats_flags := ""
Expand All @@ -73,10 +85,7 @@ test-%: prepare-test
@echo "== testing $*"
set -x
# Each type of image ("agent" or "inbound-agent") has its own tests suite
IMAGE=$* bats/bin/bats $(CURDIR)/tests/tests_$(shell echo $* | cut -d "_" -f 1).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"
IMAGE=$* bats/bin/bats $(CURDIR)/tests/tests_$(shell echo $* | cut -d "_" -f 1).bats $(bats_flags) --formatter junit | tee target/junit-results-$*.xml

test: prepare-test
@make --silent list | while read image; do make --silent "test-$${image}"; done
203 changes: 203 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,206 @@ See [the `agent` README](./README_agent.md)
This is an image based on `agent` for [Jenkins](https://jenkins.io) agents using TCP or WebSockets to establish inbound connection to the Jenkins controller.

See [the `inbound-agent` README](./README_inbound-agent.md)

## Building

### Building and testing on Linux

#### Target images

If you want to see the target images (matching your current architecture) that will be built, you can issue the following command:

```bash
$ make list
agent_alpine_jdk21
agent_debian_jdk11
agent_debian_jdk17
agent_debian_jdk21
inbound-agent_alpine_jdk21
inbound-agent_debian_jdk11
inbound-agent_debian_jdk17
inbound-agent_debian_jdk21
```

#### Building a specific image

If you want to build a specific image, you can issue the following command:

```bash
make build-<AGENT_TYPE>_<LINUX_FLAVOR>_<JDK_VERSION>
```

That would give for an image of an inbound agent with JDK 17 on Debian:

```bash
make build-inbound-agent_debian_jdk17
```

#### Building images supported by your current architecture

Then, you can build the images supported by your current architecture by running:

```bash
make build
```

#### Testing all images

If you want to test these images, you can run:

```bash
make test
```
#### Testing a specific image

If you want to test a specific image, you can run:

```bash
make test-<AGENT_TYPE>_<LINUX_FLAVOR>_<JDK_VERSION>
```

That would give for an image of an inbound agent with JDK 17 on Debian:

```bash
make test-inbound-agent_debian_jdk17
```

#### Building all images

You can build all images (even those unsupported by your current architecture) by running:

```bash
make every-build
```

#### Other `make` targets

`show` gives us a detailed view of the images that will be built, with the tags, platforms, and Dockerfiles.

```bash
$ make show
{
"group": {
"alpine": {
"targets": [
"agent_alpine_jdk11",
"agent_alpine_jdk17",
"agent_alpine_jdk21",
"inbound-agent_alpine_jdk11",
"inbound-agent_alpine_jdk17",
"inbound-agent_alpine_jdk21"
]
},
"debian": {
"targets": [
"agent_debian_jdk11",
"agent_debian_jdk17",
"agent_debian_jdk21",
"inbound-agent_debian_jdk11",
"inbound-agent_debian_jdk17",
"inbound-agent_debian_jdk21"
]
},
"default": {
"targets": [
"linux"
]
},
"linux": {
"targets": [
"agent_archlinux_jdk11",
"alpine",
"debian"
]
}
},
"target": {
"agent_alpine_jdk11": {
"context": ".",
"dockerfile": "alpine/Dockerfile",
"args": {
"ALPINE_TAG": "3.20.1",
"JAVA_VERSION": "11.0.23_9",
"VERSION": "3256.v88a_f6e922152"
},
"tags": [
"docker.io/jenkins/agent:alpine-jdk11",
"docker.io/jenkins/agent:alpine3.20-jdk11",
"docker.io/jenkins/agent:latest-alpine-jdk11",
"docker.io/jenkins/agent:latest-alpine3.20-jdk11"
],
"target": "agent",
"platforms": [
"linux/amd64"
],
"output": [
"type=docker"
]
},
[...]
```
`bats` is a dependency target. It will update the [`bats` submodule](https://github.com/bats-core/bats-core) and run the tests.
```bash
make bats
make: 'bats' is up to date.
```
`publish` allows the publication of all images targeted by 'linux' to a registry.
`docker-init` is dedicated to Jenkins infrastructure for initializing docker and isn't required in other contexts.
### Building and testing on Windows
#### Building all images
Run `.\build.ps1` to launch the build of the images corresponding to the "windows" target of docker-bake.hcl.
Internally, the first time you'll run this script and if there is no build-windows_<AGENT_TYPE>_<WINDOWS_FLAVOR>_<WINDOWS_VERSION>.yaml file in your repository, it will use a combination of `docker buildx bake` and `yq` to generate a build-windows_<AGENT_TYPE>_<WINDOWS_FLAVOR>_<WINDOWS_VERSION>.yaml docker compose file containing all Windows image definitions from docker-bake.hcl. Then it will run `docker compose` on this file to build these images.
You can modify this docker compose file as you want, then rerun `.\build.ps1`.
It won't regenerate the docker compose file from docker-bake.hcl unless you add the `-OverwriteDockerComposeFile` build.ps1 parameter: `.\build.ps1 -OverwriteDockerComposeFile`.
Note: you can generate this docker compose file from docker-bake.hcl yourself with the following command (require `docker buildx` and `yq`):
```console
# - Use docker buildx bake to output image definitions from the "windows" bake target
# - Convert with yq to the format expected by docker compose
# - Store the result in the docker compose file
$ docker buildx bake --progress=plain --file=docker-bake.hcl windows --print `
| yq --prettyPrint '.target[] | del(.output) | {(. | key): {\"image\": .tags[0], \"build\": .}}' | yq '{\"services\": .}' `
| Out-File -FilePath build-windows_mybuild.yaml
```
Note that you don't need build.ps1 to build (or to publish) your images from this docker compose file, you can use `docker compose --file=build-windows_mybuild.yaml build`.
#### Testing all images
Run `.\build.ps1 test` if you also want to run the tests harness suit.
Run `.\build.ps1 test -TestsDebug 'debug'` to also get commands & stderr of tests, displayed on top of them.
You can set it to `'verbose'` to also get stdout of every test command.
Note that instead of passing `-TestsDebug` parameter to build.ps1, you can set the $env:TESTS_DEBUG environment variable to the desired value.
Also note that contrary to the Linux part, you have to build the images before testing them.
#### Dry run
Add the `-DryRun` parameter to print out any build, publish or tests commands instead of executing them: `.\build.ps1 test -DryRun`
#### Building and testing a specific image
You can build (and test) only one image type by setting `-ImageType` to a combination of Windows flavors ("nanoserver" & "windowsservercore") and Windows versions ("1809", "ltsc2019", "ltsc2022").
Ex: `.\build.ps1 -ImageType 'nanoserver-ltsc2019'`
Warning: trying to build `windowsservercore-1809` will fail as there is no corresponding image from Microsoft.
You can also build (and test) only one agent type by setting `-AgentType` to either "agent" or "inbound-agent".
Ex: `.\build.ps1 -AgentType 'agent'`
Both parameters can be combined.
Loading

0 comments on commit 5b26913

Please sign in to comment.