From 02bae945c3f765f53a01c3bec7a75cb02b4fa06d Mon Sep 17 00:00:00 2001 From: Avi Deitcher Date: Sun, 19 Jun 2022 13:30:24 +0300 Subject: [PATCH] add support for oci-layout build-context Signed-off-by: Avi Deitcher --- build/build.go | 29 +++++++++++++++++++++++++++++ docs/reference/buildx_build.md | 28 +++++++++++++++++++++++++++- go.mod | 9 ++++++--- go.sum | 11 ++++++++--- vendor/modules.txt | 12 +++++++++--- 5 files changed, 79 insertions(+), 10 deletions(-) diff --git a/build/build.go b/build/build.go index c185702d..0e7805f8 100644 --- a/build/build.go +++ b/build/build.go @@ -5,6 +5,7 @@ import ( "bytes" "context" "crypto/rand" + _ "crypto/sha256" // ensure digests can be computed "encoding/hex" "encoding/json" "fmt" @@ -17,6 +18,8 @@ import ( "syscall" "time" + "github.com/containerd/containerd/content" + "github.com/containerd/containerd/content/local" "github.com/containerd/containerd/images" "github.com/containerd/containerd/platforms" "github.com/docker/buildx/driver" @@ -1333,6 +1336,32 @@ func LoadInputs(ctx context.Context, d driver.Driver, inp Inputs, pw progress.Wr target.FrontendAttrs["context:"+k] = v.Path continue } + + // handle OCI layout + if strings.HasPrefix(v.Path, "oci-layout://") { + pathAlone := strings.TrimPrefix(v.Path, "oci-layout://") + parts := strings.SplitN(pathAlone, "@", 2) + if len(parts) != 2 { + return nil, errors.Errorf("invalid oci-layout context %s, must be oci-layout:///path/to/layout@sha256:hash", v.Path) + } + localPath := parts[0] + dgst, err := digest.Parse(parts[1]) + if err != nil { + return nil, errors.Wrapf(err, "invalid oci-layout context %s, does not have proper hash, must be oci-layout:///path/to/layout@sha256:hash", v.Path) + } + store, err := local.NewStore(localPath) + if err != nil { + return nil, errors.Wrapf(err, "invalid store at %s", localPath) + } + // now we can add it + if target.OCIStores == nil { + target.OCIStores = map[string]content.Store{} + } + target.OCIStores[k] = store + + target.FrontendAttrs["context:"+k] = fmt.Sprintf("oci-layout:%s@%s", k, dgst.String()) + continue + } st, err := os.Stat(v.Path) if err != nil { return nil, errors.Wrapf(err, "failed to get build context %v", k) diff --git a/docs/reference/buildx_build.md b/docs/reference/buildx_build.md index 0f9e1140..a0e622e0 100644 --- a/docs/reference/buildx_build.md +++ b/docs/reference/buildx_build.md @@ -106,7 +106,7 @@ More built-in build args can be found in [dockerfile frontend docs](https://gith Define additional build context with specified contents. In Dockerfile the context can be accessed when `FROM name` or `--from=name` is used. When Dockerfile defines a stage with the same name it is overwritten. -The value can be a local source directory, container image (with docker-image:// prefix), Git or HTTP URL. +The value can be a local source directory, [local OCI layout compliant directory](https://github.com/opencontainers/image-spec/blob/main/image-layout.md), container image (with docker-image:// prefix), Git or HTTP URL. Replace `alpine:latest` with a pinned one: @@ -126,6 +126,32 @@ FROM alpine COPY --from=project myfile / ``` +#### Source image from OCI layout directory + +Source an image from a local [OCI layout compliant directory](https://github.com/opencontainers/image-spec/blob/main/image-layout.md): + +```console +$ docker buildx build --build-context foo=oci-layout:///path/to/local/layout@sha256:abcd12345 . +``` + +```Dockerfile +FROM alpine +RUN apk add git + +COPY --from=foo myfile / + +FROM foo +``` + +The OCI layout directory must be compliant with the [OCI layout specification](https://github.com/opencontainers/image-spec/blob/main/image-layout.md). It looks _solely_ for hashes. It does not +do any form of `image:tag` resolution to find the hash of the manifest; that is up to you. + +The format of the `--build-context` must be: `=oci-layout://@sha256:`, where: + +* `context` is the name of the build context as used in the `Dockerfile`. +* `path-to-local-layout` is the path on the local machine, where you are running `docker build`, to the spec-compliant OCI layout. +* `hash-of-manifest` is the hash of the manifest for the image. It can be a single-architecture manifest or a multi-architecture index. + ### Override the configured builder instance (--builder) Same as [`buildx --builder`](buildx.md#builder). diff --git a/go.mod b/go.mod index 05fffe3f..6c786ef5 100644 --- a/go.mod +++ b/go.mod @@ -33,9 +33,9 @@ require ( golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 google.golang.org/grpc v1.45.0 gopkg.in/yaml.v3 v3.0.1 - k8s.io/api v0.23.4 - k8s.io/apimachinery v0.23.4 - k8s.io/client-go v0.23.4 + k8s.io/api v0.23.5 + k8s.io/apimachinery v0.23.5 + k8s.io/client-go v0.23.5 ) require ( @@ -89,6 +89,7 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/klauspost/compress v1.15.1 // indirect + github.com/kr/pretty v0.3.0 // indirect github.com/mattn/go-shellwords v1.0.12 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect github.com/miekg/pkcs11 v1.1.1 // indirect @@ -108,6 +109,7 @@ require ( github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/common v0.32.1 // indirect github.com/prometheus/procfs v0.7.3 // indirect + github.com/rogpeppe/go-internal v1.8.1 // indirect github.com/theupdateframework/notary v0.6.1 // indirect github.com/tonistiigi/fsutil v0.0.0-20220510150904-0dbf3a8a7d58 // indirect github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea // indirect @@ -135,6 +137,7 @@ require ( google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368 // indirect google.golang.org/protobuf v1.27.1 // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/dancannon/gorethink.v3 v3.0.5 // indirect gopkg.in/fatih/pool.v2 v2.0.0 // indirect gopkg.in/gorethink/gorethink.v3 v3.0.5 // indirect diff --git a/go.sum b/go.sum index aeed0c9a..332267f2 100644 --- a/go.sum +++ b/go.sum @@ -419,8 +419,9 @@ github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -487,7 +488,6 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= @@ -516,6 +516,7 @@ github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCko github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM= github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -558,6 +559,9 @@ github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6So github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg= +github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= @@ -1095,8 +1099,9 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/dancannon/gorethink.v3 v3.0.5 h1:/g7PWP7zUS6vSNmHSDbjCHQh1Rqn8Jy6zSMQxAsBSMQ= gopkg.in/dancannon/gorethink.v3 v3.0.5/go.mod h1:GXsi1e3N2OcKhcP6nsYABTiUejbWMFO4GY5a4pEaeEc= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= diff --git a/vendor/modules.txt b/vendor/modules.txt index d77c51b7..e3f2555e 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -319,6 +319,8 @@ github.com/klauspost/compress/huff0 github.com/klauspost/compress/internal/snapref github.com/klauspost/compress/zstd github.com/klauspost/compress/zstd/internal/xxhash +# github.com/kr/pretty v0.3.0 +## explicit; go 1.12 # github.com/mattn/go-shellwords v1.0.12 ## explicit; go 1.13 github.com/mattn/go-shellwords @@ -461,6 +463,8 @@ github.com/prometheus/common/model github.com/prometheus/procfs github.com/prometheus/procfs/internal/fs github.com/prometheus/procfs/internal/util +# github.com/rogpeppe/go-internal v1.8.1 +## explicit; go 1.16 # github.com/serialx/hashring v0.0.0-20190422032157-8b2912629002 ## explicit github.com/serialx/hashring @@ -749,6 +753,8 @@ google.golang.org/protobuf/types/known/durationpb google.golang.org/protobuf/types/known/fieldmaskpb google.golang.org/protobuf/types/known/timestamppb google.golang.org/protobuf/types/known/wrapperspb +# gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c +## explicit; go 1.11 # gopkg.in/dancannon/gorethink.v3 v3.0.5 ## explicit # gopkg.in/fatih/pool.v2 v2.0.0 @@ -764,7 +770,7 @@ gopkg.in/yaml.v2 # gopkg.in/yaml.v3 v3.0.1 ## explicit gopkg.in/yaml.v3 -# k8s.io/api v0.23.4 => k8s.io/api v0.22.4 +# k8s.io/api v0.23.5 => k8s.io/api v0.22.4 ## explicit; go 1.16 k8s.io/api/admissionregistration/v1 k8s.io/api/admissionregistration/v1beta1 @@ -809,7 +815,7 @@ k8s.io/api/scheduling/v1beta1 k8s.io/api/storage/v1 k8s.io/api/storage/v1alpha1 k8s.io/api/storage/v1beta1 -# k8s.io/apimachinery v0.23.4 => k8s.io/apimachinery v0.22.4 +# k8s.io/apimachinery v0.23.5 => k8s.io/apimachinery v0.22.4 ## explicit; go 1.16 k8s.io/apimachinery/pkg/api/errors k8s.io/apimachinery/pkg/api/meta @@ -851,7 +857,7 @@ k8s.io/apimachinery/pkg/version k8s.io/apimachinery/pkg/watch k8s.io/apimachinery/third_party/forked/golang/netutil k8s.io/apimachinery/third_party/forked/golang/reflect -# k8s.io/client-go v0.23.4 => k8s.io/client-go v0.22.4 +# k8s.io/client-go v0.23.5 => k8s.io/client-go v0.22.4 ## explicit; go 1.16 k8s.io/client-go/applyconfigurations/admissionregistration/v1 k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1