mirror of
https://gitea.com/Lydanne/buildx.git
synced 2025-05-28 16:37:43 +08:00
build: refactor reference parsing for image layouts
We allow any valid image reference format for the oci-layout, not just limiting to name@digest, we additionally allow images of the form name:tag@digest now. The name of the reference is used to find the local directory to lookup the store in, while the tag and digest are attached to a random identity to generate the dummy reference sent to the oci-layout context. This separation of the target to replace and the value to replace it with ensures that any tag or digest set in the client is properly sent across to the server. The tag is used when a digest was not specified, and it is resolved in the context of the local directory before being sent, using the same helpers as we use for the local cache expoter. Signed-off-by: Justin Chadwell <me@jedevc.com>
This commit is contained in:
parent
4735a71fbd
commit
8b960ededd
@ -11,6 +11,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -36,8 +37,10 @@ import (
|
||||
"github.com/docker/docker/pkg/jsonmessage"
|
||||
"github.com/moby/buildkit/client"
|
||||
"github.com/moby/buildkit/client/llb"
|
||||
"github.com/moby/buildkit/client/ociindex"
|
||||
"github.com/moby/buildkit/exporter/containerimage/exptypes"
|
||||
gateway "github.com/moby/buildkit/frontend/gateway/client"
|
||||
"github.com/moby/buildkit/identity"
|
||||
"github.com/moby/buildkit/session"
|
||||
"github.com/moby/buildkit/session/upload/uploadprovider"
|
||||
"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
|
||||
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 := pathAlone
|
||||
localPath, dig, hasDigest := strings.Cut(localPath, "@")
|
||||
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]
|
||||
dgst, err := digest.Parse(parts[1])
|
||||
if !hasDigest {
|
||||
return nil, errors.Errorf("oci-layout reference %q could not be resolved", v.Path)
|
||||
}
|
||||
_, err := digest.Parse(dig)
|
||||
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)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "invalid store at %s", localPath)
|
||||
}
|
||||
// now we can add it
|
||||
storeName := identity.NewID()
|
||||
if target.OCIStores == nil {
|
||||
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
|
||||
}
|
||||
st, err := os.Stat(v.Path)
|
||||
|
Loading…
x
Reference in New Issue
Block a user