Skip to content

Commit

Permalink
Initial commit of Windows docker image support.
Browse files Browse the repository at this point in the history
 * Currently only supports Windows Server Core
 * Files in place to support nanoserver, but more testing needs to be done
 * Both JDK 8 and JDK 11 images are supported
  • Loading branch information
slide committed Jul 12, 2019
1 parent 218e262 commit 4d226ac
Show file tree
Hide file tree
Showing 7 changed files with 346 additions and 3 deletions.
61 changes: 61 additions & 0 deletions Dockerfile-windows
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# escape=`

# The MIT License
#
# Copyright (c) 2019, Alex Earl and other Jenkins Contributors
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

ARG WINDOWS_DOCKER_TAG=1809

FROM openjdk:8-jdk-windowsservercore-$WINDOWS_DOCKER_TAG
MAINTAINER Alex Earl <[email protected]>

SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]

ARG VERSION=3.29
LABEL Description="This is a base image, which provides the Jenkins agent executable (agent.jar)" Vendor="Jenkins project" Version="${VERSION}"

ARG user=jenkins

ARG AGENT_FILENAME=agent.jar
ARG AGENT_HASH_FILENAME=$AGENT_FILENAME.sha1

RUN net user "$env:user" /add
RUN mkdir C:/ProgramData/Jenkins | Out-Null

ARG AGENT_ROOT=C:/Users/$user/Jenkins
ARG AGENT_WORKDIR=${AGENT_ROOT}/Agent

ENV AGENT_WORKDIR=${AGENT_WORKDIR}

# Get the Agent from the Jenkins Artifacts Repository
RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; `
Invoke-WebRequest $('https://repo.jenkins-ci.org/public/org/jenkins-ci/main/remoting/{0}/remoting-{0}.jar' -f $env:VERSION) -OutFile $(Join-Path C:/ProgramData/Jenkins $env:AGENT_FILENAME) -UseBasicParsing ;`
Invoke-WebRequest $('https://repo.jenkins-ci.org/public/org/jenkins-ci/main/remoting/{0}/remoting-{0}.jar.sha1' -f $env:VERSION) -OutFile (Join-Path C:/ProgramData/Jenkins $env:AGENT_HASH_FILENAME) -UseBasicParsing ;`
if ((Get-FileHash (Join-Path C:/ProgramData/Jenkins $env:AGENT_FILENAME) -Algorithm SHA1).Hash -ne (Get-Content (Join-Path C:/ProgramData/Jenkins $env:AGENT_HASH_FILENAME))) {exit 1}

USER $user

RUN New-Item -Type Directory $('{0}/.jenkins' -f $env:AGENT_ROOT) | Out-Null ; `
New-Item -Type Directory $env:AGENT_WORKDIR | Out-Null

VOLUME ${AGENT_ROOT}/.jenkins
VOLUME ${AGENT_WORKDIR}
WORKDIR ${AGENT_ROOT}
61 changes: 61 additions & 0 deletions Dockerfile-windows-jdk11
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# escape=`

# The MIT License
#
# Copyright (c) 2019, Alex Earl and other Jenkins Contributors
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

ARG WINDOWS_DOCKER_TAG=1809

FROM openjdk:11-jdk-windowsservercore-$WINDOWS_DOCKER_TAG
MAINTAINER Alex Earl <[email protected]>

SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]

ARG VERSION=3.29
LABEL Description="This is a base image, which provides the Jenkins agent executable (agent.jar)" Vendor="Jenkins project" Version="${VERSION}"

ARG user=jenkins

ARG AGENT_FILENAME=agent.jar
ARG AGENT_HASH_FILENAME=$AGENT_FILENAME.sha1

RUN net user "$env:user" /add
RUN mkdir C:/ProgramData/Jenkins | Out-Null

ARG AGENT_ROOT=C:/Users/$user/Jenkins
ARG AGENT_WORKDIR=${AGENT_ROOT}/Agent

ENV AGENT_WORKDIR=${AGENT_WORKDIR}

# Get the Agent from the Jenkins Artifacts Repository
RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; `
Invoke-WebRequest $('https://repo.jenkins-ci.org/public/org/jenkins-ci/main/remoting/{0}/remoting-{0}.jar' -f $env:VERSION) -OutFile $(Join-Path C:/ProgramData/Jenkins $env:AGENT_FILENAME) -UseBasicParsing ;`
Invoke-WebRequest $('https://repo.jenkins-ci.org/public/org/jenkins-ci/main/remoting/{0}/remoting-{0}.jar.sha1' -f $env:VERSION) -OutFile (Join-Path C:/ProgramData/Jenkins $env:AGENT_HASH_FILENAME) -UseBasicParsing ;`
if ((Get-FileHash (Join-Path C:/ProgramData/Jenkins $env:AGENT_FILENAME) -Algorithm SHA1).Hash -ne (Get-Content (Join-Path C:/ProgramData/Jenkins $env:AGENT_HASH_FILENAME))) {exit 1}

USER $user

RUN New-Item -Type Directory $('{0}/.jenkins' -f $env:AGENT_ROOT) | Out-Null ; `
New-Item -Type Directory $env:AGENT_WORKDIR | Out-Null

