From a50ec832942c9b4689c27d231b5a60ee8600b6ed Mon Sep 17 00:00:00 2001 From: Claudio Netto Date: Thu, 29 Jun 2023 20:11:01 -0300 Subject: [PATCH] fix(buildkit): return the image's exposed ports in ascending order --- pkg/build/buildkit/build.go | 7 +------ pkg/build/buildkit/build_test.go | 30 ++++++++++++++++++++++++++++++ pkg/build/helpers.go | 29 +++++++++++++++++++++++++++++ pkg/build/helpers_test.go | 25 +++++++++++++++++++++++++ 4 files changed, 85 insertions(+), 6 deletions(-) diff --git a/pkg/build/buildkit/build.go b/pkg/build/buildkit/build.go index fd7433b..5e4ad3c 100644 --- a/pkg/build/buildkit/build.go +++ b/pkg/build/buildkit/build.go @@ -271,16 +271,11 @@ func extractContainerImageConfigFromImageManifest(ctx context.Context, imageStr return nil, err } - var exposedPorts []string - for k := range cf.Config.ExposedPorts { - exposedPorts = append(exposedPorts, k) - } - return &pb.ContainerImageConfig{ Entrypoint: cf.Config.Entrypoint, Cmd: cf.Config.Cmd, WorkingDir: cf.Config.WorkingDir, - ExposedPorts: exposedPorts, + ExposedPorts: build.SortExposedPorts(cf.Config.ExposedPorts), }, nil } diff --git a/pkg/build/buildkit/build_test.go b/pkg/build/buildkit/build_test.go index c8ae055..a5c8923 100644 --- a/pkg/build/buildkit/build_test.go +++ b/pkg/build/buildkit/build_test.go @@ -619,6 +619,36 @@ EXPOSE 8888/tcp }, }, appFiles) }) + + t.Run("multiple exposed ports, should ensure the ascending order of ports", func(t *testing.T) { + destImage := baseRegistry(t, "my-app", "") + + dockerfile := `FROM busybox + +EXPOSE 100/udp 53/udp 443/udp +EXPOSE 8080/tcp 80/tcp 8000/tcp 9090 8888 +` + req := &pb.BuildRequest{ + Kind: pb.BuildKind_BUILD_KIND_APP_BUILD_WITH_CONTAINER_FILE, + App: &pb.TsuruApp{ + Name: "my-app", + }, + DestinationImages: []string{destImage}, + Containerfile: string(dockerfile), + PushOptions: &pb.PushOptions{ + InsecureRegistry: registryHTTP, + }, + } + + appFiles, err := NewBuildKit(bc, BuildKitOptions{TempDir: t.TempDir()}).Build(context.TODO(), req, os.Stdout) + require.NoError(t, err) + assert.Equal(t, &pb.TsuruConfig{ + ImageConfig: &pb.ContainerImageConfig{ + Cmd: []string{"sh"}, + ExposedPorts: []string{"53/udp", "80/tcp", "100/udp", "443/udp", "8000/tcp", "8080/tcp", "8888/tcp", "9090/tcp"}, + }, + }, appFiles) + }) } func compressGZIP(t *testing.T, path string) []byte { diff --git a/pkg/build/helpers.go b/pkg/build/helpers.go index a7a7265..3527781 100644 --- a/pkg/build/helpers.go +++ b/pkg/build/helpers.go @@ -13,6 +13,9 @@ import ( "fmt" "io" "path/filepath" + "sort" + "strconv" + "strings" "sync" "text/template" @@ -264,3 +267,29 @@ func (w *BuildResponseOutputWriter) Fd() uintptr { // required to implement cons func (w *BuildResponseOutputWriter) Name() string { // required to implement console.File return "" } + +func SortExposedPorts(ports map[string]struct{}) []string { + var ps []string + for p := range ports { + ps = append(ps, p) + } + + sort.Slice(ps, func(i, j int) bool { + a, b := ps[i], ps[j] + + // Example of exposed port: "8080/tcp" + portAStr, protoAStr, _ := strings.Cut(a, "/") + portBStr, protoBStr, _ := strings.Cut(b, "/") + + portA, _ := strconv.Atoi(portAStr) + portB, _ := strconv.Atoi(portBStr) + + if portA == portB { + return protoAStr < protoBStr + } + + return portA < portB + }) + + return ps +} diff --git a/pkg/build/helpers_test.go b/pkg/build/helpers_test.go index 3bd5d5b..661272c 100644 --- a/pkg/build/helpers_test.go +++ b/pkg/build/helpers_test.go @@ -410,3 +410,28 @@ RUN --mount=type=secret,id=tsuru-app-envvars,target=/var/run/secrets/envs.sh,uid }) } } + +func TestSortExposedPorts(t *testing.T) { + t.Parallel() + + tests := []struct { + ports map[string]struct{} + expected []string + }{ + {}, + { + ports: map[string]struct{}{"8888/tcp": {}}, + expected: []string{"8888/tcp"}, + }, + { + ports: map[string]struct{}{"8888/tcp": {}, "80/tcp": {}, "53/udp": {}, "80/udp": {}, "8000/tcp": {}}, + expected: []string{"53/udp", "80/tcp", "80/udp", "8000/tcp", "8888/tcp"}, + }, + } + + for _, tt := range tests { + t.Run("", func(t *testing.T) { + assert.Equal(t, tt.expected, SortExposedPorts(tt.ports)) + }) + } +}