فهرست منبع

builder: Fix entrypoint and cmd semantics in evaluator. Test c/o @cnf

Docker-DCO-1.1-Signed-off-by: Erik Hollensbe <github@hollensbe.org> (github: erikh)
Erik Hollensbe 11 سال پیش
والد
کامیت
ac107995ae
5فایلهای تغییر یافته به همراه52 افزوده شده و 6 حذف شده
  1. 19 3
      builder/dispatchers.go
  2. 1 1
      builder/evaluator.go
  3. 5 0
      builder/internals.go
  4. 5 1
      builder/support.go
  5. 22 1
      integration-cli/docker_cli_build_test.go

+ 19 - 3
builder/dispatchers.go

@@ -168,11 +168,17 @@ func workdir(b *Builder, args []string, attributes map[string]bool) error {
 func run(b *Builder, args []string, attributes map[string]bool) error {
 func run(b *Builder, args []string, attributes map[string]bool) error {
 	args = handleJsonArgs(args, attributes)
 	args = handleJsonArgs(args, attributes)
 
 
+	if len(args) == 1 {
+		args = append([]string{"/bin/sh", "-c"}, args[0])
+	}
+
+	args = append([]string{b.image}, args...)
+
 	if b.image == "" {
 	if b.image == "" {
 		return fmt.Errorf("Please provide a source image with `from` prior to run")
 		return fmt.Errorf("Please provide a source image with `from` prior to run")
 	}
 	}
 
 
-	config, _, _, err := runconfig.Parse(append([]string{b.image}, args...), nil)
+	config, _, _, err := runconfig.Parse(args, nil)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -223,11 +229,18 @@ func run(b *Builder, args []string, attributes map[string]bool) error {
 func cmd(b *Builder, args []string, attributes map[string]bool) error {
 func cmd(b *Builder, args []string, attributes map[string]bool) error {
 	b.Config.Cmd = handleJsonArgs(args, attributes)
 	b.Config.Cmd = handleJsonArgs(args, attributes)
 
 
+	if !attributes["json"] && len(b.Config.Entrypoint) == 0 {
+		b.Config.Entrypoint = []string{"/bin/sh", "-c"}
+	}
+
 	if err := b.commit("", b.Config.Cmd, fmt.Sprintf("CMD %v", b.Config.Cmd)); err != nil {
 	if err := b.commit("", b.Config.Cmd, fmt.Sprintf("CMD %v", b.Config.Cmd)); err != nil {
 		return err
 		return err
 	}
 	}
 
 
-	b.cmdSet = true
+	if len(args) != 0 {
+		b.cmdSet = true
+	}
+
 	return nil
 	return nil
 }
 }
 
 
@@ -242,7 +255,10 @@ func cmd(b *Builder, args []string, attributes map[string]bool) error {
 func entrypoint(b *Builder, args []string, attributes map[string]bool) error {
 func entrypoint(b *Builder, args []string, attributes map[string]bool) error {
 	b.Config.Entrypoint = handleJsonArgs(args, attributes)
 	b.Config.Entrypoint = handleJsonArgs(args, attributes)
 
 
-	// if there is no cmd in current Dockerfile - cleanup cmd
+	if len(b.Config.Entrypoint) == 0 {
+		b.Config.Entrypoint = []string{"/bin/sh", "-c"}
+	}
+
 	if !b.cmdSet {
 	if !b.cmdSet {
 		b.Config.Cmd = nil
 		b.Config.Cmd = nil
 	}
 	}

+ 1 - 1
builder/evaluator.go

@@ -144,7 +144,7 @@ func (b *Builder) Run(context io.Reader) (string, error) {
 	b.dockerfile = ast
 	b.dockerfile = ast
 
 
 	// some initializations that would not have been supplied by the caller.
 	// some initializations that would not have been supplied by the caller.
-	b.Config = &runconfig.Config{}
+	b.Config = &runconfig.Config{Entrypoint: []string{}, Cmd: []string{"/bin/sh", "-c"}, Env: []string{"PATH=" + daemon.DefaultPathEnv}}
 	b.TmpContainers = map[string]struct{}{}
 	b.TmpContainers = map[string]struct{}{}
 
 
 	for i, n := range b.dockerfile.Children {
 	for i, n := range b.dockerfile.Children {

+ 5 - 0
builder/internals.go

@@ -89,6 +89,11 @@ func (b *Builder) commit(id string, autoCmd []string, comment string) error {
 	// Note: Actually copy the struct
 	// Note: Actually copy the struct
 	autoConfig := *b.Config
 	autoConfig := *b.Config
 	autoConfig.Cmd = autoCmd
 	autoConfig.Cmd = autoCmd
+
+	if autoConfig.Entrypoint == nil {
+		autoConfig.Entrypoint = []string{"/bin/sh", "-c"}
+	}
+
 	// Commit the container
 	// Commit the container
 	image, err := b.Daemon.Commit(container, "", "", "", b.maintainer, true, &autoConfig)
 	image, err := b.Daemon.Commit(container, "", "", "", b.maintainer, true, &autoConfig)
 	if err != nil {
 	if err != nil {

+ 5 - 1
builder/support.go

@@ -28,10 +28,14 @@ func (b *Builder) replaceEnv(str string) string {
 }
 }
 
 
 func handleJsonArgs(args []string, attributes map[string]bool) []string {
 func handleJsonArgs(args []string, attributes map[string]bool) []string {
+	if len(args) == 0 {
+		return []string{}
+	}
+
 	if attributes != nil && attributes["json"] {
 	if attributes != nil && attributes["json"] {
 		return args
 		return args
 	}
 	}
 
 
 	// literal string command, not an exec array
 	// literal string command, not an exec array
-	return append([]string{"/bin/sh", "-c", strings.Join(args, " ")})
+	return []string{strings.Join(args, " ")}
 }
 }

+ 22 - 1
integration-cli/docker_cli_build_test.go

@@ -1184,7 +1184,7 @@ func TestContextTarNoCompression(t *testing.T) {
 	testContextTar(t, archive.Uncompressed)
 	testContextTar(t, archive.Uncompressed)
 }
 }
 
 
-func TestNoContext(t *testing.T) {
+func TestBuildNoContext(t *testing.T) {
 	buildCmd := exec.Command(dockerBinary, "build", "-t", "nocontext", "-")
 	buildCmd := exec.Command(dockerBinary, "build", "-t", "nocontext", "-")
 	buildCmd.Stdin = strings.NewReader("FROM busybox\nCMD echo ok\n")
 	buildCmd.Stdin = strings.NewReader("FROM busybox\nCMD echo ok\n")
 
 
@@ -1899,3 +1899,24 @@ func TestBuildCleanupCmdOnEntrypoint(t *testing.T) {
 	}
 	}
 	logDone("build - cleanup cmd on ENTRYPOINT")
 	logDone("build - cleanup cmd on ENTRYPOINT")
 }
 }
+
+func TestBuildClearCmd(t *testing.T) {
+	name := "testbuildclearcmd"
+	defer deleteImages(name)
+	_, err := buildImage(name,
+		`From scratch
+   ENTRYPOINT ["/bin/bash"]
+   CMD []`,
+		true)
+	if err != nil {
+		t.Fatal(err)
+	}
+	res, err := inspectFieldJSON(name, "Config.Cmd")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if res != "[]" {
+		t.Fatalf("Cmd %s, expected %s", res, "[]")
+	}
+	logDone("build - clearcmd")
+}