Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: align with docker-ssh-agent build process #827

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
974969e
chore: define jdks to build at a single place in docker bake
lemeurherve Jun 22, 2024
22934df
chore: add `TestsDebug` parameter
lemeurherve Jun 22, 2024
19cce30
chore: lint *.ps1
lemeurherve Jun 22, 2024
57d5a57
chore: add log output to Windows tests
lemeurherve Jun 22, 2024
f96d882
fix: implement `docker` calls as `make` targets
lemeurherve Jun 22, 2024
af17f85
chore: shortens `agentSelector` comments
lemeurherve Jun 22, 2024
f48ef34
fix: remove interpolation in last sh and powershell calls
lemeurherve Jun 22, 2024
2bc7774
chore: set bats formatter to junit
lemeurherve Jun 23, 2024
4cc014e
chore: use docker bake to generate docker compose file
lemeurherve Jun 22, 2024
52b4455
chore: get rid of build.sh and env.props
lemeurherve Jun 23, 2024
3ebdb13
chore: import 'building' README section from jenkinsci/docker-ssh-agent
lemeurherve Jun 23, 2024
affb8e4
doc: adapt docker-ssh-agent's 'building' section to this repository
lemeurherve Jun 23, 2024
2e77995
Merge branch 'master' into align-with-docker-ssh-agent-process
lemeurherve Jul 8, 2024
1086ab1
remove Windows Server Core version pinning workaround
lemeurherve Jul 10, 2024
c4bcede
fix merge conflicts
lemeurherve Jul 10, 2024
da1e5ed
Merge branch 'master' into align-with-docker-ssh-agent-process
lemeurherve Jul 17, 2024
404c748
Merge branch 'master' into align-with-docker-ssh-agent-process
lemeurherve Jul 22, 2024
9b667c8
Merge branch 'master' into align-with-docker-ssh-agent-process
lemeurherve Jul 25, 2024
a886418
fix merge conflicts
lemeurherve Jul 26, 2024
850fd7b
fix merge conflict
lemeurherve Aug 10, 2024
7bfdeb4
Merge branch 'master' into align-with-docker-ssh-agent-process
lemeurherve Aug 13, 2024
ffed12e
Merge branch 'master' into align-with-docker-ssh-agent-process
dduportal Sep 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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]}"]
) {
Comment on lines +84 to +87
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
withEnv(
["REMOTING_VERSION=${tagItems[0]}"],
["BUILD_NUMBER=${tagItems[1]}"]
) {
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