diff --git a/image/descriptor.go b/image/descriptor.go index 21bae8b..edf902d 100644 --- a/image/descriptor.go +++ b/image/descriptor.go @@ -23,6 +23,7 @@ import ( "strings" "github.com/opencontainers/go-digest" + "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" ) @@ -50,17 +51,26 @@ func (d *descriptor) hash() string { func listReferences(w walker) (map[string]*descriptor, error) { refs := make(map[string]*descriptor) + var index v1.ImageIndex if err := w.walk(func(path string, info os.FileInfo, r io.Reader) error { - if info.IsDir() || !strings.HasPrefix(path, "refs") { + if info.IsDir() || filepath.Clean(path) != "index.json" { return nil } - var d descriptor - if err := json.NewDecoder(r).Decode(&d); err != nil { + if err := json.NewDecoder(r).Decode(&index); err != nil { return err } - refs[info.Name()] = &d + + var d descriptor + for i := 0; i < len(index.Manifests); i++ { + if index.Manifests[i].Descriptor.Annotations["org.opencontainers.ref.name"] != "" { + d.MediaType = index.Manifests[i].Descriptor.MediaType + d.Digest = string(index.Manifests[i].Descriptor.Digest) + d.Size = index.Manifests[i].Descriptor.Size + refs[index.Manifests[i].Descriptor.Annotations["org.opencontainers.ref.name"]] = &d + } + } return nil }); err != nil { @@ -71,21 +81,30 @@ func listReferences(w walker) (map[string]*descriptor, error) { func findDescriptor(w walker, name string) (*descriptor, error) { var d descriptor - dpath := filepath.Join("refs", name) + var index v1.ImageIndex switch err := w.walk(func(path string, info os.FileInfo, r io.Reader) error { - if info.IsDir() || filepath.Clean(path) != dpath { + if info.IsDir() || filepath.Clean(path) != "index.json" { return nil } - if err := json.NewDecoder(r).Decode(&d); err != nil { + if err := json.NewDecoder(r).Decode(&index); err != nil { return err } - return errEOW + for i := 0; i < len(index.Manifests); i++ { + if index.Manifests[i].Descriptor.Annotations["org.opencontainers.ref.name"] == name { + d.MediaType = index.Manifests[i].Descriptor.MediaType + d.Digest = string(index.Manifests[i].Descriptor.Digest) + d.Size = index.Manifests[i].Descriptor.Size + return errEOW + } + } + + return nil }); err { case nil: - return nil, fmt.Errorf("%s: descriptor not found", dpath) + return nil, fmt.Errorf("index.json: descriptor not found") case errEOW: return &d, nil default: diff --git a/image/image_test.go b/image/image_test.go index 35ecb29..f2499a4 100644 --- a/image/image_test.go +++ b/image/image_test.go @@ -31,8 +31,7 @@ import ( ) const ( - refTag = "latest" - + refTag = "latest" layoutStr = `{"imageLayoutVersion": "1.0.0"}` configStr = `{ @@ -91,8 +90,44 @@ const ( ) var ( - refStr = `{"digest":"","mediaType":"application/vnd.oci.image.manifest.v1+json","size":}` - + indexStr = `{ + "schemaVersion": 2, + "manifests": [ + { + "mediaType": "application/vnd.oci.image.index.v1+json", + "size": , + "digest": "", + "annotations": { + "org.opencontainers.ref.name": "v1.0" + } + }, + { + "mediaType": "application/vnd.oci.image.manifest.v1+json", + "size": , + "digest": "", + "platform": { + "architecture": "ppc64le", + "os": "linux" + }, + "annotations": { + "org.opencontainers.ref.name": "latest" + } + }, + { + "mediaType": "application/xml", + "size": , + "digest": "", + "annotations": { + "org.freedesktop.specifications.metainfo.version": "1.0", + "org.freedesktop.specifications.metainfo.type": "AppStream" + } + } + ], + "annotations": { + "com.example.index.revision": "r124356" + } +} + ` manifestStr = `{ "annotations": null, "config": { @@ -162,11 +197,6 @@ func createImageLayoutBundle(il imageLayout) error { return err } - err = os.MkdirAll(filepath.Join(il.rootDir, "refs"), 0700) - if err != nil { - return err - } - // create image layout file err = createLayoutFile(il.rootDir) if err != nil { @@ -194,7 +224,7 @@ func createImageLayoutBundle(il imageLayout) error { return err } - return createRefFile(il.rootDir, il.ref, desc) + return createIndexFile(il.rootDir, desc) } func createLayoutFile(root string) error { @@ -208,16 +238,16 @@ func createLayoutFile(root string) error { return err } -func createRefFile(root, ref string, mft descriptor) error { - refpath := filepath.Join(root, "refs", ref) - f, err := os.Create(refpath) +func createIndexFile(root string, mft descriptor) error { + indexpath := filepath.Join(root, "index.json") + f, err := os.Create(indexpath) if err != nil { return err } defer f.Close() - refStr = strings.Replace(refStr, "", mft.Digest, -1) - refStr = strings.Replace(refStr, "", strconv.FormatInt(mft.Size, 10), -1) - _, err = io.Copy(f, bytes.NewBuffer([]byte(refStr))) + indexStr = strings.Replace(indexStr, "", mft.Digest, -1) + indexStr = strings.Replace(indexStr, "", strconv.FormatInt(mft.Size, 10), -1) + _, err = io.Copy(f, bytes.NewBuffer([]byte(indexStr))) return err }