diff --git a/Dockerfile-windows b/Dockerfile-windows index b6ab5d068..dee1fb1eb 100644 --- a/Dockerfile-windows +++ b/Dockerfile-windows @@ -24,7 +24,7 @@ ARG WINDOWS_DOCKER_TAG=1809 -FROM openjdk:8-jdk-windowsservercore-$WINDOWS_DOCKER_TAG +FROM adoptopenjdk:8-jdk-hotspot-windowsservercore-$WINDOWS_DOCKER_TAG MAINTAINER Alex Earl SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] @@ -32,25 +32,36 @@ SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPref ARG VERSION=4.3 LABEL Description="This is a base image, which provides the Jenkins agent executable (agent.jar)" Vendor="Jenkins project" Version="${VERSION}" -ARG GIT_VERSION=2.24.0 -ARG GIT_PATCH_VERSION=2 - +ARG GIT_VERSION=2.26.0 +ARG GIT_PATCH_VERSION=1 RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; ` - Invoke-WebRequest $('https://github.com/git-for-windows/git/releases/download/v{0}.windows.{1}/MinGit-{0}.{1}-busybox-64-bit.zip' -f $env:GIT_VERSION, $env:GIT_PATCH_VERSION) -OutFile 'mingit.zip' -UseBasicParsing ; ` + $url = $('https://github.com/git-for-windows/git/releases/download/v{0}.windows.{1}/MinGit-{0}-busybox-64-bit.zip' -f $env:GIT_VERSION, $env:GIT_PATCH_VERSION) ; ` + Write-Host "Retrieving $url..." ; ` + Invoke-WebRequest $url -OutFile 'mingit.zip' -UseBasicParsing ; ` Expand-Archive mingit.zip -DestinationPath c:\mingit ; ` Remove-Item mingit.zip -Force ; ` setx /M PATH $('c:\mingit\cmd;{0}' -f $env:PATH) +ARG GIT_LFS_VERSION=2.10.0 +RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; ` + $url = $('https://github.com/git-lfs/git-lfs/releases/download/v{0}/git-lfs-windows-amd64-v{0}.zip' -f $env:GIT_LFS_VERSION) ; ` + Write-Host "Retrieving $url..." ; ` + Invoke-WebRequest $url -OutFile 'GitLfs.zip' -UseBasicParsing ; ` + Expand-Archive GitLfs.zip -DestinationPath c:\mingit\mingw64\bin ; ` + Remove-Item GitLfs.zip -Force ; ` + & C:\mingit\cmd\git.exe lfs install + ARG user=jenkins ARG AGENT_FILENAME=agent.jar ARG AGENT_HASH_FILENAME=$AGENT_FILENAME.sha1 -RUN net user "$env:user" /add /expire:never /passwordreq:no -RUN mkdir C:/ProgramData/Jenkins | Out-Null +RUN net user "$env:user" /add /expire:never /passwordreq:no ; ` + net localgroup Administrators /add $env:user ; ` + New-Item -ItemType Directory -Path C:/ProgramData/Jenkins | Out-Null -ARG AGENT_ROOT=C:/Users/$user/Jenkins -ARG AGENT_WORKDIR=${AGENT_ROOT}/Agent +ARG AGENT_ROOT=C:/Users/$user +ARG AGENT_WORKDIR=${AGENT_ROOT}/Work ENV AGENT_WORKDIR=${AGENT_WORKDIR} diff --git a/Dockerfile-windows-jdk11 b/Dockerfile-windows-jdk11 index 78e70fab7..c7a97c0b5 100644 --- a/Dockerfile-windows-jdk11 +++ b/Dockerfile-windows-jdk11 @@ -1,71 +1,82 @@ -# escape=` - -# The MIT License -# -# Copyright (c) 2020, 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 - -SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] - -ARG VERSION=4.3 -LABEL Description="This is a base image, which provides the Jenkins agent executable (agent.jar)" Vendor="Jenkins project" Version="${VERSION}" - -ARG GIT_VERSION=2.24.0 -ARG GIT_PATCH_VERSION=2 - -RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; ` - Invoke-WebRequest $('https://github.com/git-for-windows/git/releases/download/v{0}.windows.{1}/MinGit-{0}.{1}-busybox-64-bit.zip' -f $env:GIT_VERSION, $env:GIT_PATCH_VERSION) -OutFile 'mingit.zip' -UseBasicParsing ; ` - Expand-Archive mingit.zip -DestinationPath c:\mingit ; ` - Remove-Item mingit.zip -Force ; ` - setx /M PATH $('c:\mingit\cmd;{0}' -f $env:PATH) - -ARG user=jenkins - -ARG AGENT_FILENAME=agent.jar -ARG AGENT_HASH_FILENAME=$AGENT_FILENAME.sha1 - -RUN net user "$env:user" /add /expire:never /passwordreq:no -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} ; ` - Remove-Item -Force (Join-Path C:/ProgramData/Jenkins $env:AGENT_HASH_FILENAME) - -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} +# escape=` + +# The MIT License +# +# Copyright (c) 2020, 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 adoptopenjdk:11-jdk-hotspot-windowsservercore-$WINDOWS_DOCKER_TAG +MAINTAINER Alex Earl + +SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] + +ARG VERSION=4.3 +LABEL Description="This is a base image, which provides the Jenkins agent executable (agent.jar)" Vendor="Jenkins project" Version="${VERSION}" + +ARG GIT_VERSION=2.26.0 +ARG GIT_PATCH_VERSION=1 +RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; ` + $url = $('https://github.com/git-for-windows/git/releases/download/v{0}.windows.{1}/MinGit-{0}-busybox-64-bit.zip' -f $env:GIT_VERSION, $env:GIT_PATCH_VERSION) ; ` + Write-Host "Retrieving $url..." ; ` + Invoke-WebRequest $url -OutFile 'mingit.zip' -UseBasicParsing ; ` + Expand-Archive mingit.zip -DestinationPath c:\mingit ; ` + Remove-Item mingit.zip -Force ; ` + setx /M PATH $('c:\mingit\cmd;{0}' -f $env:PATH) + +ARG GIT_LFS_VERSION=2.10.0 +RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; ` + $url = $('https://github.com/git-lfs/git-lfs/releases/download/v{0}/git-lfs-windows-amd64-v{0}.zip' -f $env:GIT_LFS_VERSION) ; ` + Write-Host "Retrieving $url..." ; ` + Invoke-WebRequest $url -OutFile 'GitLfs.zip' -UseBasicParsing ; ` + Expand-Archive GitLfs.zip -DestinationPath c:\mingit\mingw64\bin ; ` + Remove-Item GitLfs.zip -Force ; ` + & C:\mingit\cmd\git.exe lfs install + +ARG user=jenkins + +ARG AGENT_FILENAME=agent.jar +ARG AGENT_HASH_FILENAME=$AGENT_FILENAME.sha1 + +RUN net user "$env:user" /add /expire:never /passwordreq:no ; ` + net localgroup Administrators /add $env:user ; ` + New-Item -ItemType Directory -Path C:/ProgramData/Jenkins | Out-Null + +ARG AGENT_ROOT=C:/Users/$user +ARG AGENT_WORKDIR=${AGENT_ROOT}/Work + +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} ; ` + Remove-Item -Force (Join-Path C:/ProgramData/Jenkins $env:AGENT_HASH_FILENAME) + +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} diff --git a/Dockerfile-windows-nanoserver b/Dockerfile-windows-nanoserver index b62c00f7b..d2530f7e9 100644 --- a/Dockerfile-windows-nanoserver +++ b/Dockerfile-windows-nanoserver @@ -1,95 +1,109 @@ -# escape=` - -# The MIT License -# -# Copyright (c) 2019-2020, 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 - -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 GIT_VERSION=2.24.0 -ARG GIT_PATCH_VERSION=2 - -RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; ` - Invoke-WebRequest $('https://github.com/git-for-windows/git/releases/download/v{0}.windows.{1}/MinGit-{0}.{1}-busybox-64-bit.zip' -f $env:GIT_VERSION, $env:GIT_PATCH_VERSION) -OutFile 'mingit.zip' -UseBasicParsing ; ` - Expand-Archive mingit.zip -DestinationPath c:\mingit ; ` - Remove-Item mingit.zip -Force ; ` - setx /M PATH $('c:\mingit\cmd;{0}' -f $env:PATH) - -ARG VERSION=4.3 -ARG user=jenkins - -ARG AGENT_FILENAME=agent.jar -ARG AGENT_HASH_FILENAME=$AGENT_FILENAME.sha1 - -RUN NET USER "$env:user" /add /expire:never /passwordreq:no -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} +# escape=` + +# The MIT License +# +# Copyright (c) 2019-2020, 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_VERSION=8u242-b08 +ARG JAVA_SHA256=8288e4d0983019706db89c153d18bfce28d033f646be65c8ae1c33c6c65b943e +ARG JAVA_HOME=C:\jdk${JAVA_VERSION} +# If you pass in a POWERSHELL_VERSION, make sure it ends with a hyphen, leaving it empty will +# use the 'latest' +ARG POWERSHELL_VERSION= + +FROM mcr.microsoft.com/powershell:${POWERSHELL_VERSION}nanoserver-$WINDOWS_DOCKER_TAG +MAINTAINER Alex Earl + +ARG JAVA_VERSION +ARG JAVA_SHA256 +ARG JAVA_HOME + +SHELL ["pwsh.exe", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] + +USER ContainerAdministrator + +RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; ` + $javaRoot = 'OpenJDK8U-jdk_x64_windows_hotspot_{0}' -f $env:JAVA_VERSION.Replace('-', '') ; ` + $url = $('https://github.com/AdoptOpenJDK/openjdk8-binaries/releases/download/jdk{0}/{1}.zip' -f $env:JAVA_VERSION, $javaRoot) ; ` + Write-Host "Retrieving $url..." ; ` + Invoke-WebRequest $url -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:/ ; ` + Remove-Item -Path openjdk.zip + +ARG JAVA_HOME + +ARG VERSION=4.0.1 +LABEL Description="This is a base image, which provides the Jenkins agent executable (agent.jar)" Vendor="Jenkins project" Version="${VERSION}" + +ARG GIT_VERSION=2.26.0 +ARG GIT_PATCH_VERSION=1 +RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; ` + $url = $('https://github.com/git-for-windows/git/releases/download/v{0}.windows.{1}/MinGit-{0}-busybox-64-bit.zip' -f $env:GIT_VERSION, $env:GIT_PATCH_VERSION) ; ` + Write-Host "Retrieving $url..." ; ` + Invoke-WebRequest $url -OutFile 'mingit.zip' -UseBasicParsing ; ` + Expand-Archive mingit.zip -DestinationPath c:\mingit ; ` + Remove-Item mingit.zip -Force + +ARG GIT_LFS_VERSION=2.10.0 +RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; ` + $url = $('https://github.com/git-lfs/git-lfs/releases/download/v{0}/git-lfs-windows-amd64-v{0}.zip' -f $env:GIT_LFS_VERSION) ; ` + Write-Host "Retrieving $url..." ; ` + Invoke-WebRequest $url -OutFile 'GitLfs.zip' -UseBasicParsing ; ` + Expand-Archive GitLfs.zip -DestinationPath c:\mingit\mingw64\bin ; ` + Remove-Item GitLfs.zip -Force ; ` + & C:\mingit\cmd\git.exe lfs install + + +ENV ProgramFiles="C:\Program Files" +ENV WindowsPATH="C:\Windows\system32;C:\Windows" +ENV PATH="${WindowsPATH};${ProgramFiles}\PowerShell;${JAVA_HOME}\bin;C:\mingit\cmd" + +ARG user=jenkins + +ARG AGENT_FILENAME=agent.jar +ARG AGENT_HASH_FILENAME=$AGENT_FILENAME.sha1 + +RUN net user "$env:user" /add /expire:never /passwordreq:no ; ` + net localgroup Administrators /add $env:user ; ` + New-Item -ItemType Directory -Path C:/ProgramData/Jenkins | Out-Null + +ARG AGENT_ROOT=C:/Users/$user +ARG AGENT_WORKDIR=${AGENT_ROOT}/Work + +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} ; ` + Remove-Item -Force (Join-Path C:/ProgramData/Jenkins $env:AGENT_HASH_FILENAME) + +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} diff --git a/Dockerfile-windows-nanoserver-jdk11 b/Dockerfile-windows-nanoserver-jdk11 index 34efcb761..e12a3ae86 100644 --- a/Dockerfile-windows-nanoserver-jdk11 +++ b/Dockerfile-windows-nanoserver-jdk11 @@ -1,95 +1,110 @@ -# escape=` - -# The MIT License -# -# Copyright (c) 2020, 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 - -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 GIT_VERSION=2.24.0 -ARG GIT_PATCH_VERSION=2 - -RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; ` - Invoke-WebRequest $('https://github.com/git-for-windows/git/releases/download/v{0}.windows.{1}/MinGit-{0}.{1}-busybox-64-bit.zip' -f $env:GIT_VERSION, $env:GIT_PATCH_VERSION) -OutFile 'mingit.zip' -UseBasicParsing ; ` - Expand-Archive mingit.zip -DestinationPath c:\mingit ; ` - Remove-Item mingit.zip -Force ; ` - setx /M PATH $('c:\mingit\cmd;{0}' -f $env:PATH) - -ARG VERSION=4.3 -ARG user=jenkins - -ARG AGENT_FILENAME=agent.jar -ARG AGENT_HASH_FILENAME=$AGENT_FILENAME.sha1 - -RUN NET USER "$env:user" /add /expire:never /passwordreq:no -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} +# escape=` + +# The MIT License +# +# Copyright (c) 2020, 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_VERSION=11.0.6+10 +ARG JAVA_SHA256=6fb8b6c254ec0e1091acd421ac79c1bb07b295de0b679c0595fd284caf7734e5 +ARG JAVA_HOME=C:\jdk-${JAVA_VERSION} +# If you pass in a POWERSHELL_VERSION, make sure it ends with a hyphen, leaving it empty will +# use the 'latest' +ARG POWERSHELL_VERSION= + +FROM mcr.microsoft.com/powershell:${POWERSHELL_VERSION}nanoserver-$WINDOWS_DOCKER_TAG +MAINTAINER Alex Earl + +ARG JAVA_VERSION +ARG JAVA_SHA256 +ARG JAVA_HOME + +SHELL ["pwsh.exe", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] + +USER ContainerAdministrator + +# https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.6%2B10/OpenJDK11U-jdk_x64_windows_hotspot_11.0.6_10.zip + +RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; ` + $javaRoot = 'OpenJDK11U-jdk_x64_windows_hotspot_{0}' -f $env:JAVA_VERSION.Replace('+', '_') ; ` + $url = 'https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-{0}/{1}.zip' -f [System.Uri]::EscapeDataString($env:JAVA_VERSION), $javaRoot ; ` + Write-Host "Retrieving $url..." ; ` + Invoke-WebRequest $url -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:/ ; ` + Remove-Item -Path openjdk.zip + +ARG JAVA_HOME + +ARG VERSION=4.0.1 +LABEL Description="This is a base image, which provides the Jenkins agent executable (agent.jar)" Vendor="Jenkins project" Version="${VERSION}" + +ARG GIT_VERSION=2.26.0 +ARG GIT_PATCH_VERSION=1 +RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; ` + $url = $('https://github.com/git-for-windows/git/releases/download/v{0}.windows.{1}/MinGit-{0}-busybox-64-bit.zip' -f $env:GIT_VERSION, $env:GIT_PATCH_VERSION) ; ` + Write-Host "Retrieving $url..." ; ` + Invoke-WebRequest $url -OutFile 'mingit.zip' -UseBasicParsing ; ` + Expand-Archive mingit.zip -DestinationPath c:\mingit ; ` + Remove-Item mingit.zip -Force + +ARG GIT_LFS_VERSION=2.10.0 +RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; ` + $url = $('https://github.com/git-lfs/git-lfs/releases/download/v{0}/git-lfs-windows-amd64-v{0}.zip' -f $env:GIT_LFS_VERSION) ; ` + Write-Host "Retrieving $url..." ; ` + Invoke-WebRequest $url -OutFile 'GitLfs.zip' -UseBasicParsing ; ` + Expand-Archive GitLfs.zip -DestinationPath c:\mingit\mingw64\bin ; ` + Remove-Item GitLfs.zip -Force + +ENV ProgramFiles="C:\Program Files" +ENV WindowsPATH="C:\Windows\system32;C:\Windows" +ENV PATH="${WindowsPATH};${ProgramFiles}\PowerShell;${JAVA_HOME}\bin;C:\mingit\cmd" + +ARG user=jenkins + +ARG AGENT_FILENAME=agent.jar +ARG AGENT_HASH_FILENAME=$AGENT_FILENAME.sha1 + +RUN net user "$env:user" /add /expire:never /passwordreq:no ; ` + net localgroup Administrators /add $env:user ; ` + setx /M PATH '%PATH%;%JAVA_HOME%\bin' ; ` + New-Item -ItemType Directory -Path C:/ProgramData/Jenkins | Out-Null + +ARG AGENT_ROOT=C:/Users/$user +ARG AGENT_WORKDIR=${AGENT_ROOT}/Work + +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} ; ` + Remove-Item -Force (Join-Path C:/ProgramData/Jenkins $env:AGENT_HASH_FILENAME) + +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} diff --git a/Jenkinsfile b/Jenkinsfile index 348027bc7..687cf6ad5 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -18,7 +18,7 @@ pipeline { label "windock" } options { - timeout(time: 30, unit: 'MINUTES') + timeout(time: 60, unit: 'MINUTES') } environment { DOCKERHUB_ORGANISATION = "${infra.isTrusted() ? 'jenkins' : 'jenkins4eval'}" @@ -26,7 +26,9 @@ pipeline { steps { script { powershell '& ./make.ps1 build' - + + powershell '& ./make.ps1 test' + def branchName = "${env.BRANCH_NAME}" if (branchName ==~ 'master') { // we can't use dockerhub builds for windows @@ -35,7 +37,7 @@ pipeline { powershell '& ./make.ps1 publish' } } - + // cleanup any docker images powershell '& docker system prune --force --all' } diff --git a/README.md b/README.md index 4c0c322a2..b207ed0b8 100644 --- a/README.md +++ b/README.md @@ -29,10 +29,10 @@ docker run -i --rm --name agent --init jenkins/slave java -jar /usr/share/jenkin after setting **Remote root directory** to `/home/jenkins/agent`. -or if using Windows +or if using Windows Containers ``` -docker run -i --rm --name agent --init jenkins/agent:latest-windows java -jar C:/ProgramData/Jenkins/agent.jar +docker run -i --rm --name agent --init jenkins/agent java -jar C:/ProgramData/Jenkins/agent.jar ``` after setting **Remote root directory** to `C:\Users\jenkins\Agent`. @@ -49,10 +49,10 @@ Call example for Linux: docker run -i --rm --name agent1 --init -v agent1-workdir:/home/jenkins/agent jenkins/slave java -jar /usr/share/jenkins/agent.jar -workDir /home/jenkins/agent ``` -Call example for Windows: +Call example for Windows Containers: ``` -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 +docker run -i --rm --name agent1 --init -v agent1-workdir:C:/Users/jenkins/Work jenkins/agent java -jar C:/ProgramData/Jenkins/agent.jar -workDir C:/Users/jenkins/Work ``` ## Configurations @@ -62,11 +62,10 @@ The image has several supported configurations, which can be accessed via the fo * `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`) -* `jenkins4eval/agent:latest-windows`: Latest version with the newest remoting (based on `openjdk:8-jdk-windowsservercore-1809`) -* `jenkins4eval/agent: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 +* `jenkins4eval/agent:windowsservercore-1809`: Latest version with the newest remoting (based on `adoptopenjdk:8-jdk-hotspot-windowsservercore-1809`) +* `jenkins4eval/agent:windowsservercore-1809-jdk11`: Latest version with the newest remoting and Java 11 (based on `adoptopenjdk:11-jdk-hotspot-windowsservercore-1809`) +* `jenkins4eval/agent:nanoserver-1809`: Latest version with the newest remoting with Windows Nano Server +* `jenkins4eval/agent:nanoserver-1809-jdk11`: Latest version with the newest remoting with Windows Nano Server and Java 11 ## Java 11 Support diff --git a/make.ps1 b/make.ps1 index b4e48ba80..0a068dca7 100644 --- a/make.ps1 +++ b/make.ps1 @@ -1,61 +1,118 @@ -[CmdletBinding()] -Param( - [Parameter(Position=1)] - [String] $target = "build", - [String] $TagPrefix = 'latest', - [String] $AdditionalArgs = '', - [String] $Build = '' -) - -$Repository = 'agent' -$Organization = 'jenkins' - -if(![String]::IsNullOrWhiteSpace($env:DOCKERHUB_REPO)) { - $Repository = $env:DOCKERHUB_REPO -} - -if(![String]::IsNullOrWhiteSpace($env:DOCKERHUB_ORGANISATION)) { - $Organization = $env:DOCKERHUB_ORGANISATION -} - -$builds = @{ - 'default' = @{'Dockerfile' = 'Dockerfile-windows' ; 'TagSuffix' = '-windows' }; - 'jdk11' = @{'DockerFile' = 'Dockerfile-windows-jdk11'; 'TagSuffix' = '-windows-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}/{2}:{3}{4} {5} ." -f $builds[$Build]['Dockerfile'], $Organization, $Repository, $TagPrefix, $builds[$Build]['TagSuffix'], $AdditionalArgs - Invoke-Expression $cmd -} else { - foreach($b in $builds.Keys) { - Write-Host "Building $b => tag=$TagPrefix$($builds[$b]['TagSuffix'])" - $cmd = "docker build -f {0} -t {1}/{2}:{3}{4} {5} ." -f $builds[$b]['Dockerfile'], $Organization, $Repository, $TagPrefix, $builds[$b]['TagSuffix'], $AdditionalArgs - Invoke-Expression $cmd - } -} - -if($lastExitCode -ne 0) { - exit $lastExitCode -} - -if($target -eq "publish") { - if(![System.String]::IsNullOrWhiteSpace($Build) -and $builds.ContainsKey($Build)) { - Write-Host "Publishing $Build => tag=$TagPrefix$($builds[$Build]['TagSuffix'])" - $cmd = "docker push {0}/{1}:{2}{3}" -f $Organization, $Repository, $TagPrefix, $builds[$Build]['TagSuffix'] - Invoke-Expression $cmd - } else { - foreach($b in $builds.Keys) { - Write-Host "Publishing $b => tag=$TagPrefix$($builds[$b]['TagSuffix'])" - $cmd = "docker push {0}/{1}:{2}{3}" -f $Organization, $Repository, $TagPrefix, $builds[$b]['TagSuffix'] - Invoke-Expression $cmd - } - } -} - -if($lastExitCode -ne 0) { - Write-Error "Build failed!" -} else { - Write-Host "Build finished successfully" -} -exit $lastExitCode +[CmdletBinding()] +Param( + [Parameter(Position=1)] + [String] $Target = "build", + [String] $AdditionalArgs = '', + [String] $Build = '', + [String] $RemotingVersion = '4.3', + [String] $BuildNumber = "1", + [int] $WindowsTag = (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion").ReleaseId +) + +$Repository = 'agent' +$Organization = 'jenkins' + +if(![String]::IsNullOrWhiteSpace($env:DOCKERHUB_REPO)) { + $Repository = $env:DOCKERHUB_REPO +} + +if(![String]::IsNullOrWhiteSpace($env:DOCKERHUB_ORGANISATION)) { + $Organization = $env:DOCKERHUB_ORGANISATION +} + +$builds = @{ + 'jdk8' = @{'Dockerfile' = 'Dockerfile-windows' ; 'Tags' = @( "latest", "windowsservercore-$WindowsTag", "jdk8", "windowsservercore-$WindowsTag-jdk8" ) }; + 'jdk11' = @{'DockerFile' = 'Dockerfile-windows-jdk11'; 'Tags' = @( "windowsservercore-$WindowsTag-jdk11", "jdk11" ) }; + 'nanoserver' = @{'DockerFile' = 'Dockerfile-windows-nanoserver'; 'Tags' = @( "nanoserver-$WindowsTag", "nanoserver-$WindowsTag-jdk8" ) }; + 'nanoserver-jdk11' = @{'DockerFile' = 'Dockerfile-windows-nanoserver-jdk11'; 'Tags' = @( "nanoserver-$WindowsTag-jdk11" ) }; +} + +if(![System.String]::IsNullOrWhiteSpace($Build) -and $builds.ContainsKey($Build)) { + foreach($tag in $builds[$Build]['Tags']) { + Write-Host "Building $Build => tag=$tag" + $cmd = "docker build -f {0} --build-arg WINDOWS_DOCKER_TAG=$WindowsTag --build-arg VERSION='$RemotingVersion' -t {1}/{2}:{3} {4} ." -f $builds[$Build]['Dockerfile'], $Organization, $Repository, $tag, $AdditionalArgs + Invoke-Expression $cmd + + $buildTag = "$RemotingVersion-$BuildNumber-$tag" + if($tag -eq 'latest') { + $buildTag = "$RemotingVersion-$BuildNumber" + } + Write-Host "Building $Build => tag=$buildTag" + $cmd = "docker build -f {0} --build-arg WINDOWS_DOCKER_TAG=$WindowsTag --build-arg VERSION='$RemotingVersion' -t {1}/{2}:{3} {4} ." -f $builds[$Build]['Dockerfile'], $Organization, $Repository, $buildTag, $AdditionalArgs + Invoke-Expression $cmd + } +} else { + foreach($b in $builds.Keys) { + foreach($tag in $builds[$b]['Tags']) { + Write-Host "Building $b => tag=$tag" + $cmd = "docker build -f {0} --build-arg WINDOWS_DOCKER_TAG=$WindowsTag --build-arg VERSION='$RemotingVersion' -t {1}/{2}:{3} {4} ." -f $builds[$b]['Dockerfile'], $Organization, $Repository, $tag, $AdditionalArgs + Invoke-Expression $cmd + + $buildTag = "$RemotingVersion-$BuildNumber-$tag" + if($tag -eq 'latest') { + $buildTag = "$RemotinvVersion-$BuildNumber" + } + Write-Host "Building $Build => tag=$buildTag" + $cmd = "docker build -f {0} --build-arg WINDOWS_DOCKER_TAG=$WindowsTag --build-arg VERSION='$RemotingVersion' -t {1}/{2}:{3} {4} ." -f $builds[$b]['Dockerfile'], $Organization, $Repository, $buildTag, $AdditionalArgs + Invoke-Expression $cmd + } + } +} + +if($lastExitCode -ne 0) { + exit $lastExitCode +} + +if($target -eq "test") { + $mod = Get-InstalledModule -Name Pester -RequiredVersion 4.9.0 -ErrorAction SilentlyContinue + if($null -eq $mod) { + $module = "c:\Program Files\WindowsPowerShell\Modules\Pester" + takeown /F $module /A /R + icacls $module /reset + icacls $module /grant Administrators:'F' /inheritance:d /T + Remove-Item -Path $module -Recurse -Force -Confirm:$false + Install-Module -Force -Name Pester -RequiredVersion 4.9.0 + } + + if(![System.String]::IsNullOrWhiteSpace($Build) -and $builds.ContainsKey($Build)) { + $env:FLAVOR = $Build + Invoke-Pester -Path tests -EnableExit + Remove-Item env:\FLAVOR + } else { + foreach($b in $builds.Keys) { + $env:FLAVOR = $b + Invoke-Pester -Path tests -EnableExit + Remove-Item env:\FLAVOR + } + } +} + +if($target -eq "publish") { + if(![System.String]::IsNullOrWhiteSpace($Build) -and $builds.ContainsKey($Build)) { + foreach($tag in $Builds[$Build]['Tags']) { + Write-Host "Publishing $Build => tag=$tag" + $cmd = "docker push {0}/{1}:{2}" -f $Organization, $Repository, $tag + Invoke-Expression $cmd + } + } else { + foreach($b in $builds.Keys) { + foreach($tag in $Builds[$b]['Tags']) { + Write-Host "Publishing $b => tag=$tag" + $cmd = "docker push {0}/{1}:{2}" -f $Organization, $Repository, $tag + Invoke-Expression $cmd + } + } + + Write-Host "Publishing $b => tag=$Version" + $cmd = "docker push {0}/{1}:{2}" -f $Organization, $Repository, $Version + Invoke-Expression $cmd + } +} + + +if($lastExitCode -ne 0) { + Write-Error "Build failed!" +} else { + Write-Host "Build finished successfully" +} +exit $lastExitCode diff --git a/tests/agent.Tests.ps1 b/tests/agent.Tests.ps1 new file mode 100644 index 000000000..36cfa96df --- /dev/null +++ b/tests/agent.Tests.ps1 @@ -0,0 +1,181 @@ +Import-Module -DisableNameChecking -Force $PSScriptRoot/test_helpers.psm1 + +$DOCKERFILE='Dockerfile-windows' +$JDK=8 +$AGENT_IMAGE='jenkins-agent' +$AGENT_CONTAINER='pester-jenkins-agent' +$SHELL="powershell.exe" + +$FLAVOR = Get-EnvOrDefault 'FLAVOR' '' + +if([System.String]::IsNullOrWhiteSpace($FLAVOR)) { + $FLAVOR = 'jdk8' +} elseif($flavor -eq "jdk11") { + $DOCKERFILE += "-jdk11" + $JDK=11 + $AGENT_IMAGE += ":jdk11" + $AGENT_CONTAINER += "-jdk11" +} elseif($flavor -eq "nanoserver") { + $DOCKERFILE += "-nanoserver" + $AGENT_IMAGE += ":nanoserver-1809" + $AGENT_CONTAINER += "-nanoserver" + $SHELL="pwsh.exe" +} elseif($flavor -eq "nanoserver-jdk11") { + $DOCKERFILE += "-nanoserver-jdk11" + $JDK=11 + $AGENT_IMAGE += ":nanoserver-1809-jdk11" + $AGENT_CONTAINER += "-nanoserver-jdk11" + $SHELL="pwsh.exe" +} + +Cleanup($AGENT_CONTAINER) + +Describe "[$FLAVOR] build image" { + BeforeEach { + Push-Location -StackName 'agent' -Path "$PSScriptRoot/.." + } + + It 'builds image' { + $exitCode, $stdout, $stderr = Run-Program 'docker.exe' "build -t $AGENT_IMAGE -f ./$DOCKERFILE ." + $exitCode | Should -Be 0 + } + + AfterEach { + Pop-Location -StackName 'agent' + } +} + +Describe "[$FLAVOR] correct image metadata" { + It 'has correct volumes' { + $exitCode, $stdout, $stderr = Run-Program 'docker.exe' "inspect -f '{{.Config.Volumes}}' $AGENT_IMAGE" + $stdout | Should -Match 'C:/Users/jenkins/.jenkins' + $stdout | Should -Match 'C:/Users/jenkins/Work' + } +} + +Describe "[$FLAVOR] image has correct applications in the PATH" { + BeforeAll { + if($DOCKERFILE.Contains('nanoserver')) { + docker run -d -it --name "$AGENT_CONTAINER" -P "$AGENT_IMAGE" pwsh + } else { + docker run -d -it --name "$AGENT_CONTAINER" -P "$AGENT_IMAGE" powershell + } + Is-AgentContainerRunning $AGENT_CONTAINER + } + + It 'has java installed and in the path' { + $exitCode, $stdout, $stderr = Run-Program 'docker.exe' "exec $AGENT_CONTAINER $SHELL -C `"if(`$null -eq (Get-Command java.exe -ErrorAction SilentlyContinue)) { exit -1 } else { exit 0 }`"" + $exitCode | Should -Be 0 + + $exitCode, $stdout, $stderr = Run-Program 'docker.exe' "exec $AGENT_CONTAINER $SHELL -C `"`$version = java -version 2>&1 ; Write-Host `$version`"" + if($JDK -eq 8) { + $r = [regex] "^openjdk version `"(?\d+)\.(?\d+)\.(?\d+).*`"" + $m = $r.Match($stdout) + $m | Should -Not -Be $null + $m.Groups['minor'].ToString() | Should -Be "$JDK" + } else { + $r = [regex] "^openjdk version `"(?\d+)" + $m = $r.Match($stdout) + $m | Should -Not -Be $null + $m.Groups['major'].ToString() | Should -Be "$JDK" + } + } + + It 'has AGENT_WORKDIR in the envrionment' { + $exitCode, $stdout, $stderr = Run-Program 'docker.exe' "exec $AGENT_CONTAINER $SHELL -C `"Get-ChildItem env:`"" + $exitCode | Should -Be 0 + $stdout | Should -Match "AGENT_WORKDIR.*C:/Users/jenkins/Work" + } + + AfterAll { + Cleanup($AGENT_CONTAINER) + } +} + +Describe "[$FLAVOR] check user access to directories" { + BeforeAll { + if($DOCKERFILE.Contains('nanoserver')) { + docker run -d -it --name "$AGENT_CONTAINER" -P "$AGENT_IMAGE" pwsh + } else { + docker run -d -it --name "$AGENT_CONTAINER" -P "$AGENT_IMAGE" powershell + } + Is-AgentContainerRunning $AGENT_CONTAINER + } + + It 'can write to HOME' { + $exitCode, $stdout, $stderr = Run-Program 'docker.exe' "exec $AGENT_CONTAINER $SHELL -C `"New-Item -ItemType File -Path C:/Users/jenkins/a.txt | Out-Null ; if(Test-Path C:/Users/jenkins/a.txt) { exit 0 } else { exit -1 }`"" + $exitCode | Should -Be 0 + } + + It 'can write to HOME/.jenkins' { + $exitCode, $stdout, $stderr = Run-Program 'docker.exe' "exec $AGENT_CONTAINER $SHELL -C `"New-Item -ItemType File -Path C:/Users/jenkins/.jenkins/a.txt | Out-Null ; if(Test-Path C:/Users/jenkins/.jenkins/a.txt) { exit 0 } else { exit -1 }`"" + $exitCode | Should -Be 0 + } + + It 'can write to HOME/Work' { + $exitCode, $stdout, $stderr = Run-Program 'docker.exe' "exec $AGENT_CONTAINER $SHELL -C `"New-Item -ItemType File -Path C:/Users/jenkins/Work/a.txt | Out-Null ; if(Test-Path C:/Users/jenkins/Work/a.txt) { exit 0 } else { exit -1 }`"" + $exitCode | Should -Be 0 + } + + AfterAll { + Cleanup($AGENT_CONTAINER) + } +} + +$TEST_VERSION="3.36" +$TEST_USER="test-user" +$TEST_AGENT_WORKDIR="C:/test-user/something" + +Describe "[$FLAVOR] use build args correctly" { + BeforeAll { + Push-Location -StackName 'agent' -Path "$PSScriptRoot/.." + + $exitCode, $stdout, $stderr = Run-Program 'docker.exe' "build --build-arg `"VERSION=${TEST_VERSION}`" --build-arg `"user=${TEST_USER}`" --build-arg `"AGENT_WORKDIR=${TEST_AGENT_WORKDIR}`" -t ${AGENT_IMAGE} -f ./${DOCKERFILE} ." + $exitCode | Should -Be 0 + + if($DOCKERFILE.Contains('nanoserver')) { + docker run -d -it --name "$AGENT_CONTAINER" -P "$AGENT_IMAGE" pwsh + } else { + docker run -d -it --name "$AGENT_CONTAINER" -P "$AGENT_IMAGE" powershell + } + Is-AgentContainerRunning $AGENT_CONTAINER + } + + It 'has the correct version of remoting' { + $exitCode, $stdout, $stderr = Run-Program 'docker.exe' "exec $AGENT_CONTAINER $SHELL -C `"`$version = java -cp C:/ProgramData/Jenkins/agent.jar hudson.remoting.jnlp.Main -version ; Write-Host `$version`"" + $exitCode | Should -Be 0 + $stdout | Should -Match $TEST_VERSION + } + + It 'has correct user' { + $exitCode, $stdout, $stderr = Run-Program 'docker.exe' "exec $AGENT_CONTAINER $SHELL -C `"(Get-ChildItem env:\ | Where-Object { `$_.Name -eq 'USERNAME' }).Value`"" + $exitCode | Should -Be 0 + $stdout | Should -Match $TEST_USER + } + + It 'has correct AGENT_WORKDIR' { + $exitCode, $stdout, $stderr = Run-Program 'docker.exe' "exec $AGENT_CONTAINER $SHELL -C `"Get-ChildItem env:`"" + $exitCode | Should -Be 0 + $stdout | Should -Match "AGENT_WORKDIR.*${TEST_AGENT_WORKDIR}" + } + + It 'can write to HOME' { + $exitCode, $stdout, $stderr = Run-Program 'docker.exe' "exec $AGENT_CONTAINER $SHELL -C `"New-Item -ItemType File -Path C:/Users/${TEST_USER}/a.txt | Out-Null ; if(Test-Path C:/Users/${TEST_USER}/a.txt) { exit 0 } else { exit -1 }`"" + $exitCode | Should -Be 0 + } + + It 'can write to HOME/.jenkins' { + $exitCode, $stdout, $stderr = Run-Program 'docker.exe' "exec $AGENT_CONTAINER $SHELL -C `"New-Item -ItemType File -Path C:/Users/${TEST_USER}/.jenkins/a.txt | Out-Null ; if(Test-Path C:/Users/${TEST_USER}/.jenkins/a.txt) { exit 0 } else { exit -1 }`"" + $exitCode | Should -Be 0 + } + + It 'can write to HOME/Work' { + $exitCode, $stdout, $stderr = Run-Program 'docker.exe' "exec $AGENT_CONTAINER $SHELL -C `"New-Item -ItemType File -Path ${TEST_AGENT_WORKDIR}/a.txt | Out-Null ; if(Test-Path ${TEST_AGENT_WORKDIR}/a.txt) { exit 0 } else { exit -1 }`"" + $exitCode | Should -Be 0 + } + + AfterAll { + Pop-Location -StackName 'agent' + Cleanup($AGENT_CONTAINER) + } +} diff --git a/tests/test_helpers.psm1 b/tests/test_helpers.psm1 new file mode 100644 index 000000000..d1b5a44e5 --- /dev/null +++ b/tests/test_helpers.psm1 @@ -0,0 +1,122 @@ +function Test-CommandExists($command) { + $oldPreference = $ErrorActionPreference + $ErrorActionPreference = 'stop' + $res = $false + try { + if(Get-Command $command) { + $res = $true + } + } catch { + $res = $false + } finally { + $ErrorActionPreference=$oldPreference + } + return $res +} + +# check dependencies +if(-Not (Test-CommandExists docker)) { + Write-Error "docker is not available" +} + +function Get-EnvOrDefault($name, $def) { + $entry = Get-ChildItem env: | Where-Object { $_.Name -eq $name } | Select-Object -First 1 + if(($null -ne $entry) -and ![System.String]::IsNullOrWhiteSpace($entry.Value)) { + return $entry.Value + } + return $def +} + +function Retry-Command { + [CmdletBinding()] + param ( + [parameter(Mandatory, ValueFromPipeline)] + [ValidateNotNullOrEmpty()] + [scriptblock] $ScriptBlock, + [int] $RetryCount = 3, + [int] $Delay = 30, + [string] $SuccessMessage = "Command executed successfuly!", + [string] $FailureMessage = "Failed to execute the command" + ) + + process { + $Attempt = 1 + $Flag = $true + + do { + try { + $PreviousPreference = $ErrorActionPreference + $ErrorActionPreference = 'Stop' + Invoke-Command -NoNewScope -ScriptBlock $ScriptBlock -OutVariable Result 4>&1 + $ErrorActionPreference = $PreviousPreference + + # flow control will execute the next line only if the command in the scriptblock executed without any errors + # if an error is thrown, flow control will go to the 'catch' block + Write-Verbose "$SuccessMessage `n" + $Flag = $false + } + catch { + if ($Attempt -gt $RetryCount) { + Write-Verbose "$FailureMessage! Total retry attempts: $RetryCount" + Write-Verbose "[Error Message] $($_.exception.message) `n" + $Flag = $false + } else { + Write-Verbose "[$Attempt/$RetryCount] $FailureMessage. Retrying in $Delay seconds..." + Start-Sleep -Seconds $Delay + $Attempt = $Attempt + 1 + } + } + } + While ($Flag) + } +} + +function Cleanup($name='') { + if([System.String]::IsNullOrWhiteSpace($name)) { + $name = Get-EnvOrDefault 'AGENT_IMAGE' '' + } + + if(![System.String]::IsNullOrWhiteSpace($name)) { + #Write-Host "Cleaning up $name" + docker kill "$name" 2>&1 | Out-Null + docker rm -fv "$name" 2>&1 | Out-Null + } +} + +function Is-AgentContainerRunning($container='') { + if([System.String]::IsNullOrWhiteSpace($container)) { + $container = Get-EnvOrDefault 'AGENT_CONTAINER' '' + } + + Start-Sleep -Seconds 5 + Retry-Command -RetryCount 3 -Delay 1 -ScriptBlock { + $exitCode, $stdout, $stderr = Run-Program 'docker.exe' "inspect -f `"{{.State.Running}}`" $container" + if(($exitCode -ne 0) -or (-not $stdout.Contains('true')) ) { + throw('Exit code incorrect, or invalid value for running state') + } + return $true + } | Should -BeTrue +} + +function Run-Program($cmd, $params) { + #Write-Host "cmd = $cmd, params = $params" + $psi = New-Object System.Diagnostics.ProcessStartInfo + $psi.CreateNoWindow = $true + $psi.UseShellExecute = $false + $psi.RedirectStandardOutput = $true + $psi.RedirectStandardError = $true + $psi.WorkingDirectory = (Get-Location) + $psi.FileName = $cmd + $psi.Arguments = $params + $proc = New-Object System.Diagnostics.Process + $proc.StartInfo = $psi + [void]$proc.Start() + $stdout = $proc.StandardOutput.ReadToEnd() + $stderr = $proc.StandardError.ReadToEnd() + $proc.WaitForExit() + if($proc.ExitCode -ne 0) { + Write-Host "`n`nstdout:`n$stdout`n`nstderr:`n$stderr`n`n" + } + + return $proc.ExitCode, $stdout, $stderr +}