Преглед на файлове

Merge pull request #29624 from yongtang/29619-build-label-order

Sort the labels passed from `build --labels`
Tõnis Tiigi преди 8 години
родител
ревизия
aacc2c8880
променени са 2 файла, в които са добавени 79 реда и са изтрити 10 реда
  1. 25 10
      builder/dockerfile/builder.go
  2. 54 0
      builder/dockerfile/builder_test.go

+ 25 - 10
builder/dockerfile/builder.go

@@ -7,6 +7,7 @@ import (
 	"io"
 	"io/ioutil"
 	"os"
+	"sort"
 	"strings"
 
 	"github.com/Sirupsen/logrus"
@@ -203,6 +204,28 @@ func sanitizeRepoAndTags(names []string) ([]reference.Named, error) {
 	return repoAndTags, nil
 }
 
+func (b *Builder) processLabels() error {
+	if len(b.options.Labels) == 0 {
+		return nil
+	}
+
+	var labels []string
+	for k, v := range b.options.Labels {
+		labels = append(labels, fmt.Sprintf("%q='%s'", k, v))
+	}
+	// Sort the label to have a repeatable order
+	sort.Strings(labels)
+
+	line := "LABEL " + strings.Join(labels, " ")
+	_, node, err := parser.ParseLine(line, &b.directive, false)
+	if err != nil {
+		return err
+	}
+	b.dockerfile.Children = append(b.dockerfile.Children, node)
+
+	return nil
+}
+
 // build runs the Dockerfile builder from a context and a docker object that allows to make calls
 // to Docker.
 //
@@ -233,16 +256,8 @@ func (b *Builder) build(stdout io.Writer, stderr io.Writer, out io.Writer) (stri
 		return "", err
 	}
 
-	if len(b.options.Labels) > 0 {
-		line := "LABEL "
-		for k, v := range b.options.Labels {
-			line += fmt.Sprintf("%q='%s' ", k, v)
-		}
-		_, node, err := parser.ParseLine(line, &b.directive, false)
-		if err != nil {
-			return "", err
-		}
-		b.dockerfile.Children = append(b.dockerfile.Children, node)
+	if err := b.processLabels(); err != nil {
+		return "", err
 	}
 
 	var shortImgID string

+ 54 - 0
builder/dockerfile/builder_test.go

@@ -0,0 +1,54 @@
+package dockerfile
+
+import (
+	"strings"
+
+	"testing"
+
+	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/api/types/container"
+	"github.com/docker/docker/builder/dockerfile/parser"
+)
+
+func TestBuildProcessLabels(t *testing.T) {
+	dockerfile := "FROM scratch"
+	d := parser.Directive{}
+	parser.SetEscapeToken(parser.DefaultEscapeToken, &d)
+	n, err := parser.Parse(strings.NewReader(dockerfile), &d)
+	if err != nil {
+		t.Fatalf("Error when parsing Dockerfile: %s", err)
+	}
+
+	options := &types.ImageBuildOptions{
+		Labels: map[string]string{
+			"org.e": "cli-e",
+			"org.d": "cli-d",
+			"org.c": "cli-c",
+			"org.b": "cli-b",
+			"org.a": "cli-a",
+		},
+	}
+	b := &Builder{
+		runConfig:  &container.Config{},
+		options:    options,
+		directive:  d,
+		dockerfile: n,
+	}
+	err = b.processLabels()
+	if err != nil {
+		t.Fatalf("Error when processing labels: %s", err)
+	}
+
+	expected := []string{
+		"FROM scratch",
+		`LABEL "org.a"='cli-a' "org.b"='cli-b' "org.c"='cli-c' "org.d"='cli-d' "org.e"='cli-e'`,
+	}
+	if len(b.dockerfile.Children) != 2 {
+		t.Fatalf("Expect 2, got %d", len(b.dockerfile.Children))
+	}
+	for i, v := range b.dockerfile.Children {
+		if v.Original != expected[i] {
+			t.Fatalf("Expect '%s' for %dth children, got, '%s'", expected[i], i, v.Original)
+		}
+	}
+}