From 280c008f815dbef8eaeeb70aaa230611dd804710 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Wed, 23 Feb 2022 23:09:46 -0800 Subject: [PATCH] bake: make named contexts relative to remote bake input Signed-off-by: Tonis Tiigi --- bake/bake.go | 30 +++++++++++++++++++++++++++++- bake/bake_test.go | 12 ++++++------ build/build.go | 24 +++++++++++++++++++----- commands/build.go | 6 +++--- 4 files changed, 57 insertions(+), 15 deletions(-) diff --git a/bake/bake.go b/bake/bake.go index 114cc3a8..e703860e 100644 --- a/bake/bake.go +++ b/bake/bake.go @@ -715,6 +715,21 @@ func updateContext(t *build.Inputs, inp *Input) { if inp == nil || inp.State == nil { return } + + for k, v := range t.NamedContexts { + if v.Path == "." { + t.NamedContexts[k] = build.NamedContext{Path: inp.URL} + } + if strings.HasPrefix(v.Path, "cwd://") || strings.HasPrefix(v.Path, "target:") || strings.HasPrefix(v.Path, "docker-image:") { + continue + } + if IsRemoteURL(v.Path) { + continue + } + st := llb.Scratch().File(llb.Copy(*inp.State, v.Path, "/"), llb.WithCustomNamef("set context %s to %s", k, v.Path)) + t.NamedContexts[k] = build.NamedContext{State: &st} + } + if t.ContextPath == "." { t.ContextPath = inp.URL return @@ -769,7 +784,7 @@ func toBuildOpt(t *Target, inp *Input) (*build.Options, error) { bi := build.Inputs{ ContextPath: contextPath, DockerfilePath: dockerfilePath, - NamedContexts: t.Contexts, + NamedContexts: toNamedContexts(t.Contexts), } if t.DockerfileInline != nil { bi.DockerfileInline = *t.DockerfileInline @@ -778,6 +793,11 @@ func toBuildOpt(t *Target, inp *Input) (*build.Options, error) { if strings.HasPrefix(bi.ContextPath, "cwd://") { bi.ContextPath = path.Clean(strings.TrimPrefix(bi.ContextPath, "cwd://")) } + for k, v := range bi.NamedContexts { + if strings.HasPrefix(v.Path, "cwd://") { + bi.NamedContexts[k] = build.NamedContext{Path: path.Clean(strings.TrimPrefix(v.Path, "cwd://"))} + } + } t.Context = &bi.ContextPath @@ -903,3 +923,11 @@ func sliceEqual(s1, s2 []string) bool { } return true } + +func toNamedContexts(m map[string]string) map[string]build.NamedContext { + m2 := make(map[string]build.NamedContext, len(m)) + for k, v := range m { + m2[k] = build.NamedContext{Path: v} + } + return m2 +} diff --git a/bake/bake_test.go b/bake/bake_test.go index 0df5440f..9864e85b 100644 --- a/bake/bake_test.go +++ b/bake/bake_test.go @@ -386,8 +386,8 @@ func TestReadContexts(t *testing.T) { ctxs := bo["app"].Inputs.NamedContexts require.Equal(t, 2, len(ctxs)) - require.Equal(t, "baz", ctxs["foo"]) - require.Equal(t, "def", ctxs["abc"]) + require.Equal(t, "baz", ctxs["foo"].Path) + require.Equal(t, "def", ctxs["abc"].Path) m, _, err = ReadTargets(ctx, []File{fp}, []string{"app"}, []string{"app.contexts.foo=bay", "base.contexts.ghi=jkl"}, nil) require.NoError(t, err) @@ -402,9 +402,9 @@ func TestReadContexts(t *testing.T) { ctxs = bo["app"].Inputs.NamedContexts require.Equal(t, 3, len(ctxs)) - require.Equal(t, "bay", ctxs["foo"]) - require.Equal(t, "def", ctxs["abc"]) - require.Equal(t, "jkl", ctxs["ghi"]) + require.Equal(t, "bay", ctxs["foo"].Path) + require.Equal(t, "def", ctxs["abc"].Path) + require.Equal(t, "jkl", ctxs["ghi"].Path) // test resetting base values m, _, err = ReadTargets(ctx, []File{fp}, []string{"app"}, []string{"app.contexts.foo="}, nil) @@ -419,7 +419,7 @@ func TestReadContexts(t *testing.T) { ctxs = bo["app"].Inputs.NamedContexts require.Equal(t, 1, len(ctxs)) - require.Equal(t, "def", ctxs["abc"]) + require.Equal(t, "def", ctxs["abc"].Path) } func TestReadContextFromTargetUnknown(t *testing.T) { diff --git a/build/build.go b/build/build.go index eb194f59..b6da2fa5 100644 --- a/build/build.go +++ b/build/build.go @@ -84,7 +84,12 @@ type Inputs struct { InStream io.Reader ContextState *llb.State DockerfileInline string - NamedContexts map[string]string + NamedContexts map[string]NamedContext +} + +type NamedContext struct { + Path string + State *llb.State } type DriverInfo struct { @@ -1160,11 +1165,20 @@ func LoadInputs(ctx context.Context, d driver.Driver, inp Inputs, pw progress.Wr for k, v := range inp.NamedContexts { target.FrontendAttrs["frontend.caps"] = "moby.buildkit.frontend.contexts+forward" - if urlutil.IsGitURL(v) || urlutil.IsURL(v) || strings.HasPrefix(v, "docker-image://") || strings.HasPrefix(v, "target:") { - target.FrontendAttrs["context:"+k] = v + if v.State != nil { + target.FrontendAttrs["context:"+k] = "input:" + k + if target.FrontendInputs == nil { + target.FrontendInputs = make(map[string]llb.State) + } + target.FrontendInputs[k] = *v.State + continue + } + + if urlutil.IsGitURL(v.Path) || urlutil.IsURL(v.Path) || strings.HasPrefix(v.Path, "docker-image://") || strings.HasPrefix(v.Path, "target:") { + target.FrontendAttrs["context:"+k] = v.Path continue } - st, err := os.Stat(v) + st, err := os.Stat(v.Path) if err != nil { return nil, errors.Wrapf(err, "failed to get build context %v", k) } @@ -1175,7 +1189,7 @@ func LoadInputs(ctx context.Context, d driver.Driver, inp Inputs, pw progress.Wr if k == "context" || k == "dockerfile" { localName = "_" + k // underscore to avoid collisions } - target.LocalDirs[localName] = v + target.LocalDirs[localName] = v.Path target.FrontendAttrs["context:"+k] = "local:" + localName } diff --git a/commands/build.go b/commands/build.go index 2b00c2c7..c8259ec1 100644 --- a/commands/build.go +++ b/commands/build.go @@ -480,11 +480,11 @@ func listToMap(values []string, defaultEnv bool) map[string]string { return result } -func parseContextNames(values []string) (map[string]string, error) { +func parseContextNames(values []string) (map[string]build.NamedContext, error) { if len(values) == 0 { return nil, nil } - result := make(map[string]string, len(values)) + result := make(map[string]build.NamedContext, len(values)) for _, value := range values { kv := strings.SplitN(value, "=", 2) if len(kv) != 2 { @@ -495,7 +495,7 @@ func parseContextNames(values []string) (map[string]string, error) { return nil, errors.Wrapf(err, "invalid context name %s", kv[0]) } name := strings.TrimSuffix(reference.FamiliarString(named), ":latest") - result[name] = kv[1] + result[name] = build.NamedContext{Path: kv[1]} } return result, nil }