-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix Windows args and ArgsEscaped
handling
#4723
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1662,7 +1662,16 @@ func dispatchCmd(d *dispatchState, c *instructions.CmdCommand, lint *linter.Lint | |
args = withShell(d.image, args) | ||
} | ||
d.image.Config.Cmd = args | ||
d.image.Config.ArgsEscaped = true //nolint:staticcheck // ignore SA1019: field is deprecated in OCI Image spec, but used for backward-compatibility with Docker image spec. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: does moving this into the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, it absolutely does -- that was the original intent of my looking into this in the first place. In short, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The For example, if we have CMD ["\"c:\\Path to\\Some\\application.exe\" "some space delimited arg" someOtherArg"] And that gets passed along to I think this change is okay, as long as we just log the inconsistency in place of that TODO, similarly to what happens in moby now. |
||
if d.image.OS == "windows" { | ||
argsEscaped := c.PrependShell | ||
// We warn here as Windows shell processing operates differently to Linux. | ||
// Linux: /bin/sh -c "echo hello" world --> hello | ||
// Windows: cmd /s /c "echo hello" world --> hello world | ||
if d.image.Config.ArgsEscaped != argsEscaped && len(d.image.Config.Entrypoint) > 0 { | ||
// TODO error or warning about mixing CMD and ENTRYPOINT having unexpected results: https://github.com/moby/moby/blob/b8aa8579cad7b9c8712327093cbc602cfb6b417f/builder/dockerfile/dispatchers.go#L443 | ||
} | ||
d.image.Config.ArgsEscaped = argsEscaped //nolint:staticcheck // ignore SA1019: field is deprecated in OCI Image spec, but used for backward-compatibility with Docker image spec. | ||
} | ||
return commitToHistory(&d.image, fmt.Sprintf("CMD %q", args), false, nil, d.epoch) | ||
} | ||
|
||
|
@@ -1677,6 +1686,23 @@ func dispatchEntrypoint(d *dispatchState, c *instructions.EntrypointCommand, lin | |
} | ||
args = withShell(d.image, args) | ||
} | ||
if d.image.OS == "windows" { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: this block is repeated twice, L1390 and here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Correct -- we need separate, similar (but slightly different) handling for |
||
argsEscaped := c.PrependShell | ||
// This warning is a little more complex than in dispatchCmd(), as the Windows base images (similar | ||
// universally to almost every Linux image out there) have a single .Cmd field populated so that | ||
// `docker run --rm image` starts the default shell which would typically be sh on Linux, | ||
// or cmd on Windows. The catch to this is that if a dockerfile had `CMD ["c:\\windows\\system32\\cmd.exe"]`, | ||
// we wouldn't be able to tell the difference. However, that would be highly unlikely, and besides, this | ||
// is only trying to give a helpful warning of possibly unexpected results. | ||
if d.image.Config.ArgsEscaped != argsEscaped && | ||
(len(d.image.Config.Cmd) > 1 || | ||
(len(d.image.Config.Cmd) == 1 && | ||
strings.ToLower(d.image.Config.Cmd[0]) != `c:\windows\system32\cmd.exe` && | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: how about if the user just had There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See the comment above (and the linked original PR) -- this is just to handle the special case of the default |
||
len(d.image.Config.Shell) == 0)) { | ||
// TODO error or warning about mixing CMD and ENTRYPOINT having unexpected results: https://github.com/moby/moby/blob/b8aa8579cad7b9c8712327093cbc602cfb6b417f/builder/dockerfile/dispatchers.go#L495 | ||
} | ||
d.image.Config.ArgsEscaped = argsEscaped //nolint:staticcheck // ignore SA1019: field is deprecated in OCI Image spec, but used for backward-compatibility with Docker image spec. | ||
} | ||
d.image.Config.Entrypoint = args | ||
if !d.cmd.IsSet { | ||
d.image.Config.Cmd = nil | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On my system, with the default shell that buildkitd uses (
cmd /S /C
) this change will make the followingRUN
stanza:result in the following:
And if we use a space in the command:
results in the following error:
So escaping the args before sending them as part of the
CmdLine
, will break the default shell which is undesirable. The string in theRUN
stanza gets passed to the default shell as is, as one string. As long as the command is already escaped in the Dockerfile, it should work. See bellow.Without the change:
results in:
And:
results in:
If we replace the default shell with something more forgiving, escaping every arg does not make a difference: