Signed-off-by: John Howard <jhoward@microsoft.com>
(cherry picked from commit 155435b6ceeb05b2927ecc726216666b898b6459)
Signed-off-by: Victor Vieux <victorvieux@gmail.com>
... | ... |
@@ -2,7 +2,7 @@ |
2 | 2 |
|
3 | 3 |
# ----------------------------------------------------------------------------------------- |
4 | 4 |
# This file describes the standard way to build Docker in a container on Windows |
5 |
-# Server 2016. |
|
5 |
+# Server 2016 or Windows 10. |
|
6 | 6 |
# |
7 | 7 |
# Maintainer: @jhowardmsft |
8 | 8 |
# ----------------------------------------------------------------------------------------- |
... | ... |
@@ -11,21 +11,25 @@ |
11 | 11 |
# Prerequisites: |
12 | 12 |
# -------------- |
13 | 13 |
# |
14 |
-# 1. Windows Server 2016 with all Windows updates applied. Pre-release versions |
|
15 |
-# of Windows are not supported (eg Windows Server 2016 TP5). The build number |
|
16 |
-# must be at least 14393. This can be confirmed, for example, by running the |
|
17 |
-# following from an elevated PowerShell prompt - this sample output is from a |
|
18 |
-# fully up to date machine as at late October 2016: |
|
14 |
+# 1. Windows Server 2016 or Windows 10 with all Windows updates applied. The major |
|
15 |
+# build number must be at least 14393. This can be confirmed, for example, by |
|
16 |
+# running the following from an elevated PowerShell prompt - this sample output |
|
17 |
+# is from a fully up to date machine as at mid-November 2016: |
|
19 | 18 |
# |
20 | 19 |
# >> PS C:\> $(gin).WindowsBuildLabEx |
21 |
-# >> 14393.321.amd64fre.rs1_release_inmarket.161004-2338 |
|
20 |
+# >> 14393.447.amd64fre.rs1_release_inmarket.161102-0100 |
|
22 | 21 |
# |
23 | 22 |
# 2. Git for Windows (or another git client) must be installed. https://git-scm.com/download/win. |
24 | 23 |
# |
25 | 24 |
# 3. The machine must be configured to run containers. For example, by following |
26 | 25 |
# the quick start guidance at https://msdn.microsoft.com/en-us/virtualization/windowscontainers/quick_start/quick_start or |
27 | 26 |
# https://github.com/docker/labs/blob/master/windows/windows-containers/Setup.md |
28 |
- |
|
27 |
+# |
|
28 |
+# 4. If building in a Hyper-V VM: For Windows Server 2016 using Windows Server |
|
29 |
+# containers as the default option, it is recommended you have at least 1GB |
|
30 |
+# of memory assigned; For Windows 10 where Hyper-V Containers are employed, you |
|
31 |
+# should have at least 4GB of memory assigned. Note also, to run Hyper-V |
|
32 |
+# containers in a VM, it is necessary to configure the VM for nested virtualization. |
|
29 | 33 |
|
30 | 34 |
# ----------------------------------------------------------------------------------------- |
31 | 35 |
|
... | ... |
@@ -63,18 +67,16 @@ |
63 | 63 |
# >> docker build -t nativebuildimage -f Dockerfile.windows . |
64 | 64 |
# |
65 | 65 |
# |
66 |
-# 4. Build the docker executable binaries in a container: |
|
66 |
+# 4. Build the docker executable binaries: |
|
67 | 67 |
# |
68 |
-# >> docker run --name binaries nativebuildimage sh -c 'cd /c/go/src/github.com/docker/docker; hack/make.sh binary' |
|
68 |
+# >> docker run --name binaries nativebuildimage hack\make.ps1 -Binary |
|
69 | 69 |
# |
70 | 70 |
# |
71 |
-# 5. Copy the binaries out of the above container, replacing HostPath with an appropriate destination |
|
71 |
+# 5. Copy the binaries out of the container, replacing HostPath with an appropriate destination |
|
72 | 72 |
# folder on the host system where you want the binaries to be located. |
73 | 73 |
# |
74 |
-# >> $v=$(Get-Content ".\VERSION" -raw).ToString().Replace("`n","").Trim() |
|
75 |
-# >> docker cp binaries:C:\go\src\github.com\docker\docker\bundles\$v\binary-client\docker-$v.exe C:\HostPath\docker.exe |
|
76 |
-# >> docker cp binaries:C:\go\src\github.com\docker\docker\bundles\$v\binary-daemon\dockerd.exe C:\HostPath\dockerd.exe |
|
77 |
-# >> docker cp binaries:C:\go\src\github.com\docker\docker\bundles\$v\binary-daemon\docker-proxy-$v.exe C:\HostPath\docker-proxy.exe |
|
74 |
+# >> docker cp binaries:C:\go\src\github.com\docker\docker\bundles\docker.exe C:\HostPath\docker.exe |
|
75 |
+# >> docker cp binaries:C:\go\src\github.com\docker\docker\bundles\dockerd.exe C:\HostPath\dockerd.exe |
|
78 | 76 |
# |
79 | 77 |
# |
80 | 78 |
# 6. (Optional) Remove the interim container holding the built executable binaries: |
... | ... |
@@ -88,6 +90,39 @@ |
88 | 88 |
# image which has all the components required to build the binaries already installed. |
89 | 89 |
# |
90 | 90 |
# >> docker rmi nativebuildimage |
91 |
+# |
|
92 |
+ |
|
93 |
+# ----------------------------------------------------------------------------------------- |
|
94 |
+ |
|
95 |
+ |
|
96 |
+# The validation tests can either run in a container, or directly on the host. To run in a |
|
97 |
+# container, ensure you have created the nativebuildimage above. Then run the following |
|
98 |
+# from an (elevated) Windows PowerShell prompt: |
|
99 |
+# |
|
100 |
+# >> docker run --rm nativebuildimage hack\make.ps1 -DCO -PkgImports -GoFormat |
|
101 |
+ |
|
102 |
+# To run the validation tests on the host, from the root of the repository, run the |
|
103 |
+# following from a Windows PowerShell prompt (elevation is not required): (Note Go |
|
104 |
+# must be installed to run these tests) |
|
105 |
+# |
|
106 |
+# >> hack\make.ps1 -DCO -PkgImports -GoFormat |
|
107 |
+ |
|
108 |
+# ----------------------------------------------------------------------------------------- |
|
109 |
+ |
|
110 |
+ |
|
111 |
+# To run unit tests, ensure you have created the nativebuildimage above. Then run the |
|
112 |
+# following from an (elevated) Windows PowerShell prompt: |
|
113 |
+# |
|
114 |
+# >> docker run --rm nativebuildimage hack\make.ps1 -TestUnit |
|
115 |
+ |
|
116 |
+ |
|
117 |
+# ----------------------------------------------------------------------------------------- |
|
118 |
+ |
|
119 |
+ |
|
120 |
+# To run all tests and binary build, ensure you have created the nativebuildimage above. Then |
|
121 |
+# run the following from an (elevated) Windows PowerShell prompt: |
|
122 |
+# |
|
123 |
+# >> docker run nativebuildimage hack\make.ps1 -All |
|
91 | 124 |
|
92 | 125 |
|
93 | 126 |
# ----------------------------------------------------------------------------------------- |
... | ... |
@@ -96,28 +131,26 @@ |
96 | 96 |
# Important notes: |
97 | 97 |
# --------------- |
98 | 98 |
# |
99 |
-# The posix utilities from git aren't usable interactively as at October 2016. This |
|
100 |
-# is because they require a console window which isn't present in a container in Windows. |
|
101 |
-# See the example at the top of this file. Do NOT use -it in that docker run. It will not work. |
|
99 |
+# Don't attempt to use a bind-mount to pass a local directory as the bundles target |
|
100 |
+# directory. It does not work (golang attempts for follow a mapped folder incorrectly). |
|
101 |
+# Instead, use docker cp as per the example. |
|
102 | 102 |
# |
103 |
-# Don't attempt to use a volume for passing the source through to the container. The posix utilities will |
|
104 |
-# balk at reparse points. |
|
103 |
+# go.zip is not removed from the image as it is used by the Windows CI servers |
|
104 |
+# to ensure the host and image are running consistent versions of go. |
|
105 | 105 |
# |
106 |
-# The downloaded files are not cleared from the image. go.zip is used by the Windows |
|
107 |
-# CI servers to ensure the host and image are running consistent versions of go. |
|
106 |
+# Nanoserver support is a work in progress. Although the image will build if the |
|
107 |
+# FROM statement is updated, it will not work when running autogen through hack\make.ps1. |
|
108 |
+# It is suspected that the required GCC utilities (eg gcc, windres, windmc) silently |
|
109 |
+# quit due to the use of console hooks which are not available. |
|
108 | 110 |
# |
109 |
-# The GIT installer isn't very good at unattended install. We use techniques described |
|
110 |
-# at the links below to force it to set the path and other options accordingly. |
|
111 |
-# >> http://superuser.com/questions/944576/git-for-windows-silent-install-silent-arguments |
|
112 |
-# and follow through to installer at |
|
113 |
-# >> https://github.com/ferventcoder/chocolatey-packages/blob/master/automatic/git.install/tools/chocolateyInstall.ps1 |
|
111 |
+# The docker integration tests do not currently run in a container on Windows, predominantly |
|
112 |
+# due to Windows not supporting privileged mode, so anything using a volume would fail. |
|
113 |
+# They (along with the rest of the docker CI suite) can be run using |
|
114 |
+# https://github.com/jhowardmsft/docker-w2wCIScripts/blob/master/runCI/Invoke-DockerCI.ps1. |
|
114 | 115 |
# |
115 |
-# As of October 2016, this does not work on Windows 10 client, just Windows Server 2016, |
|
116 |
-# and only with the default isolation mode (process). It does not work with isolation mode |
|
117 |
-# set to Hyper-V containers (hyperv). |
|
118 |
- |
|
119 | 116 |
# ----------------------------------------------------------------------------------------- |
120 | 117 |
|
118 |
+ |
|
121 | 119 |
# The number of build steps below are explicitly minimised to improve performance. |
122 | 120 |
FROM microsoft/windowsservercore |
123 | 121 |
|
... | ... |
@@ -128,55 +161,102 @@ SHELL ["powershell", "-command"] |
128 | 128 |
# - GO_VERSION must be consistent with 'Dockerfile' used by Linux. |
129 | 129 |
# - FROM_DOCKERFILE is used for detection of building within a container. |
130 | 130 |
ENV GO_VERSION=1.7.3 ` |
131 |
- GIT_LOCATION=https://github.com/git-for-windows/git/releases/download/v2.10.1.windows.1/Git-2.10.1-64-bit.exe ` |
|
131 |
+ GIT_VERSION=2.10.2 ` |
|
132 | 132 |
GOPATH=C:\go ` |
133 | 133 |
FROM_DOCKERFILE=1 |
134 | 134 |
|
135 |
-WORKDIR C:\ |
|
136 |
- |
|
137 | 135 |
RUN ` |
138 |
- setx /M Path $($Env:PATH+';C:\gcc\bin;C:\go\bin'); ` |
|
139 |
- ` |
|
140 | 136 |
$ErrorActionPreference = 'Stop'; ` |
137 |
+ $ProgressPreference = 'SilentlyContinue'; ` |
|
138 |
+ ` |
|
139 |
+ Function Test-Nano() { ` |
|
140 |
+ $EditionId = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' -Name 'EditionID').EditionId; ` |
|
141 |
+ return (($EditionId -eq 'ServerStandardNano') -or ($EditionId -eq 'ServerDataCenterNano') -or ($EditionId -eq 'NanoServer')); ` |
|
142 |
+ }` |
|
143 |
+ ` |
|
141 | 144 |
Function Download-File([string] $source, [string] $target) { ` |
142 |
- $wc = New-Object net.webclient; $wc.Downloadfile($source, $target) ` |
|
145 |
+ if (Test-Nano) { ` |
|
146 |
+ $handler = New-Object System.Net.Http.HttpClientHandler; ` |
|
147 |
+ $client = New-Object System.Net.Http.HttpClient($handler); ` |
|
148 |
+ $client.Timeout = New-Object System.TimeSpan(0, 30, 0); ` |
|
149 |
+ $cancelTokenSource = [System.Threading.CancellationTokenSource]::new(); ` |
|
150 |
+ $responseMsg = $client.GetAsync([System.Uri]::new($source), $cancelTokenSource.Token); ` |
|
151 |
+ $responseMsg.Wait(); ` |
|
152 |
+ if (!$responseMsg.IsCanceled) { ` |
|
153 |
+ $response = $responseMsg.Result; ` |
|
154 |
+ if ($response.IsSuccessStatusCode) { ` |
|
155 |
+ $downloadedFileStream = [System.IO.FileStream]::new($target, [System.IO.FileMode]::Create, [System.IO.FileAccess]::Write); ` |
|
156 |
+ $copyStreamOp = $response.Content.CopyToAsync($downloadedFileStream); ` |
|
157 |
+ $copyStreamOp.Wait(); ` |
|
158 |
+ $downloadedFileStream.Close(); ` |
|
159 |
+ if ($copyStreamOp.Exception -ne $null) { throw $copyStreamOp.Exception } ` |
|
160 |
+ } ` |
|
161 |
+ } else { ` |
|
162 |
+ Throw ("Failed to download " + $source) ` |
|
163 |
+ }` |
|
164 |
+ } else { ` |
|
165 |
+ $webClient = New-Object System.Net.WebClient; ` |
|
166 |
+ $webClient.DownloadFile($source, $target); ` |
|
167 |
+ } ` |
|
143 | 168 |
} ` |
144 | 169 |
` |
170 |
+ setx /M PATH $('C:\git\bin;C:\git\usr\bin;'+$Env:PATH+';C:\gcc\bin;C:\go\bin'); ` |
|
171 |
+ ` |
|
145 | 172 |
Write-Host INFO: Downloading git...; ` |
146 |
- Download-File $Env:GIT_LOCATION gitsetup.exe; ` |
|
173 |
+ $location='https://github.com/git-for-windows/git/releases/download/v'+$env:GIT_VERSION+'.windows.1/PortableGit-'+$env:GIT_VERSION+'-64-bit.7z.exe'; ` |
|
174 |
+ Download-File $location C:\gitsetup.7z.exe; ` |
|
147 | 175 |
` |
148 | 176 |
Write-Host INFO: Downloading go...; ` |
149 |
- Download-File $('https://golang.org/dl/go'+$Env:GO_VERSION+'.windows-amd64.zip') go.zip; ` |
|
177 |
+ Download-File $('https://golang.org/dl/go'+$Env:GO_VERSION+'.windows-amd64.zip') C:\go.zip; ` |
|
150 | 178 |
` |
151 | 179 |
Write-Host INFO: Downloading compiler 1 of 3...; ` |
152 |
- Download-File https://raw.githubusercontent.com/jhowardmsft/docker-tdmgcc/master/gcc.zip gcc.zip; ` |
|
180 |
+ Download-File https://raw.githubusercontent.com/jhowardmsft/docker-tdmgcc/master/gcc.zip C:\gcc.zip; ` |
|
153 | 181 |
` |
154 | 182 |
Write-Host INFO: Downloading compiler 2 of 3...; ` |
155 |
- Download-File https://raw.githubusercontent.com/jhowardmsft/docker-tdmgcc/master/runtime.zip runtime.zip; ` |
|
183 |
+ Download-File https://raw.githubusercontent.com/jhowardmsft/docker-tdmgcc/master/runtime.zip C:\runtime.zip; ` |
|
156 | 184 |
` |
157 | 185 |
Write-Host INFO: Downloading compiler 3 of 3...; ` |
158 |
- Download-File https://raw.githubusercontent.com/jhowardmsft/docker-tdmgcc/master/binutils.zip binutils.zip; ` |
|
186 |
+ Download-File https://raw.githubusercontent.com/jhowardmsft/docker-tdmgcc/master/binutils.zip C:\binutils.zip; ` |
|
159 | 187 |
` |
160 |
- Write-Host INFO: Installing git...; ` |
|
161 |
- $installPath = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'; ` |
|
162 |
- $installItem = 'Git_is1'; ` |
|
163 |
- New-Item -Path $installPath -Name $installItem -Force; ` |
|
164 |
- $installKey = $installPath+'\'+$installItem; ` |
|
165 |
- New-ItemProperty $installKey -Name 'Inno Setup CodeFile: Path Option' -Value 'CmdTools' -PropertyType 'String' -Force; ` |
|
166 |
- New-ItemProperty $installKey -Name 'Inno Setup CodeFile: Bash Terminal Option' -Value 'ConHost' -PropertyType 'String' -Force; ` |
|
167 |
- New-ItemProperty $installKey -Name 'Inno Setup CodeFile: CRLF Option' -Value 'CRLFCommitAsIs' -PropertyType 'String' -Force; ` |
|
168 |
- Start-Process gitsetup.exe -ArgumentList '/VERYSILENT /SUPPRESSMSGBOXES /CLOSEAPPLICATIONS /DIR=C:\git\' -Wait; ` |
|
188 |
+ Write-Host INFO: Installing PS7Zip package...; ` |
|
189 |
+ Install-Package PS7Zip -Force | Out-Null; ` |
|
190 |
+ Write-Host INFO: Importing PS7Zip...; ` |
|
191 |
+ Import-Module PS7Zip -Force; ` |
|
192 |
+ New-Item C:\git -ItemType Directory | Out-Null ; ` |
|
193 |
+ cd C:\git; ` |
|
194 |
+ Write-Host INFO: Extracting git...; ` |
|
195 |
+ Expand-7Zip C:\gitsetup.7z.exe | Out-Null; ` |
|
196 |
+ cd C:\; ` |
|
169 | 197 |
` |
170 | 198 |
Write-Host INFO: Expanding go...; ` |
171 | 199 |
Expand-Archive C:\go.zip -DestinationPath C:\; ` |
172 | 200 |
` |
173 |
- Write-Host INFO: Expanding compiler...; ` |
|
201 |
+ Write-Host INFO: Expanding compiler 1 of 3...; ` |
|
174 | 202 |
Expand-Archive C:\gcc.zip -DestinationPath C:\gcc -Force; ` |
203 |
+ Write-Host INFO: Expanding compiler 2 of 3...; ` |
|
175 | 204 |
Expand-Archive C:\runtime.zip -DestinationPath C:\gcc -Force; ` |
205 |
+ Write-Host INFO: Expanding compiler 3 of 3...; ` |
|
176 | 206 |
Expand-Archive C:\binutils.zip -DestinationPath C:\gcc -Force; ` |
177 | 207 |
` |
208 |
+ Write-Host INFO: Removing downloaded files...; ` |
|
209 |
+ Remove-Item C:\gcc.zip; ` |
|
210 |
+ Remove-Item C:\runtime.zip; ` |
|
211 |
+ Remove-Item C:\binutils.zip; ` |
|
212 |
+ Remove-Item C:\gitsetup.7z.exe; ` |
|
213 |
+ ` |
|
214 |
+ Write-Host INFO: Creating source directory...; ` |
|
215 |
+ New-Item -ItemType Directory -Path C:\go\src\github.com\docker\docker | Out-Null; ` |
|
216 |
+ ` |
|
217 |
+ Write-Host INFO: Configuring git core.autocrlf...; ` |
|
218 |
+ C:\git\bin\git config --global core.autocrlf true; ` |
|
219 |
+ ` |
|
178 | 220 |
Write-Host INFO: Completed |
179 | 221 |
|
180 |
-# Prepare for building |
|
181 |
-COPY . C:\go\src\github.com\docker\docker |
|
222 |
+# Make PowerShell the default entrypoint |
|
223 |
+ENTRYPOINT ["powershell.exe"] |
|
224 |
+ |
|
225 |
+# Set the working directory to the location of the sources |
|
226 |
+WORKDIR C:\go\src\github.com\docker\docker |
|
182 | 227 |
|
228 |
+# Copy the sources into the container |
|
229 |
+COPY . . |
183 | 230 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,401 @@ |
0 |
+<# |
|
1 |
+.NOTES |
|
2 |
+ Author: @jhowardmsft |
|
3 |
+ |
|
4 |
+ Summary: Windows native build script. This is similar to functionality provided |
|
5 |
+ by hack\make.sh, but uses native Windows PowerShell semantics. It does |
|
6 |
+ not support the full set of options provided by the Linux counterpart. |
|
7 |
+ For example: |
|
8 |
+ |
|
9 |
+ - You can't cross-build Linux docker binaries on Windows |
|
10 |
+ - Hashes aren't generated on binaries |
|
11 |
+ - 'Releasing' isn't supported. |
|
12 |
+ - Integration tests. This is because they currently cannot run inside a container, |
|
13 |
+ and require significant external setup. |
|
14 |
+ |
|
15 |
+ It does however provided the minimum necessary to support parts of local Windows |
|
16 |
+ development and Windows to Windows CI. |
|
17 |
+ |
|
18 |
+ Usage Examples (run from repo root): |
|
19 |
+ "hack\make.ps1 -Binary" to build the binaries |
|
20 |
+ "hack\make.ps1 -Client" to build just the client 64-bit binary |
|
21 |
+ "hack\make.ps1 -TestUnit" to run unit tests |
|
22 |
+ "hack\make.ps1 -Binary -TestUnit" to build the binaries and run unit tests |
|
23 |
+ "hack\make.ps1 -All" to run everything this script knows about |
|
24 |
+ |
|
25 |
+.PARAMETER Client |
|
26 |
+ Builds the client binaries. |
|
27 |
+ |
|
28 |
+.PARAMETER Daemon |
|
29 |
+ Builds the daemon binary. |
|
30 |
+ |
|
31 |
+.PARAMETER Binary |
|
32 |
+ Builds the client binaries and the daemon binary. A convenient shortcut to `make.ps1 -Client -Daemon`. |
|
33 |
+ |
|
34 |
+.PARAMETER Race |
|
35 |
+ Use -race in go build and go test. |
|
36 |
+ |
|
37 |
+.PARAMETER Noisy |
|
38 |
+ Use -v in go build. |
|
39 |
+ |
|
40 |
+.PARAMETER ForceBuildAll |
|
41 |
+ Use -a in go build. |
|
42 |
+ |
|
43 |
+.PARAMETER NoOpt |
|
44 |
+ Use -gcflags -N -l in go build to disable optimisation (can aide debugging). |
|
45 |
+ |
|
46 |
+.PARAMETER CommitSuffix |
|
47 |
+ Adds a custom string to be appended to the commit ID (spaces are stripped). |
|
48 |
+ |
|
49 |
+.PARAMETER DCO |
|
50 |
+ Runs the DCO (Developer Certificate Of Origin) test. |
|
51 |
+ |
|
52 |
+.PARAMETER PkgImports |
|
53 |
+ Runs the pkg\ directory imports test. |
|
54 |
+ |
|
55 |
+.PARAMETER GoFormat |
|
56 |
+ Runs the Go formatting test. |
|
57 |
+ |
|
58 |
+.PARAMETER TestUnit |
|
59 |
+ Runs unit tests. |
|
60 |
+ |
|
61 |
+.PARAMETER All |
|
62 |
+ Runs everything this script knows about. |
|
63 |
+ |
|
64 |
+ |
|
65 |
+TODO |
|
66 |
+- Unify the head commit |
|
67 |
+- Sort out the GITCOMMIT environment variable in the absense of a .git (longer term) |
|
68 |
+- Add golint and other checks (swagger maybe?) |
|
69 |
+ |
|
70 |
+#> |
|
71 |
+ |
|
72 |
+ |
|
73 |
+param( |
|
74 |
+ [Parameter(Mandatory=$False)][switch]$Client, |
|
75 |
+ [Parameter(Mandatory=$False)][switch]$Daemon, |
|
76 |
+ [Parameter(Mandatory=$False)][switch]$Binary, |
|
77 |
+ [Parameter(Mandatory=$False)][switch]$Race, |
|
78 |
+ [Parameter(Mandatory=$False)][switch]$Noisy, |
|
79 |
+ [Parameter(Mandatory=$False)][switch]$ForceBuildAll, |
|
80 |
+ [Parameter(Mandatory=$False)][switch]$NoOpt, |
|
81 |
+ [Parameter(Mandatory=$False)][string]$CommitSuffix="", |
|
82 |
+ [Parameter(Mandatory=$False)][switch]$DCO, |
|
83 |
+ [Parameter(Mandatory=$False)][switch]$PkgImports, |
|
84 |
+ [Parameter(Mandatory=$False)][switch]$GoFormat, |
|
85 |
+ [Parameter(Mandatory=$False)][switch]$TestUnit, |
|
86 |
+ [Parameter(Mandatory=$False)][switch]$All |
|
87 |
+) |
|
88 |
+ |
|
89 |
+$ErrorActionPreference = "Stop" |
|
90 |
+$pushed=$False # To restore the directory if we have temporarily pushed to one. |
|
91 |
+ |
|
92 |
+# Utility function to get the commit ID of the repository |
|
93 |
+Function Get-GitCommit() { |
|
94 |
+ if (-not (Test-Path ".\.git")) { |
|
95 |
+ # If we don't have a .git directory, but we do have the environment |
|
96 |
+ # variable DOCKER_GITCOMMIT set, that can override it. |
|
97 |
+ if ($env:DOCKER_GITCOMMIT.Length -eq 0) { |
|
98 |
+ Throw ".git directory missing and DOCKER_GITCOMMIT environment variable not specified." |
|
99 |
+ } |
|
100 |
+ Write-Host "INFO: Git commit assumed from DOCKER_GITCOMMIT environment variable" |
|
101 |
+ return $env:DOCKER_GITCOMMIT |
|
102 |
+ } |
|
103 |
+ $gitCommit=$(git rev-parse --short HEAD) |
|
104 |
+ if ($(git status --porcelain --untracked-files=no).Length -ne 0) { |
|
105 |
+ $gitCommit="$gitCommit-unsupported" |
|
106 |
+ Write-Host "" |
|
107 |
+ Write-Warning "This version is unsupported because there are uncommitted file(s)." |
|
108 |
+ Write-Warning "Either commit these changes, or add them to .gitignore." |
|
109 |
+ git status --porcelain --untracked-files=no | Write-Warning |
|
110 |
+ Write-Host "" |
|
111 |
+ } |
|
112 |
+ return $gitCommit |
|
113 |
+} |
|
114 |
+ |
|
115 |
+# Utility function to get get the current build version of docker |
|
116 |
+Function Get-DockerVersion() { |
|
117 |
+ if (-not (Test-Path ".\VERSION")) { Throw "VERSION file not found. Is this running from the root of a docker repository?" } |
|
118 |
+ return $(Get-Content ".\VERSION" -raw).ToString().Replace("`n","").Trim() |
|
119 |
+} |
|
120 |
+ |
|
121 |
+# Utility function to determine if we are running in a container or not. |
|
122 |
+# In Windows, we get this through an environment variable set in `Dockerfile.Windows` |
|
123 |
+Function Check-InContainer() { |
|
124 |
+ if ($env:FROM_DOCKERFILE.Length -eq 0) { |
|
125 |
+ Write-Host "" |
|
126 |
+ Write-Warning "Not running in a container. The result might be an incorrect build." |
|
127 |
+ Write-Host "" |
|
128 |
+ } |
|
129 |
+} |
|
130 |
+ |
|
131 |
+# Utility function to get the commit for HEAD |
|
132 |
+Function Get-HeadCommit() { |
|
133 |
+ $head = Invoke-Expression "git rev-parse --verify HEAD" |
|
134 |
+ if ($LASTEXITCODE -ne 0) { Throw "Failed getting HEAD commit" } |
|
135 |
+ |
|
136 |
+ return $head |
|
137 |
+} |
|
138 |
+ |
|
139 |
+# Utility function to get the commit for upstream |
|
140 |
+Function Get-UpstreamCommit() { |
|
141 |
+ Invoke-Expression "git fetch -q https://github.com/docker/docker.git refs/heads/master" |
|
142 |
+ if ($LASTEXITCODE -ne 0) { Throw "Failed fetching" } |
|
143 |
+ |
|
144 |
+ $upstream = Invoke-Expression "git rev-parse --verify FETCH_HEAD" |
|
145 |
+ if ($LASTEXITCODE -ne 0) { Throw "Failed getting upstream commit" } |
|
146 |
+ |
|
147 |
+ return $upstream |
|
148 |
+} |
|
149 |
+ |
|
150 |
+# Build a binary (client or daemon) |
|
151 |
+Function Execute-Build($type, $additionalBuildTags, $directory) { |
|
152 |
+ # Generate the build flags |
|
153 |
+ $buildTags = "autogen" |
|
154 |
+ if ($Noisy) { $verboseParm=" -v" } |
|
155 |
+ if ($Race) { Write-Warning "Using race detector"; $raceParm=" -race"} |
|
156 |
+ if ($ForceBuildAll) { $allParm=" -a" } |
|
157 |
+ if ($NoOpt) { $optParm=" -gcflags "+""""+"-N -l"+"""" } |
|
158 |
+ if ($addtionalBuildTags -ne "") { $buildTags += $(" " + $additionalBuildTags) } |
|
159 |
+ |
|
160 |
+ # Do the go build in the appropriate directory |
|
161 |
+ # Note -linkmode=internal is required to be able to debug on Windows. |
|
162 |
+ # https://github.com/golang/go/issues/14319#issuecomment-189576638 |
|
163 |
+ Write-Host "INFO: Building $type..." |
|
164 |
+ Push-Location $root\cmd\$directory; $global:pushed=$True |
|
165 |
+ $buildCommand = "go build" + ` |
|
166 |
+ $raceParm + ` |
|
167 |
+ $verboseParm + ` |
|
168 |
+ $allParm + ` |
|
169 |
+ $optParm + ` |
|
170 |
+ " -tags """ + $buildTags + """" + ` |
|
171 |
+ " -ldflags """ + "-linkmode=internal" + """" + ` |
|
172 |
+ " -o $root\bundles\"+$directory+".exe" |
|
173 |
+ Invoke-Expression $buildCommand |
|
174 |
+ if ($LASTEXITCODE -ne 0) { Throw "Failed to compile $type" } |
|
175 |
+ Pop-Location; $global:pushed=$False |
|
176 |
+} |
|
177 |
+ |
|
178 |
+# Validates the DCO marker is present on each commit |
|
179 |
+Function Validate-DCO($headCommit, $upstreamCommit) { |
|
180 |
+ Write-Host "INFO: Validating Developer Certificate of Origin..." |
|
181 |
+ # Username may only contain alphanumeric characters or dashes and cannot begin with a dash |
|
182 |
+ $usernameRegex='[a-zA-Z0-9][a-zA-Z0-9-]+' |
|
183 |
+ |
|
184 |
+ $dcoPrefix="Signed-off-by:" |
|
185 |
+ $dcoRegex="^(Docker-DCO-1.1-)?$dcoPrefix ([^<]+) <([^<>@]+@[^<>]+)>( \\(github: ($githubUsernameRegex)\\))?$" |
|
186 |
+ |
|
187 |
+ $counts = Invoke-Expression "git diff --numstat $upstreamCommit...$headCommit" |
|
188 |
+ if ($LASTEXITCODE -ne 0) { Throw "Failed git diff --numstat" } |
|
189 |
+ |
|
190 |
+ # Counts of adds and deletes after removing multiple white spaces. AWK anyone? :( |
|
191 |
+ $adds=0; $dels=0; $($counts -replace '\s+', ' ') | %{ $a=$_.Split(" "); $adds+=[int]$a[0]; $dels+=[int]$a[1] } |
|
192 |
+ if (($adds -eq 0) -and ($dels -eq 0)) { |
|
193 |
+ Write-Warning "DCO validation - nothing to validate!" |
|
194 |
+ return |
|
195 |
+ } |
|
196 |
+ |
|
197 |
+ $commits = Invoke-Expression "git log $upstreamCommit..$headCommit --format=format:%H%n" |
|
198 |
+ if ($LASTEXITCODE -ne 0) { Throw "Failed git log --format" } |
|
199 |
+ $commits = $($commits -split '\s+' -match '\S') |
|
200 |
+ $badCommits=@() |
|
201 |
+ $commits | %{ |
|
202 |
+ # Skip commits with no content such as merge commits etc |
|
203 |
+ if ($(git log -1 --format=format: --name-status $_).Length -gt 0) { |
|
204 |
+ # Ignore exit code on next call - always process regardless |
|
205 |
+ $commitMessage = Invoke-Expression "git log -1 --format=format:%B --name-status $_" |
|
206 |
+ if (($commitMessage -match $dcoRegex).Length -eq 0) { $badCommits+=$_ } |
|
207 |
+ } |
|
208 |
+ } |
|
209 |
+ if ($badCommits.Length -eq 0) { |
|
210 |
+ Write-Host "Congratulations! All commits are properly signed with the DCO!" |
|
211 |
+ } else { |
|
212 |
+ $e = "`nThese commits do not have a proper '$dcoPrefix' marker:`n" |
|
213 |
+ $badCommits | %{ $e+=" - $_`n"} |
|
214 |
+ $e += "`nPlease amend each commit to include a properly formatted DCO marker.`n`n" |
|
215 |
+ $e += "Visit the following URL for information about the Docker DCO:`n" |
|
216 |
+ $e += "https://github.com/docker/docker/blob/master/CONTRIBUTING.md#sign-your-work`n" |
|
217 |
+ Throw $e |
|
218 |
+ } |
|
219 |
+} |
|
220 |
+ |
|
221 |
+# Validates that .\pkg\... is safely isolated from internal code |
|
222 |
+Function Validate-PkgImports($headCommit, $upstreamCommit) { |
|
223 |
+ Write-Host "INFO: Validating pkg import isolation..." |
|
224 |
+ |
|
225 |
+ # Get a list of go source-code files which have changed under pkg\. Ignore exit code on next call - always process regardless |
|
226 |
+ $files=@(); $files = Invoke-Expression "git diff $upstreamCommit...$headCommit --diff-filter=ACMR --name-only -- `'pkg\*.go`'" |
|
227 |
+ $badFiles=@(); $files | %{ |
|
228 |
+ $file=$_ |
|
229 |
+ # For the current changed file, get its list of dependencies, sorted and uniqued. |
|
230 |
+ $imports = Invoke-Expression "go list -e -f `'{{ .Deps }}`' $file" |
|
231 |
+ if ($LASTEXITCODE -ne 0) { Throw "Failed go list for dependencies on $file" } |
|
232 |
+ $imports = $imports -Replace "\[" -Replace "\]", "" -Split(" ") | Sort-Object | Get-Unique |
|
233 |
+ # Filter out what we are looking for |
|
234 |
+ $imports = $imports -NotMatch "^github.com/docker/docker/pkg/" ` |
|
235 |
+ -NotMatch "^github.com/docker/docker/vendor" ` |
|
236 |
+ -Match "^github.com/docker/docker" ` |
|
237 |
+ -Replace "`n", "" |
|
238 |
+ $imports | % { $badFiles+="$file imports $_`n" } |
|
239 |
+ } |
|
240 |
+ if ($badFiles.Length -eq 0) { |
|
241 |
+ Write-Host 'Congratulations! ".\pkg\*.go" is safely isolated from internal code.' |
|
242 |
+ } else { |
|
243 |
+ $e = "`nThese files import internal code: (either directly or indirectly)`n" |
|
244 |
+ $badFiles | %{ $e+=" - $_"} |
|
245 |
+ Throw $e |
|
246 |
+ } |
|
247 |
+} |
|
248 |
+ |
|
249 |
+# Validates that changed files are correctly go-formatted |
|
250 |
+Function Validate-GoFormat($headCommit, $upstreamCommit) { |
|
251 |
+ Write-Host "INFO: Validating go formatting on changed files..." |
|
252 |
+ |
|
253 |
+ # Verify gofmt is installed |
|
254 |
+ if ($(Get-Command gofmt -ErrorAction SilentlyContinue) -eq $nil) { Throw "gofmt does not appear to be installed" } |
|
255 |
+ |
|
256 |
+ # Get a list of all go source-code files which have changed. Ignore exit code on next call - always process regardless |
|
257 |
+ $files=@(); $files = Invoke-Expression "git diff $upstreamCommit...$headCommit --diff-filter=ACMR --name-only -- `'*.go`'" |
|
258 |
+ $files = $files | Select-String -NotMatch "^vendor/" |
|
259 |
+ $badFiles=@(); $files | %{ |
|
260 |
+ # Deliberately ignore error on next line - treat as failed |
|
261 |
+ $content=Invoke-Expression "git show $headCommit`:$_" |
|
262 |
+ |
|
263 |
+ # Next set of hoops are to ensure we have LF not CRLF semantics as otherwise gofmt on Windows will not succeed. |
|
264 |
+ # Also note that gofmt on Windows does not appear to support stdin piping correctly. Hence go through a temporary file. |
|
265 |
+ $content=$content -join "`n" |
|
266 |
+ $content+="`n" |
|
267 |
+ $outputFile=[System.IO.Path]::GetTempFileName() |
|
268 |
+ if (Test-Path $outputFile) { Remove-Item $outputFile } |
|
269 |
+ [System.IO.File]::WriteAllText($outputFile, $content, (New-Object System.Text.UTF8Encoding($False))) |
|
270 |
+ $valid=Invoke-Expression "gofmt -s -l $outputFile" |
|
271 |
+ Write-Host "Checking $outputFile" |
|
272 |
+ if ($valid.Length -ne 0) { $badFiles+=$_ } |
|
273 |
+ if (Test-Path $outputFile) { Remove-Item $outputFile } |
|
274 |
+ } |
|
275 |
+ if ($badFiles.Length -eq 0) { |
|
276 |
+ Write-Host 'Congratulations! All Go source files are properly formatted.' |
|
277 |
+ } else { |
|
278 |
+ $e = "`nThese files are not properly gofmt`'d:`n" |
|
279 |
+ $badFiles | %{ $e+=" - $_`n"} |
|
280 |
+ $e+= "`nPlease reformat the above files using `"gofmt -s -w`" and commit the result." |
|
281 |
+ Throw $e |
|
282 |
+ } |
|
283 |
+} |
|
284 |
+ |
|
285 |
+# Run the unit tests |
|
286 |
+Function Run-UnitTests() { |
|
287 |
+ Write-Host "INFO: Running unit tests..." |
|
288 |
+ $testPath="./..." |
|
289 |
+ $goListCommand = "go list -e -f '{{if ne .Name """ + '\"github.com/docker/docker\"' + """}}{{.ImportPath}}{{end}}' $testPath" |
|
290 |
+ $pkgList = $(Invoke-Expression $goListCommand) |
|
291 |
+ if ($LASTEXITCODE -ne 0) { Throw "go list for unit tests failed" } |
|
292 |
+ $pkgList = $pkgList | Select-String -Pattern "github.com/docker/docker" |
|
293 |
+ $pkgList = $pkgList | Select-String -NotMatch "github.com/docker/docker/vendor" |
|
294 |
+ $pkgList = $pkgList | Select-String -NotMatch "github.com/docker/docker/man" |
|
295 |
+ $pkgList = $pkgList | Select-String -NotMatch "github.com/docker/docker/integration-cli" |
|
296 |
+ $pkgList = $pkgList -replace "`r`n", " " |
|
297 |
+ $goTestCommand = "go test" + $raceParm + " -cover -ldflags -w -tags """ + "autogen daemon" + """ -a """ + "-test.timeout=10m" + """ $pkgList" |
|
298 |
+ Invoke-Expression $goTestCommand |
|
299 |
+ if ($LASTEXITCODE -ne 0) { Throw "Unit tests failed" } |
|
300 |
+} |
|
301 |
+ |
|
302 |
+# Start of main code. |
|
303 |
+Try { |
|
304 |
+ Write-Host -ForegroundColor Cyan "INFO: make.ps1 starting at $(Get-Date)" |
|
305 |
+ $root=$(pwd) |
|
306 |
+ |
|
307 |
+ # Handle the "-All" shortcut to turn on all things we can handle. |
|
308 |
+ if ($All) { $Client=$True; $Daemon=$True; $DCO=$True; $PkgImports=$True; $GoFormat=$True; $TestUnit=$True } |
|
309 |
+ |
|
310 |
+ # Handle the "-Binary" shortcut to build both client and daemon. |
|
311 |
+ if ($Binary) { $Client = $True; $Daemon = $True } |
|
312 |
+ |
|
313 |
+ # Make sure we have something to do |
|
314 |
+ if (-not($Client) -and -not($Daemon) -and -not($DCO) -and -not($PkgImports) -and -not($GoFormat) -and -not($TestUnit)) { Throw 'Nothing to do. Try adding "-All" for everything I can do' } |
|
315 |
+ |
|
316 |
+ # Verify git is installed |
|
317 |
+ if ($(Get-Command git -ErrorAction SilentlyContinue) -eq $nil) { Throw "Git does not appear to be installed" } |
|
318 |
+ |
|
319 |
+ # Verify go is installed |
|
320 |
+ if ($(Get-Command go -ErrorAction SilentlyContinue) -eq $nil) { Throw "GoLang does not appear to be installed" } |
|
321 |
+ |
|
322 |
+ # Get the git commit. This will also verify if we are in a repo or not. Then add a custom string if supplied. |
|
323 |
+ $gitCommit=Get-GitCommit |
|
324 |
+ if ($CommitSuffix -ne "") { $gitCommit += "-"+$CommitSuffix -Replace ' ', '' } |
|
325 |
+ |
|
326 |
+ # Get the version of docker (eg 1.14.0-dev) |
|
327 |
+ $dockerVersion=Get-DockerVersion |
|
328 |
+ |
|
329 |
+ # Give a warning if we are not running in a container and are building binaries or running unit tests. |
|
330 |
+ # Not relevant for validation tests as these are fine to run outside of a container. |
|
331 |
+ if ($Client -or $Daemon -or $TestUnit) { Check-InContainer } |
|
332 |
+ |
|
333 |
+ # Verify GOPATH is set |
|
334 |
+ if ($env:GOPATH.Length -eq 0) { Throw "Missing GOPATH environment variable. See https://golang.org/doc/code.html#GOPATH" } |
|
335 |
+ |
|
336 |
+ # Run autogen if building binaries or running unit tests. |
|
337 |
+ if ($Client -or $Daemon -or $TestUnit) { |
|
338 |
+ Write-Host "INFO: Invoking autogen..." |
|
339 |
+ Try { .\hack\make\.go-autogen.ps1 -CommitString $gitCommit -DockerVersion $dockerVersion } |
|
340 |
+ Catch [Exception] { Throw $_ } |
|
341 |
+ } |
|
342 |
+ |
|
343 |
+ # DCO, Package import and Go formatting tests. |
|
344 |
+ if ($DCO -or $PkgImports -or $GoFormat) { |
|
345 |
+ # We need the head and upstream commits for these |
|
346 |
+ $headCommit=Get-HeadCommit |
|
347 |
+ $upstreamCommit=Get-UpstreamCommit |
|
348 |
+ |
|
349 |
+ # Run DCO validation |
|
350 |
+ if ($DCO) { Validate-DCO $headCommit $upstreamCommit } |
|
351 |
+ |
|
352 |
+ # Run `gofmt` validation |
|
353 |
+ if ($GoFormat) { Validate-GoFormat $headCommit $upstreamCommit } |
|
354 |
+ |
|
355 |
+ # Run pkg isolation validation |
|
356 |
+ if ($PkgImports) { Validate-PkgImports $headCommit $upstreamCommit } |
|
357 |
+ } |
|
358 |
+ |
|
359 |
+ # Build the binaries |
|
360 |
+ if ($Client -or $Daemon) { |
|
361 |
+ # Create the bundles directory if it doesn't exist |
|
362 |
+ if (-not (Test-Path ".\bundles")) { New-Item ".\bundles" -ItemType Directory | Out-Null } |
|
363 |
+ |
|
364 |
+ # Perform the actual build |
|
365 |
+ if ($Daemon) { Execute-Build "daemon" "daemon" "dockerd" } |
|
366 |
+ if ($Client) { Execute-Build "client" "" "docker" } |
|
367 |
+ } |
|
368 |
+ |
|
369 |
+ # Run unit tests |
|
370 |
+ if ($TestUnit) { Run-UnitTests } |
|
371 |
+ |
|
372 |
+ # Gratuitous ASCII art. |
|
373 |
+ if ($Daemon -or $Client) { |
|
374 |
+ Write-Host |
|
375 |
+ Write-Host -ForegroundColor Green " ________ ____ __." |
|
376 |
+ Write-Host -ForegroundColor Green " \_____ \ `| `|/ _`|" |
|
377 |
+ Write-Host -ForegroundColor Green " / `| \`| `<" |
|
378 |
+ Write-Host -ForegroundColor Green " / `| \ `| \" |
|
379 |
+ Write-Host -ForegroundColor Green " \_______ /____`|__ \" |
|
380 |
+ Write-Host -ForegroundColor Green " \/ \/" |
|
381 |
+ Write-Host |
|
382 |
+ } |
|
383 |
+} |
|
384 |
+Catch [Exception] { |
|
385 |
+ Write-Host -ForegroundColor Red ("`nERROR: make.ps1 failed:`n$_") |
|
386 |
+ |
|
387 |
+ # More gratuitous ASCII art. |
|
388 |
+ Write-Host |
|
389 |
+ Write-Host -ForegroundColor Red "___________ .__.__ .___" |
|
390 |
+ Write-Host -ForegroundColor Red "\_ _____/____ `|__`| `| ____ __`| _/" |
|
391 |
+ Write-Host -ForegroundColor Red " `| __) \__ \ `| `| `| _/ __ \ / __ `| " |
|
392 |
+ Write-Host -ForegroundColor Red " `| \ / __ \`| `| `|_\ ___// /_/ `| " |
|
393 |
+ Write-Host -ForegroundColor Red " \___ / (____ /__`|____/\___ `>____ `| " |
|
394 |
+ Write-Host -ForegroundColor Red " \/ \/ \/ \/ " |
|
395 |
+ Write-Host |
|
396 |
+} |
|
397 |
+Finally { |
|
398 |
+ if ($global:pushed) { Pop-Location } |
|
399 |
+ Write-Host -ForegroundColor Cyan "INFO: make.ps1 ended at $(Get-Date)" |
|
400 |
+} |
... | ... |
@@ -10,16 +10,11 @@ |
10 | 10 |
|
11 | 11 |
.PARAMETER DockerVersion |
12 | 12 |
The version such as 1.14.0-dev. This is calculated externally to this script. |
13 |
- |
|
14 |
-.PARAMETER StaticSQLite |
|
15 |
- A string indicating if the daemon binary is compiled with the SQLite |
|
16 |
- sources compiled in. This is calculated externally to this script. |
|
17 | 13 |
#> |
18 | 14 |
|
19 | 15 |
param( |
20 | 16 |
[Parameter(Mandatory=$true)][string]$CommitString, |
21 |
- [Parameter(Mandatory=$true)][string]$DockerVersion, |
|
22 |
- [Parameter(Mandatory=$true)][string]$StaticSQLiteString |
|
17 |
+ [Parameter(Mandatory=$true)][string]$DockerVersion |
|
23 | 18 |
) |
24 | 19 |
|
25 | 20 |
$ErrorActionPreference = "Stop" |
... | ... |
@@ -48,7 +43,6 @@ const ( |
48 | 48 |
GitCommit string = "'+$CommitString+'" |
49 | 49 |
Version string = "'+$DockerVersion+'" |
50 | 50 |
BuildTime string = "'+$buildDateTime+'" |
51 |
- StaticSQLite string = "'+$StaticSQLiteString+'" |
|
52 | 51 |
) |
53 | 52 |
|
54 | 53 |
// AUTOGENERATED FILE; see hack\make\.go-autogen.ps1 |