Builder - add --platform to FROM statement

Signed-off-by: John Howard <jhoward@microsoft.com>
This commit is contained in:
John Howard 2017-10-03 15:34:33 -07:00
parent 9cae03900f
commit 7f0c2d23e1
4 changed files with 40 additions and 11 deletions

View file

@ -148,7 +148,7 @@ func (d *dispatchRequest) getImageMount(imageRefOrID string) (*imageMount, error
return d.builder.imageSources.Get(imageRefOrID, localOnly)
}
// FROM imagename[:tag | @digest] [AS build-stage-name]
// FROM [--platform=platform] imagename[:tag | @digest] [AS build-stage-name]
//
func initializeStage(d dispatchRequest, cmd *instructions.Stage) error {
d.builder.imageProber.Reset()

View file

@ -357,10 +357,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
Name string
Commands []Command
BaseName string
SourceCode string
OperatingSystem string
}
// AddCommand to the stage

View file

@ -3,6 +3,7 @@ package instructions // import "github.com/docker/docker/builder/dockerfile/inst
import (
"fmt"
"regexp"
"runtime"
"sort"
"strconv"
"strings"
@ -12,6 +13,7 @@ import (
"github.com/docker/docker/api/types/strslice"
"github.com/docker/docker/builder/dockerfile/command"
"github.com/docker/docker/builder/dockerfile/parser"
"github.com/docker/docker/pkg/system"
"github.com/pkg/errors"
)
@ -271,16 +273,31 @@ func parseFrom(req parseRequest) (*Stage, error) {
return nil, err
}
flPlatform := req.flags.AddString("platform", "")
if err := req.flags.Parse(); err != nil {
return nil, err
}
specPlatform := system.ParsePlatform(flPlatform.Value)
if specPlatform.OS == "" {
specPlatform.OS = runtime.GOOS
}
if err := system.ValidatePlatform(specPlatform); err != nil {
return nil, fmt.Errorf("invalid platform %q on FROM", flPlatform.Value)
}
if !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)
fmt.Println("JJH", specPlatform.OS)
return &Stage{
BaseName: req.args[0],
Name: stageName,
SourceCode: code,
Commands: []Command{},
BaseName: req.args[0],
Name: stageName,
SourceCode: code,
Commands: []Command{},
OperatingSystem: specPlatform.OS,
}, nil
}

View file

@ -1,6 +1,8 @@
package instructions // import "github.com/docker/docker/builder/dockerfile/instructions"
import (
"fmt"
"runtime"
"strings"
"testing"
@ -184,6 +186,16 @@ 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)
@ -196,5 +208,4 @@ func TestErrorCases(t *testing.T) {
_, err = ParseInstruction(n)
testutil.ErrorContains(t, err, c.expectedError)
}
}