Skip to content

Commit fe7b4d8

Browse files
author
John Howard
committed
LCOW: Set correct default shell for platform in builder
Signed-off-by: John Howard <jhoward@microsoft.com>
1 parent d82e26a commit fe7b4d8

File tree

6 files changed

+26
-18
lines changed

6 files changed

+26
-18
lines changed

builder/dockerfile/builder_unix.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,6 @@
22

33
package dockerfile
44

5-
var defaultShell = []string{"/bin/sh", "-c"}
5+
func defaultShellForPlatform(platform string) []string {
6+
return []string{"/bin/sh", "-c"}
7+
}
Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
11
package dockerfile
22

3-
var defaultShell = []string{"cmd", "/S", "/C"}
3+
func defaultShellForPlatform(platform string) []string {
4+
if platform == "linux" {
5+
return []string{"/bin/sh", "-c"}
6+
}
7+
return []string{"cmd", "/S", "/C"}
8+
}

builder/dockerfile/dispatchers.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ func workdir(req dispatchRequest) error {
399399
}
400400

401401
comment := "WORKDIR " + runConfig.WorkingDir
402-
runConfigWithCommentCmd := copyRunConfig(runConfig, withCmdCommentString(comment))
402+
runConfigWithCommentCmd := copyRunConfig(runConfig, withCmdCommentString(comment, req.builder.platform))
403403
containerID, err := req.builder.probeAndCreate(req.state, runConfigWithCommentCmd)
404404
if err != nil || containerID == "" {
405405
return err
@@ -417,7 +417,7 @@ func workdir(req dispatchRequest) error {
417417
// the current SHELL which defaults to 'sh -c' under linux or 'cmd /S /C' under
418418
// Windows, in the event there is only one argument The difference in processing:
419419
//
420-
// RUN echo hi # sh -c echo hi (Linux)
420+
// RUN echo hi # sh -c echo hi (Linux and LCOW)
421421
// RUN echo hi # cmd /S /C echo hi (Windows)
422422
// RUN [ "echo", "hi" ] # echo hi
423423
//
@@ -433,7 +433,7 @@ func run(req dispatchRequest) error {
433433
stateRunConfig := req.state.runConfig
434434
args := handleJSONArgs(req.args, req.attributes)
435435
if !req.attributes["json"] {
436-
args = append(getShell(stateRunConfig), args...)
436+
args = append(getShell(stateRunConfig, req.builder.platform), args...)
437437
}
438438
cmdFromArgs := strslice.StrSlice(args)
439439
buildArgs := req.builder.buildArgs.FilterAllowed(stateRunConfig.Env)
@@ -518,7 +518,7 @@ func cmd(req dispatchRequest) error {
518518
runConfig := req.state.runConfig
519519
cmdSlice := handleJSONArgs(req.args, req.attributes)
520520
if !req.attributes["json"] {
521-
cmdSlice = append(getShell(runConfig), cmdSlice...)
521+
cmdSlice = append(getShell(runConfig, req.builder.platform), cmdSlice...)
522522
}
523523

524524
runConfig.Cmd = strslice.StrSlice(cmdSlice)
@@ -670,7 +670,7 @@ func entrypoint(req dispatchRequest) error {
670670
runConfig.Entrypoint = nil
671671
default:
672672
// ENTRYPOINT echo hi
673-
runConfig.Entrypoint = strslice.StrSlice(append(getShell(runConfig), parsed[0]))
673+
runConfig.Entrypoint = strslice.StrSlice(append(getShell(runConfig, req.builder.platform), parsed[0]))
674674
}
675675

676676
// when setting the entrypoint if a CMD was not explicitly set then

builder/dockerfile/dispatchers_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,7 @@ func TestRunWithBuildArgs(t *testing.T) {
474474

475475
runConfig := &container.Config{}
476476
origCmd := strslice.StrSlice([]string{"cmd", "in", "from", "image"})
477-
cmdWithShell := strslice.StrSlice(append(getShell(runConfig), "echo foo"))
477+
cmdWithShell := strslice.StrSlice(append(getShell(runConfig, runtime.GOOS), "echo foo"))
478478
envVars := []string{"|1", "one=two"}
479479
cachedCmd := strslice.StrSlice(append(envVars, cmdWithShell...))
480480

builder/dockerfile/internals.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ func (b *Builder) commit(dispatchState *dispatchState, comment string) error {
2525
return errors.New("Please provide a source image with `from` prior to commit")
2626
}
2727

28-
runConfigWithCommentCmd := copyRunConfig(dispatchState.runConfig, withCmdComment(comment))
28+
runConfigWithCommentCmd := copyRunConfig(dispatchState.runConfig, withCmdComment(comment, b.platform))
2929
hit, err := b.probeCache(dispatchState, runConfigWithCommentCmd)
3030
if err != nil || hit {
3131
return err
@@ -110,7 +110,7 @@ func (b *Builder) performCopy(state *dispatchState, inst copyInstruction) error
110110
// TODO: should this have been using origPaths instead of srcHash in the comment?
111111
runConfigWithCommentCmd := copyRunConfig(
112112
state.runConfig,
113-
withCmdCommentString(fmt.Sprintf("%s %s in %s ", inst.cmdName, srcHash, inst.dest)))
113+
withCmdCommentString(fmt.Sprintf("%s %s in %s ", inst.cmdName, srcHash, inst.dest), b.platform))
114114
hit, err := b.probeCache(state, runConfigWithCommentCmd)
115115
if err != nil || hit {
116116
return err
@@ -190,19 +190,19 @@ func withCmd(cmd []string) runConfigModifier {
190190

191191
// withCmdComment sets Cmd to a nop comment string. See withCmdCommentString for
192192
// why there are two almost identical versions of this.
193-
func withCmdComment(comment string) runConfigModifier {
193+
func withCmdComment(comment string, platform string) runConfigModifier {
194194
return func(runConfig *container.Config) {
195-
runConfig.Cmd = append(getShell(runConfig), "#(nop) ", comment)
195+
runConfig.Cmd = append(getShell(runConfig, platform), "#(nop) ", comment)
196196
}
197197
}
198198

199199
// withCmdCommentString exists to maintain compatibility with older versions.
200200
// A few instructions (workdir, copy, add) used a nop comment that is a single arg
201201
// where as all the other instructions used a two arg comment string. This
202202
// function implements the single arg version.
203-
func withCmdCommentString(comment string) runConfigModifier {
203+
func withCmdCommentString(comment string, platform string) runConfigModifier {
204204
return func(runConfig *container.Config) {
205-
runConfig.Cmd = append(getShell(runConfig), "#(nop) "+comment)
205+
runConfig.Cmd = append(getShell(runConfig, platform), "#(nop) "+comment)
206206
}
207207
}
208208

@@ -229,9 +229,9 @@ func withEntrypointOverride(cmd []string, entrypoint []string) runConfigModifier
229229

230230
// getShell is a helper function which gets the right shell for prefixing the
231231
// shell-form of RUN, ENTRYPOINT and CMD instructions
232-
func getShell(c *container.Config) []string {
232+
func getShell(c *container.Config, platform string) []string {
233233
if 0 == len(c.Shell) {
234-
return append([]string{}, defaultShell[:]...)
234+
return append([]string{}, defaultShellForPlatform(platform)[:]...)
235235
}
236236
return append([]string{}, c.Shell[:]...)
237237
}

builder/dockerfile/internals_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package dockerfile
22

33
import (
44
"fmt"
5+
"runtime"
56
"testing"
67

78
"github.com/docker/docker/api/types"
@@ -97,9 +98,9 @@ func TestCopyRunConfig(t *testing.T) {
9798
},
9899
{
99100
doc: "Set the command to a comment",
100-
modifiers: []runConfigModifier{withCmdComment("comment")},
101+
modifiers: []runConfigModifier{withCmdComment("comment", runtime.GOOS)},
101102
expected: &container.Config{
102-
Cmd: append(defaultShell, "#(nop) ", "comment"),
103+
Cmd: append(defaultShellForPlatform(runtime.GOOS), "#(nop) ", "comment"),
103104
Env: defaultEnv,
104105
},
105106
},

0 commit comments

Comments
 (0)