mirror of https://github.com/docker/docs.git
Merge pull request #7806 from erikh/fix_cmd_handling_in_parser
Fix cmd and entrypoint handling in parser
This commit is contained in:
commit
08f1a91ccd
|
@ -166,13 +166,19 @@ func workdir(b *Builder, args []string, attributes map[string]bool) error {
|
||||||
// RUN [ "echo", "hi" ] # echo hi
|
// RUN [ "echo", "hi" ] # echo hi
|
||||||
//
|
//
|
||||||
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)
|
|
||||||
|
|
||||||
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)
|
args = handleJsonArgs(args, attributes)
|
||||||
|
|
||||||
|
if len(args) == 1 {
|
||||||
|
args = append([]string{"/bin/sh", "-c"}, args[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
args = append([]string{b.image}, args...)
|
||||||
|
|
||||||
|
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 err := b.commit("", b.Config.Cmd, fmt.Sprintf("CMD %v", cmd)); err != nil {
|
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 {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(args) != 0 {
|
||||||
b.cmdSet = true
|
b.cmdSet = true
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,8 +255,9 @@ 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 && len(b.Config.Cmd) == 0 {
|
||||||
if !b.cmdSet {
|
b.Config.Entrypoint = []string{"/bin/sh", "-c"}
|
||||||
|
} else if !b.cmdSet {
|
||||||
b.Config.Cmd = nil
|
b.Config.Cmd = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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"}}
|
||||||
b.TmpContainers = map[string]struct{}{}
|
b.TmpContainers = map[string]struct{}{}
|
||||||
|
|
||||||
for i, n := range b.dockerfile.Children {
|
for i, n := range b.dockerfile.Children {
|
||||||
|
|
|
@ -89,6 +89,7 @@ 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
|
||||||
|
|
||||||
// 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 {
|
||||||
|
|
|
@ -26,7 +26,7 @@ func main() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
} else {
|
} else {
|
||||||
fmt.Print(ast.Dump())
|
fmt.Println(ast.Dump())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,8 +81,10 @@ func parseLine(line string) (string, *Node, error) {
|
||||||
return "", nil, err
|
return "", nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if sexp.Value != "" || sexp.Next != nil || sexp.Children != nil {
|
||||||
node.Next = sexp
|
node.Next = sexp
|
||||||
node.Attributes = attrs
|
node.Attributes = attrs
|
||||||
|
}
|
||||||
|
|
||||||
return "", node, nil
|
return "", node, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package parser
|
package parser
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -69,7 +70,9 @@ func TestTestData(t *testing.T) {
|
||||||
t.Fatalf("Error reading %s's result file: %s", dir.Name(), err.Error())
|
t.Fatalf("Error reading %s's result file: %s", dir.Name(), err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
if ast.Dump() != string(content) {
|
if ast.Dump()+"\n" != string(content) {
|
||||||
|
fmt.Fprintln(os.Stderr, ast.Dump())
|
||||||
|
fmt.Fprintln(os.Stderr, string(content))
|
||||||
t.Fatalf("%s: AST dump of dockerfile does not match result", dir.Name())
|
t.Fatalf("%s: AST dump of dockerfile does not match result", dir.Name())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
(from "brimstone/ubuntu:14.04")
|
(from "brimstone/ubuntu:14.04")
|
||||||
(cmd "")
|
(cmd)
|
||||||
(entrypoint "/usr/bin/consul" "agent" "-server" "-data-dir=/consul" "-client=0.0.0.0" "-ui-dir=/webui")
|
(entrypoint "/usr/bin/consul" "agent" "-server" "-data-dir=/consul" "-client=0.0.0.0" "-ui-dir=/webui")
|
||||||
(expose "8500" "8600" "8400" "8301" "8302")
|
(expose "8500" "8600" "8400" "8301" "8302")
|
||||||
(run "apt-get update && apt-get install -y unzip wget && apt-get clean && rm -rf /var/lib/apt/lists")
|
(run "apt-get update && apt-get install -y unzip wget && apt-get clean && rm -rf /var/lib/apt/lists")
|
||||||
|
|
|
@ -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, " ")}
|
||||||
}
|
}
|
||||||
|
|
|
@ -773,6 +773,29 @@ func TestBuildExpose(t *testing.T) {
|
||||||
logDone("build - expose")
|
logDone("build - expose")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBuildEmptyEntrypoint(t *testing.T) {
|
||||||
|
name := "testbuildentrypoint"
|
||||||
|
defer deleteImages(name)
|
||||||
|
expected := "[]"
|
||||||
|
|
||||||
|
_, err := buildImage(name,
|
||||||
|
`FROM busybox
|
||||||
|
ENTRYPOINT []`,
|
||||||
|
true)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
res, err := inspectField(name, "Config.Entrypoint")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if res != expected {
|
||||||
|
t.Fatalf("Entrypoint %s, expected %s", res, expected)
|
||||||
|
}
|
||||||
|
|
||||||
|
logDone("build - empty entrypoint")
|
||||||
|
}
|
||||||
|
|
||||||
func TestBuildEntrypoint(t *testing.T) {
|
func TestBuildEntrypoint(t *testing.T) {
|
||||||
name := "testbuildentrypoint"
|
name := "testbuildentrypoint"
|
||||||
expected := "[/bin/echo]"
|
expected := "[/bin/echo]"
|
||||||
|
@ -791,6 +814,7 @@ func TestBuildEntrypoint(t *testing.T) {
|
||||||
if res != expected {
|
if res != expected {
|
||||||
t.Fatalf("Entrypoint %s, expected %s", res, expected)
|
t.Fatalf("Entrypoint %s, expected %s", res, expected)
|
||||||
}
|
}
|
||||||
|
|
||||||
logDone("build - entrypoint")
|
logDone("build - entrypoint")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1184,7 +1208,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 +1923,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")
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue