1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Builder: Review feedback

Signed-off-by: John Howard <jhoward@microsoft.com>
This commit is contained in:
John Howard 2018-02-23 13:03:49 -08:00
parent 317513d698
commit 14429056d3
4 changed files with 31 additions and 52 deletions

View file

@ -152,7 +152,10 @@ func (d *dispatchRequest) getImageMount(imageRefOrID string) (*imageMount, error
//
func initializeStage(d dispatchRequest, cmd *instructions.Stage) error {
d.builder.imageProber.Reset()
image, err := d.getFromImage(d.shlex, cmd.BaseName, cmd.OperatingSystem)
if err := system.ValidatePlatform(&cmd.Platform); err != nil {
return err
}
image, err := d.getFromImage(d.shlex, cmd.BaseName, cmd.Platform.OS)
if err != nil {
return err
}
@ -215,32 +218,29 @@ func (d *dispatchRequest) getExpandedImageName(shlex *shell.Lex, name string) (s
// stagePlatform contains the value supplied by optional `--platform=` on
// a current FROM statement. b.builder.options.Platform contains the operating
// system part of the optional flag passed in the API call (or CLI flag
// through `docker build --platform=...`).
func (d *dispatchRequest) getOsFromFlagsAndStage(stagePlatform string) string {
osForPull := ""
// First, take the API platform if nothing provided on FROM
if stagePlatform == "" && d.builder.options.Platform != "" {
osForPull = d.builder.options.Platform
// through `docker build --platform=...`). Precedence is for an explicit
// platform indication in the FROM statement.
func (d *dispatchRequest) getOsFromFlagsAndStage(stageOS string) string {
switch {
case stageOS != "":
return stageOS
case d.builder.options.Platform != "":
// Note this is API "platform", but by this point, as the daemon is not
// multi-arch aware yet, it is guaranteed to only hold the OS part here.
return d.builder.options.Platform
default:
return runtime.GOOS
}
// Next, use the FROM flag if that was provided
if osForPull == "" && stagePlatform != "" {
osForPull = stagePlatform
}
// Finally, assume the host OS
if osForPull == "" {
osForPull = runtime.GOOS
}
return osForPull
}
func (d *dispatchRequest) getImageOrStage(name string, stagePlatform string) (builder.Image, error) {
func (d *dispatchRequest) getImageOrStage(name string, stageOS string) (builder.Image, error) {
var localOnly bool
if im, ok := d.stages.getByName(name); ok {
name = im.Image
localOnly = true
}
os := d.getOsFromFlagsAndStage(stagePlatform)
os := d.getOsFromFlagsAndStage(stageOS)
// Windows cannot support a container with no base image unless it is LCOW.
if name == api.NoBaseImageSpecifier {
@ -267,12 +267,12 @@ func (d *dispatchRequest) getImageOrStage(name string, stagePlatform string) (bu
}
return imageMount.Image(), nil
}
func (d *dispatchRequest) getFromImage(shlex *shell.Lex, name string, stagePlatform string) (builder.Image, error) {
func (d *dispatchRequest) getFromImage(shlex *shell.Lex, name string, stageOS string) (builder.Image, error) {
name, err := d.getExpandedImageName(shlex, name)
if err != nil {
return nil, err
}
return d.getImageOrStage(name, stagePlatform)
return d.getImageOrStage(name, stageOS)
}
func dispatchOnbuild(d dispatchRequest, c *instructions.OnbuildCommand) error {

View file

@ -7,6 +7,7 @@ import (
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/strslice"
specs "github.com/opencontainers/image-spec/specs-go/v1"
)
// KeyValuePair represent an arbitrary named value (useful in slice instead of map[string] string to preserve ordering)
@ -357,11 +358,11 @@ type ShellCommand struct {
// Stage represents a single stage in a multi-stage build
type Stage struct {
Name string
Commands []Command
BaseName string
SourceCode string
OperatingSystem string
Name string
Commands []Command
BaseName string
SourceCode string
Platform specs.Platform
}
// AddCommand to the stage

View file

@ -276,23 +276,13 @@ func parseFrom(req parseRequest) (*Stage, error) {
if err := req.flags.Parse(); err != nil {
return nil, err
}
specPlatform := system.ParsePlatform(flPlatform.Value)
if err := system.ValidatePlatform(specPlatform); err != nil {
return nil, fmt.Errorf("invalid platform %q on FROM", flPlatform.Value)
}
if specPlatform.OS != "" && !system.IsOSSupported(specPlatform.OS) {
return nil, fmt.Errorf("unsupported platform %q on FROM", flPlatform.Value)
}
if err != nil {
return nil, err
}
code := strings.TrimSpace(req.original)
return &Stage{
BaseName: req.args[0],
Name: stageName,
SourceCode: code,
Commands: []Command{},
OperatingSystem: specPlatform.OS,
BaseName: req.args[0],
Name: stageName,
SourceCode: code,
Commands: []Command{},
Platform: *system.ParsePlatform(flPlatform.Value),
}, nil
}

View file

@ -1,8 +1,6 @@
package instructions // import "github.com/docker/docker/builder/dockerfile/instructions"
import (
"fmt"
"runtime"
"strings"
"testing"
@ -186,16 +184,6 @@ func TestErrorCases(t *testing.T) {
dockerfile: `foo bar`,
expectedError: "unknown instruction: FOO",
},
{
name: "Invalid platform",
dockerfile: `FROM --platform=invalid busybox`,
expectedError: `invalid platform "invalid"`,
},
{
name: "Only OS",
dockerfile: fmt.Sprintf(`FROM --platform=%s/%s busybox`, runtime.GOOS, runtime.GOARCH),
expectedError: `invalid platform`,
},
}
for _, c := range cases {
r := strings.NewReader(c.dockerfile)