bake: make named contexts relative to remote bake input

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
This commit is contained in:
Tonis Tiigi 2022-02-23 23:09:46 -08:00
parent 7f1041164e
commit 280c008f81
4 changed files with 57 additions and 15 deletions

View File

@ -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
}

View File

@ -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) {

View File

@ -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
}
st, err := os.Stat(v)
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.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
}

View File

@ -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
}