dockerfile: allow automatic platform variables
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>docker-18.09
parent
33f4382b69
commit
69bb8e8a15
|
@ -58,6 +58,11 @@ func Dockerfile2LLB(ctx context.Context, dt []byte, opt ConvertOpt) (*llb.State,
|
|||
|
||||
platformOpt := buildPlatformOpt(&opt)
|
||||
|
||||
optMetaArgs := getPlatformArgs(platformOpt)
|
||||
for i, arg := range optMetaArgs {
|
||||
optMetaArgs[i] = setKVValue(arg, opt.BuildArgs)
|
||||
}
|
||||
|
||||
dockerfile, err := parser.Parse(bytes.NewReader(dt))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
|
@ -70,7 +75,6 @@ func Dockerfile2LLB(ctx context.Context, dt []byte, opt ConvertOpt) (*llb.State,
|
|||
return nil, nil, err
|
||||
}
|
||||
|
||||
optMetaArgs := []instructions.KeyValuePairOptional{}
|
||||
for _, metaArg := range metaArgs {
|
||||
optMetaArgs = append(optMetaArgs, setKVValue(metaArg.KeyValuePairOptional, opt.BuildArgs))
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package dockerfile2llb
|
|||
|
||||
import (
|
||||
"github.com/containerd/containerd/platforms"
|
||||
"github.com/moby/buildkit/frontend/dockerfile/instructions"
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
|
@ -34,3 +35,24 @@ func buildPlatformOpt(opt *ConvertOpt) *platformOpt {
|
|||
implicitTarget: implicitTargetPlatform,
|
||||
}
|
||||
}
|
||||
|
||||
func getPlatformArgs(po *platformOpt) []instructions.KeyValuePairOptional {
|
||||
bp := po.buildPlatforms[0]
|
||||
tp := po.targetPlatform
|
||||
m := map[string]string{
|
||||
"BUILDPLATFORM": platforms.Format(bp),
|
||||
"BUILDOS": bp.OS,
|
||||
"BUILDARCH": bp.Architecture,
|
||||
"BUILDVARIANT": bp.Variant,
|
||||
"TARGETPLATFORM": platforms.Format(tp),
|
||||
"TARGETOS": tp.OS,
|
||||
"TARGETARCH": tp.Architecture,
|
||||
"TARGETVARIANT": tp.Variant,
|
||||
}
|
||||
opts := make([]instructions.KeyValuePairOptional, 0, len(m))
|
||||
for k, v := range m {
|
||||
s := v
|
||||
opts = append(opts, instructions.KeyValuePairOptional{Key: k, Value: &s})
|
||||
}
|
||||
return opts
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
|
@ -69,6 +70,8 @@ func TestIntegration(t *testing.T) {
|
|||
testNoSnapshotLeak,
|
||||
testCopySymlinks,
|
||||
testContextChangeDirToFile,
|
||||
testPlatformArgsImplicit,
|
||||
testPlatformArgsExplicit,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -2281,6 +2284,106 @@ COPY --from=s1 unique2 /
|
|||
require.NotEqual(t, string(unique2Dir1), string(unique2Dir3))
|
||||
}
|
||||
|
||||
func testPlatformArgsImplicit(t *testing.T, sb integration.Sandbox) {
|
||||
t.Parallel()
|
||||
|
||||
dockerfile := []byte(fmt.Sprintf(`
|
||||
FROM scratch AS build-%s
|
||||
COPY foo bar
|
||||
FROM build-${TARGETOS}
|
||||
COPY foo2 bar2
|
||||
`, runtime.GOOS))
|
||||
|
||||
dir, err := tmpdir(
|
||||
fstest.CreateFile("Dockerfile", dockerfile, 0600),
|
||||
fstest.CreateFile("foo", []byte("d0"), 0600),
|
||||
fstest.CreateFile("foo2", []byte("d1"), 0600),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
c, err := client.New(context.TODO(), sb.Address())
|
||||
require.NoError(t, err)
|
||||
defer c.Close()
|
||||
|
||||
destDir, err := ioutil.TempDir("", "buildkit")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(destDir)
|
||||
|
||||
opt := client.SolveOpt{
|
||||
Frontend: "dockerfile.v0",
|
||||
Exporter: client.ExporterLocal,
|
||||
ExporterOutputDir: destDir,
|
||||
LocalDirs: map[string]string{
|
||||
builder.LocalNameDockerfile: dir,
|
||||
builder.LocalNameContext: dir,
|
||||
},
|
||||
}
|
||||
|
||||
_, err = c.Solve(context.TODO(), nil, opt, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
dt, err := ioutil.ReadFile(filepath.Join(destDir, "bar"))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "d0", string(dt))
|
||||
|
||||
dt, err = ioutil.ReadFile(filepath.Join(destDir, "bar2"))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "d1", string(dt))
|
||||
}
|
||||
|
||||
func testPlatformArgsExplicit(t *testing.T, sb integration.Sandbox) {
|
||||
t.Parallel()
|
||||
|
||||
dockerfile := []byte(`
|
||||
FROM --platform=$BUILDPLATFORM busybox AS build
|
||||
ARG TARGETPLATFORM
|
||||
ARG TARGETOS
|
||||
RUN mkdir /out && echo -n $TARGETPLATFORM > /out/platform && echo -n $TARGETOS > /out/os
|
||||
FROM scratch
|
||||
COPY --from=build out .
|
||||
`)
|
||||
|
||||
dir, err := tmpdir(
|
||||
fstest.CreateFile("Dockerfile", dockerfile, 0600),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
c, err := client.New(context.TODO(), sb.Address())
|
||||
require.NoError(t, err)
|
||||
defer c.Close()
|
||||
|
||||
destDir, err := ioutil.TempDir("", "buildkit")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(destDir)
|
||||
|
||||
opt := client.SolveOpt{
|
||||
Frontend: "dockerfile.v0",
|
||||
Exporter: client.ExporterLocal,
|
||||
FrontendAttrs: map[string]string{
|
||||
"platform": "darwin/ppc64le",
|
||||
"build-arg:TARGETOS": "freebsd",
|
||||
},
|
||||
ExporterOutputDir: destDir,
|
||||
LocalDirs: map[string]string{
|
||||
builder.LocalNameDockerfile: dir,
|
||||
builder.LocalNameContext: dir,
|
||||
},
|
||||
}
|
||||
|
||||
_, err = c.Solve(context.TODO(), nil, opt, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
dt, err := ioutil.ReadFile(filepath.Join(destDir, "platform"))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "darwin/ppc64le", string(dt))
|
||||
|
||||
dt, err = ioutil.ReadFile(filepath.Join(destDir, "os"))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "freebsd", string(dt))
|
||||
}
|
||||
|
||||
func testBuiltinArgs(t *testing.T, sb integration.Sandbox) {
|
||||
t.Parallel()
|
||||
|
||||
|
|
Loading…
Reference in New Issue