Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions Dockerfile.node-labeler
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Copyright 2025 The Kubernetes Authors.
Comment thread
hdp617 marked this conversation as resolved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

FROM --platform=$BUILDPLATFORM golang:1.25.5 AS builder

ARG STAGINGVERSION
ARG TARGETPLATFORM

WORKDIR /go/src/sigs.k8s.io/gcp-compute-persistent-disk-csi-driver
ADD . .
RUN GOARCH=$(echo $TARGETPLATFORM | cut -f2 -d '/') GCE_PD_CSI_STAGING_VERSION=$STAGINGVERSION make gce-pd-node-labeler

FROM gcr.io/distroless/static:nonroot
WORKDIR /
COPY --from=builder /go/src/sigs.k8s.io/gcp-compute-persistent-disk-csi-driver/bin/gce-pd-node-labeler .
USER 65532:65532

ENTRYPOINT ["/gce-pd-node-labeler"]
22 changes: 22 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ REV=$(shell git describe --long --tags --match='v*' --dirty 2>/dev/null || git r
GCE_PD_CSI_STAGING_VERSION ?= ${REV}
STAGINGVERSION=${GCE_PD_CSI_STAGING_VERSION}
STAGINGIMAGE=${GCE_PD_CSI_STAGING_IMAGE}
LABELERSTAGINGIMAGE?=${STAGINGIMAGE}/gce-pd-node-labeler
DRIVERBINARY=gce-pd-csi-driver
LABELERBINARY=gce-pd-node-labeler
DRIVERWINDOWSBINARY=${DRIVERBINARY}.exe

DOCKER=DOCKER_CLI_EXPERIMENTAL=enabled docker
Expand All @@ -40,6 +42,10 @@ gce-pd-driver: require-GCE_PD_CSI_STAGING_VERSION
mkdir -p bin
CGO_ENABLED=0 go build -mod=vendor -gcflags=$(GCFLAGS) -ldflags "-extldflags=static -X main.version=$(STAGINGVERSION)" -o bin/${DRIVERBINARY} ./cmd/gce-pd-csi-driver/

gce-pd-node-labeler: require-GCE_PD_CSI_STAGING_VERSION
mkdir -p bin
CGO_ENABLED=0 go build -mod=vendor -gcflags=$(GCFLAGS) -ldflags "-extldflags=static -X main.version=$(STAGINGVERSION)" -o bin/${LABELERBINARY} ./cmd/gce-pd-node-labeler/

gce-pd-driver-windows: require-GCE_PD_CSI_STAGING_VERSION
ifeq (${GOARCH}, amd64)
mkdir -p bin
Expand Down Expand Up @@ -77,6 +83,10 @@ build-and-push-multi-arch-debug: build-and-push-container-linux-debug build-and-
STAGINGIMAGE="$(STAGINGIMAGE)" STAGINGVERSION="$(STAGINGVERSION)" WINDOWS_IMAGE_TAGS="ltsc2019, ltsc2022" WINDOWS_BASE_IMAGES="$(BASE_IMAGE_LTSC2019), $(BASE_IMAGE_LTSC2022)" ./manifest_osversion.sh
$(DOCKER) manifest push -p $(STAGINGIMAGE):$(STAGINGVERSION)

build-and-push-node-labeler-multi-arch: build-node-labeler-container-linux-amd64 build-node-labeler-container-linux-arm64
$(DOCKER) manifest create $(LABELERSTAGINGIMAGE):$(STAGINGVERSION) $(LABELERSTAGINGIMAGE):$(STAGINGVERSION)_linux_amd64 $(LABELERSTAGINGIMAGE):$(STAGINGVERSION)_linux_arm64
$(DOCKER) manifest push -p $(LABELERSTAGINGIMAGE):$(STAGINGVERSION)

push-container: build-container

# Used by hack/verify-docker-deps.sh, not used for building artifacts
Expand Down Expand Up @@ -111,6 +121,18 @@ build-and-push-container-linux-arm64: require-GCE_PD_CSI_STAGING_IMAGE init-buil
--build-arg BUILDPLATFORM=linux \
--build-arg STAGINGVERSION=$(STAGINGVERSION) --push --provenance=false .

build-node-labeler-container-linux-amd64: require-GCE_PD_CSI_STAGING_IMAGE init-buildx
$(DOCKER) buildx build --file=Dockerfile.node-labeler --platform=linux/amd64 \
-t $(LABELERSTAGINGIMAGE):$(STAGINGVERSION)_linux_amd64 \
--build-arg BUILDPLATFORM=linux \
--build-arg STAGINGVERSION=$(STAGINGVERSION) --push --provenance=false .

build-node-labeler-container-linux-arm64: require-GCE_PD_CSI_STAGING_IMAGE init-buildx
$(DOCKER) buildx build --file=Dockerfile.node-labeler --platform=linux/arm64 \
-t $(LABELERSTAGINGIMAGE):$(STAGINGVERSION)_linux_arm64 \
--build-arg BUILDPLATFORM=linux \
--build-arg STAGINGVERSION=$(STAGINGVERSION) --push --provenance=false .

build-and-push-container-linux-debug: require-GCE_PD_CSI_STAGING_IMAGE init-buildx
$(DOCKER) buildx build --file=Dockerfile.debug --platform=linux \
-t $(STAGINGIMAGE):$(STAGINGVERSION)_linux \
Expand Down
26 changes: 26 additions & 0 deletions cloudbuild-node-labeler.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# See https://cloud.google.com/cloud-build/docs/build-config
# For more information about Image pushing refer to https://github.com/kubernetes/test-infra/blob/master/config/jobs/image-pushing/README.md
timeout: 3600s

options:
substitution_option: ALLOW_LOOSE

steps:
- name: "gcr.io/k8s-staging-test-infra/gcb-docker-gcloud:v20250513-9264efb079"
entrypoint: make
env:
- GCE_PD_CSI_STAGING_IMAGE=gcr.io/${_STAGING_PROJECT}/gce-pd-node-labeler
- GCE_PD_CSI_STAGING_VERSION=${_PULL_BASE_REF}
# default cloudbuild has HOME=/builder/home and docker buildx is in /root/.docker/cli-plugins/docker-buildx
# set the home to /root explicitly to if using docker buildx
- HOME=/root
args:
- build-and-push-node-labeler-multi-arch

substitutions:
_STAGING_PROJECT: "k8s-staging-cloud-provider-gcp"
_PULL_BASE_REF: "master"

tags:
- "gce-pd-node-labeler"
- ${_PULL_BASE_REF}
93 changes: 93 additions & 0 deletions cmd/gce-pd-node-labeler/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
Copyright 2025 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
Comment thread
hdp617 marked this conversation as resolved.
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Package main is the GCE PD Node Labeler entrypoint.
package main

import (
"flag"

corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/builder"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/config"
"sigs.k8s.io/controller-runtime/pkg/handler"
"sigs.k8s.io/controller-runtime/pkg/healthz"
"sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/manager"
"sigs.k8s.io/controller-runtime/pkg/manager/signals"
"sigs.k8s.io/controller-runtime/pkg/predicate"
"sigs.k8s.io/gcp-compute-persistent-disk-csi-driver/pkg/nodelabeler"
)

var (
configmapName = flag.String("configmap-name", "machine-pd-compatibility", "Name of the ConfigMap to use for machine & PD compatibility information.")
configmapNamespace = flag.String("configmap-namespace", "gce-pd-csi-driver", "Namespace of the ConfigMap to use for machine & PD compatibility information.")
httpEndpoint = flag.String("http-endpoint", ":22015", "HTTP endpoint for health checks.")
)

func main() {
klog.InitFlags(nil)
flag.Parse()
log.SetLogger(klog.NewKlogr())
ctx := signals.SetupSignalHandler()

mgr, err := manager.New(config.GetConfigOrDie(), manager.Options{
HealthProbeBindAddress: *httpEndpoint,
})
if err != nil {
klog.Fatalf("Failed to create manager: %v", err)
}

if err := mgr.AddHealthzCheck("healthz/node-labeler", healthz.Ping); err != nil {
klog.Fatalf("Failed to set up health check: %v", err)
}

reconciler := &nodelabeler.Reconciler{
Client: mgr.GetClient(),
ConfigMapName: *configmapName,
ConfigMapNamespace: *configmapNamespace,
}

eventHandler := &nodelabeler.ConfigMapEventHandler{
Client: mgr.GetClient(),
Reconciler: reconciler,
}

err = builder.ControllerManagedBy(mgr).
For(&corev1.Node{}).
Watches(
&corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: *configmapName,
Namespace: *configmapNamespace,
},
},
handler.EnqueueRequestsFromMapFunc(eventHandler.Map),
builder.WithPredicates(predicate.NewPredicateFuncs(func(obj client.Object) bool {
return obj.GetName() == *configmapName && obj.GetNamespace() == *configmapNamespace
})),
).
Complete(reconciler)
if err != nil {
klog.Fatalf("Failed to build controller: %v", err)
}

klog.Info("Starting manager")
if err := mgr.Start(ctx); err != nil {
klog.Fatalf("Failed to start manager: %v", err)
}
}
Loading