mirror of
https://gitea.com/Lydanne/buildx.git
synced 2025-07-03 18:07:41 +08:00
Merge pull request #1456 from jedevc/oci-layout-reference-parsing
build: refactor reference parsing for oci image layouts
This commit is contained in:
commit
ff6754eb04
@ -11,6 +11,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -36,8 +37,10 @@ import (
|
|||||||
"github.com/docker/docker/pkg/jsonmessage"
|
"github.com/docker/docker/pkg/jsonmessage"
|
||||||
"github.com/moby/buildkit/client"
|
"github.com/moby/buildkit/client"
|
||||||
"github.com/moby/buildkit/client/llb"
|
"github.com/moby/buildkit/client/llb"
|
||||||
|
"github.com/moby/buildkit/client/ociindex"
|
||||||
"github.com/moby/buildkit/exporter/containerimage/exptypes"
|
"github.com/moby/buildkit/exporter/containerimage/exptypes"
|
||||||
gateway "github.com/moby/buildkit/frontend/gateway/client"
|
gateway "github.com/moby/buildkit/frontend/gateway/client"
|
||||||
|
"github.com/moby/buildkit/identity"
|
||||||
"github.com/moby/buildkit/session"
|
"github.com/moby/buildkit/session"
|
||||||
"github.com/moby/buildkit/session/upload/uploadprovider"
|
"github.com/moby/buildkit/session/upload/uploadprovider"
|
||||||
"github.com/moby/buildkit/solver/errdefs"
|
"github.com/moby/buildkit/solver/errdefs"
|
||||||
@ -1497,26 +1500,59 @@ func LoadInputs(ctx context.Context, d driver.Driver, inp Inputs, pw progress.Wr
|
|||||||
// handle OCI layout
|
// handle OCI layout
|
||||||
if strings.HasPrefix(v.Path, "oci-layout://") {
|
if strings.HasPrefix(v.Path, "oci-layout://") {
|
||||||
pathAlone := strings.TrimPrefix(v.Path, "oci-layout://")
|
pathAlone := strings.TrimPrefix(v.Path, "oci-layout://")
|
||||||
parts := strings.SplitN(pathAlone, "@", 2)
|
localPath := pathAlone
|
||||||
if len(parts) != 2 {
|
localPath, dig, hasDigest := strings.Cut(localPath, "@")
|
||||||
return nil, errors.Errorf("invalid oci-layout context %s, must be oci-layout:///path/to/layout@sha256:hash", v.Path)
|
localPath, tag, hasTag := strings.Cut(localPath, ":")
|
||||||
|
if !hasDigest {
|
||||||
|
indexPath := path.Join(localPath, "index.json")
|
||||||
|
index, err := ociindex.ReadIndexJSONFileLocked(indexPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "failed to read oci-layout index at %s", indexPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(index.Manifests) == 1 {
|
||||||
|
dig = string(index.Manifests[0].Digest)
|
||||||
|
hasDigest = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if !hasTag {
|
||||||
|
tag = "latest"
|
||||||
|
}
|
||||||
|
for _, m := range index.Manifests {
|
||||||
|
if m.Annotations[specs.AnnotationRefName] == tag {
|
||||||
|
dig = string(m.Digest)
|
||||||
|
hasDigest = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
localPath := parts[0]
|
if !hasDigest {
|
||||||
dgst, err := digest.Parse(parts[1])
|
return nil, errors.Errorf("oci-layout reference %q could not be resolved", v.Path)
|
||||||
|
}
|
||||||
|
_, err := digest.Parse(dig)
|
||||||
if err != nil {
|
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)
|
return nil, errors.Wrapf(err, "invalid oci-layout digest %s", dig)
|
||||||
}
|
}
|
||||||
|
|
||||||
store, err := local.NewStore(localPath)
|
store, err := local.NewStore(localPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "invalid store at %s", localPath)
|
return nil, errors.Wrapf(err, "invalid store at %s", localPath)
|
||||||
}
|
}
|
||||||
// now we can add it
|
storeName := identity.NewID()
|
||||||
if target.OCIStores == nil {
|
if target.OCIStores == nil {
|
||||||
target.OCIStores = map[string]content.Store{}
|
target.OCIStores = map[string]content.Store{}
|
||||||
}
|
}
|
||||||
target.OCIStores[k] = store
|
target.OCIStores[storeName] = store
|
||||||
|
|
||||||
target.FrontendAttrs["context:"+k] = fmt.Sprintf("oci-layout:%s@%s", k, dgst.String())
|
layout := "oci-layout://" + storeName
|
||||||
|
if hasTag {
|
||||||
|
layout += ":" + tag
|
||||||
|
}
|
||||||
|
if hasDigest {
|
||||||
|
layout += "@" + dig
|
||||||
|
}
|
||||||
|
|
||||||
|
target.FrontendAttrs["context:"+k] = layout
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
st, err := os.Stat(v.Path)
|
st, err := os.Stat(v.Path)
|
||||||
|
@ -139,10 +139,12 @@ COPY --from=project myfile /
|
|||||||
|
|
||||||
#### <a name="source-oci-layout"></a> Source image from OCI layout directory
|
#### <a name="source-oci-layout"></a> 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):
|
Source an image from a local [OCI layout compliant directory](https://github.com/opencontainers/image-spec/blob/main/image-layout.md),
|
||||||
|
either by tag, or by digest:
|
||||||
|
|
||||||
```console
|
```console
|
||||||
$ docker buildx build --build-context foo=oci-layout:///path/to/local/layout@sha256:abcd12345 .
|
$ docker buildx build --build-context foo=oci-layout:///path/to/local/layout:<tag>
|
||||||
|
$ docker buildx build --build-context foo=oci-layout:///path/to/local/layout@sha256:<digest>
|
||||||
```
|
```
|
||||||
|
|
||||||
```dockerfile
|
```dockerfile
|
||||||
@ -154,14 +156,8 @@ COPY --from=foo myfile /
|
|||||||
FROM foo
|
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
|
The OCI layout directory must be compliant with the [OCI layout specification](https://github.com/opencontainers/image-spec/blob/main/image-layout.md).
|
||||||
do any form of `image:tag` resolution to find the hash of the manifest; that is up to you.
|
You can reference an image in the layout using either tags, or the exact digest.
|
||||||
|
|
||||||
The format of the `--build-context` must be: `<context>=oci-layout://<path-to-local-layout>@sha256:<hash-of-manifest>`, 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.
|
|
||||||
|
|
||||||
### <a name="builder"></a> Override the configured builder instance (--builder)
|
### <a name="builder"></a> Override the configured builder instance (--builder)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user