From 159f1734a9ccdacc9c092986edc1bd36e0f65975 Mon Sep 17 00:00:00 2001 From: "Daniel, Dao Quang Minh" Date: Wed, 12 Nov 2014 03:22:08 -0500 Subject: [PATCH] expose sorts its ports before saving as comment Saving ports as `map[nat.Port]struct{}` directly has ordering issue which is more replicatable where we expose a huge number of ports at the same time. As a result, the cache will be burst whenever the map order is different from the previous build. This sorts the ports first and save them as a whitespace-separated list instead of the map representation, so the order will always be consistent if the port list isnt changed. NOTICE: this will burst the old expose caches Docker-DCO-1.1-Signed-off-by: Daniel, Dao Quang Minh (github: dqminh) Upstream-commit: 87d0562c61b80aba05f4c3b4f49f5527afb55989 Component: engine --- components/engine/builder/dispatchers.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/components/engine/builder/dispatchers.go b/components/engine/builder/dispatchers.go index f2fdd35955..b138fe3031 100644 --- a/components/engine/builder/dispatchers.go +++ b/components/engine/builder/dispatchers.go @@ -12,6 +12,7 @@ import ( "io/ioutil" "path/filepath" "regexp" + "sort" "strings" log "github.com/Sirupsen/logrus" @@ -302,14 +303,21 @@ func expose(b *Builder, args []string, attributes map[string]bool, original stri return err } + // instead of using ports directly, we build a list of ports and sort it so + // the order is consistent. This prevents cache burst where map ordering + // changes between builds + portList := make([]string, len(ports)) + var i int for port := range ports { if _, exists := b.Config.ExposedPorts[port]; !exists { b.Config.ExposedPorts[port] = struct{}{} } + portList[i] = string(port) + i++ } + sort.Strings(portList) b.Config.PortSpecs = nil - - return b.commit("", b.Config.Cmd, fmt.Sprintf("EXPOSE %v", ports)) + return b.commit("", b.Config.Cmd, fmt.Sprintf("EXPOSE %s", strings.Join(portList, " "))) } // USER foo