Skip to content

Commit 68e4f1f

Browse files
authored
Merge pull request kubernetes#91452 from claudiubelu/windows/pause-image
Add support for building Windows pause image
2 parents 254f3e2 + fd1e113 commit 68e4f1f

File tree

11 files changed

+281
-57
lines changed

11 files changed

+281
-57
lines changed

build/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ filegroup(
2020
name = "all-srcs",
2121
srcs = [
2222
":package-srcs",
23+
"//build/pause/windows/wincat:all-srcs",
2324
"//build/release-tars:all-srcs",
2425
"//build/visible_to:all-srcs",
2526
],

build/dependencies.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ dependencies:
152152
match: tag =
153153

154154
- name: "k8s.gcr.io/pause"
155-
version: 3.3
155+
version: 3.4
156156
refPaths:
157157
- path: build/pause/Makefile
158158
match: TAG =

build/pause/Dockerfile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
FROM scratch
15+
ARG BASE
16+
FROM ${BASE}
1617
ARG ARCH
17-
ADD bin/pause-${ARCH} /pause
18+
ADD bin/pause-linux-${ARCH} /pause
1819
ENTRYPOINT ["/pause"]

build/pause/Dockerfile_windows

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Copyright 2020 The Kubernetes Authors.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
ARG BASE
16+
FROM ${BASE}
17+
ARG ARCH
18+
ADD bin/pause-windows-${ARCH}.exe /pause.exe
19+
ADD bin/wincat-windows-amd64 /Windows/System32/wincat.exe
20+
21+
# NOTE(claudiub): docker buildx sets the PATH env variable to a Linux-like PATH,
22+
# which is not desirable. See: https://github.com/moby/buildkit/issues/1560
23+
# TODO(claudiub): remove this once the issue has been resolved.
24+
ENV PATH="C:\Windows\system32;C:\Windows;"
25+
ENTRYPOINT ["/pause.exe"]

build/pause/Makefile

Lines changed: 95 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -12,91 +12,132 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
.PHONY: all push container clean orphan all-push push-manifest
15+
.PHONY: all container clean orphan all-push push-manifest
1616

1717
REGISTRY ?= staging-k8s.gcr.io
1818
IMAGE = $(REGISTRY)/pause
19-
IMAGE_WITH_ARCH = $(IMAGE)-$(ARCH)
19+
IMAGE_WITH_OS_ARCH = $(IMAGE)-$(OS)-$(ARCH)
2020

21-
TAG = 3.3
21+
TAG = 3.4
2222
REV = $(shell git describe --contains --always --match='v*')
2323

2424
# Architectures supported: amd64, arm, arm64, ppc64le and s390x
2525
ARCH ?= amd64
26-
27-
ALL_ARCH = amd64 arm arm64 ppc64le s390x
26+
# Operating systems supported: linux, windows
27+
OS ?= linux
28+
# OS Version for the Windows images: 1809, 1903, 1909 2004
29+
OSVERSION ?= 1809 1903 1909 2004
30+
31+
# The output type could either be docker (local), or registry.
32+
# If it is registry, it will also allow us to push the Windows images.
33+
OUTPUT_TYPE ?= docker
34+
35+
ALL_OS = linux windows
36+
ALL_ARCH.linux = amd64 arm arm64 ppc64le s390x
37+
ALL_OS_ARCH.linux = $(foreach arch, ${ALL_ARCH.linux}, linux-$(arch))
38+
ALL_ARCH.windows = amd64
39+
ALL_OSVERSIONS.windows := 1809 1903 1909 2004
40+
ALL_OS_ARCH.windows = $(foreach arch, $(ALL_ARCH.windows), $(foreach osversion, ${ALL_OSVERSIONS.windows}, windows-$(arch)-${osversion}))
41+
ALL_OS_ARCH = $(foreach os, $(ALL_OS), ${ALL_OS_ARCH.${os}})
2842

2943
CFLAGS = -Os -Wall -Werror -static -DVERSION=v$(TAG)-$(REV)
30-
KUBE_CROSS_IMAGE ?= k8s.gcr.io/build-image/kube-cross
31-
KUBE_CROSS_VERSION ?= $(shell cat ../build-image/cross/VERSION)
32-
33-
BIN = pause
34-
SRCS = pause.c
35-
36-
ifeq ($(ARCH),amd64)
37-
TRIPLE ?= x86_64-linux-gnu
38-
endif
39-
40-
ifeq ($(ARCH),arm)
41-
TRIPLE ?= arm-linux-gnueabihf
42-
endif
43-
44-
ifeq ($(ARCH),arm64)
45-
TRIPLE ?= aarch64-linux-gnu
46-
endif
47-
48-
ifeq ($(ARCH),ppc64le)
49-
TRIPLE ?= powerpc64le-linux-gnu
50-
endif
51-
52-
ifeq ($(ARCH),s390x)
53-
TRIPLE ?= s390x-linux-gnu
54-
endif
44+
KUBE_CROSS_IMAGE.linux ?= k8s.gcr.io/build-image/kube-cross
45+
KUBE_CROSS_VERSION.linux ?= $(shell cat ../build-image/cross/VERSION)
46+
KUBE_CROSS_IMAGE.windows ?= dockcross/windows-static-x64
47+
KUBE_CROSS_VERSION.windows ?= latest
48+
KUBE_CROSS_IMAGE := ${KUBE_CROSS_IMAGE.${OS}}
49+
KUBE_CROSS_VERSION := ${KUBE_CROSS_VERSION.${OS}}
50+
51+
# NOTE(claudiub): The Windows pause image also requires the wincat binary we're compiling for the
52+
# port-forwarding scenarios. If it's no longer necessary, it can be removed.
53+
# For more information, see: https://github.com/kubernetes/kubernetes/pull/91452
54+
BIN.linux = pause
55+
BIN.windows = pause wincat
56+
BIN := ${BIN.${OS}}
57+
SRCS.linux = linux/pause.c
58+
SRCS.windows = windows/pause.c
59+
SRCS := ${SRCS.${OS}}
60+
61+
EXTENSION.linux =
62+
EXTENSION.windows = .exe
63+
EXTENSION := ${EXTENSION.${OS}}
64+
65+
# The manifest command is still experimental as of Docker 18.09.3
66+
export DOCKER_CLI_EXPERIMENTAL=enabled
67+
68+
TRIPLE.windows-amd64 := x86_64-w64-mingw32.static
69+
TRIPLE.linux-amd64 := x86_64-linux-gnu
70+
TRIPLE.linux-arm := arm-linux-gnueabihf
71+
TRIPLE.linux-arm64 := aarch64-linux-gnu
72+
TRIPLE.linux-ppc64le := powerpc64le-linux-gnu
73+
TRIPLE.linux-s390x := s390x-linux-gnu
74+
TRIPLE := ${TRIPLE.${OS}-${ARCH}}
75+
BASE.linux := scratch
76+
BASE.windows := mcr.microsoft.com/windows/nanoserver
77+
BASE := ${BASE.${OS}}
5578

5679
# If you want to build AND push all containers, see the 'all-push' rule.
57-
all: all-container
80+
all: all-container-docker
5881

59-
all-push: all-push-images push-manifest
82+
# NOTE(claudiub): A non-default builder instance is needed in order to build Windows images.
83+
all-push: all-container-registry push-manifest
6084

6185
push-manifest:
62-
docker manifest create --amend $(IMAGE):$(TAG) $(shell echo $(ALL_ARCH) | sed -e "s~[^ ]*~$(IMAGE)\-&:$(TAG)~g")
63-
set -x; for arch in $(ALL_ARCH); do docker manifest annotate --arch $${arch} ${IMAGE}:${TAG} ${IMAGE}-$${arch}:${TAG}; done
86+
docker manifest create --amend $(IMAGE):$(TAG) $(shell echo $(ALL_OS_ARCH) | sed -e "s~[^ ]*~$(IMAGE)\-&:$(TAG)~g")
87+
set -x; for arch in $(ALL_ARCH.linux); do docker manifest annotate --os linux --arch $${arch} ${IMAGE}:${TAG} ${IMAGE}-linux-$${arch}:${TAG}; done
88+
# For Windows images, we also need to include the "os.version" in the manifest list, so the Windows node can pull the proper image it needs.
89+
# At the moment, docker manifest annotate doesn't allow us to set the os.version, so we'll have to it ourselves. The manifest list can be found locally as JSONs.
90+
# See: https://github.com/moby/moby/issues/41417
91+
# TODO(claudiub): Clean this up once the above issue has been fixed.
92+
set -x; \
93+
registry_prefix=$(shell (echo ${REGISTRY} | grep -Eq "[a-z]*") && echo "docker.io/" || echo ""); \
94+
manifest_image_folder=`echo "$${registry_prefix}${IMAGE}" | sed "s|/|_|g" | sed "s/:/-/"`; \
95+
for arch in $(ALL_ARCH.windows); do \
96+
for osversion in ${ALL_OSVERSIONS.windows}; do \
97+
docker manifest annotate --os windows --arch $${arch} ${IMAGE}:${TAG} ${IMAGE}-windows-$${arch}-$${osversion}:${TAG}; \
98+
BASEIMAGE=${BASE.windows}:$${osversion}; \
99+
full_version=`docker manifest inspect ${BASE.windows}:$${osversion} | grep "os.version" | head -n 1 | awk '{print $$2}'` || true; \
100+
sed -i -r "s/(\"os\"\:\"windows\")/\0,\"os.version\":$${full_version}/" "${HOME}/.docker/manifests/$${manifest_image_folder}-${TAG}/$${manifest_image_folder}-windows-$${arch}-$${osversion}-${TAG}"; \
101+
done; \
102+
done
64103
docker manifest push --purge ${IMAGE}:${TAG}
65104

66-
sub-container-%:
67-
$(MAKE) ARCH=$* container
68-
69-
sub-push-%:
70-
$(MAKE) ARCH=$* push
71-
72-
all-container: $(addprefix sub-container-,$(ALL_ARCH))
105+
all-container-docker: $(addprefix sub-container-docker-,$(ALL_OS_ARCH.linux))
106+
all-container-registry: $(addprefix sub-container-registry-,$(ALL_OS_ARCH))
73107

74-
all-push-images: $(addprefix sub-push-,$(ALL_ARCH))
108+
# split words on hyphen, access by 1-index
109+
word-hyphen = $(word $2,$(subst -, ,$1))
110+
sub-container-%:
111+
$(MAKE) OUTPUT_TYPE=$(call word-hyphen,$*,1) OS=$(call word-hyphen,$*,2) ARCH=$(call word-hyphen,$*,3) OSVERSION=$(call word-hyphen,$*,4) container
75112

76-
build: bin/$(BIN)-$(ARCH)
113+
build: $(foreach binary, ${BIN}, bin/${binary}-${OS}-${ARCH})
77114

78-
bin/$(BIN)-$(ARCH): $(SRCS)
115+
bin/${BIN.linux}-$(OS)-$(ARCH): $(SRCS)
79116
mkdir -p bin
80117
docker run --rm -u $$(id -u):$$(id -g) -v $$(pwd):/build \
81118
$(KUBE_CROSS_IMAGE):$(KUBE_CROSS_VERSION) \
82119
/bin/bash -c "\
83120
cd /build && \
84121
$(TRIPLE)-gcc $(CFLAGS) -o $@ $^ && \
85-
$(TRIPLE)-strip $@"
122+
$(TRIPLE)-strip $(foreach binary, $@, ${binary}${EXTENSION})"
123+
124+
bin/wincat-windows-${ARCH}: windows/wincat/wincat.go
125+
CGO_ENABLED=0 GOOS=windows GOARCH=${ARCH} go build -o $@ $^
86126

87-
container: .container-$(ARCH)
88-
.container-$(ARCH): bin/$(BIN)-$(ARCH)
89-
DOCKER_CLI_EXPERIMENTAL=enabled docker buildx build --load --pull --platform linux/$(ARCH) -t $(IMAGE_WITH_ARCH):$(TAG) --build-arg ARCH=$(ARCH) .
127+
container: .container-${OS}-$(ARCH)
128+
.container-linux-$(ARCH): bin/$(BIN)-$(OS)-$(ARCH)
129+
docker buildx build --pull --output=type=${OUTPUT_TYPE} --platform ${OS}/$(ARCH) \
130+
-t $(IMAGE_WITH_OS_ARCH):$(TAG) --build-arg BASE=${BASE} --build-arg ARCH=$(ARCH) .
90131
touch $@
91132

92-
push: .push-$(ARCH)
93-
.push-$(ARCH): .container-$(ARCH)
94-
docker push $(IMAGE_WITH_ARCH):$(TAG)
133+
.container-windows-$(ARCH): $(foreach binary, ${BIN}, bin/${binary}-${OS}-${ARCH})
134+
docker buildx build --pull --output=type=${OUTPUT_TYPE} --platform ${OS}/$(ARCH) \
135+
-t $(IMAGE_WITH_OS_ARCH)-${OSVERSION}:$(TAG) --build-arg BASE=${BASE}:${OSVERSION} --build-arg ARCH=$(ARCH) -f Dockerfile_windows .
95136
touch $@
96137

97138
# Useful for testing, not automatically included in container image
98-
orphan: bin/orphan-$(ARCH)
99-
bin/orphan-$(ARCH): orphan.c
139+
orphan: bin/orphan-linux-$(ARCH)
140+
bin/orphan-linux-$(ARCH): linux/orphan.c
100141
mkdir -p bin
101142
docker run -u $$(id -u):$$(id -g) -v $$(pwd):/build \
102143
$(KUBE_CROSS_IMAGE):$(KUBE_CROSS_VERSION) \
@@ -106,4 +147,4 @@ bin/orphan-$(ARCH): orphan.c
106147
$(TRIPLE)-strip $@"
107148

108149
clean:
109-
rm -rf .container-* .push-* bin/
150+
rm -rf .*-container-* .push-* bin/

build/pause/cloudbuild.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@ steps:
1616
- '-c'
1717
- |
1818
gcloud auth configure-docker \
19+
&& docker buildx create --name img-builder --use \
1920
&& make all-push
File renamed without changes.
File renamed without changes.

build/pause/windows/pause.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
Copyright 2020 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#include <windows.h>
18+
#include <stdio.h>
19+
20+
BOOL WINAPI CtrlHandler(DWORD fdwCtrlType)
21+
{
22+
switch (fdwCtrlType)
23+
{
24+
case CTRL_C_EVENT:
25+
fprintf(stderr, "Shutting down, got signal\n");
26+
exit(0);
27+
28+
case CTRL_BREAK_EVENT:
29+
fprintf(stderr, "Shutting down, got signal\n");
30+
exit(0);
31+
32+
default:
33+
return FALSE;
34+
}
35+
}
36+
37+
int main(void)
38+
{
39+
if (SetConsoleCtrlHandler(CtrlHandler, TRUE))
40+
{
41+
Sleep(INFINITE);
42+
}
43+
else
44+
{
45+
printf("\nERROR: Could not set control handler\n");
46+
return 1;
47+
}
48+
return 0;
49+
}

build/pause/windows/wincat/BUILD

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
2+
3+
go_library(
4+
name = "go_default_library",
5+
srcs = ["wincat.go"],
6+
importpath = "k8s.io/kubernetes/build/pause/windows/wincat",
7+
visibility = ["//visibility:private"],
8+
)
9+
10+
go_binary(
11+
name = "windows",
12+
embed = [":go_default_library"],
13+
visibility = ["//visibility:public"],
14+
)
15+
16+
filegroup(
17+
name = "package-srcs",
18+
srcs = glob(["**"]),
19+
tags = ["automanaged"],
20+
visibility = ["//visibility:private"],
21+
)
22+
23+
filegroup(
24+
name = "all-srcs",
25+
srcs = [":package-srcs"],
26+
tags = ["automanaged"],
27+
visibility = ["//visibility:public"],
28+
)

0 commit comments

Comments
 (0)