From cb15ddcf180bdcb32e4243c060a024d97f441eda Mon Sep 17 00:00:00 2001 From: Christoph Mewes Date: Mon, 3 Nov 2025 15:33:09 +0100 Subject: [PATCH 1/4] =?UTF-8?q?cleanup=20Makefile,=20use=20=C2=B5get=20to?= =?UTF-8?q?=20download=20prebuilt=20binaries=20when=20available?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On-behalf-of: @SAP christoph.mewes@sap.com --- Makefile | 134 ++++---- contrib/kcp/Makefile | 22 +- docs/content/contributing/index.md | 2 +- docs/content/setup/kcp-setup.md | 5 +- docs/content/setup/quickstart.md | 10 +- go.mod | 9 - go.sum | 26 -- hack/go-install.sh | 62 ---- hack/tools.checksums | 7 + hack/tools.go | 6 - hack/uget.sh | 497 +++++++++++++++++++++++++++++ 11 files changed, 596 insertions(+), 184 deletions(-) delete mode 100755 hack/go-install.sh create mode 100644 hack/tools.checksums create mode 100755 hack/uget.sh diff --git a/Makefile b/Makefile index 3796fd6a8..34f14bd63 100644 --- a/Makefile +++ b/Makefile @@ -15,30 +15,24 @@ # We need bash for some conditional logic below. SHELL := /usr/bin/env bash -e -GO_INSTALL = ./hack/go-install.sh - ROOT_DIR=$(abspath .) TOOLS_DIR=hack/tools -TOOLS_GOBIN_DIR := $(abspath $(TOOLS_DIR)) -GOBIN_DIR=$(abspath ./bin ) -PATH := $(GOBIN_DIR):$(TOOLS_GOBIN_DIR):$(PATH) -TMPDIR := $(shell mktemp -d) +BUILD_DIR=bin/ +ABS_TOOLS_DIR := $(abspath $(TOOLS_DIR)) +ABS_BUILD_DIR=$(abspath $(BUILD_DIR)) +PATH := $(ABS_BUILD_DIR):$(ABS_TOOLS_DIR):$(PATH) + +export UGET_DIRECTORY = $(TOOLS_DIR) +export UGET_CHECKSUMS = hack/tools.checksums # Image build configuration # REV is the short git sha of latest commit. REV ?= $(shell git rev-parse --short HEAD) IMAGE_REPO ?= kube-bind -# Detect the path used for the install target -ifeq (,$(shell go env GOBIN)) -INSTALL_GOBIN=$(shell go env GOPATH)/bin -else -INSTALL_GOBIN=$(shell go env GOBIN) -endif - CONTROLLER_GEN_VER := v0.17.3 CONTROLLER_GEN_BIN := controller-gen -CONTROLLER_GEN := $(TOOLS_DIR)/$(CONTROLLER_GEN_BIN)-$(CONTROLLER_GEN_VER) +CONTROLLER_GEN := $(TOOLS_DIR)/$(CONTROLLER_GEN_BIN) export CONTROLLER_GEN # so hack scripts can use it KUBE_CLIENT_GEN_VER := v0.32.0 @@ -50,46 +44,46 @@ KUBE_INFORMER_GEN_BIN := informer-gen KUBE_APPLYCONFIGURATION_GEN_VER := v0.32.0 KUBE_APPLYCONFIGURATION_GEN_BIN := applyconfiguration-gen -KUBE_CLIENT_GEN := $(GOBIN_DIR)/$(KUBE_CLIENT_GEN_BIN)-$(KUBE_CLIENT_GEN_VER) +KUBE_CLIENT_GEN := $(ABS_BUILD_DIR)/$(KUBE_CLIENT_GEN_BIN) export KUBE_CLIENT_GEN -KUBE_LISTER_GEN := $(GOBIN_DIR)/$(KUBE_LISTER_GEN_BIN)-$(KUBE_LISTER_GEN_VER) +KUBE_LISTER_GEN := $(ABS_BUILD_DIR)/$(KUBE_LISTER_GEN_BIN) export KUBE_LISTER_GEN -KUBE_INFORMER_GEN := $(GOBIN_DIR)/$(KUBE_INFORMER_GEN_BIN)-$(KUBE_INFORMER_GEN_VER) +KUBE_INFORMER_GEN := $(ABS_BUILD_DIR)/$(KUBE_INFORMER_GEN_BIN) export KUBE_INFORMER_GEN -KUBE_APPLYCONFIGURATION_GEN := $(GOBIN_DIR)/$(KUBE_APPLYCONFIGURATION_GEN_BIN)-$(KUBE_APPLYCONFIGURATION_GEN_VER) +KUBE_APPLYCONFIGURATION_GEN := $(ABS_BUILD_DIR)/$(KUBE_APPLYCONFIGURATION_GEN_BIN) export KUBE_APPLYCONFIGURATION_GEN YAML_PATCH_VER ?= v0.0.11 YAML_PATCH_BIN := yaml-patch -YAML_PATCH := $(TOOLS_DIR)/$(YAML_PATCH_BIN)-$(YAML_PATCH_VER) +YAML_PATCH := $(TOOLS_DIR)/$(YAML_PATCH_BIN) export YAML_PATCH # so hack scripts can use it -GOLANGCI_LINT_VER := v2.1.6 +GOLANGCI_LINT_VER := 2.1.6 GOLANGCI_LINT_BIN := golangci-lint -GOLANGCI_LINT := $(TOOLS_GOBIN_DIR)/$(GOLANGCI_LINT_BIN)-$(GOLANGCI_LINT_VER) +GOLANGCI_LINT := $(ABS_TOOLS_DIR)/$(GOLANGCI_LINT_BIN) GOTESTSUM_VER := v1.8.1 GOTESTSUM_BIN := gotestsum -GOTESTSUM := $(abspath $(TOOLS_DIR))/$(GOTESTSUM_BIN)-$(GOTESTSUM_VER) +GOTESTSUM := $(abspath $(TOOLS_DIR))/$(GOTESTSUM_BIN) LOGCHECK_VER := v0.2.0 LOGCHECK_BIN := logcheck -LOGCHECK := $(TOOLS_GOBIN_DIR)/$(LOGCHECK_BIN)-$(LOGCHECK_VER) +LOGCHECK := $(ABS_TOOLS_DIR)/$(LOGCHECK_BIN) export LOGCHECK # so hack scripts can use it CODE_GENERATOR_VER := v2.4.0 CODE_GENERATOR_BIN := code-generator -CODE_GENERATOR := $(TOOLS_GOBIN_DIR)/$(CODE_GENERATOR_BIN)-$(CODE_GENERATOR_VER) +CODE_GENERATOR := $(ABS_TOOLS_DIR)/$(CODE_GENERATOR_BIN) export CODE_GENERATOR # so hack scripts can use it -KCP_VER := v0.28.3 +KCP_VER := 0.28.3 KCP_BIN := kcp -KCP := $(TOOLS_GOBIN_DIR)/$(KCP_BIN)-$(KCP_VER) +KCP := $(ABS_TOOLS_DIR)/$(KCP_BIN) KCP_CMD ?= $(KCP) DEX_VER := v2.43.1 DEX_BIN := dex -DEX := $(TOOLS_GOBIN_DIR)/$(DEX_BIN)-$(DEX_VER) +DEX := $(ABS_TOOLS_DIR)/$(DEX_BIN) ARCH := $(shell go env GOARCH) OS := $(shell go env GOOS) @@ -132,12 +126,16 @@ ldflags: require-%: @if ! command -v $* 1> /dev/null 2>&1; then echo "$* not found in \$$PATH"; exit 1; fi +.PHONY: clean +clean: ## Remove all build artifacts + rm -rf $(BUILD_DIR) $(TOOLS_DIR) + build: WHAT ?= ./cmd/... ./cli/cmd/... ./contrib/kcp/cmd/kcp-init/... build: require-jq require-go require-git verify-go-versions ## Build the project - mkdir -p $(GOBIN_DIR) + mkdir -p $(ABS_BUILD_DIR) set -x; for W in $(WHAT); do \ pushd . && cd $${W%..}; \ - GOOS=$(OS) GOARCH=$(ARCH) CGO_ENABLED=0 go build $(BUILDFLAGS) -ldflags="$(LDFLAGS)" -o $(GOBIN_DIR) ./...; \ + GOOS=$(OS) GOARCH=$(ARCH) CGO_ENABLED=0 go build $(BUILDFLAGS) -ldflags="$(LDFLAGS)" -o $(ABS_BUILD_DIR) ./...; \ popd; \ done .PHONY: build @@ -147,15 +145,17 @@ install: ## install binaries to GOBIN GOOS=$(OS) GOARCH=$(ARCH) go install -ldflags="$(LDFLAGS)" $(WHAT) .PHONY: install - $(GOLANGCI_LINT): - GOBIN=$(TOOLS_GOBIN_DIR) $(GO_INSTALL) github.com/golangci/golangci-lint/v2/cmd/golangci-lint $(GOLANGCI_LINT_BIN) $(GOLANGCI_LINT_VER) + @hack/uget.sh \ + https://github.com/golangci/golangci-lint/releases/download/v{VERSION}/golangci-lint-{VERSION}-{GOOS}-{GOARCH}.tar.gz \ + ${GOLANGCI_LINT_BIN} \ + ${GOLANGCI_LINT_VER} $(LOGCHECK): - GOBIN=$(TOOLS_GOBIN_DIR) $(GO_INSTALL) sigs.k8s.io/logtools/logcheck $(LOGCHECK_BIN) $(LOGCHECK_VER) + @GO_MODULE=true hack/uget.sh sigs.k8s.io/logtools/logcheck ${LOGCHECK_BIN} $(LOGCHECK_VER) $(CODE_GENERATOR): - GOBIN=$(TOOLS_GOBIN_DIR) $(GO_INSTALL) github.com/kcp-dev/code-generator/v2 $(CODE_GENERATOR_BIN) $(CODE_GENERATOR_VER) + @GO_MODULE=true hack/uget.sh github.com/kcp-dev/code-generator/v2 ${CODE_GENERATOR_BIN} $(CODE_GENERATOR_VER) lint: $(GOLANGCI_LINT) $(LOGCHECK) ## Run golangci-lint @if [ -n "$(WHAT)" ]; then \ @@ -180,23 +180,30 @@ tools: $(GOLANGCI_LINT) $(CONTROLLER_GEN) $(YAML_PATCH) $(GOTESTSUM) $(CODE_GENE .PHONY: tools $(CONTROLLER_GEN): - GOBIN=$(TOOLS_GOBIN_DIR) $(GO_INSTALL) sigs.k8s.io/controller-tools/cmd/controller-gen $(CONTROLLER_GEN_BIN) $(CONTROLLER_GEN_VER) + @UNCOMPRESSED=true hack/uget.sh \ + https://github.com/kubernetes-sigs/controller-tools/releases/download/{VERSION}/controller-gen-{GOOS}-{GOARCH} \ + ${CONTROLLER_GEN_BIN} \ + ${CONTROLLER_GEN_VER} \ + ${CONTROLLER_GEN_BIN}* $(YAML_PATCH): - GOBIN=$(TOOLS_GOBIN_DIR) $(GO_INSTALL) github.com/pivotal-cf/yaml-patch/cmd/yaml-patch $(YAML_PATCH_BIN) $(YAML_PATCH_VER) + @GO_MODULE=true hack/uget.sh github.com/pivotal-cf/yaml-patch/cmd/yaml-patch $(YAML_PATCH_BIN) $(YAML_PATCH_VER) $(GOTESTSUM): - GOBIN=$(TOOLS_GOBIN_DIR) $(GO_INSTALL) gotest.tools/gotestsum $(GOTESTSUM_BIN) $(GOTESTSUM_VER) + @hack/uget.sh \ + https://github.com/gotestyourself/gotestsum/releases/download/v{VERSION}/gotestsum_{VERSION}_{GOOS}_{GOARCH}.tar.gz \ + ${GOTESTSUM_BIN} \ + ${GOTESTSUM_VER} \ + ${GOTESTSUM_BIN} $(KUBE_CLIENT_GEN): - GOBIN=$(GOBIN_DIR) $(GO_INSTALL) k8s.io/code-generator/cmd/$(KUBE_CLIENT_GEN_BIN) $(KUBE_CLIENT_GEN_BIN) $(KUBE_CLIENT_GEN_VER) + @GO_MODULE=true hack/uget.sh k8s.io/code-generator/cmd/$(KUBE_CLIENT_GEN_BIN) $(KUBE_CLIENT_GEN_BIN) $(KUBE_CLIENT_GEN_VER) $(KUBE_LISTER_GEN): - GOBIN=$(GOBIN_DIR) $(GO_INSTALL) k8s.io/code-generator/cmd/$(KUBE_LISTER_GEN_BIN) $(KUBE_LISTER_GEN_BIN) $(KUBE_LISTER_GEN_VER) + @GO_MODULE=true hack/uget.sh k8s.io/code-generator/cmd/$(KUBE_LISTER_GEN_BIN) $(KUBE_LISTER_GEN_BIN) $(KUBE_LISTER_GEN_VER) $(KUBE_INFORMER_GEN): - GOBIN=$(GOBIN_DIR) $(GO_INSTALL) k8s.io/code-generator/cmd/$(KUBE_INFORMER_GEN_BIN) $(KUBE_INFORMER_GEN_BIN) $(KUBE_INFORMER_GEN_VER) + @GO_MODULE=true hack/uget.sh k8s.io/code-generator/cmd/$(KUBE_INFORMER_GEN_BIN) $(KUBE_INFORMER_GEN_BIN) $(KUBE_INFORMER_GEN_VER) $(KUBE_APPLYCONFIGURATION_GEN): - GOBIN=$(GOBIN_DIR) $(GO_INSTALL) k8s.io/code-generator/cmd/$(KUBE_APPLYCONFIGURATION_GEN_BIN) $(KUBE_APPLYCONFIGURATION_GEN_BIN) $(KUBE_APPLYCONFIGURATION_GEN_VER) - + @GO_MODULE=true hack/uget.sh k8s.io/code-generator/cmd/$(KUBE_APPLYCONFIGURATION_GEN_BIN) $(KUBE_APPLYCONFIGURATION_GEN_BIN) $(KUBE_APPLYCONFIGURATION_GEN_VER) codegen: $(CONTROLLER_GEN) $(YAML_PATCH) $(CODE_GENERATOR) $(KUBE_CLIENT_GEN) $(KUBE_LISTER_GEN) $(KUBE_INFORMER_GEN) $(KUBE_APPLYCONFIGURATION_GEN) ## Generate code go mod download @@ -232,13 +239,15 @@ imports: $(GOLANGCI_LINT) verify-go-versions ## Fix imports and format code fi $(TOOLS_DIR)/verify_boilerplate.py: - mkdir -p $(TOOLS_DIR) - curl --fail --retry 3 -L -o $(TOOLS_DIR)/verify_boilerplate.py https://raw.githubusercontent.com/kubernetes/repo-infra/master/hack/verify_boilerplate.py - chmod +x $(TOOLS_DIR)/verify_boilerplate.py + @UNCOMPRESSED=true hack/uget.sh \ + https://raw.githubusercontent.com/kubernetes/repo-infra/master/hack/verify_boilerplate.py \ + verify_boilerplate.py \ + 201dcad9616c117927232ee0bc499ff38a27023e \ + verify_boilerplate.py .PHONY: verify-boilerplate verify-boilerplate: $(TOOLS_DIR)/verify_boilerplate.py - $(TOOLS_DIR)/verify_boilerplate.py --boilerplate-dir=hack/boilerplate --skip dex + $(TOOLS_DIR)/verify_boilerplate.py --boilerplate-dir=hack/boilerplate --skip dex --skip hack/uget.sh ifdef ARTIFACT_DIR GOTESTSUM_ARGS += --junitfile=$(ARTIFACT_DIR)/junit.xml @@ -257,23 +266,34 @@ else E2E_PARALLELISM_FLAG := endif +# dex does not publish binaries for their releases, and their go.mod file +# is missing "/v2" and so dex cannot be installed as a Go dependency. Cloning +# the repo and building it by hand is the best of the worst approaches remaining. +DEX_TMP_DIR = $(TOOLS_DIR)/dex-clone-$(DEX_VER) $(DEX): mkdir -p $(TOOLS_DIR) - git clone --branch $(DEX_VER) --depth 1 https://github.com/dexidp/dex $(TOOLS_DIR)/dex-clone-$(DEX_VER) || true - cd $(TOOLS_DIR)/dex-clone-$(DEX_VER) && GOWORK=off make build - cp -a $(TOOLS_DIR)/dex-clone-$(DEX_VER)/bin/dex $(DEX) - ln -sf $(DEX) $(TOOLS_GOBIN_DIR)/dex + git clone --branch $(DEX_VER) --depth 1 https://github.com/dexidp/dex $(DEX_TMP_DIR) || true + cd $(DEX_TMP_DIR) && GOWORK=off make build + cp -a $(DEX_TMP_DIR)/bin/dex $(DEX) + rm -rf $(DEX_TMP_DIR) +.PHONY: dex +dex: $(DEX) + +.PHONY: run-dex run-dex: $(DEX) $(DEX) serve hack/dex-config-dev.yaml $(KCP): - mkdir -p $(TOOLS_DIR) - curl --fail --retry 3 -L "https://github.com/kcp-dev/kcp/releases/download/$(KCP_VER)/kcp_$(KCP_VER:v%=%)_$(OS)_$(ARCH).tar.gz" | \ - tar xz -C "$(TOOLS_DIR)" --strip-components="1" bin/kcp - mv $(TOOLS_DIR)/kcp $(KCP) - ln -sf $(KCP) $(TOOLS_GOBIN_DIR)/kcp + @hack/uget.sh \ + https://github.com/kcp-dev/kcp/releases/download/v{VERSION}/kcp_{VERSION}_{GOOS}_{GOARCH}.tar.gz \ + $(KCP_BIN) \ + $(KCP_VER) +.PHONY: kcp +kcp: $(KCP) + +.PHONY: run-kcp run-kcp: $(KCP) $(KCP_CMD) start --bind-address=127.0.0.1 @@ -375,7 +395,7 @@ deploy-docs: venv ## Deploy docs . $(VENV)/activate; \ REMOTE=$(REMOTE) BRANCH=$(BRANCH) docs/scripts/deploy-docs.sh -# Example: make IMAGE_REPO=ghcr.io/ image-local +# Example: make IMAGE_REPO=ghcr.io/ image-local .PHONY: image-local image-local: @echo "Building images locally with tag $(REV)" @@ -410,7 +430,7 @@ kind-load: helm-build-local: ## Build and package Helm charts locally for testing @echo "Building Helm charts locally..." @command -v helm >/dev/null 2>&1 || { echo "helm not found. Install from: https://helm.sh/docs/intro/install/"; exit 1; } - + @# Set chart version to semver format for local builds (0.0.0-) CHART_VERSION="0.0.0-$(REV)"; \ for chart_dir in deploy/charts/*/; do \ @@ -439,7 +459,7 @@ helm-clean: ## Clean up built helm charts helm-push-local: ## Push Helm charts to IMAGE_REPO registry @echo "Pushing Helm charts to registry: $(IMAGE_REPO)" @command -v helm >/dev/null 2>&1 || { echo "helm not found. Install from: https://helm.sh/docs/intro/install/"; exit 1; } - + CHART_VERSION="0.0.0-$(REV)"; \ export HELM_EXPERIMENTAL_OCI=1; \ for chart_file in ./bin/*-$$CHART_VERSION.tgz; do \ diff --git a/contrib/kcp/Makefile b/contrib/kcp/Makefile index 78c64259c..26350dcc4 100644 --- a/contrib/kcp/Makefile +++ b/contrib/kcp/Makefile @@ -16,23 +16,17 @@ SHELL := /usr/bin/env bash -e ROOT_DIR=$(abspath ../..) -GO_INSTALL = $(ROOT_DIR)/hack/go-install.sh -TOOLS_GOBIN_DIR = $(ROOT_DIR)/hack/tools -GOBIN_DIR = $(ROOT_DIR)/bin -PATH := $(GOBIN_DIR):$(TOOLS_GOBIN_DIR):$(PATH) -TMPDIR := $(shell mktemp -d) - -# Detect the path used for the install target -ifeq (,$(shell go env GOBIN)) -INSTALL_GOBIN=$(shell go env GOPATH)/bin -else -INSTALL_GOBIN=$(shell go env GOBIN) -endif +UGET = $(ROOT_DIR)/hack/uget.sh +ABS_TOOLS_DIR = $(ROOT_DIR)/hack/tools +ABS_BUILD_DIR = $(ROOT_DIR)/bin +PATH := $(ABS_BUILD_DIR):$(ABS_TOOLS_DIR):$(PATH) +export UGET_DIRECTORY = $(ABS_TOOLS_DIR) +export UGET_CHECKSUMS = $(ROOT_DIR)/hack/tools.checksums KCP_APIGEN_VER := v0.28.0 KCP_APIGEN_BIN := apigen -KCP_APIGEN_GEN := $(TOOLS_GOBIN_DIR)/$(KCP_APIGEN_BIN)-$(KCP_APIGEN_VER) +KCP_APIGEN_GEN := $(ABS_TOOLS_DIR)/$(KCP_APIGEN_BIN) export KCP_APIGEN_GEN # so hack scripts can use it all: build @@ -44,7 +38,7 @@ require-%: # KCP tool installation targets $(KCP_APIGEN_GEN): - GOBIN=$(TOOLS_GOBIN_DIR) $(GO_INSTALL) github.com/kcp-dev/kcp/sdk/cmd/apigen $(KCP_APIGEN_BIN) $(KCP_APIGEN_VER) + @GO_MODULE=true $(UGET) github.com/kcp-dev/kcp/sdk/cmd/apigen $(KCP_APIGEN_BIN) $(KCP_APIGEN_VER) # KCP runtime targets run-kcp: $(KCP) ## Start KCP server diff --git a/docs/content/contributing/index.md b/docs/content/contributing/index.md index a996e3b3f..17e3f4f12 100644 --- a/docs/content/contributing/index.md +++ b/docs/content/contributing/index.md @@ -17,7 +17,7 @@ contribution. See the [DCO](https://github.com/kube-bind/kube-bind/tree/main/DCO ### Prerequisites 1. Clone this repository. -2. [Install Go](https://golang.org/doc/install) (currently 1.22). +2. [Install Go](https://golang.org/doc/install) (kube-bind requires 1.24+). 3. Install [kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl). ## Finding Areas to Contribute diff --git a/docs/content/setup/kcp-setup.md b/docs/content/setup/kcp-setup.md index e831a0968..4c01d3c40 100644 --- a/docs/content/setup/kcp-setup.md +++ b/docs/content/setup/kcp-setup.md @@ -35,8 +35,7 @@ make run-kcp Clone and configure dex: ```bash -git clone https://github.com/dexidp/dex.git -cd dex && make build +make dex ``` Configure dex (`examples/config-dev.yaml`): @@ -53,7 +52,7 @@ staticClients: Start dex: ```bash -./bin/dex serve examples/config-dev.yaml +./hack/tools/dex serve examples/config-dev.yaml ``` ### 3. Bootstrap kcp diff --git a/docs/content/setup/quickstart.md b/docs/content/setup/quickstart.md index c20b32ee8..86b4e96ed 100644 --- a/docs/content/setup/quickstart.md +++ b/docs/content/setup/quickstart.md @@ -1,6 +1,6 @@ --- description: > - Get started with kube bind. + Get started with kube-bind. --- # Quickstart @@ -35,9 +35,7 @@ the oauth2 workflow. We use dex to manage OIDC, following the steps below you can run a local OIDC issuer using dex: -* First, clone the dex repo: `git clone https://github.com/dexidp/dex.git` -* `cd dex` and then build the dex binary `make build` -* The binary will be created in `bin/dex` +* First, build dex: `make dex`, the binary will be created in `hack/tools/dex`. * Adjust the config file(`examples/config-dev.yaml`) for dex by specifying the server callback method: ```yaml staticClients: @@ -47,9 +45,9 @@ We use dex to manage OIDC, following the steps below you can run a local OIDC is name: 'Kube Bind' secret: ZXhhbXBsZS1hcHAtc2VjcmV0 ``` -* Run dex: `./bin/dex serve examples/config-dev.yaml` +* Run dex: `./hack/tools/dex serve examples/config-dev.yaml` -Next you should be able to run the backend. For it you need a kubernetes cluster (e.g. kind) +Next you should be able to run the backend. For it you need a Kubernetes cluster (e.g. kind) accessible. ***Note: make sure before running the backend that you have the dex server up and running as mentioned above diff --git a/go.mod b/go.mod index dd61a9704..c44a17658 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,6 @@ require ( github.com/gorilla/mux v1.8.0 github.com/gorilla/securecookie v1.1.1 github.com/headzoo/surf v1.0.1 - github.com/kcp-dev/code-generator/v3 v3.0.0-20250707080944-4094fb87e20f github.com/kcp-dev/kcp/pkg/apis v0.11.0 github.com/kcp-dev/kcp/sdk v0.28.1 github.com/kcp-dev/multicluster-provider v0.2.1-0.20251002133408-9a8d21dc2872 @@ -41,7 +40,6 @@ require ( k8s.io/klog/v2 v2.130.1 k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 sigs.k8s.io/controller-runtime v0.21.0 - sigs.k8s.io/controller-tools v0.16.1 sigs.k8s.io/multicluster-runtime v0.21.0-alpha.9.0.20251002124257-36facc7fbe82 sigs.k8s.io/yaml v1.4.0 ) @@ -55,7 +53,6 @@ require ( github.com/antlr4-go/antlr/v4 v4.13.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect - github.com/bombsimon/logrusr/v3 v3.1.0 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/coreos/go-semver v0.3.1 // indirect @@ -63,7 +60,6 @@ require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/emicklei/go-restful/v3 v3.12.1 // indirect github.com/evanphx/json-patch v5.9.11+incompatible // indirect - github.com/fatih/color v1.18.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect @@ -75,7 +71,6 @@ require ( github.com/go-openapi/jsonpointer v0.21.0 // indirect github.com/go-openapi/jsonreference v0.21.0 // indirect github.com/go-openapi/swag v0.23.0 // indirect - github.com/gobuffalo/flect v1.0.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/btree v1.1.3 // indirect @@ -95,8 +90,6 @@ require ( github.com/kylelemons/godebug v1.1.0 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect github.com/mailru/easyjson v0.9.0 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect github.com/mdp/qrterminal/v3 v3.2.0 // indirect github.com/moby/term v0.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect @@ -111,7 +104,6 @@ require ( github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.62.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect - github.com/sirupsen/logrus v1.9.3 // indirect github.com/stoewer/go-strcase v1.3.0 // indirect github.com/vmihailenco/tagparser v0.1.1 // indirect github.com/x448/float16 v0.8.4 // indirect @@ -149,7 +141,6 @@ require ( google.golang.org/protobuf v1.36.5 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect k8s.io/gengo/v2 v2.0.0-20250207200755-1244d31929d7 // indirect k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect rsc.io/qr v0.2.0 // indirect diff --git a/go.sum b/go.sum index e3387965e..39576ea90 100644 --- a/go.sum +++ b/go.sum @@ -14,8 +14,6 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= -github.com/bombsimon/logrusr/v3 v3.1.0 h1:zORbLM943D+hDMGgyjMhSAz/iDz86ZV72qaak/CA0zQ= -github.com/bombsimon/logrusr/v3 v3.1.0/go.mod h1:PksPPgSFEL2I52pla2glgCyyd2OqOHAnFF5E+g8Ixco= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= @@ -43,8 +41,6 @@ github.com/evanphx/json-patch v5.9.11+incompatible h1:ixHHqfcGvxhWkniF1tWxBHA0yb github.com/evanphx/json-patch v5.9.11+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU= github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM= -github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= -github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= @@ -70,8 +66,6 @@ github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+Gr github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -github.com/gobuffalo/flect v1.0.2 h1:eqjPGSo2WmjgY2XlpGwo2NXgL3RucAKo4k4qQMNA5sA= -github.com/gobuffalo/flect v1.0.2/go.mod h1:A5msMlrHtLqh9umBSnvabjsMrCcCpAyzglnDvkbYKHs= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= @@ -129,8 +123,6 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kcp-dev/apimachinery/v2 v2.0.1-0.20250728122101-adbf20db3e51 h1:l38RDS+VUMx9etvyaCgJIZa4nM7FaNevNubWN0kDZY4= github.com/kcp-dev/apimachinery/v2 v2.0.1-0.20250728122101-adbf20db3e51/go.mod h1:rF1jfvUfPjFXs+HV/LN1BtPzAz1bfjJOwVa+hAVfroQ= -github.com/kcp-dev/code-generator/v3 v3.0.0-20250707080944-4094fb87e20f h1:Qfpk7+Y5gwWV8FNY6zu+l5hbKWlFZ6oJqgL67RoCEJg= -github.com/kcp-dev/code-generator/v3 v3.0.0-20250707080944-4094fb87e20f/go.mod h1:1EZhJqiFvXq1N0xKJnJOf8kQ++wuwLkqFGIRVSoVACk= github.com/kcp-dev/kcp/pkg/apis v0.11.0 h1:K6p+tNHNcvfACCPLcHgY0EMLeaIwR1jS491FyLfXMII= github.com/kcp-dev/kcp/pkg/apis v0.11.0/go.mod h1:8cUAmfMJcksauz53UtsLYG8Phhx62rvuCnd/5t/Zihk= github.com/kcp-dev/kcp/sdk v0.28.1 h1:bTtuHVjFRjbwFEqXTPxc1J1JP2Hc3mTYqQ2xfJsi16M= @@ -158,11 +150,6 @@ github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4 github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/martinlindhe/base36 v1.1.1 h1:1F1MZ5MGghBXDZ2KJ3QfxmiydlWOGB8HCEtkap5NkVg= github.com/martinlindhe/base36 v1.1.1/go.mod h1:vMS8PaZ5e/jV9LwFKlm0YLnXl/hpOihiBxKkIoc3g08= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mdp/qrterminal/v3 v3.2.0 h1:qteQMXO3oyTK4IHwj2mWsKYYRBOp1Pj2WRYFYYNTCdk= github.com/mdp/qrterminal/v3 v3.2.0/go.mod h1:XGGuua4Lefrl7TLEsSONiD+UEjQXJZ4mPzF+gWYIJkk= github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= @@ -176,10 +163,6 @@ github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/ github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.22.1 h1:QW7tbJAUDyVDVOM5dFa7qaybo+CRfR7bemlQUN6Z8aM= github.com/onsi/ginkgo/v2 v2.22.1/go.mod h1:S6aTpoRsSq2cZOd+pssHAlKW/Q/jZt6cPrPlnj4a1xM= github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8= @@ -317,9 +300,6 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -368,10 +348,6 @@ gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= @@ -407,8 +383,6 @@ sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 h1:jpcvIRr3GLoUo sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= sigs.k8s.io/controller-runtime v0.21.0 h1:CYfjpEuicjUecRk+KAeyYh+ouUBn4llGyDYytIGcJS8= sigs.k8s.io/controller-runtime v0.21.0/go.mod h1:OSg14+F65eWqIu4DceX7k/+QRAbTTvxeQSNSOQpukWM= -sigs.k8s.io/controller-tools v0.16.1 h1:gvIsZm+2aimFDIBiDKumR7EBkc+oLxljoUVfRbDI6RI= -sigs.k8s.io/controller-tools v0.16.1/go.mod h1:0I0xqjR65YTfoO12iR+mZR6s6UAVcUARgXRlsu0ljB0= sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/kustomize/api v0.19.0 h1:F+2HB2mU1MSiR9Hp1NEgoU2q9ItNOaBJl0I4Dlus5SQ= diff --git a/hack/go-install.sh b/hack/go-install.sh deleted file mode 100755 index baa7dbc02..000000000 --- a/hack/go-install.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env bash - -# Copyright 2021 The Kube Bind Authors. -# -# 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. - -# Originally copied from -# https://github.com/kubernetes-sigs/cluster-api-provider-gcp/blob/c26a68b23e9317323d5d37660fe9d29b3d2ff40c/scripts/go_install.sh - -set -o errexit -set -o nounset -set -o pipefail - -if [[ -z "${1:-}" ]]; then - echo "must provide module as first parameter" - exit 1 -fi - -if [[ -z "${2:-}" ]]; then - echo "must provide binary name as second parameter" - exit 1 -fi - -if [[ -z "${3:-}" ]]; then - echo "must provide version as third parameter" - exit 1 -fi - -if [[ -z "${GOBIN:-}" ]]; then - echo "GOBIN is not set. Must set GOBIN to install the bin in a specified directory." - exit 1 -fi - -mkdir -p "${GOBIN}" - -tmp_dir=$(mktemp -d -t goinstall_XXXXXXXXXX) -function clean { - rm -rf "${tmp_dir}" -} -trap clean EXIT - -rm "${GOBIN}/${2}"* > /dev/null 2>&1 || true - -cd "${tmp_dir}" - -# create a new module in the tmp directory -go mod init fake/mod - -# install the golang module specified as the first argument -go install -tags tools "${1}@${3}" -mv "${GOBIN}/${2}" "${GOBIN}/${2}-${3}" -ln -sf "${GOBIN}/${2}-${3}" "${GOBIN}/${2}" \ No newline at end of file diff --git a/hack/tools.checksums b/hack/tools.checksums new file mode 100644 index 000000000..a050097f3 --- /dev/null +++ b/hack/tools.checksums @@ -0,0 +1,7 @@ +controller-gen|GOARCH=amd64;GOOS=linux|21e5f3239666fc0c5e2d23c2a3a83fd655af40a969ede7a118b86832c35a829f +controller-gen|GOARCH=arm64;GOOS=linux|a1a1f758435d05933c4b2f8c292f8ab2448e81a02c45f14dbd81c10e87ec4b20 +golangci-lint|GOARCH=amd64;GOOS=linux|7009324a8aad93c1f84dce1c3cf61181bdd6b68e5f1b8b5d6971662258255050 +golangci-lint|GOARCH=arm64;GOOS=linux|c51ff5b21be688b043baea44de7dd855cf07b855c14f0de405bfaf922b1d7634 +kcp|GOARCH=amd64;GOOS=linux|41149ef78d2092243b14164a363dfdacc3e0f2bece8c00b715457c21c423a80b +kcp|GOARCH=arm64;GOOS=linux|bd2412179c1e3294dc81641630e0a2184892d4b45c6ef5bed7dc15fbd2c333fe +verify_boilerplate.py||6928a807e2ffc2e6902de705ce7a7cddbbbf5ef61a43901432c4f4551b4e9a7b diff --git a/hack/tools.go b/hack/tools.go index e35a8ffa8..e996264ca 100644 --- a/hack/tools.go +++ b/hack/tools.go @@ -19,11 +19,5 @@ limitations under the License. package tools import ( - _ "github.com/kcp-dev/code-generator/v3/cmd/cluster-client-gen" - _ "github.com/kcp-dev/kcp/sdk/cmd/apigen" _ "k8s.io/code-generator" - _ "k8s.io/code-generator/cmd/conversion-gen" - _ "k8s.io/code-generator/cmd/deepcopy-gen" - _ "k8s.io/code-generator/cmd/defaulter-gen" - _ "sigs.k8s.io/controller-tools/cmd/controller-gen" ) diff --git a/hack/uget.sh b/hack/uget.sh new file mode 100755 index 000000000..932f0280a --- /dev/null +++ b/hack/uget.sh @@ -0,0 +1,497 @@ +#!/usr/bin/env bash + +# SPDX-FileCopyrightText: 2025 Christoph Mewes, https://codeberg.org/xrstf/uget +# SPDX-License-Identifier: MIT +# +# µget 0.2.1 – your friendly downloader +# ------------------------------------- +# +# µget can download software as binaries, archives or Go modules. +# +# Usage: ./uget.sh URL_PATTERN VERSION +# +# µget supports a large range of environment variables to customize its +# behaviour. + +set -euo pipefail + +############################################################################### +# Configuration + +# UGET_UPDATE can be set to true when the VERSION parameter of a program has +# been updated and you want µget to update all known variants (based on the +# checksums file). When UGET_CHECKSUMS is not in use, this variable has no +# effect. +UGET_UPDATE=${UGET_UPDATE:-false} + +# UGET_DIRECTORY is where downloaded binaries will be placed. +UGET_DIRECTORY="${UGET_DIRECTORY:-_tools}" + +# UGET_CHECKSUMS is an optional path to a checksum file that µget should use to +# ensure subsequent downloads match previously known checksums to prevent +# tampering on the server side. +UGET_CHECKSUMS="${UGET_CHECKSUMS:-}" + +# UGET_TEMPDIR is the root directory to use when creating new temporary dirs. +UGET_TEMPDIR="${UGET_TEMPDIR:-/tmp}" + +# UGET_PRINT_PATH can be set to "relative" to make µget only omit log output +# and only print the relative path to the binary, and set to "absolute" to +# output the absolute path. +UGET_PRINT_PATH="${UGET_PRINT_PATH:-no}" + +# UGET_HASHFUNC is the hashing function used to calculate file checksums. The +# output of this program is processed with awk to only print the first column. +UGET_HASHFUNC="${UGET_HASHFUNC:-sha256sum}" + +# UGET_GO_BUILD_CMD overwrites the default call to "go build" when installing +# a Go module. Use this to inject custom Go flags or toolchains. +# The given command is called with "-o BINARY_NAME MODULE_URL" with the pwd +# being inside a fake module that depends on the given module. +UGET_GO_BUILD_CMD="${UGET_GO_BUILD_CMD:-go build}" + +# UGET_GO_CHECKSUMS can be set to true to force checksums even for Go modules. +# This is disabled by default because the exact binaries being built depend on +# a lot of factors and usually it's a hassle to ensure everyone in a project +# has the *exact* same build environment. Go modules already make use of Google's +# GOSUMDB and should be "safe enough" by default with µget checksums. +UGET_GO_CHECKSUMS=${UGET_GO_CHECKSUMS:-false} + +############################################################################### +# Function library + +uget::mktemp() { + # --tmpdir does not work on MacOS + mktemp -d -p "$ABS_UGET_TEMPDIR" +} + +uget::log() { + if [[ "$UGET_PRINT_PATH" == "no" ]]; then + echo "$@" >&2 + fi +} + +uget::error() { + echo "$@" >&2 +} + +uget::lowercase() { + cat | tr '[:upper:]' '[:lower:]' +} + +uget::checksum::enabled() { + [[ -n "$UGET_CHECKSUMS" ]] +} + +uget::checksum::check() { + local kvString="$1" + local downloadedBinary="$2" + + if ! uget::checksum::enabled; then return; fi + + local newChecksum + newChecksum="$(uget::checksum::calculate "$downloadedBinary")" + + local oldChecksum + oldChecksum="$(uget::checksum::read "$kvString")" + + if [[ -n "$oldChecksum" ]] && [[ "$oldChecksum" != "$newChecksum" ]]; then + uget::error + uget::error " *************************************************************************" + uget::error " SECURITY ERROR" + uget::error + uget::error " The downloaded file $downloadedBinary does not have the expected checksum." + uget::error + uget::error " Expected: $oldChecksum" + uget::error " Actual : $newChecksum" + uget::error + uget::error " If you are updating $BINARY, this error is expected." + uget::error " Re-run this command with the environment variable UGET_UPDATE=true to make" + uget::error " µget update the checksums for all known variants of $BINARY." + uget::error " *************************************************************************" + uget::error + + return 1 + fi + + uget::checksum::write "$kvString" "$newChecksum" +} + +uget::checksum::read() { + local kvString="$1" + + if [[ -f "$UGET_CHECKSUMS" ]]; then + awk -F'|' "{ if (\$1 == \"$BINARY\" && \$2 == \"$kvString\") print \$3 }" "$UGET_CHECKSUMS" + fi +} + +uget::checksum::calculate() { + "$UGET_HASHFUNC" "$1" | awk '{ print $1 }' +} + +uget::checksum::write() { + local kvString="$1" + local checksum="$2" + + if [[ -f "$UGET_CHECKSUMS" ]]; then + local tempDir + tempDir="$(uget::mktemp)" + + # use awk to drop any existing hash for this binary/keyvalue combo + # (for better readability, do not invert the condition here); + # grep will drop any empty lines + awk \ + -F'|' \ + "{ if (\$1 == \"$BINARY\" && \$2 == \"$kvString\") {} else print }" \ + "$UGET_CHECKSUMS" | (grep . || true) > "$tempDir/checksums.txt" + + # add our new checksum + echo "$BINARY|$kvString|$checksum" >> "$tempDir/checksums.txt" + + # sort the file because it looks nicer and prevents ugly git diffs + cat "$tempDir/checksums.txt" | sort > "$UGET_CHECKSUMS" + + rm -rf -- "$tempDir" + else + # start a new file + echo "$BINARY|$kvString|$checksum" >> "$UGET_CHECKSUMS" + fi +} + +uget::url::placeholder() { + case "$1" in + GOARCH) go env GOARCH ;; + GOOS) go env GOOS ;; + UARCH) uname -m | uget::lowercase ;; + UOS) uname -s | uget::lowercase ;; + *) uget::error "Unexpected placeholder $1."; return 1 ;; + esac +} + +# valueFromPair returns "foo" for ";myvalue=foo;myothervalue=bar;" when called with +# "myvalue" as the key. The kv string must already be surrounded with semicolons. +uget::url::valueFromPair() { + local kvString="$1" + local key="$2" + + (echo "$kvString" | grep -oE ";$key=([^;]+)" || true) | cut -f2 -d'=' +} + +uget::url::setKeyInPairs() { + local kvString="$1" + local key="$2" + local value="$3" + + # first take the existing pairs but without the one for the given key, + # then add a new pair and sort it all together, strip empty lines in case + # kvstring as empty, then join the multiple lines back into a single line + # and drop the trailing ';' + ( + echo "$kvString" | tr ';' "\n" | (grep -vE "^$key=" || true) + echo "$key=$value" + ) | sort | sed '/^[[:space:]]*$/d' | tr "\n" ';' | sed 's/;$//' +} + +uget::url::findPlaceholders() { + # match all {...}, + # then sort and return only unique values (no need to replace the + # same placeholder multiple times) (this is important to allow for consistent + # matches when awk'ing through the checksum file), + # then remove braces and + # finally turn into a singleline string + echo "$1" | + grep -oE '\{[A-Z0-9_]+\}' | + sort -u | + tr -d '{}' | + awk '{printf("%s ", $0)}' +} + +# replaceLive() use live system-data to replace placeholders in the given pattern. +# It returns a string of form "KVSTRING|URL". +uget::url::replaceLive() { + local urlPattern="$1" + local usedPlaceholders="" + + for placeholder in $(uget::url::findPlaceholders "$urlPattern"); do + # version is treated specially + [[ "$placeholder" == "VERSION" ]] && continue + + replacement="$(uget::url::placeholder "$placeholder")" + urlPattern="${urlPattern//\{$placeholder\}/$replacement}" + + # remember this placeholder and its value + usedPlaceholders="$usedPlaceholders;$placeholder=$replacement" + done + + # trim leading ";" (this is safe even for zero-length strings) + usedPlaceholders="${usedPlaceholders:1}" + + echo "$usedPlaceholders|$urlPattern" +} + +# replaceWithArgs() does not ask the current system for the values when replacing +# a placeholder, but uses a given key-value pair string as the source. It also +# only returns the resulting string, since the used placeholders are known to +# the caller already. +uget::url::replaceWithArgs() { + local urlPattern="$1" + local kvString="$2" + + # make matching easier + kvString=";$kvString;" + + for placeholder in $(uget::url::findPlaceholders "$urlPattern"); do + # version is treated specially + [[ "$placeholder" == "VERSION" ]] && continue + + replacement="$(uget::url::valueFromPair "$kvString" "$placeholder")" + if [[ -z "$replacement" ]]; then + uget::error "Found no replacement string for placeholder $placeholder." + exit 1 + fi + + urlPattern="${urlPattern//\{$placeholder\}/$replacement}" + done + + echo "$urlPattern" +} + +# returns "KVSTRING URL" +uget::url::build() { + local kvString="${1:-}" + local pattern + + if [[ -z "$kvString" ]]; then + result="$(uget::url::replaceLive "$URL_PATTERN")" + kvString="$(echo "$result" | cut -d'|' -f1)" + pattern="$(echo "$result" | cut -d'|' -f2)" + else + pattern="$(uget::url::replaceWithArgs "$URL_PATTERN" "$kvString")" + fi + + pattern="${pattern//\{VERSION\}/$VERSION}" + + echo "$kvString|$pattern" +} + +# uget::fetch() detects whether wget or curl is available for downloading something. +uget::fetch() { + local url="$1" + + if command -v curl &> /dev/null; then + curl --fail -LO "$url" + elif command -v wget &> /dev/null; then + wget "$url" + else + uget::error "Neither curl nor wget are available." + return 1 + fi +} + +# uget::download performs the actual download +# and places the binary in a given directory. +uget::download() { + local destinationDir="$1" + local kvString="$2" + local url="$3" + + local startDir + startDir="$(pwd)" + + local tempDir + tempDir="$(uget::mktemp)" + + cd "$tempDir" + + if $GO_MODULE; then + # make sure GOARCH and GOOS are set correctly + os="$(uget::url::valueFromPair ";$kvString;" "GOOS")" + arch="$(uget::url::valueFromPair ";$kvString;" "GOARCH")" + + # since we crosscompile, we cannot do "GOBIN=(somewhere) go install url@version", + # because Go considers this to be dangerous behaviour: + # https://github.com/golang/go/issues/57485 + # Instead we create a dummy module and use the desired program as a dependency, + # *then* we're allowed to crosscompile it anywhere using "go build". Go figure. + + go mod init temp 2>/dev/null + go get "$url@$VERSION" + + GOFLAGS=-trimpath GOARCH="$arch" GOOS="$os" GOBIN=$(realpath .) $UGET_GO_BUILD_CMD -o "$BINARY" "$url" + + mv "$BINARY" "$destinationDir/$BINARY" + else + uget::fetch "$url" + archive="$(ls)" + + if ! $UNCOMPRESSED; then + case "$archive" in + *.tar.gz | *.tgz) + tar xzf "$archive" + ;; + *.tar.bz2 | *.tbz2) + tar xjf "$archive" + ;; + *.tar.xz | *.txz) + tar xJf "$archive" + ;; + *.zip) + unzip "$archive" + ;; + *) + uget::error "Unknown file type: $archive" + return 1 + esac + fi + + # pattern is explicitly meant to be interpreted by the shell + # shellcheck disable=SC2086 + mv $BINARY_PATTERN "$destinationDir/$BINARY" + chmod +x "$destinationDir/$BINARY" + fi + + cd "$startDir" + rm -rf -- "$tempDir" +} + +# ready() checks if the desired binary already exists in the desired version. +uget::ready() { + local fullFinalPath="$ABS_UGET_DIRECTORY/$BINARY" + local versionFile="$fullFinalPath.version" + + [ -f "$fullFinalPath" ] && [ -f "$versionFile" ] && [ "$VERSION" == "$(cat "$versionFile")" ] +} + +# install() downloads the binary, checks the checksum and places it in UGET_DIRECTORY. +uget::install() { + local kvString="$1" + local url="$2" + local fullFinalPath="$ABS_UGET_DIRECTORY/$BINARY" + local versionFile="$fullFinalPath.version" + + local startDir + startDir="$(pwd)" + + local tempDir + tempDir="$(uget::mktemp)" + + uget::log "Downloading $BINARY version $VERSION ..." + uget::download "$tempDir" "$kvString" "$url" + + fullBinaryPath="$tempDir/$BINARY" + uget::checksum::check "$kvString" "$fullBinaryPath" + + # if everything is fine, place the binary in its final location + mv "$fullBinaryPath" "$fullFinalPath" + echo -n "$VERSION" > "$versionFile" + + uget::log "Installed at $UGET_DIRECTORY/$BINARY." + + cd "$startDir" + rm -rf -- "$tempDir" +} + +# update() downloads the binary, updates the checksums and discards the binary. +uget::update() { + local kvString="$1" + local url="$2" + + local startDir + startDir="$(pwd)" + + local tempDir + tempDir="$(uget::mktemp)" + + uget::log " ~> $kvString" + uget::download "$tempDir" "$kvString" "$url" + + fullBinaryPath="$tempDir/$BINARY" + + local checksum + checksum="$(uget::checksum::calculate "$fullBinaryPath")" + + uget::checksum::write "$kvString" "$checksum" + + cd "$startDir" + rm -rf -- "$tempDir" +} + +############################################################################### +# General Setup Logic + +# get CLI flags +export URL_PATTERN="$1" +export BINARY="$2" +export VERSION="$3" +BINARY_PATTERN="${4:-**/$BINARY}" + +# additional per-tool configuration, which is not prefixed with UGET_ because +# it's scoped to single tools only +GO_MODULE=${GO_MODULE:-false} +UNCOMPRESSED=${UNCOMPRESSED:-false} + +# ensure target directory exists +mkdir -p "$UGET_DIRECTORY" "$UGET_TEMPDIR" + +ABS_UGET_DIRECTORY="$(realpath "$UGET_DIRECTORY")" +ABS_UGET_TEMPDIR="$(realpath "$UGET_TEMPDIR")" + +if $GO_MODULE && ! $UGET_GO_CHECKSUMS; then + UGET_CHECKSUMS="" +fi + +if uget::checksum::enabled; then + touch "$UGET_CHECKSUMS" + UGET_CHECKSUMS="$(realpath "$UGET_CHECKSUMS")" +else + if $UGET_UPDATE && $GO_MODULE; then + uget::error "Checksums are disabled for Go modules, cannot update them." + exit 1 + fi + + UGET_UPDATE=false +fi + +############################################################################### +# Main application logic + +# When in update mode, we do not download the binary for the current system +# only, but instead for all known variants based on the checksums file, +# recalculate the checksums and then discard the temporary binaries. + +if $UGET_UPDATE; then + uget::log "Updating checksums for $BINARY ..." + + # Find and process all known variants... + while read -r kvString; do + result="$(uget::url::build "$kvString")" + url="$(echo "$result" | cut -d'|' -f2)" + + # download binary into tempdir, update checksums, but then delete it again + uget::update "$kvString" "$url" + done < <(awk -F'|' "{ if (\$1 == \"$BINARY\") print \$2 }" "$UGET_CHECKSUMS") + + uget::log "All checksums were updated." +else + if ! uget::ready; then + # Replace placeholders in the URL with system-specific data, like arch or OS + result="$(uget::url::build)" + kvString="$(echo "$result" | cut -d'|' -f1)" + url="$(echo "$result" | cut -d'|' -f2)" + + # Go modules usually do not have arch/os infos in their module names, but + # the resulting binary still depends on the local system. To support checksums + # for different machines, we always assume GOARCH and GOOS are "used placeholders". + if $GO_MODULE; then + kvString="$(uget::url::setKeyInPairs "$kvString" "GOARCH" "$(go env GOARCH)")" + kvString="$(uget::url::setKeyInPairs "$kvString" "GOOS" "$(go env GOOS)")" + fi + + uget::install "$kvString" "$url" + fi + + case "$UGET_PRINT_PATH" in + absolute) echo "$ABS_UGET_DIRECTORY/$BINARY" ;; + relative) echo "$UGET_DIRECTORY/$BINARY" ;; + esac +fi From 13ae1305d9f425df47c555fd0af8a70916ba95b1 Mon Sep 17 00:00:00 2001 From: Christoph Mewes Date: Tue, 4 Nov 2025 13:31:33 +0100 Subject: [PATCH 2/4] =?UTF-8?q?update=20to=20=C2=B5get=200.2.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On-behalf-of: @SAP christoph.mewes@sap.com --- hack/uget.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/hack/uget.sh b/hack/uget.sh index 932f0280a..ef5de2489 100755 --- a/hack/uget.sh +++ b/hack/uget.sh @@ -3,7 +3,7 @@ # SPDX-FileCopyrightText: 2025 Christoph Mewes, https://codeberg.org/xrstf/uget # SPDX-License-Identifier: MIT # -# µget 0.2.1 – your friendly downloader +# µget 0.2.2 – your friendly downloader # ------------------------------------- # # µget can download software as binaries, archives or Go modules. @@ -121,7 +121,7 @@ uget::checksum::read() { local kvString="$1" if [[ -f "$UGET_CHECKSUMS" ]]; then - awk -F'|' "{ if (\$1 == \"$BINARY\" && \$2 == \"$kvString\") print \$3 }" "$UGET_CHECKSUMS" + awk -F'|' -v "binary=$BINARY" -v "kv=$kvString" '{ if ($1 == binary && $2 == kv) print $3 }' "$UGET_CHECKSUMS" fi } @@ -141,8 +141,8 @@ uget::checksum::write() { # (for better readability, do not invert the condition here); # grep will drop any empty lines awk \ - -F'|' \ - "{ if (\$1 == \"$BINARY\" && \$2 == \"$kvString\") {} else print }" \ + -F'|' -v "binary=$BINARY" -v "kv=$kvString" \ + '{ if ($1 == binary && $2 == kv) {} else print }' \ "$UGET_CHECKSUMS" | (grep . || true) > "$tempDir/checksums.txt" # add our new checksum @@ -469,7 +469,7 @@ if $UGET_UPDATE; then # download binary into tempdir, update checksums, but then delete it again uget::update "$kvString" "$url" - done < <(awk -F'|' "{ if (\$1 == \"$BINARY\") print \$2 }" "$UGET_CHECKSUMS") + done < <(awk -F'|' -v "binary=$BINARY" '{ if ($1 == binary) print $2 }' "$UGET_CHECKSUMS") uget::log "All checksums were updated." else From 9d3e521a4b3d67fd3e30939a6e5f332e9afa99b5 Mon Sep 17 00:00:00 2001 From: Christoph Mewes Date: Tue, 4 Nov 2025 14:21:27 +0100 Subject: [PATCH 3/4] fix indentation in docs On-behalf-of: @SAP christoph.mewes@sap.com --- docs/content/setup/local-setup-with-kind.md | 30 ++++++++++++--------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/docs/content/setup/local-setup-with-kind.md b/docs/content/setup/local-setup-with-kind.md index d7122baf7..548a92052 100644 --- a/docs/content/setup/local-setup-with-kind.md +++ b/docs/content/setup/local-setup-with-kind.md @@ -3,10 +3,10 @@ This guide will walk you through setting up kube-bind between two Kubernetes clusters, where * **Backend cluster**: - * Deploys dex, cert-manager and kube-bind/backend - * Provides kube-bind compatible backend for MangoDB resources + * Deploys dex, cert-manager and kube-bind/backend + * Provides kube-bind compatible backend for MangoDB resources * **App cluster**: - * Provides an application consuming MangoDBs + * Provides an application consuming MangoDBs ## Pre-requisites @@ -35,7 +35,7 @@ The provider cluster we'll prepare in this section will provide a kube-bind comp > What is MangoDB? It is just an example CRD to demonstrate kube-bind's capabilities and testing, without any workloads. See its definition in [/test/e2e/bind/fixtures/provider/crd-mangodb.yaml](/test/e2e/bind/fixtures/provider/crd-mangodb.yaml). -### Step one: create the Backend cluster +### Step 1: Create the Backend Cluster First, stash the host's external IP in a variable as we're going to use it often: @@ -68,7 +68,7 @@ EOF_BackendClusterDefinition > Note: the port mappings will become clear later on, but in general this setup is solely specific to how Kind exposes ports of its nodes on the host. Specifically, we're exposing ports from containers through NodePort services on Kind's nodes, and to make these ports available on the host we need to map them to host's ports through `extraPortMappings`. -### Step two: deploy an identity provider +### Step 2: Deploy an Identity Provider kube-bind relies on OAuth2 for securely authenticating consumer and producer clusters. There are many ways to handle that in Kubernetes, for example with [dex IDP](https://github.com/dexidp/dex). It depends on cert-manager, which we'll deploy first: @@ -132,7 +132,7 @@ helm install \ -f - ``` -### Step three: deploy the MangoDB kube-bind backend +### Step 3: Deploy the MangoDB kube-bind Backend Now we'll deploy a kube-bind--compatible backend for MangoDB. Let's start with kube-bind CRDs: @@ -147,9 +147,10 @@ kubectl apply -f test/e2e/bind/fixtures/provider/crd-mangodb.yaml ``` To set up the MangoDB backend we'll need: -* ServiceAccount and ClusterRoleBinding for kube-bind's user, -* Deployment that runs the MangoDB backend -* Service that exposes the backend's address + +* `ServiceAccount` and `ClusterRoleBinding` for kube-bind's user, +* `Deployment` that runs the MangoDB backend +* `Service` that exposes the backend's address ```sh kubectl create namespace backend @@ -203,7 +204,7 @@ replicaset.apps/mangodb-6ff44cbbf 1 1 1 100s The App cluster will consume MangoDB CRs provided by the Backend. -### Step one: create the App cluster +### Step 1: Create the App Cluster Again, let's start by stashing the host's external IP in a variable as we're going to use it often (possibly the same one as for the Backend cluster): @@ -223,7 +224,7 @@ networking: EOF_AppClusterDefinition ``` -### Binding MangoDB backend +### Step 2: Bind the MangoDB Backend Now we'll bring in MangoDB CRDs from the Backend cluster (you can run `kubectl get crds` to see there are none yet): @@ -241,11 +242,13 @@ To authenticate, visit in your browser: ``` The client is now waiting for you to visit the address similar to the one displayed in the output above. After completing the steps to create an OAuth2 token, it is then used by the kube-bind backend to pass the ServiceAccount's kubeconfig (in the Backend cluster) to the App cluster securely: + 1. on the "Log in to dex" landing page, select "Log in with Example", 2. on the "Grant Access" page, click the "Grant Access" button, 3. lastly, click "Bind" when the page displays the mangodb resource. Go back to the terminal where `kubectl bind` command was run, and you should see the following output: + ``` 🔑 Successfully authenticated to http://${BACKEND_HOST_IP}:8080/export 🔒 Created secret kube-bind/kubeconfig-x9bd5 for host https://${BACKEND_HOST_IP}:34595, namespace kube-bind-gfsqn @@ -260,7 +263,7 @@ NAME PROVIDER READY MESSAGE apiservicebinding.kube-bind.io/mangodbs.mangodb.com False Pending 0s ``` -### Step two: demo time! +### Step 3: Demo Time! Let's see if we have CRDs for the MangoDB resource: @@ -288,6 +291,7 @@ kubectl describe mangodb my-db ``` And finally, switch to the backend cluster and see that the CR is mirrored there: + ```sh $ kubectl config use-context kind-backend Switched to context "kind-backend". @@ -312,7 +316,7 @@ Spec: Events: ``` -### Step three: clean up +### Step 4: Clean up Once you're done, you may clean up the setup simply by deleting the two kind clusters: From fda1111f4d7fa591a1ef3b9b6dcbbeb1db01ccaa Mon Sep 17 00:00:00 2001 From: Christoph Mewes Date: Tue, 4 Nov 2025 16:02:44 +0100 Subject: [PATCH 4/4] make the kcp guide easier to find On-behalf-of: @SAP christoph.mewes@sap.com --- docs/content/setup/.pages | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/content/setup/.pages b/docs/content/setup/.pages index 285ade1aa..f8868992d 100644 --- a/docs/content/setup/.pages +++ b/docs/content/setup/.pages @@ -2,5 +2,6 @@ nav: - index.md - quickstart.md - local-setup-with-kind.md + - kcp-setup.md - helm.md - kubectl-plugin.md