VOLUME ${AGENT_ROOT}/.jenkins
VOLUME ${AGENT_WORKDIR}
WORKDIR ${AGENT_ROOT}
86 changes: 86 additions & 0 deletions Dockerfile-windows-nanoserver
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# escape=`

# The MIT License
#
# Copyright (c) 2019, Alex Earl and other Jenkins Contributors
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

ARG WINDOWS_DOCKER_TAG=1809
ARG JAVA_BASE_VERSION=1.8.0
ARG JAVA_VERSION=1.8.0.212-1
ARG JAVA_ZIP_VERSION=${JAVA_VERSION}.b04
ARG JAVA_SHA256=a40d7ab150bb2c2b3ad19e388942c4fe47b92a89dd49c468e09ce9d8bc631934
ARG JAVA_HOME=C:/openjdk-${JAVA_VERSION}
ARG POWERSHELL_VERSION=6.2.1

FROM mcr.microsoft.com/powershell:$POWERSHELL_VERSION-nanoserver-$WINDOWS_DOCKER_TAG
MAINTAINER Alex Earl <[email protected]>

ARG JAVA_VERSION
ARG JAVA_ZIP_VERSION
ARG JAVA_SHA256
ARG JAVA_HOME
ARG JAVA_BASE_VERSION

SHELL ["pwsh.exe", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]

USER Administrator

RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; `
$javaRoot = 'java-{0}-openjdk-{1}.ojdkbuild.windows.x86_64' -f $env:JAVA_BASE_VERSION, $env:JAVA_ZIP_VERSION ; `
Write-Host "Retrieving $('https://github.com/ojdkbuild/ojdkbuild/releases/download/{0}/{1}.zip' -f $env:JAVA_VERSION, $javaRoot)..." ; `
Invoke-WebRequest $('https://github.com/ojdkbuild/ojdkbuild/releases/download/{0}/{1}.zip' -f $env:JAVA_VERSION, $javaRoot) -OutFile 'openjdk.zip' -UseBasicParsing ; `
if ((Get-FileHash openjdk.zip -Algorithm sha256).Hash -ne $env:JAVA_SHA256) { Write-Error 'Java SHA256 mismatch' ; exit 1} ; `
Expand-Archive openjdk.zip -DestinationPath C:/ ; `
Move-Item -Path $('C:/{0}' -f $javaRoot) -Destination $('C:/openjdk-{0}' -f $env:JAVA_VERSION) ; `
Remove-Item -Path openjdk.zip

ARG JAVA_HOME

ARG VERSION=3.29
ARG user=jenkins

ARG AGENT_FILENAME=agent.jar
ARG AGENT_HASH_FILENAME=$AGENT_FILENAME.sha1

RUN NET USER "$env:user" /add
RUN setx /M PATH '%PATH%;%JAVA_HOME%\bin' ; mkdir C:/ProgramData/Jenkins | Out-Null

LABEL Description="This is a base image, which provides the Jenkins agent executable (agent.jar)" Vendor="Jenkins project" Version="${VERSION}"

ARG AGENT_ROOT=C:/Users/$user/Jenkins
ARG AGENT_WORKDIR=${AGENT_ROOT}/Agent

ENV AGENT_WORKDIR=${AGENT_WORKDIR}

# Get the Agent from the Jenkins Artifacts Repository
RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; `
Invoke-WebRequest $('https://repo.jenkins-ci.org/public/org/jenkins-ci/main/remoting/{0}/remoting-{0}.jar' -f $env:VERSION) -OutFile $(Join-Path C:/ProgramData/Jenkins $env:AGENT_FILENAME) -UseBasicParsing ;`
Invoke-WebRequest $('https://repo.jenkins-ci.org/public/org/jenkins-ci/main/remoting/{0}/remoting-{0}.jar.sha1' -f $env:VERSION) -OutFile (Join-Path C:/ProgramData/Jenkins $env:AGENT_HASH_FILENAME) -UseBasicParsing ;`
if ((Get-FileHash (Join-Path C:/ProgramData/Jenkins $env:AGENT_FILENAME) -Algorithm SHA1).Hash -ne (Get-Content (Join-Path C:/ProgramData/Jenkins $env:AGENT_HASH_FILENAME))) {exit 1}

USER $user

