From be35512eb705db4ad2172082d454a3813f1e4edd Mon Sep 17 00:00:00 2001 From: yakom Date: Tue, 4 Feb 2025 21:35:42 +0100 Subject: [PATCH 1/4] fix: GOFLAGS changed so that the build process uses the vendor directory; --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index cdd8d7d6e..780112781 100644 --- a/Makefile +++ b/Makefile @@ -72,7 +72,7 @@ TESTS := ./... TESTFLAGS := LDFLAGS := -w -s -X github.com/k3d-io/k3d/v5/version.Version=${GIT_TAG} -X github.com/k3d-io/k3d/v5/version.K3sVersion=${K3S_TAG} GCFLAGS := -GOFLAGS := -mod=readonly +GOFLAGS := -mod=vendor BINDIR := $(CURDIR)/bin BINARIES := k3d From 55afaee82cdaa4fa77088136521775dc780ba1bc Mon Sep 17 00:00:00 2001 From: yakom Date: Tue, 4 Feb 2025 21:37:28 +0100 Subject: [PATCH 2/4] fix: a redundant makefile line removed, prevents local cache build-up; --- Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/Makefile b/Makefile index 780112781..80794f231 100644 --- a/Makefile +++ b/Makefile @@ -66,7 +66,6 @@ K3D_HELPER_VERSION ?= # Go options GO ?= go GOENVPATH := $(shell go env GOPATH) -PKG := $(shell go work vendor) TAGS := TESTS := ./... TESTFLAGS := From 01e7d3b23180c34fb064a50c5337ddc573c98072 Mon Sep 17 00:00:00 2001 From: yakom Date: Tue, 4 Feb 2025 21:49:10 +0100 Subject: [PATCH 3/4] feat(GH-1406): enforcing the internal registry port matching the external one. --- cmd/cluster/clusterCreate.go | 2 +- cmd/registry/registryCreate.go | 2 +- cmd/util/ports.go | 16 ++++++++++++++-- pkg/client/registry.go | 4 ++++ pkg/config/transform.go | 2 +- tests/test_registry.sh | 2 +- 6 files changed, 22 insertions(+), 6 deletions(-) diff --git a/cmd/cluster/clusterCreate.go b/cmd/cluster/clusterCreate.go index bd11b408c..335a10460 100644 --- a/cmd/cluster/clusterCreate.go +++ b/cmd/cluster/clusterCreate.go @@ -575,7 +575,7 @@ func applyCLIOverrides(cfg conf.SimpleConfig) (conf.SimpleConfig, error) { } cfg.Registries.Create.Name = fvSplit[0] if len(fvSplit) > 1 { - exposeAPI, err = cliutil.ParsePortExposureSpec(fvSplit[1], "1234") // internal port is unused after all + exposeAPI, err = cliutil.ParseRegistryPortExposureSpec(fvSplit[1]) if err != nil { return cfg, fmt.Errorf("failed to registry port spec: %w", err) } diff --git a/cmd/registry/registryCreate.go b/cmd/registry/registryCreate.go index 244e8f718..2bfc3cc8d 100644 --- a/cmd/registry/registryCreate.go +++ b/cmd/registry/registryCreate.go @@ -134,7 +134,7 @@ func parseCreateRegistryCmd(cmd *cobra.Command, args []string, flags *regCreateF } // --port - exposePort, err := cliutil.ParsePortExposureSpec(ppFlags.Port, k3d.DefaultRegistryPort) + exposePort, err := cliutil.ParseRegistryPortExposureSpec(ppFlags.Port) if err != nil { l.Log().Errorln("Failed to parse registry port") l.Log().Fatalln(err) diff --git a/cmd/util/ports.go b/cmd/util/ports.go index 74e015519..88b6976e2 100644 --- a/cmd/util/ports.go +++ b/cmd/util/ports.go @@ -36,8 +36,16 @@ import ( var apiPortRegexp = regexp.MustCompile(`^(?P(?P\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})|(?P\S+):)?(?P(\d{1,5}|random))$`) -// ParsePortExposureSpec parses/validates a string to create an exposePort struct from it func ParsePortExposureSpec(exposedPortSpec, internalPort string) (*k3d.ExposureOpts, error) { + return parsePortExposureSpec(exposedPortSpec, internalPort, false) +} + +func ParseRegistryPortExposureSpec(exposedPortSpec string) (*k3d.ExposureOpts, error) { + return parsePortExposureSpec(exposedPortSpec, k3d.DefaultRegistryPort, true) +} + +// ParsePortExposureSpec parses/validates a string to create an exposePort struct from it +func parsePortExposureSpec(exposedPortSpec, internalPort string, enforcePortMatch bool) (*k3d.ExposureOpts, error) { match := apiPortRegexp.FindStringSubmatch(exposedPortSpec) if len(match) == 0 { @@ -83,7 +91,7 @@ func ParsePortExposureSpec(exposedPortSpec, internalPort string) (*k3d.ExposureO } // port: get a free one if there's none defined or set to random - if submatches["port"] == "" || submatches["port"] == "random" { + if submatches["port"] == "random" { l.Log().Debugf("Port Exposure Mapping didn't specify hostPort, choosing one randomly...") freePort, err := GetFreePort() if err != nil || freePort == 0 { @@ -96,6 +104,10 @@ func ParsePortExposureSpec(exposedPortSpec, internalPort string) (*k3d.ExposureO } } + if enforcePortMatch { + internalPort = submatches["port"] + } + realPortString += fmt.Sprintf("%s:%s/tcp", submatches["port"], internalPort) portMapping, err := nat.ParsePortSpec(realPortString) diff --git a/pkg/client/registry.go b/pkg/client/registry.go index 54066b37d..4653e3ba1 100644 --- a/pkg/client/registry.go +++ b/pkg/client/registry.go @@ -76,6 +76,10 @@ func RegistryCreate(ctx context.Context, runtime runtimes.Runtime, reg *k3d.Regi Env: []string{}, } + if reg.ExposureOpts.Binding.HostPort != "" { + registryNode.Env = append(registryNode.Env, fmt.Sprintf("REGISTRY_HTTP_ADDR=:%s", reg.ExposureOpts.Binding.HostPort)) + } + if reg.Options.Proxy.RemoteURL != "" { registryNode.Env = append(registryNode.Env, fmt.Sprintf("REGISTRY_PROXY_REMOTEURL=%s", reg.Options.Proxy.RemoteURL)) diff --git a/pkg/config/transform.go b/pkg/config/transform.go index 969f9075a..3c8737da1 100644 --- a/pkg/config/transform.go +++ b/pkg/config/transform.go @@ -320,7 +320,7 @@ func TransformSimpleToClusterConfig(ctx context.Context, runtime runtimes.Runtim epSpecHost = simpleConfig.Registries.Create.Host } - regPort, err := cliutil.ParsePortExposureSpec(fmt.Sprintf("%s:%s", epSpecHost, epSpecPort), k3d.DefaultRegistryPort) + regPort, err := cliutil.ParseRegistryPortExposureSpec(fmt.Sprintf("%s:%s", epSpecHost, epSpecPort)) if err != nil { return nil, fmt.Errorf("failed to get port for registry: %w", err) } diff --git a/tests/test_registry.sh b/tests/test_registry.sh index 84c0926ce..04506a89d 100755 --- a/tests/test_registry.sh +++ b/tests/test_registry.sh @@ -52,7 +52,7 @@ kubectl get configmap -n kube-public local-registry-hosting -o go-template='{{in # 3. load an image into the registry info "Pushing an image to the registry..." -registryPort=$(docker inspect $registryname | jq '.[0].NetworkSettings.Ports["5000/tcp"][0].HostPort' | sed -E 's/"//g') +registryPort=$(docker inspect $registryname | jq '.[0].NetworkSettings.Ports | with_entries(select(.value | . != null)) | to_entries[0].value[0].HostPort' | sed -E 's/"//g') docker pull alpine:latest > /dev/null docker tag alpine:latest "localhost:$registryPort/alpine:local" > /dev/null docker push "localhost:$registryPort/alpine:local" || failed "Failed to push image to managed registry" From 61664d8312ad50c027198839b859d788516f1319 Mon Sep 17 00:00:00 2001 From: yakom Date: Thu, 6 Feb 2025 14:29:28 +0100 Subject: [PATCH 4/4] feat(GH-1406): added a unit test. --- cmd/util/ports_test.go | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 cmd/util/ports_test.go diff --git a/cmd/util/ports_test.go b/cmd/util/ports_test.go new file mode 100644 index 000000000..e27bd1765 --- /dev/null +++ b/cmd/util/ports_test.go @@ -0,0 +1,41 @@ +package util + +import ( + "strings" + "testing" + + "gotest.tools/assert" +) + +func Test_ParsePortExposureSpec_PortMatchEnforcement(t *testing.T) { + + r, err := ParsePortExposureSpec("9999", "1111") + if nil != err { + t.Fail() + } else { + assert.Equal(t, string(r.Port), "1111/tcp") + assert.Equal(t, string(r.Binding.HostPort), "9999") + } + + r, err = ParseRegistryPortExposureSpec("9999") + if nil != err { + t.Fail() + } else { + assert.Equal(t, string(r.Port), "9999/tcp") + assert.Equal(t, string(r.Binding.HostPort), "9999") + } + + r, err = ParsePortExposureSpec("random", "1") + if nil != err { + t.Fail() + } else { + assert.Assert(t, strings.Split(string(r.Port), "/")[0] != string(r.Binding.HostPort)) + } + + r, err = ParseRegistryPortExposureSpec("random") + if nil != err { + t.Fail() + } else { + assert.Equal(t, strings.Split(string(r.Port), "/")[0], string(r.Binding.HostPort)) + } +}