FetchContainer: Inject Docker image metadata into LLB

Fixes #130

Signed-off-by: Andrea Luzzardi <aluzzardi@gmail.com>
This commit is contained in:
Andrea Luzzardi
2021-02-25 14:17:01 -08:00
parent dce79f0a3e
commit 4bd0ffd3fc
5 changed files with 67 additions and 13 deletions

View File

@@ -196,7 +196,7 @@ func bkCleanError(err error) error {
noise := []string{
"executor failed running ",
"buildkit-runc did not terminate successfully",
"rpc error: code = Unknown desc =",
"rpc error: code = Unknown desc = ",
"failed to solve: ",
}

View File

@@ -7,6 +7,7 @@ import (
"fmt"
"strings"
"github.com/docker/distribution/reference"
"github.com/moby/buildkit/client/llb"
dockerfilebuilder "github.com/moby/buildkit/frontend/dockerfile/builder"
bkgw "github.com/moby/buildkit/frontend/gateway/client"
@@ -484,17 +485,57 @@ func (p *Pipeline) Load(ctx context.Context, op *compiler.Value) error {
}
func (p *Pipeline) FetchContainer(ctx context.Context, op *compiler.Value) error {
ref, err := op.Get("ref").String()
rawRef, err := op.Get("ref").String()
if err != nil {
return err
}
// FIXME: preserve docker image metadata
p.fs = p.fs.Set(
llb.Image(ref, llb.WithCustomName(p.vertexNamef("FetchContainer %s", ref))),
ref, err := reference.ParseNormalizedNamed(rawRef)
if err != nil {
return fmt.Errorf("failed to parse ref %s: %w", rawRef, err)
}
// Add the default tag "latest" to a reference if it only has a repo name.
ref = reference.TagNameOnly(ref)
state := llb.Image(
ref.String(),
llb.WithCustomName(p.vertexNamef("FetchContainer %s", rawRef)),
)
// Load image metadata and convert to to LLB.
// FIXME: metadata MUST be injected back into the gateway result
// FIXME: there are unhandled sections of the image config
image, err := p.s.ResolveImageConfig(ctx, ref.String(), llb.ResolveImageConfigOpt{
LogName: p.vertexNamef("load metadata for %s", ref.String()),
})
if err != nil {
return err
}
for _, env := range image.Config.Env {
k, v := parseKeyValue(env)
state = state.AddEnv(k, v)
}
if image.Config.WorkingDir != "" {
state = state.Dir(image.Config.WorkingDir)
}
if image.Config.User != "" {
state = state.User(image.Config.User)
}
p.fs = p.fs.Set(state)
return nil
}
func parseKeyValue(env string) (string, string) {
parts := strings.SplitN(env, "=", 2)
v := ""
if len(parts) > 1 {
v = parts[1]
}
return parts[0], v
}
func (p *Pipeline) FetchGit(ctx context.Context, op *compiler.Value) error {
remote, err := op.Get("remote").String()
if err != nil {

View File

@@ -6,6 +6,7 @@ import (
"fmt"
"github.com/moby/buildkit/client/llb"
"github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb"
bkgw "github.com/moby/buildkit/frontend/gateway/client"
bkpb "github.com/moby/buildkit/solver/pb"
"github.com/opencontainers/go-digest"
@@ -39,6 +40,23 @@ func (s Solver) SessionID() string {
return s.c.BuildOpts().SessionID
}
func (s Solver) ResolveImageConfig(ctx context.Context, ref string, opts llb.ResolveImageConfigOpt) (dockerfile2llb.Image, error) {
var image dockerfile2llb.Image
// Load image metadata and convert to to LLB.
// Inspired by https://github.com/moby/buildkit/blob/master/frontend/dockerfile/dockerfile2llb/convert.go
// FIXME: this needs to handle platform
_, meta, err := s.c.ResolveImageConfig(ctx, ref, opts)
if err != nil {
return image, err
}
if err := json.Unmarshal(meta, &image); err != nil {
return image, err
}
return image, nil
}
// Solve will block until the state is solved and returns a Reference.
func (s Solver) SolveRequest(ctx context.Context, req bkgw.SolveRequest) (bkgw.Reference, error) {
// call solve