RUN mkdir (Join-Path $env:AGENT_ROOT .jenkins) | Out-Null ; `
mkdir "$env:AGENT_WORKDIR" | Out-Null

VOLUME ${AGENT_ROOT}/.jenkins
VOLUME ${AGENT_WORKDIR}
WORKDIR ${AGENT_ROOT}
86 changes: 86 additions & 0 deletions Dockerfile-windows-nanoserver-jdk11
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# escape=`

# The MIT License
#
# Copyright (c) 2019, Alex Earl and other Jenkins Contributors
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

ARG WINDOWS_DOCKER_TAG=1809
ARG JAVA_BASE_VERSION=11
ARG JAVA_VERSION=11.0.3-1
ARG JAVA_ZIP_VERSION=11.0.3.7-1
ARG JAVA_SHA256=b13703a7ee5ff3e14881b7d3488fa93942d1858ca3cd5fa9234b763df84dc937
ARG JAVA_HOME=C:/openjdk-${JAVA_VERSION}
ARG POWERSHELL_VERSION=6.2.1

FROM mcr.microsoft.com/powershell:$POWERSHELL_VERSION-nanoserver-$WINDOWS_DOCKER_TAG
MAINTAINER Alex Earl <[email protected]>

ARG JAVA_VERSION
ARG JAVA_ZIP_VERSION
ARG JAVA_SHA256
ARG JAVA_HOME
ARG JAVA_BASE_VERSION

SHELL ["pwsh.exe", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]

USER Administrator

RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; `
$javaRoot = 'java-{0}-openjdk-{1}.windows.ojdkbuild.x86_64' -f $env:JAVA_BASE_VERSION, $env:JAVA_ZIP_VERSION ; `
Write-Host "Retrieving $('https://github.com/ojdkbuild/ojdkbuild/releases/download/{0}/{1}.zip' -f $env:JAVA_VERSION, $javaRoot)..." ; `
Invoke-WebRequest $('https://github.com/ojdkbuild/ojdkbuild/releases/download/{0}/{1}.zip' -f $env:JAVA_VERSION, $javaRoot) -OutFile 'openjdk.zip' -UseBasicParsing ; `
if ((Get-FileHash openjdk.zip -Algorithm sha256).Hash -ne $env:JAVA_SHA256) { Write-Error 'Java SHA256 mismatch' ; exit 1} ; `
Expand-Archive openjdk.zip -DestinationPath C:/ ; `
Move-Item -Path $('C:/{0}' -f $javaRoot) -Destination $('C:/openjdk-{0}' -f $env:JAVA_VERSION) ; `
Remove-Item -Path openjdk.zip

ARG JAVA_HOME

ARG VERSION=3.29
ARG user=jenkins

ARG AGENT_FILENAME=agent.jar
ARG AGENT_HASH_FILENAME=$AGENT_FILENAME.sha1

RUN NET USER "$env:user" /add
RUN setx /M PATH '%PATH%;%JAVA_HOME%\bin' ; mkdir C:/ProgramData/Jenkins | Out-Null

LABEL Description="This is a base image, which provides the Jenkins agent executable (agent.jar)" Vendor="Jenkins project" Version="${VERSION}"

ARG AGENT_ROOT=C:/Users/$user/Jenkins
ARG AGENT_WORKDIR=${AGENT_ROOT}/Agent

ENV AGENT_WORKDIR=${AGENT_WORKDIR}

# Get the Agent from the Jenkins Artifacts Repository
RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; `
Invoke-WebRequest $('https://repo.jenkins-ci.org/public/org/jenkins-ci/main/remoting/{0}/remoting-{0}.jar' -f $env:VERSION) -OutFile $(Join-Path C:/ProgramData/Jenkins $env:AGENT_FILENAME) -UseBasicParsing ;`
Invoke-WebRequest $('https://repo.jenkins-ci.org/public/org/jenkins-ci/main/remoting/{0}/remoting-{0}.jar.sha1' -f $env:VERSION) -OutFile (Join-Path C:/ProgramData/Jenkins $env:AGENT_HASH_FILENAME) -UseBasicParsing ;`
if ((Get-FileHash (Join-Path C:/ProgramData/Jenkins $env:AGENT_FILENAME) -Algorithm SHA1).Hash -ne (Get-Content (Join-Path C:/ProgramData/Jenkins $env:AGENT_HASH_FILENAME))) {exit 1}

USER $user

