build: fix oci-layout named context serialization
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
This commit is contained in:
+10
-6
@@ -917,29 +917,33 @@ func loadInputs(ctx context.Context, d *driver.DriverHandle, inp *Inputs, pw pro
|
||||
}
|
||||
|
||||
// handle OCI layout
|
||||
if localPath, ok := strings.CutPrefix(v.Path, "oci-layout://"); ok {
|
||||
ref, _, err := ocilayout.Parse("oci-layout://" + localPath)
|
||||
if ref, ok, err := ocilayout.Parse(v.Path); ok {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
localPath, dig, tag := ref.Path, ref.Digest.String(), ref.Tag
|
||||
if dig == "" {
|
||||
dig, err = resolveDigest(localPath, tag)
|
||||
localPath := ref.Path
|
||||
|
||||
if ref.Digest == "" {
|
||||
dig, err := resolveDigest(localPath, ref.Tag)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "oci-layout reference %q could not be resolved", v.Path)
|
||||
}
|
||||
ref.Digest = digest.Digest(dig)
|
||||
}
|
||||
|
||||
store, err := local.NewStore(localPath)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "invalid store at %s", localPath)
|
||||
}
|
||||
|
||||
storeName := identity.NewID()
|
||||
if target.OCIStores == nil {
|
||||
target.OCIStores = map[string]content.Store{}
|
||||
}
|
||||
target.OCIStores[storeName] = store
|
||||
|
||||
target.FrontendAttrs["context:"+k] = "oci-layout://" + storeName + ":" + tag + "@" + dig
|
||||
ref.Path = storeName
|
||||
target.FrontendAttrs["context:"+k] = ref.String()
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
package build
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/buildx/util/buildflags"
|
||||
"github.com/docker/buildx/util/ocilayout"
|
||||
"github.com/docker/buildx/util/progress"
|
||||
"github.com/moby/buildkit/client"
|
||||
"github.com/moby/buildkit/client/ociindex"
|
||||
"github.com/opencontainers/go-digest"
|
||||
ocispecs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
@@ -154,3 +160,91 @@ func TestProxyArgKeyExists(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadInputsOCILayoutNamedContext(t *testing.T) {
|
||||
layoutPath := t.TempDir()
|
||||
|
||||
idx := ociindex.NewStoreIndex(layoutPath)
|
||||
manifestDigest := digest.FromString("manifest")
|
||||
err := idx.Put(ocispecs.Descriptor{
|
||||
MediaType: ocispecs.MediaTypeImageManifest,
|
||||
Digest: manifestDigest,
|
||||
Size: 1,
|
||||
}, ociindex.Tag("latest"))
|
||||
require.NoError(t, err)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
ref string
|
||||
wantRef ocilayout.Ref
|
||||
}{
|
||||
{
|
||||
name: "digest only",
|
||||
ref: "oci-layout://" + layoutPath + "@" + manifestDigest.String(),
|
||||
wantRef: ocilayout.Ref{
|
||||
Digest: manifestDigest,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "tag only",
|
||||
ref: "oci-layout://" + layoutPath + ":latest",
|
||||
wantRef: ocilayout.Ref{
|
||||
Tag: "latest",
|
||||
Digest: manifestDigest,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "tag and digest",
|
||||
ref: "oci-layout://" + layoutPath + ":latest@" + manifestDigest.String(),
|
||||
wantRef: ocilayout.Ref{
|
||||
Tag: "latest",
|
||||
Digest: manifestDigest,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
target := &client.SolveOpt{
|
||||
FrontendAttrs: map[string]string{},
|
||||
}
|
||||
inp := &Inputs{
|
||||
ContextPath: "https://example.com/context.tar.gz",
|
||||
NamedContexts: map[string]NamedContext{
|
||||
"proxy": {
|
||||
Path: tt.ref,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
release, err := loadInputs(context.Background(), nil, inp, testProgressWriter{}, target)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, release)
|
||||
t.Cleanup(release)
|
||||
|
||||
attr, ok := target.FrontendAttrs["context:proxy"]
|
||||
require.True(t, ok)
|
||||
require.Len(t, target.OCIStores, 1)
|
||||
|
||||
parsed, ok, err := ocilayout.Parse(attr)
|
||||
require.True(t, ok)
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, parsed.Path)
|
||||
assert.Equal(t, tt.wantRef.Tag, parsed.Tag)
|
||||
assert.Equal(t, tt.wantRef.Digest, parsed.Digest)
|
||||
target.OCIStores = nil
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type testProgressWriter struct{}
|
||||
|
||||
func (testProgressWriter) Write(*client.SolveStatus) {}
|
||||
|
||||
func (testProgressWriter) WriteBuildRef(string, string) {}
|
||||
|
||||
func (testProgressWriter) ValidateLogSource(digest.Digest, any) bool { return true }
|
||||
|
||||
func (testProgressWriter) ClearLogSource(any) {}
|
||||
|
||||
var _ progress.Writer = testProgressWriter{}
|
||||
|
||||
Reference in New Issue
Block a user