fix exporter attributes interface returns

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
docker-18.09
Tonis Tiigi 2017-10-02 23:33:25 -07:00
parent 2809d01cf6
commit 80bc5f6097
9 changed files with 74 additions and 44 deletions

View File

@ -15,7 +15,6 @@ import (
"github.com/moby/buildkit/cache" "github.com/moby/buildkit/cache"
"github.com/moby/buildkit/cache/metadata" "github.com/moby/buildkit/cache/metadata"
"github.com/moby/buildkit/exporter" "github.com/moby/buildkit/exporter"
"github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb"
"github.com/moby/buildkit/snapshot" "github.com/moby/buildkit/snapshot"
"github.com/moby/buildkit/util/flightcontrol" "github.com/moby/buildkit/util/flightcontrol"
"github.com/moby/buildkit/util/progress" "github.com/moby/buildkit/util/progress"
@ -155,7 +154,7 @@ func (e *imageExporterInstance) Name() string {
return "exporting to image" return "exporting to image"
} }
func (e *imageExporterInstance) Export(ctx context.Context, ref cache.ImmutableRef, opt map[string]interface{}) error { func (e *imageExporterInstance) Export(ctx context.Context, ref cache.ImmutableRef, opt map[string][]byte) error {
layersDone := oneOffProgress(ctx, "exporting layers") layersDone := oneOffProgress(ctx, "exporting layers")
diffPairs, err := e.getBlobs(ctx, ref) diffPairs, err := e.getBlobs(ctx, ref)
if err != nil { if err != nil {
@ -169,15 +168,10 @@ func (e *imageExporterInstance) Export(ctx context.Context, ref cache.ImmutableR
} }
var dt []byte var dt []byte
if imgInterface, ok := opt[exporterImageConfig]; ok { if config, ok := opt[exporterImageConfig]; ok {
img, ok := imgInterface.(*dockerfile2llb.Image) dt, err = setDiffIDs(config, diffIDs)
if !ok {
return errors.Errorf("invalid image config")
}
setDiffIDs(img, diffIDs)
dt, err = json.Marshal(img)
if err != nil { if err != nil {
return errors.Wrap(err, "failed to marshal image config") return err
} }
} else { } else {
dt, err = json.Marshal(imageConfig(diffIDs)) dt, err = json.Marshal(imageConfig(diffIDs))
@ -270,9 +264,20 @@ func imageConfig(diffIDs []digest.Digest) ocispec.Image {
return img return img
} }
func setDiffIDs(img *dockerfile2llb.Image, diffIDs []digest.Digest) { func setDiffIDs(config []byte, diffIDs []digest.Digest) ([]byte, error) {
img.RootFS.Type = "layers" mp := map[string]json.RawMessage{}
img.RootFS.DiffIDs = diffIDs if err := json.Unmarshal(config, &mp); err != nil {
return nil, err
}
var rootFS ocispec.RootFS
rootFS.Type = "layers"
rootFS.DiffIDs = diffIDs
dt, err := json.Marshal(rootFS)
if err != nil {
return nil, err
}
mp["rootfs"] = dt
return json.Marshal(mp)
} }
func oneOffProgress(ctx context.Context, id string) func(err error) error { func oneOffProgress(ctx context.Context, id string) func(err error) error {

View File

@ -11,5 +11,5 @@ type Exporter interface {
type ExporterInstance interface { type ExporterInstance interface {
Name() string Name() string
Export(context.Context, cache.ImmutableRef, map[string]interface{}) error Export(context.Context, cache.ImmutableRef, map[string][]byte) error
} }

View File

@ -55,7 +55,7 @@ func (e *localExporterInstance) Name() string {
return "exporting to client" return "exporting to client"
} }
func (e *localExporterInstance) Export(ctx context.Context, ref cache.ImmutableRef, opt map[string]interface{}) error { func (e *localExporterInstance) Export(ctx context.Context, ref cache.ImmutableRef, opt map[string][]byte) error {
mount, err := ref.Mount(ctx, true) mount, err := ref.Mount(ctx, true)
if err != nil { if err != nil {
return err return err

View File

@ -1,6 +1,7 @@
package dockerfile package dockerfile
import ( import (
"encoding/json"
"io/ioutil" "io/ioutil"
"path" "path"
"path/filepath" "path/filepath"
@ -31,7 +32,7 @@ func NewDockerfileFrontend() frontend.Frontend {
type dfFrontend struct{} type dfFrontend struct{}
func (f *dfFrontend) Solve(ctx context.Context, llbBridge frontend.FrontendLLBBridge, opts map[string]string) (retRef cache.ImmutableRef, exporterAttr map[string]interface{}, retErr error) { func (f *dfFrontend) Solve(ctx context.Context, llbBridge frontend.FrontendLLBBridge, opts map[string]string) (retRef cache.ImmutableRef, exporterAttr map[string][]byte, retErr error) {
filename := opts[keyFilename] filename := opts[keyFilename]
if filename == "" { if filename == "" {
@ -52,7 +53,7 @@ func (f *dfFrontend) Solve(ctx context.Context, llbBridge frontend.FrontendLLBBr
return nil, nil, err return nil, nil, err
} }
ref, _, err := llbBridge.Solve(ctx, def.ToPB(), "") ref, _, err := llbBridge.Solve(ctx, def.ToPB(), "", nil)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
@ -111,13 +112,18 @@ func (f *dfFrontend) Solve(ctx context.Context, llbBridge frontend.FrontendLLBBr
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
retRef, _, err = llbBridge.Solve(ctx, def.ToPB(), "") retRef, _, err = llbBridge.Solve(ctx, def.ToPB(), "", nil)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
return retRef, map[string]interface{}{ config, err := json.Marshal(img)
exporterImageConfig: img, if err != nil {
return nil, nil, err
}
return retRef, map[string][]byte{
exporterImageConfig: config,
}, nil }, nil
} }

View File

@ -11,11 +11,11 @@ import (
) )
type Frontend interface { type Frontend interface {
Solve(ctx context.Context, llbBridge FrontendLLBBridge, opt map[string]string) (cache.ImmutableRef, map[string]interface{}, error) Solve(ctx context.Context, llb FrontendLLBBridge, opt map[string]string) (cache.ImmutableRef, map[string][]byte, error)
} }
type FrontendLLBBridge interface { type FrontendLLBBridge interface {
Solve(ctx context.Context, def *pb.Definition, frontend string) (cache.ImmutableRef, map[string]interface{}, error) Solve(ctx context.Context, def *pb.Definition, frontend string, opts map[string]string) (cache.ImmutableRef, map[string][]byte, error)
ResolveImageConfig(ctx context.Context, ref string) (digest.Digest, []byte, error) ResolveImageConfig(ctx context.Context, ref string) (digest.Digest, []byte, error)
Exec(ctx context.Context, meta worker.Meta, rootfs cache.ImmutableRef, stdin io.ReadCloser, stdout, stderr io.WriteCloser) error Exec(ctx context.Context, meta worker.Meta, rootfs cache.ImmutableRef, stdin io.ReadCloser, stdout, stderr io.WriteCloser) error
} }

View File

@ -40,7 +40,7 @@ type Client struct {
sessionID string sessionID string
} }
func (c *Client) Solve(ctx context.Context, def *opspb.Definition, frontend string, exporterAttr map[string]interface{}, final bool) (*Reference, error) { func (c *Client) Solve(ctx context.Context, def *opspb.Definition, frontend string, exporterAttr map[string][]byte, final bool) (*Reference, error) {
dt, err := json.Marshal(exporterAttr) dt, err := json.Marshal(exporterAttr)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -8,18 +8,19 @@ import (
"net" "net"
"os" "os"
"path/filepath" "path/filepath"
"strings"
"time" "time"
"github.com/docker/distribution/reference" "github.com/docker/distribution/reference"
"github.com/moby/buildkit/cache" "github.com/moby/buildkit/cache"
"github.com/moby/buildkit/client/llb" "github.com/moby/buildkit/client/llb"
"github.com/moby/buildkit/frontend" "github.com/moby/buildkit/frontend"
"github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb"
pb "github.com/moby/buildkit/frontend/gateway/pb" pb "github.com/moby/buildkit/frontend/gateway/pb"
"github.com/moby/buildkit/identity" "github.com/moby/buildkit/identity"
"github.com/moby/buildkit/session" "github.com/moby/buildkit/session"
"github.com/moby/buildkit/snapshot" "github.com/moby/buildkit/snapshot"
"github.com/moby/buildkit/worker" "github.com/moby/buildkit/worker"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"golang.org/x/net/context" "golang.org/x/net/context"
@ -42,7 +43,17 @@ func NewGatewayFrontend() frontend.Frontend {
type gatewayFrontend struct { type gatewayFrontend struct {
} }
func (gf *gatewayFrontend) Solve(ctx context.Context, llbBridge frontend.FrontendLLBBridge, opts map[string]string) (retRef cache.ImmutableRef, exporterAttr map[string]interface{}, retErr error) { func filterPrefix(opts map[string]string, pfx string) map[string]string {
m := map[string]string{}
for k, v := range opts {
if strings.HasPrefix(k, pfx) {
m[strings.TrimPrefix(k, pfx)] = v
}
}
return m
}
func (gf *gatewayFrontend) Solve(ctx context.Context, llbBridge frontend.FrontendLLBBridge, opts map[string]string) (retRef cache.ImmutableRef, exporterAttr map[string][]byte, retErr error) {
source, ok := opts[keySource] source, ok := opts[keySource]
if !ok { if !ok {
@ -52,22 +63,20 @@ func (gf *gatewayFrontend) Solve(ctx context.Context, llbBridge frontend.Fronten
sid := session.FromContext(ctx) sid := session.FromContext(ctx)
_, isDevel := opts[keyDevel] _, isDevel := opts[keyDevel]
var img dockerfile2llb.Image var img ocispec.Image
var rootFS cache.ImmutableRef var rootFS cache.ImmutableRef
if isDevel { if isDevel {
ref, exp, err := llbBridge.Solve(session.NewContext(ctx, "gateway:"+sid), nil, source) ref, exp, err := llbBridge.Solve(session.NewContext(ctx, "gateway:"+sid), nil, source, filterPrefix(opts, "gateway-"))
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
rootFS = ref rootFS = ref
config, ok := exp[exporterImageConfig] config, ok := exp[exporterImageConfig]
if ok { if ok {
// TODO: map json.RawMessage if err := json.Unmarshal(config, &img); err != nil {
img = *config.(*dockerfile2llb.Image) return nil, nil, err
// if err := json.Unmarshal(config.(*dockerfile2llb.Image), &img); err != nil { }
// return nil, nil, err
// }
} }
} else { } else {
sourceRef, err := reference.ParseNormalizedNamed(source) sourceRef, err := reference.ParseNormalizedNamed(source)
@ -75,7 +84,7 @@ func (gf *gatewayFrontend) Solve(ctx context.Context, llbBridge frontend.Fronten
return nil, nil, err return nil, nil, err
} }
dgst, config, err := llbBridge.ResolveImageConfig(ctx, source) dgst, config, err := llbBridge.ResolveImageConfig(ctx, sourceRef.String())
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
@ -96,7 +105,7 @@ func (gf *gatewayFrontend) Solve(ctx context.Context, llbBridge frontend.Fronten
return nil, nil, err return nil, nil, err
} }
ref, _, err := llbBridge.Solve(ctx, def.ToPB(), "") ref, _, err := llbBridge.Solve(ctx, def.ToPB(), "", nil)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
@ -215,7 +224,7 @@ type llbBrideForwarder struct {
llbBridge frontend.FrontendLLBBridge llbBridge frontend.FrontendLLBBridge
refs map[string]cache.ImmutableRef refs map[string]cache.ImmutableRef
lastRef cache.ImmutableRef lastRef cache.ImmutableRef
exporterAttr map[string]interface{} exporterAttr map[string][]byte
*pipe *pipe
} }
@ -231,12 +240,12 @@ func (lbf *llbBrideForwarder) ResolveImageConfig(ctx context.Context, req *pb.Re
} }
func (lbf *llbBrideForwarder) Solve(ctx context.Context, req *pb.SolveRequest) (*pb.SolveResponse, error) { func (lbf *llbBrideForwarder) Solve(ctx context.Context, req *pb.SolveRequest) (*pb.SolveResponse, error) {
ref, expResp, err := lbf.llbBridge.Solve(ctx, req.Definition, req.Frontend) ref, expResp, err := lbf.llbBridge.Solve(ctx, req.Definition, req.Frontend, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
exp := map[string]interface{}{} exp := map[string][]byte{}
if err := json.Unmarshal(req.ExporterAttr, &exp); err != nil { if err := json.Unmarshal(req.ExporterAttr, &exp); err != nil {
return nil, err return nil, err
} }

View File

@ -99,7 +99,7 @@ func (s *Solver) Solve(ctx context.Context, id string, f frontend.Frontend, def
} }
var ref Reference var ref Reference
var exporterOpt map[string]interface{} var exporterOpt map[string][]byte
if def != nil { if def != nil {
var inp *Input var inp *Input
inp, err = j.load(def, s.resolve) inp, err = j.load(def, s.resolve)
@ -583,17 +583,13 @@ type resolveImageConfig interface {
ResolveImageConfig(ctx context.Context, ref string) (digest.Digest, []byte, error) ResolveImageConfig(ctx context.Context, ref string) (digest.Digest, []byte, error)
} }
func (s *llbBridge) Solve(ctx context.Context, def *pb.Definition, frontend string) (cache.ImmutableRef, map[string]interface{}, error) { func (s *llbBridge) Solve(ctx context.Context, def *pb.Definition, frontend string, opts map[string]string) (cache.ImmutableRef, map[string][]byte, error) {
if def == nil { if def == nil {
f, ok := s.allFrontends[frontend] f, ok := s.allFrontends[frontend]
if !ok { if !ok {
return nil, nil, errors.Errorf("invalid frontend: %s", frontend) return nil, nil, errors.Errorf("invalid frontend: %s", frontend)
} }
ref, exporterOpt, err := f.Solve(ctx, &llbBridge{ ref, exporterOpt, err := f.Solve(ctx, s, opts)
job: s.job,
resolveOp: s.resolveOp,
resolveImageConfig: s,
}, nil)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }

View File

@ -44,6 +44,10 @@ func (w containerdWorker) Exec(ctx context.Context, meta worker.Meta, root cache
} }
defer container.Delete(ctx) defer container.Delete(ctx)
if stdin == nil {
stdin = &emptyReadCloser{}
}
task, err := container.NewTask(ctx, containerd.NewIO(stdin, stdout, stderr), containerd.WithRootFS(rootMounts)) task, err := container.NewTask(ctx, containerd.NewIO(stdin, stdout, stderr), containerd.WithRootFS(rootMounts))
if err != nil { if err != nil {
return err return err
@ -69,3 +73,13 @@ func (w containerdWorker) Exec(ctx context.Context, meta worker.Meta, root cache
return nil return nil
} }
type emptyReadCloser struct{}
func (_ *emptyReadCloser) Read([]byte) (int, error) {
return 0, io.EOF
}
func (_ *emptyReadCloser) Close() error {
return nil
}