소스 검색

Merge pull request #43431 from crazy-max/goversioninfo

Switch to go-winres to create Windows resources
Sebastiaan van Stijn 3 년 전
부모
커밋
86ce946945

+ 2 - 1
.dockerignore

@@ -2,5 +2,6 @@
 .go-pkg-cache
 .gopath
 bundles
+cli/winresources/**/winres.json
+cli/winresources/**/*.syso
 vendor/pkg
-

+ 0 - 1
.github/workflows/ci.yml

@@ -74,7 +74,6 @@ jobs:
         run: |
           platform=${{ matrix.platform }}
           echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
-          mkdir -p autogen
       -
         name: Set up Docker Buildx
         uses: docker/setup-buildx-action@v1

+ 2 - 3
.gitignore

@@ -13,8 +13,9 @@ test.main
 .editorconfig
 .gopath/
 .go-pkg-cache/
-autogen/
 bundles/
+cli/winresources/**/winres.json
+cli/winresources/**/*.syso
 cmd/dockerd/dockerd
 contrib/builder/rpm/*/changelog
 vendor/pkg/
@@ -24,5 +25,3 @@ junit-report.xml
 
 # top-level go.mod is not meant to be checked in
 /go.mod
-# workaround go.mod for autogen/winresources/dockerd
-/hack/make/.resources-windows/go.mod

+ 29 - 12
Dockerfile

@@ -161,6 +161,14 @@ RUN --mount=type=cache,target=/root/.cache/go-build \
         GOBIN=/build/ GO111MODULE=on go install "github.com/pelletier/go-toml/cmd/tomll@${GOTOML_VERSION}" \
      && /build/tomll --help
 
+FROM base AS gowinres
+# GOWINRES_VERSION defines go-winres tool version
+ARG GOWINRES_VERSION=v0.2.3
+RUN --mount=type=cache,target=/root/.cache/go-build \
+    --mount=type=cache,target=/go/pkg/mod \
+        GOBIN=/build/ GO111MODULE=on go install "github.com/tc-hib/go-winres@${GOWINRES_VERSION}" \
+     && /build/go-winres --help
+
 FROM dev-base AS containerd
 ARG DEBIAN_FRONTEND
 RUN --mount=type=cache,sharing=locked,id=moby-containerd-aptlib,target=/var/lib/apt \
@@ -301,6 +309,7 @@ COPY --from=dockercli     /build/ /usr/local/cli
 COPY --from=frozen-images /build/ /docker-frozen-images
 COPY --from=swagger       /build/ /usr/local/bin/
 COPY --from=tomll         /build/ /usr/local/bin/
+COPY --from=gowinres      /build/ /usr/local/bin/
 COPY --from=tini          /build/ /usr/local/bin/
 COPY --from=registry      /build/ /usr/local/bin/
 COPY --from=criu          /build/ /usr/local/bin/
@@ -346,34 +355,42 @@ ARG PRODUCT
 ENV PRODUCT=${PRODUCT}
 ARG DEFAULT_PRODUCT_LICENSE
 ENV DEFAULT_PRODUCT_LICENSE=${DEFAULT_PRODUCT_LICENSE}
+ARG PACKAGER_NAME
+ENV PACKAGER_NAME=${PACKAGER_NAME}
 ARG DOCKER_BUILDTAGS
 ENV DOCKER_BUILDTAGS="${DOCKER_BUILDTAGS}"
 ENV PREFIX=/build
 # TODO: This is here because hack/make.sh binary copies these extras binaries
 # from $PATH into the bundles dir.
 # It would be nice to handle this in a different way.
-COPY --from=tini        /build/ /usr/local/bin/
-COPY --from=runc        /build/ /usr/local/bin/
-COPY --from=containerd  /build/ /usr/local/bin/
-COPY --from=rootlesskit /build/ /usr/local/bin/
-COPY --from=vpnkit      /build/ /usr/local/bin/
+COPY --from=tini          /build/ /usr/local/bin/
+COPY --from=runc          /build/ /usr/local/bin/
+COPY --from=containerd    /build/ /usr/local/bin/
+COPY --from=rootlesskit   /build/ /usr/local/bin/
+COPY --from=vpnkit        /build/ /usr/local/bin/
+COPY --from=gowinres      /build/ /usr/local/bin/
 WORKDIR /go/src/github.com/docker/docker
 
 FROM binary-base AS build-binary
-RUN --mount=type=cache,target=/root/.cache/go-build \
-    --mount=type=bind,target=/go/src/github.com/docker/docker \
+RUN --mount=type=cache,target=/root/.cache \
+    --mount=type=bind,target=.,ro \
+    --mount=type=tmpfs,target=cli/winresources/dockerd \
+    --mount=type=tmpfs,target=cli/winresources/docker-proxy \
         hack/make.sh binary
 
 FROM binary-base AS build-dynbinary
-RUN --mount=type=cache,target=/root/.cache/go-build \
-    --mount=type=bind,target=/go/src/github.com/docker/docker \
+RUN --mount=type=cache,target=/root/.cache \
+    --mount=type=bind,target=.,ro \
+    --mount=type=tmpfs,target=cli/winresources/dockerd \
+    --mount=type=tmpfs,target=cli/winresources/docker-proxy \
         hack/make.sh dynbinary
 
 FROM binary-base AS build-cross
 ARG DOCKER_CROSSPLATFORMS
-RUN --mount=type=cache,target=/root/.cache/go-build \
-    --mount=type=bind,target=/go/src/github.com/docker/docker \
-    --mount=type=tmpfs,target=/go/src/github.com/docker/docker/autogen \
+RUN --mount=type=cache,target=/root/.cache \
+    --mount=type=bind,target=.,ro \
+    --mount=type=tmpfs,target=cli/winresources/dockerd \
+    --mount=type=tmpfs,target=cli/winresources/docker-proxy \
         hack/make.sh cross
 
 FROM scratch AS binary

+ 19 - 1
Dockerfile.windows

@@ -168,6 +168,7 @@ SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPref
 ARG GO_VERSION=1.18.1
 ARG CONTAINERD_VERSION=1.6.2
 ARG GOTESTSUM_VERSION=v1.7.0
+ARG GOWINRES_VERSION=v0.2.3
 
 # Environment variable notes:
 #  - GO_VERSION must be consistent with 'Dockerfile' used by Linux.
@@ -179,7 +180,8 @@ ENV GO_VERSION=${GO_VERSION} `
     GOPATH=C:\gopath `
     GO111MODULE=off `
     FROM_DOCKERFILE=1 `
-    GOTESTSUM_VERSION=${GOTESTSUM_VERSION}
+    GOTESTSUM_VERSION=${GOTESTSUM_VERSION} `
+    GOWINRES_VERSION=${GOWINRES_VERSION}
 
 RUN `
   Function Test-Nano() { `
@@ -289,6 +291,22 @@ RUN `
   `
   Install-GoTestSum
 
+RUN `
+  Function Install-GoWinres() { `
+    $Env:GO111MODULE = 'on'; `
+    $tmpGobin = "${Env:GOBIN_TMP}"; `
+    $Env:GOBIN = """${Env:GOPATH}`\bin"""; `
+    Write-Host "INFO: Installing go-winres version $Env:GOWINRES_VERSION in $Env:GOBIN"; `
+    &go install "github.com/tc-hib/go-winres@${Env:GOWINRES_VERSION}"; `
+    $Env:GOBIN = "${tmpGobin}"; `
+    $Env:GO111MODULE = 'off'; `
+    if ($LASTEXITCODE -ne 0) {  `
+      Throw '"go-winres install failed..."'; `
+    } `
+  } `
+  `
+  Install-GoWinres
+
 # Make PowerShell the default entrypoint
 ENTRYPOINT ["powershell.exe"]
 

+ 6 - 12
Makefile

@@ -85,7 +85,8 @@ DOCKER_ENVS := \
 	-e VERSION \
 	-e PLATFORM \
 	-e DEFAULT_PRODUCT_LICENSE \
-	-e PRODUCT
+	-e PRODUCT \
+	-e PACKAGER_NAME
 # note: we _cannot_ add "-e DOCKER_BUILDTAGS" here because even if it's unset in the shell, that would shadow the "ENV DOCKER_BUILDTAGS" set in our Dockerfile, which is very important for our official builds
 
 # to allow `make BIND_DIR=. shell` or `make BIND_DIR= test`
@@ -158,28 +159,21 @@ ifdef DOCKER_CROSSPLATFORMS
 BUILD_CROSS = --build-arg CROSS=true
 endif
 
-VERSION_AUTOGEN_ARGS = --build-arg VERSION --build-arg DOCKER_GITCOMMIT --build-arg PRODUCT --build-arg PLATFORM --build-arg DEFAULT_PRODUCT_LICENSE
+VERSION_AUTOGEN_ARGS = --build-arg VERSION --build-arg DOCKER_GITCOMMIT --build-arg PRODUCT --build-arg PLATFORM --build-arg DEFAULT_PRODUCT_LICENSE --build-arg PACKAGER_NAME
 
 default: binary
 
 all: build ## validate all checks, build linux binaries, run all tests,\ncross build non-linux binaries, and generate archives
 	$(DOCKER_RUN_DOCKER) bash -c 'hack/validate/default && hack/make.sh'
 
-# This is only used to work around read-only bind mounts of the source code into
-# binary build targets. We end up mounting a tmpfs over autogen which allows us
-# to write build-time generated assets even though the source is mounted read-only
-# ...But in order to do so, this dir needs to already exist.
-autogen:
-	mkdir -p autogen
-
-binary: buildx autogen ## build statically linked linux binaries
+binary: buildx ## build statically linked linux binaries
 	$(BUILD_CMD) $(BUILD_OPTS) --output=bundles/ --target=$@ $(VERSION_AUTOGEN_ARGS) .
 
-dynbinary: buildx autogen ## build dynamically linked linux binaries
+dynbinary: buildx ## build dynamically linked linux binaries
 	$(BUILD_CMD) $(BUILD_OPTS) --output=bundles/ --target=$@ $(VERSION_AUTOGEN_ARGS) .
 
 cross: BUILD_OPTS += --build-arg CROSS=true --build-arg DOCKER_CROSSPLATFORMS
-cross: buildx autogen ## cross build the binaries for darwin, freebsd and\nwindows
+cross: buildx ## cross build the binaries for darwin, freebsd and\nwindows
 	$(BUILD_CMD) $(BUILD_OPTS) --output=bundles/ --target=$@ $(VERSION_AUTOGEN_ARGS) .
 
 bundles:

+ 8 - 0
cli/winresources/README.md

@@ -0,0 +1,8 @@
+## Generate `event_messages.bin`
+
+```console
+$ docker run --rm -it -v "$(pwd):/winresources" debian:bullseye bash
+root@9ad2260f6ebc:/# apt-get update -y && apt-get install -y binutils-mingw-w64-x86-64
+root@9ad2260f6ebc:/# x86_64-w64-mingw32-windmc -v /winresources/event_messages.mc
+root@9ad2260f6ebc:/# mv MSG00001.bin /winresources/event_messages.bin
+```

+ 12 - 0
cli/winresources/docker-proxy/winresources.go

@@ -0,0 +1,12 @@
+// Package winresources is used to embed Windows resources into docker-proxy.exe.
+//
+// These resources are used to provide:
+// * Version information
+// * An icon
+// * A Windows manifest declaring Windows version support
+// * Events message table
+//
+// The resource object files are generated when building with go-winres
+// in hack/make/.go-autogen and are located in cli/winresources.
+// This occurs automatically when you cross build against Windows OS.
+package winresources

+ 0 - 0
hack/make/.resources-windows/dockerd.ico → cli/winresources/docker.ico


+ 12 - 0
cli/winresources/dockerd/winresources.go

@@ -0,0 +1,12 @@
+// Package winresources is used to embed Windows resources into dockerd.exe.
+//
+// These resources are used to provide:
+// * Version information
+// * An icon
+// * A Windows manifest declaring Windows version support
+// * Events message table
+//
+// The resource object files are generated when building with go-winres
+// in hack/make/.go-autogen and are located in cli/winresources.
+// This occurs automatically when you cross build against Windows OS.
+package winresources

BIN
cli/winresources/event_messages.bin


+ 0 - 0
hack/make/.resources-windows/event_messages.mc → cli/winresources/event_messages.mc


+ 5 - 0
cmd/docker-proxy/genwinres_windows.go

@@ -0,0 +1,5 @@
+//go:generate go-winres make --arch=386,amd64,arm,arm64 --in=../../cli/winresources/docker-proxy/winres.json --out=../../cli/winresources/docker-proxy/resource
+
+package main
+
+import _ "github.com/docker/docker/cli/winresources/docker-proxy"

+ 0 - 1
cmd/dockerd/docker_windows.go

@@ -5,7 +5,6 @@ import (
 	"path/filepath"
 
 	"github.com/Microsoft/go-winio/pkg/etwlogrus"
-	_ "github.com/docker/docker/autogen/winresources/dockerd"
 	"github.com/sirupsen/logrus"
 )
 

+ 5 - 0
cmd/dockerd/genwinres_windows.go

@@ -0,0 +1,5 @@
+//go:generate go-winres make --arch=386,amd64,arm,arm64 --in=../../cli/winresources/dockerd/winres.json --out=../../cli/winresources/dockerd/resource
+
+package main
+
+import _ "github.com/docker/docker/cli/winresources/dockerd"

+ 0 - 4
dockerversion/version_lib.go

@@ -1,7 +1,3 @@
-//go:build !autogen
-// +build !autogen
-
-// Package dockerversion is auto-generated at build-time
 package dockerversion // import "github.com/docker/docker/dockerversion"
 
 // Default build-time variable for library-import.

+ 0 - 9
hack/ci/windows.ps1

@@ -551,14 +551,6 @@ Try {
         Write-Host -ForegroundColor Magenta "WARN: Skipping building the binaries"
     }
 
-    Write-Host -ForegroundColor Green "INFO: Copying dockerversion from the container..."
-    $ErrorActionPreference = "SilentlyContinue"
-    docker cp "$contPath\..\dockerversion\version_autogen.go" "$env:SOURCES_DRIVE`:\$env:SOURCES_SUBDIR\src\github.com\docker\docker\dockerversion"
-    if (-not($LastExitCode -eq 0)) {
-         Throw "ERROR: Failed to docker cp the generated version_autogen.go to $env:SOURCES_DRIVE`:\$env:SOURCES_SUBDIR\src\github.com\docker\docker\dockerversion"
-    }
-    $ErrorActionPreference = "Stop"
-
     # Grab the golang installer out of the built image. That way, we know we are consistent once extracted and paths set,
     # so there's no need to re-deploy on account of an upgrade to the version of GO being used in docker.
     if ($null -eq $env:SKIP_COPY_GO) {
@@ -854,7 +846,6 @@ Try {
             $c += "`"$env:INTEGRATION_TEST_NAME`" "
             Write-Host -ForegroundColor Magenta "WARN: Only running integration tests matching $env:INTEGRATION_TEST_NAME"
         }
-        $c += "`"-tags`" " + "`"autogen`" "
         $c += "`"-test.timeout`" " + "`"200m`" "
 
         if ($null -ne $env:INTEGRATION_IN_CONTAINER) {

+ 0 - 6
hack/go-mod-prepare.sh

@@ -7,9 +7,3 @@ module github.com/docker/docker
 
 go 1.17
 EOF
-
-cat > "${ROOTDIR}/hack/make/.resources-windows/go.mod" << EOF
-module github.com/docker/docker/autogen/winresources/dockerd
-
-go 1.17
-EOF

+ 15 - 7
hack/make.ps1

@@ -168,9 +168,10 @@ Function Get-UpstreamCommit() {
 }
 
 # Build a binary (client or daemon)
-Function Execute-Build($type, $additionalBuildTags, $directory) {
+Function Execute-Build($type, $additionalBuildTags, $directory, $ldflags) {
     # Generate the build flags
-    $buildTags = "autogen"
+    $buildTags = ""
+    $ldflags = "-linkmode=internal " + $ldflags
     if ($Noisy)                     { $verboseParm=" -v" }
     if ($Race)                      { Write-Warning "Using race detector"; $raceParm=" -race"}
     if ($ForceBuildAll)             { $allParm=" -a" }
@@ -188,7 +189,7 @@ Function Execute-Build($type, $additionalBuildTags, $directory) {
                     $allParm + `
                     $optParm + `
                     " -tags """ + $buildTags + """" + `
-                    " -ldflags """ + "-linkmode=internal" + """" + `
+                    " -ldflags """ + $ldflags + """" + `
                     " -o $root\bundles\"+$directory+".exe"
     Invoke-Expression $buildCommand
     if ($LASTEXITCODE -ne 0) { Throw "Failed to compile $type" }
@@ -427,13 +428,20 @@ Try {
     # Verify GOPATH is set
     if ($env:GOPATH.Length -eq 0) { Throw "Missing GOPATH environment variable. See https://golang.org/doc/code.html#GOPATH" }
 
-    # Run autogen if building binaries or running unit tests.
-    if ($Client -or $Daemon -or $TestUnit) {
+    # Run autogen if building daemon.
+    if ($Daemon) {
         Write-Host "INFO: Invoking autogen..."
-        Try { .\hack\make\.go-autogen.ps1 -CommitString $gitCommit -DockerVersion $dockerVersion -Platform "$env:PLATFORM" -Product "$env:PRODUCT" }
+        Try { .\hack\make\.go-autogen.ps1 -CommitString $gitCommit -DockerVersion $dockerVersion -Platform "$env:PLATFORM" -Product "$env:PRODUCT" -PackagerName "$env:PACKAGER_NAME" }
         Catch [Exception] { Throw $_ }
     }
 
+    $ldflags = "-X 'github.com/docker/docker/dockerversion.Version="+$dockerVersion+"'"
+    $ldflags += " -X 'github.com/docker/docker/dockerversion.GitCommit="+$gitCommit+"'"
+    $ldflags += " -X 'github.com/docker/docker/dockerversion.BuildTime="+$env:BUILDTIME+"'"
+    $ldflags += " -X 'github.com/docker/docker/dockerversion.PlatformName="+$env:PLATFORM+"'"
+    $ldflags += " -X 'github.com/docker/docker/dockerversion.ProductName="+$env:PRODUCT+"'"
+    $ldflags += " -X 'github.com/docker/docker/dockerversion.DefaultProductLicense="+$env:DEFAULT_PRODUCT_LICENSE+"'"
+
     # DCO, Package import and Go formatting tests.
     if ($DCO -or $PkgImports -or $GoFormat) {
         # We need the head and upstream commits for these
@@ -454,7 +462,7 @@ Try {
     if ($Client -or $Daemon) {
 
         # Perform the actual build
-        if ($Daemon) { Execute-Build "daemon" "daemon" "dockerd" }
+        if ($Daemon) { Execute-Build "daemon" "daemon" "dockerd" $ldflags }
         if ($Client) {
             # Get the Docker channel and version from the environment, or use the defaults.
             if (-not ($channel = $env:DOCKERCLI_CHANNEL)) { $channel = "stable" }

+ 8 - 43
hack/make/.go-autogen

@@ -1,7 +1,5 @@
 #!/usr/bin/env bash
 
-rm -rf autogen/*
-
 source hack/dockerfile/install/runc.installer
 source hack/dockerfile/install/tini.installer
 source hack/dockerfile/install/containerd.installer
@@ -18,45 +16,12 @@ LDFLAGS="${LDFLAGS} \
 
 # Compile the Windows resources into the sources
 if [ "$(go env GOOS)" = "windows" ]; then
-	mkdir -p autogen/winresources/tmp autogen/winresources/dockerd
-	cp hack/make/.resources-windows/resources.go autogen/winresources/dockerd/
-
-	if [ "$(go env GOHOSTOS)" == "windows" ]; then
-		WINDRES=windres
-		WINDMC=windmc
-	else
-		# Cross compiling
-		WINDRES=x86_64-w64-mingw32-windres
-		WINDMC=x86_64-w64-mingw32-windmc
-	fi
-
-	# Generate a Windows file version of the form major,minor,patch,build (with any part optional)
-	if [ ! -v VERSION_QUAD ]; then
-		VERSION_QUAD=$(echo -n $VERSION | sed -re 's/^([0-9.]*).*$/\1/' | tr . ,)
-	fi
-
-	# Pass version and commit information into the resource compiler
-	defs=
-	[ ! -z $VERSION ]      && defs="$defs -D DOCKER_VERSION=\"$VERSION\""
-	[ ! -z $VERSION_QUAD ] && defs="$defs -D DOCKER_VERSION_QUAD=$VERSION_QUAD"
-	[ ! -z $GITCOMMIT ]    && defs="$defs -D DOCKER_COMMIT=\"$GITCOMMIT\""
-
-	function makeres {
-		${WINDRES} \
-			-i hack/make/.resources-windows/$1 \
-			-o $3 \
-			-F $2 \
-			--use-temp-file \
-			-I autogen/winresources/tmp \
-			$defs
-	}
-
-	${WINDMC} \
-		hack/make/.resources-windows/event_messages.mc \
-		-h autogen/winresources/tmp \
-		-r autogen/winresources/tmp
-
-	makeres dockerd.rc pe-x86-64 autogen/winresources/dockerd/rsrc_amd64.syso
-
-	rm -r autogen/winresources/tmp
+  if [ ! -x "$(command -v go-winres)" ]; then
+    >&2 echo "go-winres not found, skipping manifesting binary"
+  else
+    (
+      . hack/make/.mkwinres
+      go generate -v "${GO_PACKAGE}"
+    )
+  fi
 fi

+ 106 - 43
hack/make/.go-autogen.ps1

@@ -10,6 +10,22 @@
 
 .PARAMETER DockerVersion
      The version such as 17.04.0-dev. This is calculated externally to this script.
+
+.PARAMETER Platform
+     The platform name, such as "Docker Engine - Community".
+
+.PARAMETER Product
+     The product name, used to set version.ProductName, which is used to set BuildKit's
+     ExportedProduct variable in order to show useful error messages to users when a
+     certain version of the product doesn't support a BuildKit feature.
+
+.PARAMETER DefaultProductLicense
+     Sets the version.DefaultProductLicense string, such as "Community Engine". This field
+     can contain a summary of the product license of the daemon if a commercial license has
+     been applied to the daemon.
+
+.PARAMETER PackagerName
+     The name of the packager (e.g. "Docker, Inc."). This used to set CompanyName in the manifest.
 #>
 
 param(
@@ -17,7 +33,8 @@ param(
     [Parameter(Mandatory=$true)][string]$DockerVersion,
     [Parameter(Mandatory=$false)][string]$Platform,
     [Parameter(Mandatory=$false)][string]$Product,
-    [Parameter(Mandatory=$false)][string]$DefaultProductLicense
+    [Parameter(Mandatory=$false)][string]$DefaultProductLicense,
+    [Parameter(Mandatory=$false)][string]$PackagerName
 )
 
 $ErrorActionPreference = "Stop"
@@ -27,63 +44,109 @@ Function Get-BuildDateTime() {
     return $(Get-Date).ToUniversalTime()
 }
 
-try {
-    $buildDateTime=Get-BuildDateTime
+Function Get-Year() {
+    return $(Get-Date).year
+}
 
-    if (Test-Path ".\autogen") {
-        Remove-Item ".\autogen" -Recurse -Force | Out-Null
+Function Get-FixQuadVersionNumber($number) {
+    if ($number -eq 0) {
+        return $number
     }
+    return $number.TrimStart("0")
+}
 
-    $fileContents = '
-// +build autogen
-
-// Package dockerversion is auto-generated at build-time
-package dockerversion
-
-// Default build-time variable for library-import.
-// This file is overridden on build with build-time information.
-const (
-	GitCommit             string = "'+$CommitString+'"
-	Version               string = "'+$DockerVersion+'"
-	BuildTime             string = "'+$buildDateTime+'"
-	PlatformName          string = "'+$Platform+'"
-	ProductName           string = "'+$Product+'"
-	DefaultProductLicense string = "'+$DefaultProductLicense+'"
-)
-
-// AUTOGENERATED FILE; see hack\make\.go-autogen.ps1
-'
-
-    # Write the file without BOM
-    $outputFile="$(Get-Location)\dockerversion\version_autogen.go"
-    if (Test-Path $outputFile) { Remove-Item $outputFile }
-    [System.IO.File]::WriteAllText($outputFile, $fileContents, (New-Object System.Text.UTF8Encoding($False)))
+try {
+    $buildDateTime=Get-BuildDateTime
+    $currentYear=Get-Year
 
-    New-Item -ItemType Directory -Path "autogen\winresources\tmp" | Out-Null
-    New-Item -ItemType Directory -Path "autogen\winresources\dockerd" | Out-Null
-    Copy-Item "hack\make\.resources-windows\resources.go" "autogen\winresources\dockerd"
+    # Update PATH
+    $env:PATH="$env:GOPATH\bin;$env:PATH"
 
     # Generate a version in the form major,minor,patch,build
-    $versionQuad=$DockerVersion -replace "[^0-9.]*" -replace "\.", ","
+    $versionQuad=($DockerVersion -replace "[^0-9.]*")
+    if ($versionQuad -Match "^\d+`.\d+`.\d+$"){
+        $versionQuad = $versionQuad + ".0"
+    }
+    $versionMatches = $($versionQuad | Select-String -AllMatches -Pattern "(\d+)`.(\d+)`.(\d+)`.(\d+)").Matches
 
-    # Compile the messages
-    windmc hack\make\.resources-windows\event_messages.mc -h autogen\winresources\tmp -r autogen\winresources\tmp
-    if ($LASTEXITCODE -ne 0) { Throw "Failed to compile event message resources" }
+    $mkwinresContents = '{
+  "RT_GROUP_ICON": {
+    "#1": {
+      "0409": "../../winresources/docker.ico"
+    }
+  },
+  "RT_MANIFEST": {
+    "#1": {
+      "0409": {
+        "identity": {},
+        "description": "Docker Engine",
+        "minimum-os": "vista",
+        "execution-level": "",
+        "ui-access": false,
+        "auto-elevate": false,
+        "dpi-awareness": "unaware",
+        "disable-theming": false,
+        "disable-window-filtering": false,
+        "high-resolution-scrolling-aware": false,
+        "ultra-high-resolution-scrolling-aware": false,
+        "long-path-aware": false,
+        "printer-driver-isolation": false,
+        "gdi-scaling": false,
+        "segment-heap": false,
+        "use-common-controls-v6": false
+      }
+    }
+  },
+  "RT_MESSAGETABLE": {
+    "#1": {
+      "0409": "../../winresources/event_messages.bin"
+    }
+  },
+  "RT_VERSION": {
+    "#1": {
+      "0409": {
+        "fixed": {
+          "file_version": "'+(Get-FixQuadVersionNumber($versionMatches.Groups[1].Value))+'.'+(Get-FixQuadVersionNumber($versionMatches.Groups[2].Value))+'.'+(Get-FixQuadVersionNumber($versionMatches.Groups[3].Value))+'.'+(Get-FixQuadVersionNumber($versionMatches.Groups[4].Value))+'",
+          "product_version": "'+(Get-FixQuadVersionNumber($versionMatches.Groups[1].Value))+'.'+(Get-FixQuadVersionNumber($versionMatches.Groups[2].Value))+'.'+(Get-FixQuadVersionNumber($versionMatches.Groups[3].Value))+'.'+(Get-FixQuadVersionNumber($versionMatches.Groups[4].Value))+'",
+          "type": "Unknown"
+        },
+        "info": {
+          "0000": {
+            "CompanyName": "'+$PackagerName+'",
+            "FileVersion": "'+$DockerVersion+'",
+            "LegalCopyright": "Copyright (C) 2015-'+$currentYear+' Docker Inc.",
+            "OriginalFileName": "dockerd.exe",
+            "ProductName": "'+$Product+'",
+            "ProductVersion": "'+$DockerVersion+'",
+            "SpecialBuild": "'+$CommitString+'"
+          }
+        }
+      }
+    }
+  }
+}'
 
-    # If you really want to understand this madness below, search the Internet for powershell variables after verbatim arguments... Needed to get double-quotes passed through to the compiler options.
-    # Generate the .syso files containing all the resources and manifest needed to compile the final docker binaries. Both 32 and 64-bit clients.
-    $env:_ag_dockerVersion=$DockerVersion
-    $env:_ag_gitCommit=$CommitString
+    # Write the file
+    $outputFile="$(Get-Location)\cli\winresources\dockerd\winres.json"
+    if (Test-Path $outputFile) { Remove-Item $outputFile }
+    [System.IO.File]::WriteAllText($outputFile, $mkwinresContents)
+    Get-Content $outputFile | Out-Host
+
+    # Create winresources package stub if removed while using tmpfs in Dockerfile
+    $stubPackage="$(Get-Location)\cli\winresources\dockerd\winresources.go"
+    if(![System.IO.File]::Exists($stubPackage)){
+        Set-Content -NoNewline -Path $stubPackage -Value 'package winresources'
+    }
 
-    windres -i hack/make/.resources-windows/dockerd.rc -o autogen/winresources/dockerd/rsrc_amd64.syso -F pe-x86-64 --use-temp-file -I autogen/winresources/tmp -D DOCKER_VERSION_QUAD=$versionQuad --% -D DOCKER_VERSION=\"%_ag_dockerVersion%\" -D DOCKER_COMMIT=\"%_ag_gitCommit%\"
-    if ($LASTEXITCODE -ne 0) { Throw "Failed to compile daemon resources" }
+    # Generate
+    go generate -v "github.com/docker/docker/cmd/dockerd"
+    if ($LASTEXITCODE -ne 0) { Throw "Failed to generate version info" }
 }
 Catch [Exception] {
     # Throw the error onto the caller to display errors. We don't expect this script to be called directly 
     Throw ".go-autogen.ps1 failed with error $_"
 }
 Finally {
-    Remove-Item .\autogen\winresources\tmp -Recurse -Force -ErrorAction SilentlyContinue | Out-Null
     $env:_ag_dockerVersion=""
     $env:_ag_gitCommit=""
 }

+ 85 - 0
hack/make/.mkwinres

@@ -0,0 +1,85 @@
+#!/usr/bin/env sh
+
+quadVersionNum() {
+	num=$(echo "${1:-0}" | cut -d. -f"$2")
+	if [ "$num" != "0" ]; then
+		echo "${num#0}"
+	else
+		echo "$num"
+	fi
+}
+
+# Create version quad for Windows of the form major.minor.patch.build
+VERSION_QUAD=$(printf "%s" "$VERSION" | sed -re 's/^([0-9.]*).*$/\1/' | sed -re 's/\.$//' | sed -re 's/^[0-9]+$/\0\.0/' | sed -re 's/^[0-9]+\.[0-9]+$/\0\.0/' | sed -re 's/^[0-9]+\.[0-9]+\.[0-9]+$/\0\.0/')
+
+# Generate winres.json to be able to create a syso file which contains
+# Microsoft Windows Version Information and an icon using go-winres.
+# https://docs.microsoft.com/en-us/windows/win32/menurc/stringfileinfo-block
+# https://github.com/tc-hib/go-winres#json-format
+cat > "./cli/winresources/${BINARY_SHORT_NAME}/winres.json" << EOL
+{
+  "RT_GROUP_ICON": {
+    "#1": {
+      "0409": "../../winresources/docker.ico"
+    }
+  },
+  "RT_MANIFEST": {
+    "#1": {
+      "0409": {
+        "identity": {},
+        "description": "Docker Engine",
+        "minimum-os": "vista",
+        "execution-level": "",
+        "ui-access": false,
+        "auto-elevate": false,
+        "dpi-awareness": "unaware",
+        "disable-theming": false,
+        "disable-window-filtering": false,
+        "high-resolution-scrolling-aware": false,
+        "ultra-high-resolution-scrolling-aware": false,
+        "long-path-aware": false,
+        "printer-driver-isolation": false,
+        "gdi-scaling": false,
+        "segment-heap": false,
+        "use-common-controls-v6": false
+      }
+    }
+  },
+  "RT_MESSAGETABLE": {
+    "#1": {
+      "0409": "../../winresources/event_messages.bin"
+    }
+  },
+  "RT_VERSION": {
+    "#1": {
+      "0409": {
+        "fixed": {
+          "file_version": "$(quadVersionNum "$VERSION_QUAD" 1).$(quadVersionNum "$VERSION_QUAD" 2).$(quadVersionNum "$VERSION_QUAD" 3).$(quadVersionNum "$VERSION_QUAD" 4)",
+          "product_version": "$(quadVersionNum "$VERSION_QUAD" 1).$(quadVersionNum "$VERSION_QUAD" 2).$(quadVersionNum "$VERSION_QUAD" 3).$(quadVersionNum "$VERSION_QUAD" 4)",
+          "type": "Unknown"
+        },
+        "info": {
+          "0000": {
+            "CompanyName": "${PACKAGER_NAME}",
+            "FileVersion": "${VERSION}",
+            "LegalCopyright": "Copyright © 2015-$(date +'%Y') Docker Inc.",
+            "OriginalFileName": "$(basename "${BINARY_FULLNAME}")",
+            "ProductName": "${PRODUCT}",
+            "ProductVersion": "${VERSION}",
+            "SpecialBuild": "${GITCOMMIT}"
+          }
+        }
+      }
+    }
+  }
+}
+EOL
+(
+	set -x
+	cat "./cli/winresources/${BINARY_SHORT_NAME}/winres.json"
+)
+
+# Create winresources package stub if removed while using tmpfs in Dockerfile
+if [ ! -f "./cli/winresources/${BINARY_SHORT_NAME}/winresources.go" ]; then
+	echo "package winresources" > "./cli/winresources/${BINARY_SHORT_NAME}/winresources.go"
+fi

+ 0 - 38
hack/make/.resources-windows/common.rc

@@ -1,38 +0,0 @@
-// Application icon
-1 ICON "dockerd.ico"
-
-// Windows executable manifest
-1 24 /* RT_MANIFEST */ "dockerd.exe.manifest"
-
-// Version information
-1 VERSIONINFO
-
-#ifdef DOCKER_VERSION_QUAD
-FILEVERSION     DOCKER_VERSION_QUAD
-PRODUCTVERSION  DOCKER_VERSION_QUAD
-#endif
-
-BEGIN
-  BLOCK "StringFileInfo"
-  BEGIN
-    BLOCK "000004B0"
-    BEGIN
-      VALUE "ProductName", DOCKER_NAME
-
-#ifdef DOCKER_VERSION
-      VALUE "FileVersion", DOCKER_VERSION
-      VALUE "ProductVersion", DOCKER_VERSION
-#endif
-
-#ifdef DOCKER_COMMIT
-      VALUE "OriginalFileName", DOCKER_COMMIT
-#endif
-
-    END
-  END
-
-  BLOCK "VarFileInfo"
-  BEGIN
-    VALUE "Translation", 0x0000, 0x04B0
-  END
-END