RUN mkdir (Join-Path $env:AGENT_ROOT .jenkins) | Out-Null ; `
mkdir "$env:AGENT_WORKDIR" | Out-Null

VOLUME ${AGENT_ROOT}/.jenkins
VOLUME ${AGENT_WORKDIR}
WORKDIR ${AGENT_ROOT}
23 changes: 20 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,40 +13,57 @@ This executable is an instance of the [Jenkins Remoting library](https://github.
This image is used as the basis for the [Docker JNLP Agent](https://github.com/jenkinsci/docker-jnlp-slave/) image.
In that image, the container is launched externally and attaches to Jenkins.

This image may instead be used to launch an agent using the **Launch method** of **Launch agent via execution of command on the master**. Try for example
This image may instead be used to launch an agent using the **Launch method** of **Launch agent via execution of command on the master**. For example on Linux you can try

```sh
docker run -i --rm --name agent --init jenkins/slave java -jar /usr/share/jenkins/slave.jar
```

after setting **Remote root directory** to `/home/jenkins/agent`.

or if using Windows

```
docker run -i --rm --name agent --init jenkins/agent:latest-windows java -jar C:/ProgramData/Jenkins/agent.jar
```

after setting **Remote root directory** to `C:\Users\jenkins\Agent`.


### Agent Work Directories

Starting from [Remoting 3.8](https://github.com/jenkinsci/remoting/blob/master/CHANGELOG.md#38) there is a support of Work directories,
which provides logging by default and change the JAR Caching behavior.

Call example:
Call example for Linux:

```sh
docker run -i --rm --name agent1 --init -v agent1-workdir:/home/jenkins/agent jenkins/slave java -jar /usr/share/jenkins/slave.jar -workDir /home/jenkins/agent
```

Call example for Windows:

```
docker run -i --rm --name agent1 --init -v agent1-workdir:C:/Users/jenkins/Agent jenkins/agent:latest-windows java -jar C:/ProgramData/Jenkins/agent.jar -workDir C:/Users/jenkins/Agent
```

## Configurations

The image has several supported configurations, which can be accessed via the following tags:

* `latest`: Latest version with the newest remoting (based on `openjdk:8-jdk`)
* `latest-jdk11`: Latest version with the newest remoting and Java 11 (based on `openjdk:11-jdk`)
* `alpine`: Small image based on Alpine Linux (based on `openjdk:8-jdk-alpine`)
* `latest-windows`: Latest version with the newest remoting (based on `openjdk:8-jdk-windowsservercore-1809`)
* `latest-windows-jdk11`: Latest version with the newest remoting and Java 11 (based on `openjdk:11.0-jdk-windowsservercore-1809`)
* `2.62`: This version bundles [Remoting 2.x](https://github.com/jenkinsci/remoting#remoting-2]), which is compatible with Jenkins servers running on Java 6 (`1.609.4` and below)
* `2.62-alpine`: Small image with Remoting 2.x
* `2.62-jdk11`: Versioned image for Java 11

## Java 11 Support

Java 11 support is available in a preview mode.
Only Debian-based images are provided right now.
Only Debian-based images and Windows images are provided right now.
(see [JENKINS-54487](https://issues.jenkins-ci.org/browse/JENKINS-54487)).
There is a probability that images for Java 11 will be changed to AdoptOpenJDK
before the final release of Java 11 support in Jenkins.
28 changes: 28 additions & 0 deletions build.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[CmdletBinding()]
Param(
[String] $TagPrefix = 'latest',
[String] $AdditionalArgs = '',
[String] $Build = '',
[String] $Repository = 'jenkins4eval'
)

$builds = @{
'default' = @{'Dockerfile' = 'Dockerfile-windows' ; 'TagSuffix' = '-windows' };
'jdk11' = @{'DockerFile' = 'Dockerfile-windows-jdk11'; 'TagSuffix' = '-windows-jdk11' };
#'nanoserver' = 'Dockerfile-windows-nanoserver';
#'nanoserver-jdk11' = 'Dockerfile-windows-nanoserver-jdk11';
}

if(![System.String]::IsNullOrWhiteSpace($Build) -and $builds.ContainsKey($Build)) {
Write-Host "Building $build => tag=$TagPrefix$($builds[$build]['TagSuffix'])"
$cmd = "docker build -f {0} -t {1}/agent:{2}{3} {4} ." -f $builds[$build]['Dockerfile'], $Repository, $TagPrefix, $builds[$build]['TagSuffix'], $AdditionalArgs
Invoke-Expression $cmd
} else {
foreach($build in $builds.Keys) {
Write-Host "Building $build => tag=$TagPrefix$($builds[$build]['TagSuffix'])"
$cmd = "docker build -f {0} -t {1}/agent:{2}{3} {4} ." -f $builds[$build]['Dockerfile'], $Repository, $TagPrefix, $builds[$build]['TagSuffix'], $AdditionalArgs
Invoke-Expression $cmd
}
}

Write-Host "Build finished successfully"
Loading

0 comments on commit 4d226ac

Please sign in to comment.