diff --git a/builder/builder-next/adapters/containerimage/pull.go b/builder/builder-next/adapters/containerimage/pull.go index 9f8d76db47..86e9ba9c89 100644 --- a/builder/builder-next/adapters/containerimage/pull.go +++ b/builder/builder-next/adapters/containerimage/pull.go @@ -31,13 +31,11 @@ import ( "github.com/moby/buildkit/cache" "github.com/moby/buildkit/client/llb" "github.com/moby/buildkit/session" - "github.com/moby/buildkit/session/auth" "github.com/moby/buildkit/source" "github.com/moby/buildkit/util/flightcontrol" "github.com/moby/buildkit/util/imageutil" "github.com/moby/buildkit/util/progress" "github.com/moby/buildkit/util/resolver" - "github.com/moby/buildkit/util/tracing" digest "github.com/opencontainers/go-digest" "github.com/opencontainers/image-spec/identity" ocispec "github.com/opencontainers/image-spec/specs-go/v1" @@ -54,7 +52,7 @@ type SourceOpt struct { DownloadManager distribution.RootFSDownloadManager MetadataStore metadata.V2MetadataService ImageStore image.Store - ResolverOpt resolver.ResolveOptionsFunc + RegistryHosts docker.RegistryHosts LayerStore layer.Store } @@ -78,44 +76,15 @@ func (is *imageSource) ID() string { return source.DockerImageScheme } -func (is *imageSource) getResolver(ctx context.Context, rfn resolver.ResolveOptionsFunc, ref string, sm *session.Manager) remotes.Resolver { +func (is *imageSource) getResolver(ctx context.Context, hosts docker.RegistryHosts, ref string, sm *session.Manager) remotes.Resolver { if res := is.resolverCache.Get(ctx, ref); res != nil { return res } - - opt := docker.ResolverOptions{ - Client: tracing.DefaultClient, - } - if rfn != nil { - opt = rfn(ref) - } - opt.Credentials = is.getCredentialsFromSession(ctx, sm) - r := docker.NewResolver(opt) + r := resolver.New(ctx, hosts, sm) r = is.resolverCache.Add(ctx, ref, r) return r } -func (is *imageSource) getCredentialsFromSession(ctx context.Context, sm *session.Manager) func(string) (string, string, error) { - id := session.FromContext(ctx) - if id == "" { - // can be removed after containerd/containerd#2812 - return func(string) (string, string, error) { - return "", "", nil - } - } - return func(host string) (string, string, error) { - timeoutCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - - caller, err := sm.Get(timeoutCtx, id) - if err != nil { - return "", "", err - } - - return auth.CredentialsFunc(tracing.ContextWithSpanFromContext(context.TODO(), ctx), caller)(host) - } -} - func (is *imageSource) resolveLocal(refStr string) (*image.Image, error) { ref, err := distreference.ParseNormalizedNamed(refStr) if err != nil { @@ -138,7 +107,7 @@ func (is *imageSource) resolveRemote(ctx context.Context, ref string, platform * dt []byte } res, err := is.g.Do(ctx, ref, func(ctx context.Context) (interface{}, error) { - dgst, dt, err := imageutil.Config(ctx, ref, is.getResolver(ctx, is.ResolverOpt, ref, sm), is.ContentStore, nil, platform) + dgst, dt, err := imageutil.Config(ctx, ref, is.getResolver(ctx, is.RegistryHosts, ref, sm), is.ContentStore, nil, platform) if err != nil { return nil, err } @@ -208,7 +177,7 @@ func (is *imageSource) Resolve(ctx context.Context, id source.Identifier, sm *se p := &puller{ src: imageIdentifier, is: is, - resolver: is.getResolver(ctx, is.ResolverOpt, imageIdentifier.Reference.String(), sm), + resolver: is.getResolver(ctx, is.RegistryHosts, imageIdentifier.Reference.String(), sm), platform: platform, sm: sm, } diff --git a/builder/builder-next/adapters/localinlinecache/inlinecache.go b/builder/builder-next/adapters/localinlinecache/inlinecache.go index d14296028f..55b842e9fa 100644 --- a/builder/builder-next/adapters/localinlinecache/inlinecache.go +++ b/builder/builder-next/adapters/localinlinecache/inlinecache.go @@ -7,6 +7,7 @@ import ( "github.com/containerd/containerd/content" "github.com/containerd/containerd/images" + "github.com/containerd/containerd/remotes/docker" distreference "github.com/docker/distribution/reference" imagestore "github.com/docker/docker/image" "github.com/docker/docker/reference" @@ -15,7 +16,6 @@ import ( v1 "github.com/moby/buildkit/cache/remotecache/v1" "github.com/moby/buildkit/session" "github.com/moby/buildkit/solver" - "github.com/moby/buildkit/util/resolver" "github.com/moby/buildkit/worker" digest "github.com/opencontainers/go-digest" specs "github.com/opencontainers/image-spec/specs-go/v1" @@ -23,9 +23,9 @@ import ( ) // ResolveCacheImporterFunc returns a resolver function for local inline cache -func ResolveCacheImporterFunc(sm *session.Manager, resolverOpt resolver.ResolveOptionsFunc, cs content.Store, rs reference.Store, is imagestore.Store) remotecache.ResolveCacheImporterFunc { +func ResolveCacheImporterFunc(sm *session.Manager, resolverFunc docker.RegistryHosts, cs content.Store, rs reference.Store, is imagestore.Store) remotecache.ResolveCacheImporterFunc { - upstream := registryremotecache.ResolveCacheImporterFunc(sm, cs, resolverOpt) + upstream := registryremotecache.ResolveCacheImporterFunc(sm, cs, resolverFunc) return func(ctx context.Context, attrs map[string]string) (remotecache.Importer, specs.Descriptor, error) { if dt, err := tryImportLocal(rs, is, attrs["ref"]); err == nil { diff --git a/builder/builder-next/builder.go b/builder/builder-next/builder.go index 278f36dfef..5371911e80 100644 --- a/builder/builder-next/builder.go +++ b/builder/builder-next/builder.go @@ -11,6 +11,7 @@ import ( "time" "github.com/containerd/containerd/platforms" + "github.com/containerd/containerd/remotes/docker" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/backend" "github.com/docker/docker/builder" @@ -26,7 +27,6 @@ import ( "github.com/moby/buildkit/identity" "github.com/moby/buildkit/session" "github.com/moby/buildkit/util/entitlements" - "github.com/moby/buildkit/util/resolver" "github.com/moby/buildkit/util/tracing" "github.com/pkg/errors" "golang.org/x/sync/errgroup" @@ -70,7 +70,7 @@ type Opt struct { Dist images.DistributionServices NetworkController libnetwork.NetworkController DefaultCgroupParent string - ResolverOpt resolver.ResolveOptionsFunc + RegistryHosts docker.RegistryHosts BuilderConfig config.BuilderConfig Rootless bool IdentityMapping *idtools.IdentityMapping diff --git a/builder/builder-next/controller.go b/builder/builder-next/controller.go index d6a9d40251..99c9635519 100644 --- a/builder/builder-next/controller.go +++ b/builder/builder-next/controller.go @@ -119,7 +119,7 @@ func newController(rt http.RoundTripper, opt Opt) (*control.Controller, error) { MetadataStore: dist.V2MetadataService, ImageStore: dist.ImageStore, ReferenceStore: dist.ReferenceStore, - ResolverOpt: opt.ResolverOpt, + RegistryHosts: opt.RegistryHosts, LayerStore: dist.LayerStore, }) if err != nil { @@ -210,7 +210,7 @@ func newController(rt http.RoundTripper, opt Opt) (*control.Controller, error) { Frontends: frontends, CacheKeyStorage: cacheStorage, ResolveCacheImporterFuncs: map[string]remotecache.ResolveCacheImporterFunc{ - "registry": localinlinecache.ResolveCacheImporterFunc(opt.SessionManager, opt.ResolverOpt, store, dist.ReferenceStore, dist.ImageStore), + "registry": localinlinecache.ResolveCacheImporterFunc(opt.SessionManager, opt.RegistryHosts, store, dist.ReferenceStore, dist.ImageStore), "local": localremotecache.ResolveCacheImporterFunc(opt.SessionManager), }, ResolveCacheExporterFuncs: map[string]remotecache.ResolveCacheExporterFunc{ diff --git a/cmd/dockerd/daemon.go b/cmd/dockerd/daemon.go index b27cd5c969..ca6e2a0d26 100644 --- a/cmd/dockerd/daemon.go +++ b/cmd/dockerd/daemon.go @@ -292,7 +292,7 @@ func newRouterOptions(config *config.Config, d *daemon.Daemon) (routerOptions, e Dist: d.DistributionServices(), NetworkController: d.NetworkController(), DefaultCgroupParent: cgroupParent, - ResolverOpt: d.NewResolveOptionsFunc(), + RegistryHosts: d.RegistryHosts(), BuilderConfig: config.Builder, Rootless: d.Rootless(), IdentityMapping: d.IdentityMapping(), diff --git a/daemon/daemon.go b/daemon/daemon.go index 87d45175c1..4ece4bef5e 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -9,7 +9,6 @@ import ( "context" "fmt" "io/ioutil" - "math/rand" "net" "net/url" "os" @@ -28,7 +27,6 @@ import ( "github.com/containerd/containerd/defaults" "github.com/containerd/containerd/pkg/dialer" "github.com/containerd/containerd/remotes/docker" - "github.com/docker/distribution/reference" "github.com/docker/docker/api/types" containertypes "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/swarm" @@ -42,8 +40,8 @@ import ( "github.com/docker/docker/daemon/logger" "github.com/docker/docker/daemon/network" "github.com/docker/docker/errdefs" + bkconfig "github.com/moby/buildkit/cmd/buildkitd/config" "github.com/moby/buildkit/util/resolver" - "github.com/moby/buildkit/util/tracing" "github.com/sirupsen/logrus" // register graph drivers @@ -153,63 +151,46 @@ func (daemon *Daemon) Features() *map[string]bool { return &daemon.configStore.Features } -// NewResolveOptionsFunc returns a call back function to resolve "registry-mirrors" and -// "insecure-registries" for buildkit -func (daemon *Daemon) NewResolveOptionsFunc() resolver.ResolveOptionsFunc { - return func(ref string) docker.ResolverOptions { - var ( - registryKey = "docker.io" - mirrors = make([]string, len(daemon.configStore.Mirrors)) - m = map[string]resolver.RegistryConf{} - ) - // must trim "https://" or "http://" prefix - for i, v := range daemon.configStore.Mirrors { - if uri, err := url.Parse(v); err == nil { - v = uri.Host - } - mirrors[i] = v +// RegistryHosts returns registry configuration in containerd resolvers format +func (daemon *Daemon) RegistryHosts() docker.RegistryHosts { + var ( + registryKey = "docker.io" + mirrors = make([]string, len(daemon.configStore.Mirrors)) + m = map[string]bkconfig.RegistryConfig{} + ) + // must trim "https://" or "http://" prefix + for i, v := range daemon.configStore.Mirrors { + if uri, err := url.Parse(v); err == nil { + v = uri.Host } - // set "registry-mirrors" - m[registryKey] = resolver.RegistryConf{Mirrors: mirrors} - // set "insecure-registries" - for _, v := range daemon.configStore.InsecureRegistries { - if uri, err := url.Parse(v); err == nil { - v = uri.Host - } - plainHTTP := true - m[v] = resolver.RegistryConf{ - PlainHTTP: &plainHTTP, - } - } - def := docker.ResolverOptions{ - Client: tracing.DefaultClient, - } - - parsed, err := reference.ParseNormalizedNamed(ref) - if err != nil { - return def - } - host := reference.Domain(parsed) - - c, ok := m[host] - if !ok { - return def - } - - if len(c.Mirrors) > 0 { - // TODO ResolverOptions.Host is deprecated; ResolverOptions.Hosts should be used - def.Host = func(string) (string, error) { - return c.Mirrors[rand.Intn(len(c.Mirrors))], nil - } - } - - // TODO ResolverOptions.PlainHTTP is deprecated; ResolverOptions.Hosts should be used - if c.PlainHTTP != nil { - def.PlainHTTP = *c.PlainHTTP - } - - return def + mirrors[i] = v } + // set mirrors for default registry + m[registryKey] = bkconfig.RegistryConfig{Mirrors: mirrors} + + for _, v := range daemon.configStore.InsecureRegistries { + u, err := url.Parse(v) + c := bkconfig.RegistryConfig{} + if err == nil { + v = u.Host + t := true + if u.Scheme == "http" { + c.PlainHTTP = &t + } else { + c.Insecure = &t + } + } + m[v] = c + } + + for k, v := range m { + if d, err := registry.HostCertsDir(k); err == nil { + v.TLSConfigDir = []string{d} + m[k] = v + } + } + + return resolver.NewRegistryConfig(m) } func (daemon *Daemon) restore() error { diff --git a/registry/registry.go b/registry/registry.go index 4c82a61cb3..05072417be 100644 --- a/registry/registry.go +++ b/registry/registry.go @@ -26,6 +26,24 @@ var ( ErrAlreadyExists = errors.New("Image already exists") ) +// HostCertsDir returns the config directory for a specific host +func HostCertsDir(hostname string) (string, error) { + certsDir := CertsDir + + if rootless.RunningWithRootlessKit() { + configHome, err := homedir.GetConfigHome() + if err != nil { + return "", err + } + + certsDir = filepath.Join(configHome, "docker/certs.d") + } + + hostDir := filepath.Join(certsDir, cleanPath(hostname)) + + return hostDir, nil +} + func newTLSConfig(hostname string, isSecure bool) (*tls.Config, error) { // PreferredServerCipherSuites should have no effect tlsConfig := tlsconfig.ServerDefault() @@ -33,19 +51,11 @@ func newTLSConfig(hostname string, isSecure bool) (*tls.Config, error) { tlsConfig.InsecureSkipVerify = !isSecure if isSecure && CertsDir != "" { - certsDir := CertsDir - - if rootless.RunningWithRootlessKit() { - configHome, err := homedir.GetConfigHome() - if err != nil { - return nil, err - } - - certsDir = filepath.Join(configHome, "docker/certs.d") + hostDir, err := HostCertsDir(hostname) + if err != nil { + return nil, err } - hostDir := filepath.Join(certsDir, cleanPath(hostname)) - logrus.Debugf("hostDir: %s", hostDir) if err := ReadCertsDirectory(tlsConfig, hostDir); err != nil { return nil, err diff --git a/vendor.conf b/vendor.conf index 354a8a33df..93aee2b79b 100644 --- a/vendor.conf +++ b/vendor.conf @@ -27,8 +27,8 @@ github.com/imdario/mergo 1afb36080aec31e0d1528973ebe6 golang.org/x/sync cd5d95a43a6e21273425c7ae415d3df9ea832eeb # buildkit -github.com/moby/buildkit 4d8d91bf49c769b8458e9aa84746c842b4a0e39a -github.com/tonistiigi/fsutil 013a9fe6aee2d1658457075bf9e688bc8c0be2e0 +github.com/moby/buildkit ae7ff7174f73bcb4df89b97e1623b3fb0bfb0a0c +github.com/tonistiigi/fsutil c2c7d7b0e1441705cd802e5699c0a10b1dfe39fd github.com/grpc-ecosystem/grpc-opentracing 8e809c8a86450a29b90dcc9efbf062d0fe6d9746 github.com/opentracing/opentracing-go 1361b9cd60be79c4c3a7fa9841b3c132e40066a7 github.com/google/shlex e7afc7fbc51079733e9468cdfd1efcd7d196cd1d diff --git a/vendor/github.com/moby/buildkit/README.md b/vendor/github.com/moby/buildkit/README.md index d566e57b21..b5f6370175 100644 --- a/vendor/github.com/moby/buildkit/README.md +++ b/vendor/github.com/moby/buildkit/README.md @@ -128,7 +128,7 @@ See [Expose BuildKit as a TCP service](#expose-buildkit-as-a-tcp-service). :information_source: Notice to Fedora 31 users: -* As runc still does not work on cgroup v2 environment like Fedora 31, you need to substitute runc with crun. Run `rm -f $(which buildkit-runc) && ln -s $(which crun) /usr/local/bin/buildkit-runc` . +* As runc still does not work on cgroup v2 environment like Fedora 31, you need to substitute runc with crun. Run `buildkitd` with `--oci-worker-binary=crun`. * If you want to use runc, you need to configure the system to use cgroup v1. Run `sudo grubby --update-kernel=ALL --args="systemd.unified_cgroup_hierarchy=0"` and reboot. ### Exploring LLB @@ -205,8 +205,8 @@ By default, the build result and intermediate cache will only remain internally buildctl build ... --output type=image,name=docker.io/username/image,push=true ``` -To export and import the cache along with the image, you need to specify `--export-cache type=inline` and `--import-cache type=registry,ref=...`. -See [Export cache](#export-cache). +To export the cache embed with the image and pushing them to registry together, type `registry` is required to import the cache, you should specify `--export-cache type=inline` and `--import-cache type=registry,ref=...`. To export the cache to a local directy, you should specify `--export-cache type=local`. +Details in [Export cache](#export-cache). ```bash buildctl build ...\ @@ -357,7 +357,8 @@ The directory layout conforms to OCI Image Spec v1.0. - `ref=docker.io/user/image:tag`: reference for `registry` cache importer - `src=path/to/input-dir`: directory for `local` cache importer - `digest=sha256:deadbeef`: digest of the manifest list to import for `local` cache importer. - Defaults to the digest of "latest" tag in `index.json` +- `tag=customtag`: custom tag of image for `local` cache importer. + Defaults to the digest of "latest" tag in `index.json` is for digest, not for tag ### Consistent hashing diff --git a/vendor/github.com/moby/buildkit/cache/contenthash/tarsum.go b/vendor/github.com/moby/buildkit/cache/contenthash/tarsum.go index 601c41ecb9..3327ab2c20 100644 --- a/vendor/github.com/moby/buildkit/cache/contenthash/tarsum.go +++ b/vendor/github.com/moby/buildkit/cache/contenthash/tarsum.go @@ -5,6 +5,7 @@ import ( "io" "sort" "strconv" + "strings" ) // WriteV1TarsumHeaders writes a tar header to a writer in V1 tarsum format. @@ -38,7 +39,9 @@ func v1TarHeaderSelect(h *tar.Header) (orderedHeaders [][2]string) { // Get extended attributes. xAttrKeys := make([]string, len(h.Xattrs)) for k := range h.Xattrs { - xAttrKeys = append(xAttrKeys, k) + if !strings.HasPrefix(k, "security.") && !strings.HasPrefix(k, "system.") { + xAttrKeys = append(xAttrKeys, k) + } } sort.Strings(xAttrKeys) diff --git a/vendor/github.com/moby/buildkit/cache/remotecache/registry/registry.go b/vendor/github.com/moby/buildkit/cache/remotecache/registry/registry.go index 51e97c7839..a172917a50 100644 --- a/vendor/github.com/moby/buildkit/cache/remotecache/registry/registry.go +++ b/vendor/github.com/moby/buildkit/cache/remotecache/registry/registry.go @@ -2,15 +2,12 @@ package registry import ( "context" - "time" "github.com/containerd/containerd/content" - "github.com/containerd/containerd/remotes" "github.com/containerd/containerd/remotes/docker" "github.com/docker/distribution/reference" "github.com/moby/buildkit/cache/remotecache" "github.com/moby/buildkit/session" - "github.com/moby/buildkit/session/auth" "github.com/moby/buildkit/util/contentutil" "github.com/moby/buildkit/util/resolver" "github.com/opencontainers/go-digest" @@ -34,13 +31,13 @@ const ( attrRef = "ref" ) -func ResolveCacheExporterFunc(sm *session.Manager, resolverOpt resolver.ResolveOptionsFunc) remotecache.ResolveCacheExporterFunc { +func ResolveCacheExporterFunc(sm *session.Manager, hosts docker.RegistryHosts) remotecache.ResolveCacheExporterFunc { return func(ctx context.Context, attrs map[string]string) (remotecache.Exporter, error) { ref, err := canonicalizeRef(attrs[attrRef]) if err != nil { return nil, err } - remote := newRemoteResolver(ctx, resolverOpt, sm, ref) + remote := resolver.New(ctx, hosts, sm) pusher, err := remote.Pusher(ctx, ref) if err != nil { return nil, err @@ -49,13 +46,13 @@ func ResolveCacheExporterFunc(sm *session.Manager, resolverOpt resolver.ResolveO } } -func ResolveCacheImporterFunc(sm *session.Manager, cs content.Store, resolverOpt resolver.ResolveOptionsFunc) remotecache.ResolveCacheImporterFunc { +func ResolveCacheImporterFunc(sm *session.Manager, cs content.Store, hosts docker.RegistryHosts) remotecache.ResolveCacheImporterFunc { return func(ctx context.Context, attrs map[string]string) (remotecache.Importer, specs.Descriptor, error) { ref, err := canonicalizeRef(attrs[attrRef]) if err != nil { return nil, specs.Descriptor{}, err } - remote := newRemoteResolver(ctx, resolverOpt, sm, ref) + remote := resolver.New(ctx, hosts, sm) xref, desc, err := remote.Resolve(ctx, ref) if err != nil { return nil, specs.Descriptor{}, err @@ -97,27 +94,3 @@ func (dsl *withDistributionSourceLabel) SetDistributionSourceAnnotation(desc oci desc.Annotations["containerd.io/distribution.source.ref"] = dsl.ref return desc } - -func newRemoteResolver(ctx context.Context, resolverOpt resolver.ResolveOptionsFunc, sm *session.Manager, ref string) remotes.Resolver { - opt := resolverOpt(ref) - opt.Credentials = getCredentialsFunc(ctx, sm) - return docker.NewResolver(opt) -} - -func getCredentialsFunc(ctx context.Context, sm *session.Manager) func(string) (string, string, error) { - id := session.FromContext(ctx) - if id == "" { - return nil - } - return func(host string) (string, string, error) { - timeoutCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - - caller, err := sm.Get(timeoutCtx, id) - if err != nil { - return "", "", err - } - - return auth.CredentialsFunc(context.TODO(), caller)(host) - } -} diff --git a/vendor/github.com/moby/buildkit/client/client.go b/vendor/github.com/moby/buildkit/client/client.go index 6b8240945c..d256ec37e4 100644 --- a/vendor/github.com/moby/buildkit/client/client.go +++ b/vendor/github.com/moby/buildkit/client/client.go @@ -11,6 +11,8 @@ import ( "github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc" controlapi "github.com/moby/buildkit/api/services/control" "github.com/moby/buildkit/client/connhelper" + "github.com/moby/buildkit/session" + "github.com/moby/buildkit/session/grpchijack" "github.com/moby/buildkit/util/appdefaults" opentracing "github.com/opentracing/opentracing-go" "github.com/pkg/errors" @@ -80,6 +82,10 @@ func (c *Client) controlClient() controlapi.ControlClient { return controlapi.NewControlClient(c.conn) } +func (c *Client) Dialer() session.Dialer { + return grpchijack.Dialer(c.controlClient()) +} + func (c *Client) Close() error { return c.conn.Close() } diff --git a/vendor/github.com/moby/buildkit/client/llb/async.go b/vendor/github.com/moby/buildkit/client/llb/async.go new file mode 100644 index 0000000000..bf28a957c7 --- /dev/null +++ b/vendor/github.com/moby/buildkit/client/llb/async.go @@ -0,0 +1,98 @@ +package llb + +import ( + "context" + + "github.com/moby/buildkit/solver/pb" + "github.com/moby/buildkit/util/flightcontrol" + digest "github.com/opencontainers/go-digest" + "github.com/pkg/errors" +) + +type asyncState struct { + f func(context.Context, State) (State, error) + prev State + target State + set bool + err error + g flightcontrol.Group +} + +func (as *asyncState) Output() Output { + return as +} + +func (as *asyncState) Vertex(ctx context.Context) Vertex { + err := as.Do(ctx) + if err != nil { + return &errVertex{err} + } + if as.set { + out := as.target.Output() + if out == nil { + return nil + } + return out.Vertex(ctx) + } + return nil +} + +func (as *asyncState) ToInput(ctx context.Context, c *Constraints) (*pb.Input, error) { + err := as.Do(ctx) + if err != nil { + return nil, err + } + if as.set { + out := as.target.Output() + if out == nil { + return nil, nil + } + return out.ToInput(ctx, c) + } + return nil, nil +} + +func (as *asyncState) Do(ctx context.Context) error { + _, err := as.g.Do(ctx, "", func(ctx context.Context) (interface{}, error) { + if as.set { + return as.target, as.err + } + res, err := as.f(ctx, as.prev) + if err != nil { + select { + case <-ctx.Done(): + if errors.Cause(err) == ctx.Err() { + return res, err + } + default: + } + } + as.target = res + as.err = err + as.set = true + return res, err + }) + if err != nil { + return err + } + return as.err +} + +type errVertex struct { + err error +} + +func (v *errVertex) Validate(context.Context) error { + return v.err +} +func (v *errVertex) Marshal(context.Context, *Constraints) (digest.Digest, []byte, *pb.OpMetadata, error) { + return "", nil, nil, v.err +} +func (v *errVertex) Output() Output { + return nil +} +func (v *errVertex) Inputs() []Output { + return nil +} + +var _ Vertex = &errVertex{} diff --git a/vendor/github.com/moby/buildkit/client/llb/definition.go b/vendor/github.com/moby/buildkit/client/llb/definition.go index f21d2a5944..9be2b299ae 100644 --- a/vendor/github.com/moby/buildkit/client/llb/definition.go +++ b/vendor/github.com/moby/buildkit/client/llb/definition.go @@ -1,6 +1,9 @@ package llb import ( + "context" + "sync" + "github.com/moby/buildkit/solver/pb" digest "github.com/opencontainers/go-digest" specs "github.com/opencontainers/image-spec/specs-go/v1" @@ -13,6 +16,7 @@ import ( // LLB state can be reconstructed from the definition. type DefinitionOp struct { MarshalCache + mu sync.Mutex ops map[digest.Digest]*pb.Op defs map[digest.Digest][]byte metas map[digest.Digest]pb.OpMetadata @@ -25,6 +29,7 @@ type DefinitionOp struct { func NewDefinitionOp(def *pb.Definition) (*DefinitionOp, error) { ops := make(map[digest.Digest]*pb.Op) defs := make(map[digest.Digest][]byte) + platforms := make(map[digest.Digest]*specs.Platform) var dgst digest.Digest for _, dt := range def.Def { @@ -35,6 +40,13 @@ func NewDefinitionOp(def *pb.Definition) (*DefinitionOp, error) { dgst = digest.FromBytes(dt) ops[dgst] = &op defs[dgst] = dt + + var platform *specs.Platform + if op.Platform != nil { + spec := op.Platform.Spec() + platform = &spec + } + platforms[dgst] = platform } var index pb.OutputIndex @@ -47,26 +59,29 @@ func NewDefinitionOp(def *pb.Definition) (*DefinitionOp, error) { ops: ops, defs: defs, metas: def.Metadata, - platforms: make(map[digest.Digest]*specs.Platform), + platforms: platforms, dgst: dgst, index: index, }, nil } -func (d *DefinitionOp) ToInput(c *Constraints) (*pb.Input, error) { - return d.Output().ToInput(c) +func (d *DefinitionOp) ToInput(ctx context.Context, c *Constraints) (*pb.Input, error) { + return d.Output().ToInput(ctx, c) } -func (d *DefinitionOp) Vertex() Vertex { +func (d *DefinitionOp) Vertex(context.Context) Vertex { return d } -func (d *DefinitionOp) Validate() error { +func (d *DefinitionOp) Validate(context.Context) error { // Scratch state has no digest, ops or metas. if d.dgst == "" { return nil } + d.mu.Lock() + defer d.mu.Unlock() + if len(d.ops) == 0 || len(d.defs) == 0 || len(d.metas) == 0 { return errors.Errorf("invalid definition op with no ops %d %d", len(d.ops), len(d.metas)) } @@ -95,15 +110,18 @@ func (d *DefinitionOp) Validate() error { return nil } -func (d *DefinitionOp) Marshal(c *Constraints) (digest.Digest, []byte, *pb.OpMetadata, error) { +func (d *DefinitionOp) Marshal(ctx context.Context, c *Constraints) (digest.Digest, []byte, *pb.OpMetadata, error) { if d.dgst == "" { return "", nil, nil, errors.Errorf("cannot marshal empty definition op") } - if err := d.Validate(); err != nil { + if err := d.Validate(ctx); err != nil { return "", nil, nil, err } + d.mu.Lock() + defer d.mu.Unlock() + meta := d.metas[d.dgst] return d.dgst, d.defs[d.dgst], &meta, nil @@ -114,7 +132,11 @@ func (d *DefinitionOp) Output() Output { return nil } - return &output{vertex: d, platform: d.platform(), getIndex: func() (pb.OutputIndex, error) { + d.mu.Lock() + platform := d.platforms[d.dgst] + d.mu.Unlock() + + return &output{vertex: d, platform: platform, getIndex: func() (pb.OutputIndex, error) { return d.index, nil }} } @@ -126,7 +148,11 @@ func (d *DefinitionOp) Inputs() []Output { var inputs []Output + d.mu.Lock() op := d.ops[d.dgst] + platform := d.platforms[d.dgst] + d.mu.Unlock() + for _, input := range op.Inputs { vtx := &DefinitionOp{ ops: d.ops, @@ -136,26 +162,10 @@ func (d *DefinitionOp) Inputs() []Output { dgst: input.Digest, index: input.Index, } - inputs = append(inputs, &output{vertex: vtx, platform: d.platform(), getIndex: func() (pb.OutputIndex, error) { + inputs = append(inputs, &output{vertex: vtx, platform: platform, getIndex: func() (pb.OutputIndex, error) { return pb.OutputIndex(vtx.index), nil }}) } return inputs } - -func (d *DefinitionOp) platform() *specs.Platform { - platform, ok := d.platforms[d.dgst] - if ok { - return platform - } - - op := d.ops[d.dgst] - if op.Platform != nil { - spec := op.Platform.Spec() - platform = &spec - } - - d.platforms[d.dgst] = platform - return platform -} diff --git a/vendor/github.com/moby/buildkit/client/llb/exec.go b/vendor/github.com/moby/buildkit/client/llb/exec.go index ade992780e..75617d94dc 100644 --- a/vendor/github.com/moby/buildkit/client/llb/exec.go +++ b/vendor/github.com/moby/buildkit/client/llb/exec.go @@ -1,6 +1,7 @@ package llb import ( + "context" _ "crypto/sha256" "fmt" "net" @@ -12,19 +13,9 @@ import ( "github.com/pkg/errors" ) -type Meta struct { - Args []string - Env EnvList - Cwd string - User string - ProxyEnv *ProxyEnv - ExtraHosts []HostIP - Network pb.NetMode - Security pb.SecurityMode -} - -func NewExecOp(root Output, meta Meta, readOnly bool, c Constraints) *ExecOp { - e := &ExecOp{meta: meta, constraints: c} +func NewExecOp(base State, proxyEnv *ProxyEnv, readOnly bool, c Constraints) *ExecOp { + e := &ExecOp{base: base, constraints: c, proxyEnv: proxyEnv} + root := base.Output() rootMount := &mount{ target: pb.RootMount, source: root, @@ -58,9 +49,10 @@ type mount struct { type ExecOp struct { MarshalCache + proxyEnv *ProxyEnv root Output mounts []*mount - meta Meta + base State constraints Constraints isValidated bool secrets []SecretInfo @@ -103,19 +95,27 @@ func (e *ExecOp) GetMount(target string) Output { return nil } -func (e *ExecOp) Validate() error { +func (e *ExecOp) Validate(ctx context.Context) error { if e.isValidated { return nil } - if len(e.meta.Args) == 0 { + args, err := getArgs(e.base)(ctx) + if err != nil { + return err + } + if len(args) == 0 { return errors.Errorf("arguments are required") } - if e.meta.Cwd == "" { + cwd, err := getDir(e.base)(ctx) + if err != nil { + return err + } + if cwd == "" { return errors.Errorf("working directory is required") } for _, m := range e.mounts { if m.source != nil { - if err := m.source.Vertex().Validate(); err != nil { + if err := m.source.Vertex(ctx).Validate(ctx); err != nil { return err } } @@ -124,11 +124,11 @@ func (e *ExecOp) Validate() error { return nil } -func (e *ExecOp) Marshal(c *Constraints) (digest.Digest, []byte, *pb.OpMetadata, error) { +func (e *ExecOp) Marshal(ctx context.Context, c *Constraints) (digest.Digest, []byte, *pb.OpMetadata, error) { if e.Cached(c) { return e.Load() } - if err := e.Validate(); err != nil { + if err := e.Validate(ctx); err != nil { return "", nil, nil, err } // make sure mounts are sorted @@ -136,52 +136,86 @@ func (e *ExecOp) Marshal(c *Constraints) (digest.Digest, []byte, *pb.OpMetadata, return e.mounts[i].target < e.mounts[j].target }) + env, err := getEnv(e.base)(ctx) + if err != nil { + return "", nil, nil, err + } + if len(e.ssh) > 0 { for i, s := range e.ssh { if s.Target == "" { e.ssh[i].Target = fmt.Sprintf("/run/buildkit/ssh_agent.%d", i) } } - if _, ok := e.meta.Env.Get("SSH_AUTH_SOCK"); !ok { - e.meta.Env = e.meta.Env.AddOrReplace("SSH_AUTH_SOCK", e.ssh[0].Target) + if _, ok := env.Get("SSH_AUTH_SOCK"); !ok { + env = env.AddOrReplace("SSH_AUTH_SOCK", e.ssh[0].Target) } } if c.Caps != nil { if err := c.Caps.Supports(pb.CapExecMetaSetsDefaultPath); err != nil { - e.meta.Env = e.meta.Env.SetDefault("PATH", system.DefaultPathEnv) + env = env.SetDefault("PATH", system.DefaultPathEnv) } else { addCap(&e.constraints, pb.CapExecMetaSetsDefaultPath) } } - meta := &pb.Meta{ - Args: e.meta.Args, - Env: e.meta.Env.ToArray(), - Cwd: e.meta.Cwd, - User: e.meta.User, + args, err := getArgs(e.base)(ctx) + if err != nil { + return "", nil, nil, err } - if len(e.meta.ExtraHosts) > 0 { - hosts := make([]*pb.HostIP, len(e.meta.ExtraHosts)) - for i, h := range e.meta.ExtraHosts { + + cwd, err := getDir(e.base)(ctx) + if err != nil { + return "", nil, nil, err + } + + user, err := getUser(e.base)(ctx) + if err != nil { + return "", nil, nil, err + } + + meta := &pb.Meta{ + Args: args, + Env: env.ToArray(), + Cwd: cwd, + User: user, + } + extraHosts, err := getExtraHosts(e.base)(ctx) + if err != nil { + return "", nil, nil, err + } + if len(extraHosts) > 0 { + hosts := make([]*pb.HostIP, len(extraHosts)) + for i, h := range extraHosts { hosts[i] = &pb.HostIP{Host: h.Host, IP: h.IP.String()} } meta.ExtraHosts = hosts } + network, err := getNetwork(e.base)(ctx) + if err != nil { + return "", nil, nil, err + } + + security, err := getSecurity(e.base)(ctx) + if err != nil { + return "", nil, nil, err + } + peo := &pb.ExecOp{ Meta: meta, - Network: e.meta.Network, - Security: e.meta.Security, + Network: network, + Security: security, } - if e.meta.Network != NetModeSandbox { + if network != NetModeSandbox { addCap(&e.constraints, pb.CapExecMetaNetwork) } - if e.meta.Security != SecurityModeSandbox { + if security != SecurityModeSandbox { addCap(&e.constraints, pb.CapExecMetaSecurity) } - if p := e.meta.ProxyEnv; p != nil { + if p := e.proxyEnv; p != nil { peo.Meta.ProxyEnv = &pb.ProxyEnv{ HttpProxy: p.HttpProxy, HttpsProxy: p.HttpsProxy, @@ -215,6 +249,14 @@ func (e *ExecOp) Marshal(c *Constraints) (digest.Digest, []byte, *pb.OpMetadata, addCap(&e.constraints, pb.CapExecMountSSH) } + if e.constraints.Platform == nil { + p, err := getPlatform(e.base)(ctx) + if err != nil { + return "", nil, nil, err + } + e.constraints.Platform = p + } + pop, md := MarshalConstraints(c, &e.constraints) pop.Op = &pb.Op_Exec{ Exec: peo, @@ -227,7 +269,7 @@ func (e *ExecOp) Marshal(c *Constraints) (digest.Digest, []byte, *pb.OpMetadata, if m.tmpfs { return "", nil, nil, errors.Errorf("tmpfs mounts must use scratch") } - inp, err := m.source.ToInput(c) + inp, err := m.source.ToInput(ctx, c) if err != nil { return "", nil, nil, err } @@ -414,17 +456,11 @@ func (fn runOptionFunc) SetRunOption(ei *ExecInfo) { fn(ei) } -func Network(n pb.NetMode) RunOption { - return runOptionFunc(func(ei *ExecInfo) { - ei.State = network(n)(ei.State) - }) +func (fn StateOption) SetRunOption(ei *ExecInfo) { + ei.State = ei.State.With(fn) } -func Security(s pb.SecurityMode) RunOption { - return runOptionFunc(func(ei *ExecInfo) { - ei.State = security(s)(ei.State) - }) -} +var _ RunOption = StateOption(func(_ State) State { return State{} }) func Shlex(str string) RunOption { return runOptionFunc(func(ei *ExecInfo) { @@ -443,47 +479,12 @@ func Args(a []string) RunOption { }) } -func AddEnv(key, value string) RunOption { - return runOptionFunc(func(ei *ExecInfo) { - ei.State = ei.State.AddEnv(key, value) - }) -} - -func AddEnvf(key, value string, v ...interface{}) RunOption { - return runOptionFunc(func(ei *ExecInfo) { - ei.State = ei.State.AddEnvf(key, value, v...) - }) -} - -func User(str string) RunOption { - return runOptionFunc(func(ei *ExecInfo) { - ei.State = ei.State.User(str) - }) -} - -func Dir(str string) RunOption { - return runOptionFunc(func(ei *ExecInfo) { - ei.State = ei.State.Dir(str) - }) -} -func Dirf(str string, v ...interface{}) RunOption { - return runOptionFunc(func(ei *ExecInfo) { - ei.State = ei.State.Dirf(str, v...) - }) -} - func AddExtraHost(host string, ip net.IP) RunOption { return runOptionFunc(func(ei *ExecInfo) { ei.State = ei.State.AddExtraHost(host, ip) }) } -func Reset(s State) RunOption { - return runOptionFunc(func(ei *ExecInfo) { - ei.State = ei.State.Reset(s) - }) -} - func With(so ...StateOption) RunOption { return runOptionFunc(func(ei *ExecInfo) { ei.State = ei.State.With(so...) diff --git a/vendor/github.com/moby/buildkit/client/llb/fileop.go b/vendor/github.com/moby/buildkit/client/llb/fileop.go index c95a1d6561..de1512348c 100644 --- a/vendor/github.com/moby/buildkit/client/llb/fileop.go +++ b/vendor/github.com/moby/buildkit/client/llb/fileop.go @@ -1,6 +1,7 @@ package llb import ( + "context" _ "crypto/sha256" "os" "path" @@ -52,7 +53,7 @@ type CopyInput interface { } type subAction interface { - toProtoAction(string, pb.InputIndex) pb.IsFileAction + toProtoAction(context.Context, string, pb.InputIndex) (pb.IsFileAction, error) } type FileAction struct { @@ -146,7 +147,7 @@ type fileActionMkdir struct { info MkdirInfo } -func (a *fileActionMkdir) toProtoAction(parent string, base pb.InputIndex) pb.IsFileAction { +func (a *fileActionMkdir) toProtoAction(ctx context.Context, parent string, base pb.InputIndex) (pb.IsFileAction, error) { return &pb.FileAction_Mkdir{ Mkdir: &pb.FileActionMkDir{ Path: normalizePath(parent, a.file, false), @@ -155,7 +156,7 @@ func (a *fileActionMkdir) toProtoAction(parent string, base pb.InputIndex) pb.Is Owner: a.info.ChownOpt.marshal(base), Timestamp: marshalTime(a.info.CreatedTime), }, - } + }, nil } type MkdirOption interface { @@ -315,7 +316,7 @@ type fileActionMkfile struct { info MkfileInfo } -func (a *fileActionMkfile) toProtoAction(parent string, base pb.InputIndex) pb.IsFileAction { +func (a *fileActionMkfile) toProtoAction(ctx context.Context, parent string, base pb.InputIndex) (pb.IsFileAction, error) { return &pb.FileAction_Mkfile{ Mkfile: &pb.FileActionMkFile{ Path: normalizePath(parent, a.file, false), @@ -324,7 +325,7 @@ func (a *fileActionMkfile) toProtoAction(parent string, base pb.InputIndex) pb.I Owner: a.info.ChownOpt.marshal(base), Timestamp: marshalTime(a.info.CreatedTime), }, - } + }, nil } func Rm(p string, opts ...RmOption) *FileAction { @@ -379,14 +380,14 @@ type fileActionRm struct { info RmInfo } -func (a *fileActionRm) toProtoAction(parent string, base pb.InputIndex) pb.IsFileAction { +func (a *fileActionRm) toProtoAction(ctx context.Context, parent string, base pb.InputIndex) (pb.IsFileAction, error) { return &pb.FileAction_Rm{ Rm: &pb.FileActionRm{ Path: normalizePath(parent, a.file, false), AllowNotFound: a.info.AllowNotFound, AllowWildcard: a.info.AllowWildcard, }, - } + }, nil } func Copy(input CopyInput, src, dest string, opts ...CopyOption) *FileAction { @@ -448,9 +449,13 @@ type fileActionCopy struct { info CopyInfo } -func (a *fileActionCopy) toProtoAction(parent string, base pb.InputIndex) pb.IsFileAction { +func (a *fileActionCopy) toProtoAction(ctx context.Context, parent string, base pb.InputIndex) (pb.IsFileAction, error) { + src, err := a.sourcePath(ctx) + if err != nil { + return nil, err + } c := &pb.FileActionCopy{ - Src: a.sourcePath(), + Src: src, Dest: normalizePath(parent, a.dest, true), Owner: a.info.ChownOpt.marshal(base), AllowWildcard: a.info.AllowWildcard, @@ -468,19 +473,27 @@ func (a *fileActionCopy) toProtoAction(parent string, base pb.InputIndex) pb.IsF } return &pb.FileAction_Copy{ Copy: c, - } + }, nil } -func (c *fileActionCopy) sourcePath() string { +func (c *fileActionCopy) sourcePath(ctx context.Context) (string, error) { p := path.Clean(c.src) if !path.IsAbs(p) { if c.state != nil { - p = path.Join("/", c.state.GetDir(), p) + dir, err := c.state.GetDir(ctx) + if err != nil { + return "", err + } + p = path.Join("/", dir, p) } else if c.fas != nil { - p = path.Join("/", c.fas.state.GetDir(), p) + dir, err := c.fas.state.GetDir(ctx) + if err != nil { + return "", err + } + p = path.Join("/", dir, p) } } - return p + return p, nil } type CreatedTime time.Time @@ -517,7 +530,7 @@ type FileOp struct { isValidated bool } -func (f *FileOp) Validate() error { +func (f *FileOp) Validate(context.Context) error { if f.isValidated { return nil } @@ -529,14 +542,16 @@ func (f *FileOp) Validate() error { } type marshalState struct { + ctx context.Context visited map[*FileAction]*fileActionState inputs []*pb.Input actions []*fileActionState } -func newMarshalState() *marshalState { +func newMarshalState(ctx context.Context) *marshalState { return &marshalState{ visited: map[*FileAction]*fileActionState{}, + ctx: ctx, } } @@ -552,7 +567,7 @@ type fileActionState struct { } func (ms *marshalState) addInput(st *fileActionState, c *Constraints, o Output) (pb.InputIndex, error) { - inp, err := o.ToInput(c) + inp, err := o.ToInput(ms.ctx, c) if err != nil { return 0, err } @@ -634,11 +649,11 @@ func (ms *marshalState) add(fa *FileAction, c *Constraints) (*fileActionState, e return st, nil } -func (f *FileOp) Marshal(c *Constraints) (digest.Digest, []byte, *pb.OpMetadata, error) { +func (f *FileOp) Marshal(ctx context.Context, c *Constraints) (digest.Digest, []byte, *pb.OpMetadata, error) { if f.Cached(c) { return f.Load() } - if err := f.Validate(); err != nil { + if err := f.Validate(ctx); err != nil { return "", nil, nil, err } @@ -651,7 +666,7 @@ func (f *FileOp) Marshal(c *Constraints) (digest.Digest, []byte, *pb.OpMetadata, File: pfo, } - state := newMarshalState() + state := newMarshalState(ctx) _, err := state.add(f.action, c) if err != nil { return "", nil, nil, err @@ -666,14 +681,22 @@ func (f *FileOp) Marshal(c *Constraints) (digest.Digest, []byte, *pb.OpMetadata, var parent string if st.fa.state != nil { - parent = st.fa.state.GetDir() + parent, err = st.fa.state.GetDir(ctx) + if err != nil { + return "", nil, nil, err + } + } + + action, err := st.action.toProtoAction(ctx, parent, st.base) + if err != nil { + return "", nil, nil, err } pfo.Actions = append(pfo.Actions, &pb.FileAction{ Input: getIndex(st.input, len(state.inputs), st.inputRelative), SecondaryInput: getIndex(st.input2, len(state.inputs), st.input2Relative), Output: output, - Action: st.action.toProtoAction(parent, st.base), + Action: action, }) } diff --git a/vendor/github.com/moby/buildkit/client/llb/meta.go b/vendor/github.com/moby/buildkit/client/llb/meta.go index 54b14c4c42..ab0f59328e 100644 --- a/vendor/github.com/moby/buildkit/client/llb/meta.go +++ b/vendor/github.com/moby/buildkit/client/llb/meta.go @@ -1,6 +1,7 @@ package llb import ( + "context" "fmt" "net" "path" @@ -24,79 +25,122 @@ var ( keySecurity = contextKeyT("llb.security") ) +func AddEnvf(key, value string, v ...interface{}) StateOption { + return addEnvf(key, value, true, v...) +} + +func AddEnv(key, value string) StateOption { + return addEnvf(key, value, false) +} + func addEnvf(key, value string, replace bool, v ...interface{}) StateOption { if replace { value = fmt.Sprintf(value, v...) } return func(s State) State { - return s.WithValue(keyEnv, getEnv(s).AddOrReplace(key, value)) + return s.withValue(keyEnv, func(ctx context.Context) (interface{}, error) { + env, err := getEnv(s)(ctx) + if err != nil { + return nil, err + } + return env.AddOrReplace(key, value), nil + }) } } -func dir(str string) StateOption { +func Dir(str string) StateOption { return dirf(str, false) } +func Dirf(str string, v ...interface{}) StateOption { + return dirf(str, true, v...) +} + func dirf(value string, replace bool, v ...interface{}) StateOption { if replace { value = fmt.Sprintf(value, v...) } return func(s State) State { - if !path.IsAbs(value) { - prev := getDir(s) - if prev == "" { - prev = "/" + return s.withValue(keyDir, func(ctx context.Context) (interface{}, error) { + if !path.IsAbs(value) { + prev, err := getDir(s)(ctx) + if err != nil { + return nil, err + } + if prev == "" { + prev = "/" + } + value = path.Join(prev, value) } - value = path.Join(prev, value) - } - return s.WithValue(keyDir, value) + return value, nil + }) } } -func user(str string) StateOption { +func User(str string) StateOption { return func(s State) State { return s.WithValue(keyUser, str) } } -func reset(s_ State) StateOption { +func Reset(other State) StateOption { return func(s State) State { s = NewState(s.Output()) - s.ctx = s_.ctx + s.prev = &other return s } } -func getEnv(s State) EnvList { - v := s.Value(keyEnv) - if v != nil { - return v.(EnvList) +func getEnv(s State) func(context.Context) (EnvList, error) { + return func(ctx context.Context) (EnvList, error) { + v, err := s.getValue(keyEnv)(ctx) + if err != nil { + return nil, err + } + if v != nil { + return v.(EnvList), nil + } + return EnvList{}, nil } - return EnvList{} } -func getDir(s State) string { - v := s.Value(keyDir) - if v != nil { - return v.(string) +func getDir(s State) func(context.Context) (string, error) { + return func(ctx context.Context) (string, error) { + v, err := s.getValue(keyDir)(ctx) + if err != nil { + return "", err + } + if v != nil { + return v.(string), nil + } + return "", nil } - return "" } -func getArgs(s State) []string { - v := s.Value(keyArgs) - if v != nil { - return v.([]string) +func getArgs(s State) func(context.Context) ([]string, error) { + return func(ctx context.Context) ([]string, error) { + v, err := s.getValue(keyArgs)(ctx) + if err != nil { + return nil, err + } + if v != nil { + return v.([]string), nil + } + return nil, nil } - return nil } -func getUser(s State) string { - v := s.Value(keyUser) - if v != nil { - return v.(string) +func getUser(s State) func(context.Context) (string, error) { + return func(ctx context.Context) (string, error) { + v, err := s.getValue(keyUser)(ctx) + if err != nil { + return "", err + } + if v != nil { + return v.(string), nil + } + return "", nil } - return "" } func args(args ...string) StateOption { @@ -124,27 +168,43 @@ func platform(p specs.Platform) StateOption { } } -func getPlatform(s State) *specs.Platform { - v := s.Value(keyPlatform) - if v != nil { - p := v.(specs.Platform) - return &p +func getPlatform(s State) func(context.Context) (*specs.Platform, error) { + return func(ctx context.Context) (*specs.Platform, error) { + v, err := s.getValue(keyPlatform)(ctx) + if err != nil { + return nil, err + } + if v != nil { + p := v.(specs.Platform) + return &p, nil + } + return nil, nil } - return nil } func extraHost(host string, ip net.IP) StateOption { return func(s State) State { - return s.WithValue(keyExtraHost, append(getExtraHosts(s), HostIP{Host: host, IP: ip})) + return s.withValue(keyExtraHost, func(ctx context.Context) (interface{}, error) { + v, err := getExtraHosts(s)(ctx) + if err != nil { + return nil, err + } + return append(v, HostIP{Host: host, IP: ip}), nil + }) } } -func getExtraHosts(s State) []HostIP { - v := s.Value(keyExtraHost) - if v != nil { - return v.([]HostIP) +func getExtraHosts(s State) func(context.Context) ([]HostIP, error) { + return func(ctx context.Context) ([]HostIP, error) { + v, err := s.getValue(keyExtraHost)(ctx) + if err != nil { + return nil, err + } + if v != nil { + return v.([]HostIP), nil + } + return nil, nil } - return nil } type HostIP struct { @@ -152,32 +212,42 @@ type HostIP struct { IP net.IP } -func network(v pb.NetMode) StateOption { +func Network(v pb.NetMode) StateOption { return func(s State) State { return s.WithValue(keyNetwork, v) } } -func getNetwork(s State) pb.NetMode { - v := s.Value(keyNetwork) - if v != nil { - n := v.(pb.NetMode) - return n +func getNetwork(s State) func(context.Context) (pb.NetMode, error) { + return func(ctx context.Context) (pb.NetMode, error) { + v, err := s.getValue(keyNetwork)(ctx) + if err != nil { + return 0, err + } + if v != nil { + n := v.(pb.NetMode) + return n, nil + } + return NetModeSandbox, nil } - return NetModeSandbox } -func security(v pb.SecurityMode) StateOption { +func Security(v pb.SecurityMode) StateOption { return func(s State) State { return s.WithValue(keySecurity, v) } } -func getSecurity(s State) pb.SecurityMode { - v := s.Value(keySecurity) - if v != nil { - n := v.(pb.SecurityMode) - return n +func getSecurity(s State) func(context.Context) (pb.SecurityMode, error) { + return func(ctx context.Context) (pb.SecurityMode, error) { + v, err := s.getValue(keySecurity)(ctx) + if err != nil { + return 0, err + } + if v != nil { + n := v.(pb.SecurityMode) + return n, nil + } + return SecurityModeSandbox, nil } - return SecurityModeSandbox } type EnvList []KeyValue diff --git a/vendor/github.com/moby/buildkit/client/llb/resolver.go b/vendor/github.com/moby/buildkit/client/llb/resolver.go index 73d89e1936..31fc395993 100644 --- a/vendor/github.com/moby/buildkit/client/llb/resolver.go +++ b/vendor/github.com/moby/buildkit/client/llb/resolver.go @@ -14,6 +14,15 @@ func WithMetaResolver(mr ImageMetaResolver) ImageOption { }) } +// ResolveDigest uses the meta resolver to update the ref of image with full digest before marshaling. +// This makes image ref immutable and is recommended if you want to make sure meta resolver data +// matches the image used during the build. +func ResolveDigest(v bool) ImageOption { + return imageOptionFunc(func(ii *ImageInfo) { + ii.resolveDigest = v + }) +} + // ImageMetaResolver can resolve image config metadata from a reference type ImageMetaResolver interface { ResolveImageConfig(ctx context.Context, ref string, opt ResolveImageConfigOpt) (digest.Digest, []byte, error) diff --git a/vendor/github.com/moby/buildkit/client/llb/source.go b/vendor/github.com/moby/buildkit/client/llb/source.go index 662966e331..b64cfbcc5e 100644 --- a/vendor/github.com/moby/buildkit/client/llb/source.go +++ b/vendor/github.com/moby/buildkit/client/llb/source.go @@ -34,7 +34,7 @@ func NewSource(id string, attrs map[string]string, c Constraints) *SourceOp { return s } -func (s *SourceOp) Validate() error { +func (s *SourceOp) Validate(ctx context.Context) error { if s.err != nil { return s.err } @@ -44,11 +44,11 @@ func (s *SourceOp) Validate() error { return nil } -func (s *SourceOp) Marshal(constraints *Constraints) (digest.Digest, []byte, *pb.OpMetadata, error) { +func (s *SourceOp) Marshal(ctx context.Context, constraints *Constraints) (digest.Digest, []byte, *pb.OpMetadata, error) { if s.Cached(constraints) { return s.Load() } - if err := s.Validate(); err != nil { + if err := s.Validate(ctx); err != nil { return "", nil, nil, err } @@ -92,7 +92,8 @@ func (s *SourceOp) Inputs() []Output { func Image(ref string, opts ...ImageOption) State { r, err := reference.ParseNormalizedNamed(ref) if err == nil { - ref = reference.TagNameOnly(r).String() + r = reference.TagNameOnly(r) + ref = r.String() } var info ImageInfo for _, opt := range opts { @@ -116,21 +117,35 @@ func Image(ref string, opts ...ImageOption) State { src := NewSource("docker-image://"+ref, attrs, info.Constraints) // controversial if err != nil { src.err = err - } - if info.metaResolver != nil { - _, dt, err := info.metaResolver.ResolveImageConfig(context.TODO(), ref, ResolveImageConfigOpt{ - Platform: info.Constraints.Platform, - ResolveMode: info.resolveMode.String(), - }) - if err != nil { - src.err = err - } else { - st, err := NewState(src.Output()).WithImageConfig(dt) - if err == nil { - return st - } - src.err = err + } else if info.metaResolver != nil { + if _, ok := r.(reference.Digested); ok || !info.resolveDigest { + return NewState(src.Output()).Async(func(ctx context.Context, st State) (State, error) { + _, dt, err := info.metaResolver.ResolveImageConfig(ctx, ref, ResolveImageConfigOpt{ + Platform: info.Constraints.Platform, + ResolveMode: info.resolveMode.String(), + }) + if err != nil { + return State{}, err + } + return st.WithImageConfig(dt) + }) } + return Scratch().Async(func(ctx context.Context, _ State) (State, error) { + dgst, dt, err := info.metaResolver.ResolveImageConfig(context.TODO(), ref, ResolveImageConfigOpt{ + Platform: info.Constraints.Platform, + ResolveMode: info.resolveMode.String(), + }) + if err != nil { + return State{}, err + } + if dgst != "" { + r, err = reference.WithDigest(r, dgst) + if err != nil { + return State{}, err + } + } + return NewState(NewSource("docker-image://"+r.String(), attrs, info.Constraints).Output()).WithImageConfig(dt) + }) } return NewState(src.Output()) } @@ -176,9 +191,10 @@ func (r ResolveMode) String() string { type ImageInfo struct { constraintsWrapper - metaResolver ImageMetaResolver - resolveMode ResolveMode - RecordType string + metaResolver ImageMetaResolver + resolveDigest bool + resolveMode ResolveMode + RecordType string } func Git(remote, ref string, opts ...GitOption) State { diff --git a/vendor/github.com/moby/buildkit/client/llb/state.go b/vendor/github.com/moby/buildkit/client/llb/state.go index ba8845e086..195cee3e3d 100644 --- a/vendor/github.com/moby/buildkit/client/llb/state.go +++ b/vendor/github.com/moby/buildkit/client/llb/state.go @@ -18,13 +18,13 @@ import ( type StateOption func(State) State type Output interface { - ToInput(*Constraints) (*pb.Input, error) - Vertex() Vertex + ToInput(context.Context, *Constraints) (*pb.Input, error) + Vertex(context.Context) Vertex } type Vertex interface { - Validate() error - Marshal(*Constraints) (digest.Digest, []byte, *pb.OpMetadata, error) + Validate(context.Context) error + Marshal(context.Context, *Constraints) (digest.Digest, []byte, *pb.OpMetadata, error) Output() Output Inputs() []Output } @@ -32,17 +32,18 @@ type Vertex interface { func NewState(o Output) State { s := State{ out: o, - ctx: context.Background(), - } - s = dir("/")(s) + }.Dir("/") s = s.ensurePlatform() return s } type State struct { - out Output - ctx context.Context - opts []ConstraintsOpt + out Output + prev *State + key interface{} + value func(context.Context) (interface{}, error) + opts []ConstraintsOpt + async *asyncState } func (s State) ensurePlatform() State { @@ -57,14 +58,48 @@ func (s State) ensurePlatform() State { } func (s State) WithValue(k, v interface{}) State { + return s.withValue(k, func(context.Context) (interface{}, error) { + return v, nil + }) +} + +func (s State) withValue(k interface{}, v func(context.Context) (interface{}, error)) State { return State{ - out: s.out, - ctx: context.WithValue(s.ctx, k, v), + out: s.Output(), + prev: &s, // doesn't need to be original pointer + key: k, + value: v, } } -func (s State) Value(k interface{}) interface{} { - return s.ctx.Value(k) +func (s State) Value(ctx context.Context, k interface{}) (interface{}, error) { + return s.getValue(k)(ctx) +} + +func (s State) getValue(k interface{}) func(context.Context) (interface{}, error) { + if s.key == k { + return s.value + } + if s.async != nil { + return func(ctx context.Context) (interface{}, error) { + err := s.async.Do(ctx) + if err != nil { + return nil, err + } + return s.async.target.getValue(k)(ctx) + } + } + if s.prev == nil { + return nilValue + } + return s.prev.getValue(k) +} + +func (s State) Async(f func(context.Context, State) (State, error)) State { + s2 := State{ + async: &asyncState{f: f, prev: s}, + } + return s2 } func (s State) SetMarshalDefaults(co ...ConstraintsOpt) State { @@ -72,11 +107,11 @@ func (s State) SetMarshalDefaults(co ...ConstraintsOpt) State { return s } -func (s State) Marshal(co ...ConstraintsOpt) (*Definition, error) { +func (s State) Marshal(ctx context.Context, co ...ConstraintsOpt) (*Definition, error) { def := &Definition{ Metadata: make(map[digest.Digest]pb.OpMetadata, 0), } - if s.Output() == nil { + if s.Output() == nil || s.Output().Vertex(ctx) == nil { return def, nil } @@ -89,11 +124,11 @@ func (s State) Marshal(co ...ConstraintsOpt) (*Definition, error) { o.SetConstraintsOption(c) } - def, err := marshal(s.Output().Vertex(), def, map[digest.Digest]struct{}{}, map[Vertex]struct{}{}, c) + def, err := marshal(ctx, s.Output().Vertex(ctx), def, map[digest.Digest]struct{}{}, map[Vertex]struct{}{}, c) if err != nil { return def, err } - inp, err := s.Output().ToInput(c) + inp, err := s.Output().ToInput(ctx, c) if err != nil { return def, err } @@ -128,19 +163,19 @@ func (s State) Marshal(co ...ConstraintsOpt) (*Definition, error) { return def, nil } -func marshal(v Vertex, def *Definition, cache map[digest.Digest]struct{}, vertexCache map[Vertex]struct{}, c *Constraints) (*Definition, error) { +func marshal(ctx context.Context, v Vertex, def *Definition, cache map[digest.Digest]struct{}, vertexCache map[Vertex]struct{}, c *Constraints) (*Definition, error) { if _, ok := vertexCache[v]; ok { return def, nil } for _, inp := range v.Inputs() { var err error - def, err = marshal(inp.Vertex(), def, cache, vertexCache, c) + def, err = marshal(ctx, inp.Vertex(ctx), def, cache, vertexCache, c) if err != nil { return def, err } } - dgst, dt, opMeta, err := v.Marshal(c) + dgst, dt, opMeta, err := v.Marshal(ctx, c) if err != nil { return def, err } @@ -156,18 +191,22 @@ func marshal(v Vertex, def *Definition, cache map[digest.Digest]struct{}, vertex return def, nil } -func (s State) Validate() error { - return s.Output().Vertex().Validate() +func (s State) Validate(ctx context.Context) error { + return s.Output().Vertex(ctx).Validate(ctx) } func (s State) Output() Output { + if s.async != nil { + return s.async.Output() + } return s.out } func (s State) WithOutput(o Output) State { + prev := s s = State{ - out: o, - ctx: s.ctx, + out: o, + prev: &prev, } s = s.ensurePlatform() return s @@ -200,24 +239,10 @@ func (s State) WithImageConfig(c []byte) (State, error) { func (s State) Run(ro ...RunOption) ExecState { ei := &ExecInfo{State: s} - if p := s.GetPlatform(); p != nil { - ei.Constraints.Platform = p - } for _, o := range ro { o.SetRunOption(ei) } - meta := Meta{ - Args: getArgs(ei.State), - Cwd: getDir(ei.State), - Env: getEnv(ei.State), - User: getUser(ei.State), - ProxyEnv: ei.ProxyEnv, - ExtraHosts: getExtraHosts(ei.State), - Network: getNetwork(ei.State), - Security: getSecurity(ei.State), - } - - exec := NewExecOp(s.Output(), meta, ei.ReadonlyRootFS, ei.Constraints) + exec := NewExecOp(ei.State, ei.ProxyEnv, ei.ReadonlyRootFS, ei.Constraints) for _, m := range ei.Mounts { exec.AddMount(m.Target, m.Source, m.Opts...) } @@ -240,65 +265,74 @@ func (s State) File(a *FileAction, opts ...ConstraintsOpt) State { } func (s State) AddEnv(key, value string) State { - return addEnvf(key, value, false)(s) + return AddEnv(key, value)(s) } func (s State) AddEnvf(key, value string, v ...interface{}) State { - return addEnvf(key, value, true, v...)(s) + return AddEnvf(key, value, v...)(s) } func (s State) Dir(str string) State { - return dirf(str, false)(s) + return Dir(str)(s) } func (s State) Dirf(str string, v ...interface{}) State { - return dirf(str, true, v...)(s) + return Dirf(str, v...)(s) } -func (s State) GetEnv(key string) (string, bool) { - return getEnv(s).Get(key) +func (s State) GetEnv(ctx context.Context, key string) (string, bool, error) { + env, err := getEnv(s)(ctx) + if err != nil { + return "", false, err + } + v, ok := env.Get(key) + return v, ok, nil } -func (s State) Env() []string { - return getEnv(s).ToArray() +func (s State) Env(ctx context.Context) ([]string, error) { + env, err := getEnv(s)(ctx) + if err != nil { + return nil, err + } + return env.ToArray(), nil } -func (s State) GetDir() string { - return getDir(s) +func (s State) GetDir(ctx context.Context) (string, error) { + return getDir(s)(ctx) } -func (s State) GetArgs() []string { - return getArgs(s) +func (s State) GetArgs(ctx context.Context) ([]string, error) { + return getArgs(s)(ctx) } func (s State) Reset(s2 State) State { - return reset(s2)(s) + return Reset(s2)(s) } func (s State) User(v string) State { - return user(v)(s) + return User(v)(s) } func (s State) Platform(p specs.Platform) State { return platform(p)(s) } -func (s State) GetPlatform() *specs.Platform { - return getPlatform(s) +func (s State) GetPlatform(ctx context.Context) (*specs.Platform, error) { + return getPlatform(s)(ctx) } func (s State) Network(n pb.NetMode) State { - return network(n)(s) + return Network(n)(s) } -func (s State) GetNetwork() pb.NetMode { - return getNetwork(s) +func (s State) GetNetwork(ctx context.Context) (pb.NetMode, error) { + return getNetwork(s)(ctx) } func (s State) Security(n pb.SecurityMode) State { - return security(n)(s) + return Security(n)(s) } -func (s State) GetSecurity() pb.SecurityMode { - return getSecurity(s) +func (s State) GetSecurity(ctx context.Context) (pb.SecurityMode, error) { + return getSecurity(s)(ctx) } func (s State) With(so ...StateOption) State { @@ -321,7 +355,7 @@ type output struct { platform *specs.Platform } -func (o *output) ToInput(c *Constraints) (*pb.Input, error) { +func (o *output) ToInput(ctx context.Context, c *Constraints) (*pb.Input, error) { if o.err != nil { return nil, o.err } @@ -333,14 +367,14 @@ func (o *output) ToInput(c *Constraints) (*pb.Input, error) { return nil, err } } - dgst, _, _, err := o.vertex.Marshal(c) + dgst, _, _, err := o.vertex.Marshal(ctx, c) if err != nil { return nil, err } return &pb.Input{Digest: dgst, Index: index}, nil } -func (o *output) Vertex() Vertex { +func (o *output) Vertex(context.Context) Vertex { return o.vertex } @@ -513,3 +547,7 @@ func Require(filters ...string) ConstraintsOpt { } }) } + +func nilValue(context.Context) (interface{}, error) { + return nil, nil +} diff --git a/vendor/github.com/moby/buildkit/client/solve.go b/vendor/github.com/moby/buildkit/client/solve.go index ef0c74e0c9..1d77bc4588 100644 --- a/vendor/github.com/moby/buildkit/client/solve.go +++ b/vendor/github.com/moby/buildkit/client/solve.go @@ -115,6 +115,12 @@ func (c *Client) solve(ctx context.Context, def *llb.Definition, runGateway runG } var ex ExportEntry + if len(opt.Exports) > 1 { + return nil, errors.New("currently only single Exports can be specified") + } + if len(opt.Exports) == 1 { + ex = opt.Exports[0] + } if !opt.SessionPreInitialized { if len(syncedDirs) > 0 { @@ -125,13 +131,6 @@ func (c *Client) solve(ctx context.Context, def *llb.Definition, runGateway runG s.Allow(a) } - if len(opt.Exports) > 1 { - return nil, errors.New("currently only single Exports can be specified") - } - if len(opt.Exports) == 1 { - ex = opt.Exports[0] - } - switch ex.Type { case ExporterLocal: if ex.Output != nil { @@ -192,7 +191,7 @@ func (c *Client) solve(ctx context.Context, def *llb.Definition, runGateway runG frontendInputs := make(map[string]*pb.Definition) for key, st := range opt.FrontendInputs { - def, err := st.Marshal() + def, err := st.Marshal(ctx) if err != nil { return err } @@ -435,13 +434,13 @@ func parseCacheOptions(opt SolveOpt) (*cacheOptions, error) { continue } for _, m := range idx.Manifests { - if m.Annotations[ocispec.AnnotationRefName] == "latest" { + if (m.Annotations[ocispec.AnnotationRefName] == "latest" && attrs["tag"] == "") || (attrs["tag"] != "" && m.Annotations[ocispec.AnnotationRefName] == attrs["tag"]) { attrs["digest"] = string(m.Digest) break } } if attrs["digest"] == "" { - return nil, errors.New("local cache importer requires either explicit digest or \"latest\" tag on index.json") + return nil, errors.New("local cache importer requires either explicit digest, \"latest\" tag or custom tag on index.json") } } contentStores["local:"+csDir] = cs diff --git a/vendor/github.com/moby/buildkit/cmd/buildkitd/config/config.go b/vendor/github.com/moby/buildkit/cmd/buildkitd/config/config.go new file mode 100644 index 0000000000..fc2da18fcc --- /dev/null +++ b/vendor/github.com/moby/buildkit/cmd/buildkitd/config/config.go @@ -0,0 +1,105 @@ +package config + +// Config provides containerd configuration data for the server +type Config struct { + Debug bool `toml:"debug"` + + // Root is the path to a directory where buildkit will store persistent data + Root string `toml:"root"` + + //Entitlements e.g. security.insecure, network.host + Entitlements []string `toml:"insecure-entitlements"` + // GRPC configuration settings + GRPC GRPCConfig `toml:"grpc"` + + Workers struct { + OCI OCIConfig `toml:"oci"` + Containerd ContainerdConfig `toml:"containerd"` + } `toml:"worker"` + + Registries map[string]RegistryConfig `toml:"registry"` + + DNS *DNSConfig `toml:"dns"` +} + +type GRPCConfig struct { + Address []string `toml:"address"` + DebugAddress string `toml:"debugAddress"` + UID int `toml:"uid"` + GID int `toml:"gid"` + + TLS TLSConfig `toml:"tls"` + // MaxRecvMsgSize int `toml:"max_recv_message_size"` + // MaxSendMsgSize int `toml:"max_send_message_size"` +} + +type RegistryConfig struct { + Mirrors []string `toml:"mirrors"` + PlainHTTP *bool `toml:"http"` + Insecure *bool `toml:"insecure"` + RootCAs []string `toml:"ca"` + KeyPairs []TLSKeyPair `toml:"keypair"` + TLSConfigDir []string `toml:"tlsconfigdir"` +} + +type TLSKeyPair struct { + Key string `toml:"key"` + Certificate string `toml:"cert"` +} + +type TLSConfig struct { + Cert string `toml:"cert"` + Key string `toml:"key"` + CA string `toml:"ca"` +} + +type GCConfig struct { + GC *bool `toml:"gc"` + GCKeepStorage int64 `toml:"gckeepstorage"` + GCPolicy []GCPolicy `toml:"gcpolicy"` +} + +type NetworkConfig struct { + Mode string `toml:"networkMode"` + CNIConfigPath string `toml:"cniConfigPath"` + CNIBinaryPath string `toml:"cniBinaryPath"` +} + +type OCIConfig struct { + Enabled *bool `toml:"enabled"` + Labels map[string]string `toml:"labels"` + Platforms []string `toml:"platforms"` + Snapshotter string `toml:"snapshotter"` + Rootless bool `toml:"rootless"` + NoProcessSandbox bool `toml:"noProcessSandbox"` + GCConfig + NetworkConfig + // UserRemapUnsupported is unsupported key for testing. The feature is + // incomplete and the intention is to make it default without config. + UserRemapUnsupported string `toml:"userRemapUnsupported"` + // For use in storing the OCI worker binary name that will replace buildkit-runc + Binary string `toml:"binary"` +} + +type ContainerdConfig struct { + Address string `toml:"address"` + Enabled *bool `toml:"enabled"` + Labels map[string]string `toml:"labels"` + Platforms []string `toml:"platforms"` + Namespace string `toml:"namespace"` + GCConfig + NetworkConfig +} + +type GCPolicy struct { + All bool `toml:"all"` + KeepBytes int64 `toml:"keepBytes"` + KeepDuration int64 `toml:"keepDuration"` + Filters []string `toml:"filters"` +} + +type DNSConfig struct { + Nameservers []string `toml:"nameservers"` + Options []string `toml:"options"` + SearchDomains []string `toml:"searchDomains"` +} diff --git a/vendor/github.com/moby/buildkit/cmd/buildkitd/config/gcpolicy.go b/vendor/github.com/moby/buildkit/cmd/buildkitd/config/gcpolicy.go new file mode 100644 index 0000000000..6f3f197893 --- /dev/null +++ b/vendor/github.com/moby/buildkit/cmd/buildkitd/config/gcpolicy.go @@ -0,0 +1,31 @@ +package config + +const defaultCap int64 = 2e9 // 2GB + +func DefaultGCPolicy(p string, keep int64) []GCPolicy { + if keep == 0 { + keep = DetectDefaultGCCap(p) + } + return []GCPolicy{ + // if build cache uses more than 512MB delete the most easily reproducible data after it has not been used for 2 days + { + Filters: []string{"type==source.local,type==exec.cachemount,type==source.git.checkout"}, + KeepDuration: 48 * 3600, // 48h + KeepBytes: 512 * 1e6, // 512MB + }, + // remove any data not used for 60 days + { + KeepDuration: 60 * 24 * 3600, // 60d + KeepBytes: keep, + }, + // keep the unshared build cache under cap + { + KeepBytes: keep, + }, + // if previous policies were insufficient start deleting internal data to keep build cache under cap + { + All: true, + KeepBytes: keep, + }, + } +} diff --git a/vendor/github.com/moby/buildkit/cmd/buildkitd/config/gcpolicy_unix.go b/vendor/github.com/moby/buildkit/cmd/buildkitd/config/gcpolicy_unix.go new file mode 100644 index 0000000000..e022fba888 --- /dev/null +++ b/vendor/github.com/moby/buildkit/cmd/buildkitd/config/gcpolicy_unix.go @@ -0,0 +1,17 @@ +// +build !windows + +package config + +import ( + "syscall" +) + +func DetectDefaultGCCap(root string) int64 { + var st syscall.Statfs_t + if err := syscall.Statfs(root, &st); err != nil { + return defaultCap + } + diskSize := int64(st.Bsize) * int64(st.Blocks) + avail := diskSize / 10 + return (avail/(1<<30) + 1) * 1e9 // round up +} diff --git a/vendor/github.com/moby/buildkit/cmd/buildkitd/config/gcpolicy_windows.go b/vendor/github.com/moby/buildkit/cmd/buildkitd/config/gcpolicy_windows.go new file mode 100644 index 0000000000..81d4b82c4a --- /dev/null +++ b/vendor/github.com/moby/buildkit/cmd/buildkitd/config/gcpolicy_windows.go @@ -0,0 +1,7 @@ +// +build windows + +package config + +func DetectDefaultGCCap(root string) int64 { + return defaultCap +} diff --git a/vendor/github.com/moby/buildkit/frontend/dockerfile/builder/build.go b/vendor/github.com/moby/buildkit/frontend/dockerfile/builder/build.go index e3fb9afdb0..efcf7d851e 100644 --- a/vendor/github.com/moby/buildkit/frontend/dockerfile/builder/build.go +++ b/vendor/github.com/moby/buildkit/frontend/dockerfile/builder/build.go @@ -139,7 +139,7 @@ func Build(ctx context.Context, c client.Client) (*client.Result, error) { buildContext = st } else if httpPrefix.MatchString(opts[localNameContext]) { httpContext := llb.HTTP(opts[localNameContext], llb.Filename("context"), dockerfile2llb.WithInternalName("load remote build context")) - def, err := httpContext.Marshal(marshalOpts...) + def, err := httpContext.Marshal(ctx, marshalOpts...) if err != nil { return nil, errors.Wrapf(err, "failed to marshal httpcontext") } @@ -221,7 +221,7 @@ func Build(ctx context.Context, c client.Client) (*client.Result, error) { } } - def, err := src.Marshal(marshalOpts...) + def, err := src.Marshal(ctx, marshalOpts...) if err != nil { return nil, errors.Wrapf(err, "failed to marshal local source") } @@ -271,7 +271,7 @@ func Build(ctx context.Context, c client.Client) (*client.Result, error) { ) dockerignoreState = &st } - def, err := dockerignoreState.Marshal(marshalOpts...) + def, err := dockerignoreState.Marshal(ctx, marshalOpts...) if err != nil { return err } @@ -363,7 +363,7 @@ func Build(ctx context.Context, c client.Client) (*client.Result, error) { return errors.Wrapf(err, "failed to create LLB definition") } - def, err := st.Marshal() + def, err := st.Marshal(ctx) if err != nil { return errors.Wrapf(err, "failed to marshal LLB definition") } @@ -456,9 +456,29 @@ func forwardGateway(ctx context.Context, c client.Client, ref string, cmdline st } opts["cmdline"] = cmdline opts["source"] = ref + + gwcaps := c.BuildOpts().Caps + var frontendInputs map[string]*pb.Definition + if (&gwcaps).Supports(gwpb.CapFrontendInputs) == nil { + inputs, err := c.Inputs(ctx) + if err != nil { + return nil, errors.Wrapf(err, "failed to get frontend inputs") + } + + frontendInputs = make(map[string]*pb.Definition) + for name, state := range inputs { + def, err := state.Marshal(ctx) + if err != nil { + return nil, err + } + frontendInputs[name] = def.ToPB() + } + } + return c.Solve(ctx, client.SolveRequest{ - Frontend: "gateway.v0", - FrontendOpt: opts, + Frontend: "gateway.v0", + FrontendOpt: opts, + FrontendInputs: frontendInputs, }) } diff --git a/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert.go b/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert.go index b911938a58..441075a40e 100644 --- a/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert.go +++ b/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert.go @@ -462,7 +462,11 @@ type dispatchOpt struct { func dispatch(d *dispatchState, cmd command, opt dispatchOpt) error { if ex, ok := cmd.Command.(instructions.SupportsSingleWordExpansion); ok { err := ex.Expand(func(word string) (string, error) { - return opt.shlex.ProcessWord(word, d.state.Env()) + env, err := d.state.Env(context.TODO()) + if err != nil { + return "", err + } + return opt.shlex.ProcessWord(word, env) }) if err != nil { return err @@ -626,7 +630,10 @@ func dispatchRun(d *dispatchState, c *instructions.RunCommand, proxy *llb.ProxyE if c.PrependShell { args = withShell(d.image, args) } - env := d.state.Env() + env, err := d.state.Env(context.TODO()) + if err != nil { + return err + } opt := []llb.RunOption{llb.Args(args), dfCmd(c)} if d.ignoreCache { opt = append(opt, llb.IgnoreCache) @@ -661,7 +668,11 @@ func dispatchRun(d *dispatchState, c *instructions.RunCommand, proxy *llb.ProxyE shlex.RawQuotes = true shlex.SkipUnsetEnv = true - opt = append(opt, llb.WithCustomName(prefixCommand(d, uppercaseCmd(processCmdEnv(&shlex, c.String(), env)), d.prefixPlatform, d.state.GetPlatform()))) + pl, err := d.state.GetPlatform(context.TODO()) + if err != nil { + return err + } + opt = append(opt, llb.WithCustomName(prefixCommand(d, uppercaseCmd(processCmdEnv(&shlex, c.String(), env)), d.prefixPlatform, pl))) for _, h := range dopt.extraHosts { opt = append(opt, llb.AddExtraHost(h.Host, h.IP)) } @@ -687,7 +698,11 @@ func dispatchWorkdir(d *dispatchState, c *instructions.WorkdirCommand, commit bo if d.platform != nil { platform = *d.platform } - d.state = d.state.File(llb.Mkdir(wd, 0755, mkdirOpt...), llb.WithCustomName(prefixCommand(d, uppercaseCmd(processCmdEnv(opt.shlex, c.String(), d.state.Env())), d.prefixPlatform, &platform))) + env, err := d.state.Env(context.TODO()) + if err != nil { + return err + } + d.state = d.state.File(llb.Mkdir(wd, 0755, mkdirOpt...), llb.WithCustomName(prefixCommand(d, uppercaseCmd(processCmdEnv(opt.shlex, c.String(), env)), d.prefixPlatform, &platform))) withLayer = true } return commitToHistory(&d.image, "WORKDIR "+wd, withLayer, nil) @@ -696,7 +711,11 @@ func dispatchWorkdir(d *dispatchState, c *instructions.WorkdirCommand, commit bo } func dispatchCopyFileOp(d *dispatchState, c instructions.SourcesAndDest, sourceState llb.State, isAddCommand bool, cmdToPrint fmt.Stringer, chown string, opt dispatchOpt) error { - dest := path.Join("/", pathRelativeToWorkingDir(d.state, c.Dest())) + pp, err := pathRelativeToWorkingDir(d.state, c.Dest()) + if err != nil { + return err + } + dest := path.Join("/", pp) if c.Dest() == "." || c.Dest() == "" || c.Dest()[len(c.Dest())-1] == filepath.Separator { dest += string(filepath.Separator) } @@ -772,7 +791,12 @@ func dispatchCopyFileOp(d *dispatchState, c instructions.SourcesAndDest, sourceS platform = *d.platform } - fileOpt := []llb.ConstraintsOpt{llb.WithCustomName(prefixCommand(d, uppercaseCmd(processCmdEnv(opt.shlex, cmdToPrint.String(), d.state.Env())), d.prefixPlatform, &platform))} + env, err := d.state.Env(context.TODO()) + if err != nil { + return err + } + + fileOpt := []llb.ConstraintsOpt{llb.WithCustomName(prefixCommand(d, uppercaseCmd(processCmdEnv(opt.shlex, cmdToPrint.String(), env)), d.prefixPlatform, &platform))} if d.ignoreCache { fileOpt = append(fileOpt, llb.IgnoreCache) } @@ -787,8 +811,11 @@ func dispatchCopy(d *dispatchState, c instructions.SourcesAndDest, sourceState l } img := llb.Image(opt.copyImage, llb.MarkImageInternal, llb.Platform(opt.buildPlatforms[0]), WithInternalName("helper image for file operations")) - - dest := path.Join(".", pathRelativeToWorkingDir(d.state, c.Dest())) + pp, err := pathRelativeToWorkingDir(d.state, c.Dest()) + if err != nil { + return err + } + dest := path.Join(".", pp) if c.Dest() == "." || c.Dest() == "" || c.Dest()[len(c.Dest())-1] == filepath.Separator { dest += string(filepath.Separator) } @@ -861,7 +888,12 @@ func dispatchCopy(d *dispatchState, c instructions.SourcesAndDest, sourceState l platform = *d.platform } - runOpt := []llb.RunOption{llb.Args(args), llb.Dir("/dest"), llb.ReadonlyRootFS(), dfCmd(cmdToPrint), llb.WithCustomName(prefixCommand(d, uppercaseCmd(processCmdEnv(opt.shlex, cmdToPrint.String(), d.state.Env())), d.prefixPlatform, &platform))} + env, err := d.state.Env(context.TODO()) + if err != nil { + return err + } + + runOpt := []llb.RunOption{llb.Args(args), llb.Dir("/dest"), llb.ReadonlyRootFS(), dfCmd(cmdToPrint), llb.WithCustomName(prefixCommand(d, uppercaseCmd(processCmdEnv(opt.shlex, cmdToPrint.String(), env)), d.prefixPlatform, &platform))} if d.ignoreCache { runOpt = append(runOpt, llb.IgnoreCache) } @@ -936,8 +968,12 @@ func dispatchHealthcheck(d *dispatchState, c *instructions.HealthCheckCommand) e func dispatchExpose(d *dispatchState, c *instructions.ExposeCommand, shlex *shell.Lex) error { ports := []string{} + env, err := d.state.Env(context.TODO()) + if err != nil { + return err + } for _, p := range c.Ports { - ps, err := shlex.ProcessWords(p, d.state.Env()) + ps, err := shlex.ProcessWords(p, env) if err != nil { return err } @@ -1018,11 +1054,15 @@ func dispatchArg(d *dispatchState, c *instructions.ArgCommand, metaArgs []instru return commitToHistory(&d.image, commitStr, false, nil) } -func pathRelativeToWorkingDir(s llb.State, p string) string { +func pathRelativeToWorkingDir(s llb.State, p string) (string, error) { if path.IsAbs(p) { - return p + return p, nil } - return path.Join(s.GetDir(), p) + dir, err := s.GetDir(context.TODO()) + if err != nil { + return "", err + } + return path.Join(dir, p), nil } func splitWildcards(name string) (string, string) { diff --git a/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert_runmount.go b/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert_runmount.go index 33595abb7d..1be4849e2a 100644 --- a/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert_runmount.go +++ b/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert_runmount.go @@ -3,6 +3,7 @@ package dockerfile2llb import ( + "context" "fmt" "os" "path" @@ -132,7 +133,11 @@ func dispatchRunMounts(d *dispatchState, c *instructions.RunCommand, sources []* } target := mount.Target if !filepath.IsAbs(filepath.Clean(mount.Target)) { - target = filepath.Join("/", d.state.GetDir(), mount.Target) + dir, err := d.state.GetDir(context.TODO()) + if err != nil { + return nil, err + } + target = filepath.Join("/", dir, mount.Target) } if target == "/" { return nil, errors.Errorf("invalid mount target %q", target) diff --git a/vendor/github.com/moby/buildkit/frontend/gateway/gateway.go b/vendor/github.com/moby/buildkit/frontend/gateway/gateway.go index 91c2a82a86..a6c8b6be2f 100644 --- a/vendor/github.com/moby/buildkit/frontend/gateway/gateway.go +++ b/vendor/github.com/moby/buildkit/frontend/gateway/gateway.go @@ -135,7 +135,7 @@ func (gf *gatewayFrontend) Solve(ctx context.Context, llbBridge frontend.Fronten src := llb.Image(sourceRef.String(), &markTypeFrontend{}) - def, err := src.Marshal() + def, err := src.Marshal(ctx) if err != nil { return nil, err } diff --git a/vendor/github.com/moby/buildkit/go.mod b/vendor/github.com/moby/buildkit/go.mod index f07dc43733..d01fdcda88 100644 --- a/vendor/github.com/moby/buildkit/go.mod +++ b/vendor/github.com/moby/buildkit/go.mod @@ -3,6 +3,7 @@ module github.com/moby/buildkit go 1.13 require ( + github.com/AkihiroSuda/containerd-fuse-overlayfs v0.0.0-20200220082720-bb896865146c github.com/BurntSushi/toml v0.3.1 github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 github.com/Microsoft/hcsshim v0.8.7 // indirect @@ -23,13 +24,12 @@ require ( github.com/docker/docker v0.0.0 github.com/docker/docker-credential-helpers v0.6.0 // indirect github.com/docker/go-connections v0.3.0 - github.com/docker/go-events v0.0.0-20170721190031-9461782956ad // indirect github.com/docker/libnetwork v0.8.0-dev.2.0.20200226230617-d8334ccdb9be github.com/gofrs/flock v0.7.0 github.com/gogo/googleapis v1.3.2 github.com/gogo/protobuf v1.3.1 github.com/golang/protobuf v1.3.3 - github.com/google/go-cmp v0.3.0 + github.com/google/go-cmp v0.3.1 github.com/google/shlex v0.0.0-20150127133951-6f45313302b9 github.com/google/uuid v1.1.1 // indirect github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 @@ -54,7 +54,7 @@ require ( github.com/sirupsen/logrus v1.4.2 github.com/stretchr/testify v1.4.0 github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2 // indirect - github.com/tonistiigi/fsutil v0.0.0-20200225063759-013a9fe6aee2 + github.com/tonistiigi/fsutil v0.0.0-20200326231323-c2c7d7b0e144 github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea github.com/uber/jaeger-client-go v0.0.0-20180103221425-e02c85f9069e github.com/uber/jaeger-lib v1.2.1 // indirect diff --git a/vendor/github.com/moby/buildkit/solver/cachemanager.go b/vendor/github.com/moby/buildkit/solver/cachemanager.go index 90392f4c1e..b628b55a19 100644 --- a/vendor/github.com/moby/buildkit/solver/cachemanager.go +++ b/vendor/github.com/moby/buildkit/solver/cachemanager.go @@ -150,8 +150,12 @@ type LoadedResult struct { CacheKey *CacheKey } -func (c *cacheManager) filterResults(m map[string]Result, ck *CacheKey) (results []LoadedResult, err error) { +func (c *cacheManager) filterResults(m map[string]Result, ck *CacheKey, visited map[string]struct{}) (results []LoadedResult, err error) { id := c.getID(ck) + if _, ok := visited[id]; ok { + return nil, nil + } + visited[id] = struct{}{} if err := c.backend.WalkResults(id, func(cr CacheResult) error { res, ok := m[id] if ok { @@ -170,7 +174,7 @@ func (c *cacheManager) filterResults(m map[string]Result, ck *CacheKey) (results } for _, keys := range ck.Deps() { for _, key := range keys { - res, err := c.filterResults(m, key.CacheKey.CacheKey) + res, err := c.filterResults(m, key.CacheKey.CacheKey, visited) if err != nil { for _, r := range results { r.Result.Release(context.TODO()) @@ -207,7 +211,7 @@ func (c *cacheManager) LoadWithParents(ctx context.Context, rec *CacheRecord) ([ return nil, err } - results, err := c.filterResults(m, rec.key) + results, err := c.filterResults(m, rec.key, map[string]struct{}{}) if err != nil { for _, r := range m { r.Release(context.TODO()) diff --git a/vendor/github.com/moby/buildkit/solver/exporter.go b/vendor/github.com/moby/buildkit/solver/exporter.go index fa963f414a..6a073960df 100644 --- a/vendor/github.com/moby/buildkit/solver/exporter.go +++ b/vendor/github.com/moby/buildkit/solver/exporter.go @@ -20,11 +20,12 @@ func addBacklinks(t CacheExporterTarget, rec CacheExporterRecord, cm *cacheManag if rec == nil { var ok bool rec, ok = bkm[id] - if ok { + if ok && rec != nil { return rec, nil } _ = ok } + bkm[id] = nil if err := cm.backend.WalkBacklinks(id, func(id string, link CacheInfoLink) error { if rec == nil { rec = t.Add(link.Digest) @@ -37,7 +38,9 @@ func addBacklinks(t CacheExporterTarget, rec CacheExporterRecord, cm *cacheManag return err } } - rec.LinkFrom(r, int(link.Input), link.Selector.String()) + if r != nil { + rec.LinkFrom(r, int(link.Input), link.Selector.String()) + } return nil }); err != nil { return nil, err @@ -66,6 +69,7 @@ func (e *exporter) ExportTo(ctx context.Context, t CacheExporterTarget, opt Cach if t.Visited(e) { return e.res, nil } + t.Visit(e) deps := e.k.Deps() @@ -177,7 +181,6 @@ func (e *exporter) ExportTo(ctx context.Context, t CacheExporterTarget, opt Cach } e.res = allRec - t.Visit(e) return e.res, nil } diff --git a/vendor/github.com/moby/buildkit/source/git/gitsource.go b/vendor/github.com/moby/buildkit/source/git/gitsource.go index d2d6ff7617..419bf3b6be 100644 --- a/vendor/github.com/moby/buildkit/source/git/gitsource.go +++ b/vendor/github.com/moby/buildkit/source/git/gitsource.go @@ -272,8 +272,9 @@ func (gs *gitSourceHandler) Snapshot(ctx context.Context) (out cache.ImmutableRe } args = append(args, "origin") if !isCommitSHA(ref) { - args = append(args, ref+":tags/"+ref) - // local refs are needed so they would be advertised on next fetches + args = append(args, "--force", ref+":tags/"+ref) + // local refs are needed so they would be advertised on next fetches. Force is used + // in case the ref is a branch and it now points to a different commit sha // TODO: is there a better way to do this? } if _, err := gitWithinDir(ctx, gitDir, "", args...); err != nil { diff --git a/vendor/github.com/moby/buildkit/util/resolver/resolver.go b/vendor/github.com/moby/buildkit/util/resolver/resolver.go index 096bfc330b..8d8b9f7fee 100644 --- a/vendor/github.com/moby/buildkit/util/resolver/resolver.go +++ b/vendor/github.com/moby/buildkit/util/resolver/resolver.go @@ -1,54 +1,219 @@ package resolver import ( - "math/rand" + "context" + "crypto/tls" + "crypto/x509" + "io/ioutil" + "net" + "net/http" + "os" + "path/filepath" + "runtime" "strings" + "time" + "github.com/containerd/containerd/remotes" "github.com/containerd/containerd/remotes/docker" - "github.com/docker/distribution/reference" + "github.com/moby/buildkit/cmd/buildkitd/config" + "github.com/moby/buildkit/session" + "github.com/moby/buildkit/session/auth" "github.com/moby/buildkit/util/tracing" + "github.com/pkg/errors" ) -type RegistryConf struct { - Mirrors []string - PlainHTTP *bool +func fillInsecureOpts(host string, c config.RegistryConfig, h *docker.RegistryHost) error { + tc, err := loadTLSConfig(c) + if err != nil { + return err + } + + if c.PlainHTTP != nil && *c.PlainHTTP { + h.Scheme = "http" + } else if c.Insecure != nil && *c.Insecure { + tc.InsecureSkipVerify = true + } else if c.PlainHTTP == nil { + if ok, _ := docker.MatchLocalhost(host); ok { + h.Scheme = "http" + } + } + + transport := newDefaultTransport() + transport.TLSClientConfig = tc + + h.Client = &http.Client{ + Transport: tracing.NewTransport(transport), + } + return nil } -type ResolveOptionsFunc func(string) docker.ResolverOptions - -func NewResolveOptionsFunc(m map[string]RegistryConf) ResolveOptionsFunc { - return func(ref string) docker.ResolverOptions { - def := docker.ResolverOptions{ - Client: tracing.DefaultClient, +func loadTLSConfig(c config.RegistryConfig) (*tls.Config, error) { + for _, d := range c.TLSConfigDir { + fs, err := ioutil.ReadDir(d) + if err != nil && !os.IsNotExist(err) && !os.IsPermission(err) { + return nil, errors.WithStack(err) } + for _, f := range fs { + if strings.HasSuffix(f.Name(), ".crt") { + c.RootCAs = append(c.RootCAs, filepath.Join(d, f.Name())) + } + if strings.HasSuffix(f.Name(), ".cert") { + c.KeyPairs = append(c.KeyPairs, config.TLSKeyPair{ + Certificate: filepath.Join(d, f.Name()), + Key: filepath.Join(d, strings.TrimSuffix(f.Name(), ".cert")+".key"), + }) + } + } + } - parsed, err := reference.ParseNormalizedNamed(ref) + tc := &tls.Config{} + if len(c.RootCAs) > 0 { + systemPool, err := x509.SystemCertPool() if err != nil { - return def - } - host := reference.Domain(parsed) - - c, ok := m[host] - if !ok { - return def - } - - var mirrorHost string - if len(c.Mirrors) > 0 { - mirrorHost = c.Mirrors[rand.Intn(len(c.Mirrors))] - def.Host = func(string) (string, error) { - return mirrorHost, nil + if runtime.GOOS == "windows" { + systemPool = x509.NewCertPool() + } else { + return nil, errors.Wrapf(err, "unable to get system cert pool") } } + tc.RootCAs = systemPool + } - if c.PlainHTTP != nil { - def.PlainHTTP = *c.PlainHTTP - } else { - if mirrorHost == "localhost" || strings.HasPrefix(mirrorHost, "localhost:") { - def.PlainHTTP = true + for _, p := range c.RootCAs { + dt, err := ioutil.ReadFile(p) + if err != nil { + return nil, errors.Wrapf(err, "failed to read %s", p) + } + tc.RootCAs.AppendCertsFromPEM(dt) + } + + for _, kp := range c.KeyPairs { + cert, err := tls.LoadX509KeyPair(kp.Certificate, kp.Key) + if err != nil { + return nil, errors.Wrapf(err, "failed to load keypair for %s", kp.Certificate) + } + tc.Certificates = append(tc.Certificates, cert) + } + return tc, nil +} + +func NewRegistryConfig(m map[string]config.RegistryConfig) docker.RegistryHosts { + return docker.Registries( + func(host string) ([]docker.RegistryHost, error) { + c, ok := m[host] + if !ok { + return nil, nil } + + var out []docker.RegistryHost + + for _, mirror := range c.Mirrors { + h := docker.RegistryHost{ + Scheme: "https", + Client: newDefaultClient(), + Host: mirror, + Path: "/v2", + Capabilities: docker.HostCapabilityPull | docker.HostCapabilityResolve, + } + + if err := fillInsecureOpts(mirror, m[mirror], &h); err != nil { + return nil, err + } + + out = append(out, h) + } + + if host == "docker.io" { + host = "registry-1.docker.io" + } + + h := docker.RegistryHost{ + Scheme: "https", + Client: newDefaultClient(), + Host: host, + Path: "/v2", + Capabilities: docker.HostCapabilityPush | docker.HostCapabilityPull | docker.HostCapabilityResolve, + } + + if err := fillInsecureOpts(host, c, &h); err != nil { + return nil, err + } + + out = append(out, h) + return out, nil + }, + docker.ConfigureDefaultRegistries( + docker.WithClient(newDefaultClient()), + docker.WithPlainHTTP(docker.MatchLocalhost), + ), + ) +} + +func New(ctx context.Context, hosts docker.RegistryHosts, sm *session.Manager) remotes.Resolver { + return docker.NewResolver(docker.ResolverOptions{ + Hosts: hostsWithCredentials(ctx, hosts, sm), + }) +} + +func hostsWithCredentials(ctx context.Context, hosts docker.RegistryHosts, sm *session.Manager) docker.RegistryHosts { + id := session.FromContext(ctx) + if id == "" { + return hosts + } + return func(domain string) ([]docker.RegistryHost, error) { + res, err := hosts(domain) + if err != nil { + return nil, err + } + if len(res) == 0 { + return nil, nil } - return def + timeoutCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + caller, err := sm.Get(timeoutCtx, id) + if err != nil { + return nil, err + } + + a := docker.NewDockerAuthorizer( + docker.WithAuthClient(res[0].Client), + docker.WithAuthCreds(auth.CredentialsFunc(context.TODO(), caller)), + ) + for i := range res { + res[i].Authorizer = a + } + return res, nil + } +} + +func newDefaultClient() *http.Client { + return &http.Client{ + Transport: newDefaultTransport(), + } +} + +// newDefaultTransport is for pull or push client +// +// NOTE: For push, there must disable http2 for https because the flow control +// will limit data transfer. The net/http package doesn't provide http2 tunable +// settings which limits push performance. +// +// REF: https://github.com/golang/go/issues/14077 +func newDefaultTransport() *http.Transport { + return &http.Transport{ + Proxy: http.ProxyFromEnvironment, + DialContext: (&net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + DualStack: true, + }).DialContext, + MaxIdleConns: 10, + IdleConnTimeout: 30 * time.Second, + TLSHandshakeTimeout: 10 * time.Second, + ExpectContinueTimeout: 5 * time.Second, + DisableKeepAlives: true, + TLSNextProto: make(map[string]func(authority string, c *tls.Conn) http.RoundTripper), } } diff --git a/vendor/github.com/moby/buildkit/util/tracing/tracing.go b/vendor/github.com/moby/buildkit/util/tracing/tracing.go index 6af2b8c55e..8f2d4dd962 100644 --- a/vendor/github.com/moby/buildkit/util/tracing/tracing.go +++ b/vendor/github.com/moby/buildkit/util/tracing/tracing.go @@ -74,6 +74,12 @@ type Transport struct { http.RoundTripper } +func NewTransport(rt http.RoundTripper) http.RoundTripper { + return &Transport{ + RoundTripper: &nethttp.Transport{RoundTripper: rt}, + } +} + func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) { span := opentracing.SpanFromContext(req.Context()) if span == nil { // no tracer connected with either request or transport diff --git a/vendor/github.com/tonistiigi/fsutil/tarwriter.go b/vendor/github.com/tonistiigi/fsutil/tarwriter.go index 8dea63bab2..06f28c55ff 100644 --- a/vendor/github.com/tonistiigi/fsutil/tarwriter.go +++ b/vendor/github.com/tonistiigi/fsutil/tarwriter.go @@ -37,7 +37,11 @@ func WriteTar(ctx context.Context, fs FS, w io.Writer) error { hdr.Linkname = stat.Linkname if hdr.Linkname != "" { hdr.Size = 0 - hdr.Typeflag = tar.TypeLink + if fi.Mode() & os.ModeSymlink != 0 { + hdr.Typeflag = tar.TypeSymlink + } else { + hdr.Typeflag = tar.TypeLink + } } if len(stat.Xattrs) > 0 {