+ 0 - 18
hack/make/.resources-windows/dockerd.exe.manifest

@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
-    <description>Docker</description>
-    <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> 
-        <application> 
-            <!-- Windows 10 -->
-            <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
-            <!-- Windows 8.1 -->
-            <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
-            <!-- Windows Vista -->
-            <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> 
-            <!-- Windows 7 -->
-            <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
-            <!-- Windows 8 -->
-            <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
-        </application> 
-    </compatibility>
-</assembly>

+ 0 - 4
hack/make/.resources-windows/dockerd.rc

@@ -1,4 +0,0 @@
-#define DOCKER_NAME "Docker Engine"
-
-#include "common.rc"
-#include "event_messages.rc"

+ 0 - 18
hack/make/.resources-windows/resources.go

@@ -1,18 +0,0 @@
-/*
-
-Package winresources is used to embed Windows resources into dockerd.exe.
-These resources are used to provide
-
-    * Version information
-    * An icon
-    * A Windows manifest declaring Windows version support
-
-The resource object files are generated in hack/make/.go-autogen from
-source files in hack/make/.resources-windows. This occurs automatically
-when you run hack/make.sh.
-
-These object files are picked up automatically by go build when this package
-is included.
-
-*/
-package winresources

+ 0 - 4
vendor.mod

@@ -26,7 +26,6 @@ require (
 	github.com/creack/pty v1.1.11
 	github.com/deckarep/golang-set v0.0.0-20141123011944-ef32fa3046d9
 	github.com/docker/distribution v2.8.1+incompatible
-	github.com/docker/docker/autogen/winresources/dockerd v0.0.0-00010101000000-000000000000
 	github.com/docker/go-connections v0.4.0
 	github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c
 	github.com/docker/go-metrics v0.0.1
@@ -185,6 +184,3 @@ replace (
 
 // Removes etcd dependency
 replace github.com/rexray/gocsi => github.com/dperny/gocsi v1.2.3-pre
-
-// autogen/winresources/dockerd is generated a build time, this replacement is only for the purpose of `go mod vendor`
-replace github.com/docker/docker/autogen/winresources/dockerd => ./hack/make/.resources-windows

+ 0 - 4
vendor/modules.txt

@@ -284,9 +284,6 @@ github.com/docker/distribution/registry/client/auth/challenge
 github.com/docker/distribution/registry/client/transport
 github.com/docker/distribution/registry/storage/cache
 github.com/docker/distribution/registry/storage/cache/memory
-# github.com/docker/docker/autogen/winresources/dockerd v0.0.0-00010101000000-000000000000 => ./hack/make/.resources-windows
-## explicit; go 1.17
-github.com/docker/docker/autogen/winresources/dockerd
 # github.com/docker/go-connections v0.4.0
 ## explicit
 github.com/docker/go-connections/nat
@@ -1132,4 +1129,3 @@ gotest.tools/v3/skip
 # github.com/vishvananda/netlink => github.com/vishvananda/netlink v1.1.0
 # go.opencensus.io => go.opencensus.io v0.22.3
 # github.com/rexray/gocsi => github.com/dperny/gocsi v1.2.3-pre
-# github.com/docker/docker/autogen/winresources/dockerd => ./hack/make/.resources-windows