@@ -3,6 +3,7 @@ package oci
33import (
44 "context"
55 "fmt"
6+ "strconv"
67
78 "github.com/google/go-containerregistry/pkg/v1/layout"
89
@@ -52,7 +53,7 @@ func (p *DirectoryImageProvider) Provide(_ context.Context, userMetadata ...imag
5253 return nil , fmt .Errorf ("unable to parse OCI directory as an image: %w" , err )
5354 }
5455
55- var metadata = []image.AdditionalMetadata {
56+ metadata : = []image.AdditionalMetadata {
5657 image .WithManifestDigest (manifest .Digest .String ()),
5758 }
5859
@@ -72,3 +73,63 @@ func (p *DirectoryImageProvider) Provide(_ context.Context, userMetadata ...imag
7273
7374 return image .New (img , p .tmpDirGen , contentTempDir , metadata ... ), nil
7475}
76+
77+ // ProvideIndex provides an image index that represents the OCI image as a directory.
78+ func (p * DirectoryImageProvider ) ProvideIndex (_ context.Context , userMetadata ... image.AdditionalMetadata ) (* image.Index , error ) {
79+ pathObj , err := layout .FromPath (p .path )
80+ if err != nil {
81+ return nil , fmt .Errorf ("unable to read image from OCI directory path %q: %w" , p .path , err )
82+ }
83+
84+ index , err := layout .ImageIndexFromPath (p .path )
85+ if err != nil {
86+ return nil , fmt .Errorf ("unable to parse OCI directory index: %w" , err )
87+ }
88+
89+ indexManifest , err := index .IndexManifest ()
90+ if err != nil {
91+ return nil , fmt .Errorf ("unable to parse OCI directory indexManifest: %w" , err )
92+ }
93+
94+ if len (indexManifest .Manifests ) < 1 {
95+ return nil , fmt .Errorf ("expected at least one OCI directory manifests (found %d)" , len (indexManifest .Manifests ))
96+ }
97+
98+ images := make ([]* image.Image , len (indexManifest .Manifests ))
99+ for i , manifest := range indexManifest .Manifests {
100+ img , err := pathObj .Image (manifest .Digest )
101+ if err != nil {
102+ return nil , fmt .Errorf ("unable to parse OCI directory as an image: %w" , err )
103+ }
104+
105+ metadata := []image.AdditionalMetadata {
106+ image .WithManifestDigest (manifest .Digest .String ()),
107+ }
108+ if manifest .Platform != nil {
109+ if manifest .Platform .Architecture != "" {
110+ metadata = append (metadata , image .WithArchitecture (manifest .Platform .Architecture , manifest .Platform .Variant ))
111+ }
112+ if manifest .Platform .OS != "" {
113+ metadata = append (metadata , image .WithOS (manifest .Platform .OS ))
114+ }
115+ }
116+
117+ // make a best-effort attempt at getting the raw indexManifest
118+ rawManifest , err := img .RawManifest ()
119+ if err == nil {
120+ metadata = append (metadata , image .WithManifest (rawManifest ))
121+ }
122+
123+ // apply user-supplied metadata last to override any default behavior
124+ metadata = append (metadata , userMetadata ... )
125+
126+ contentTempDir , err := p .tmpDirGen .NewDirectory ("oci-dir-image-" + strconv .Itoa (i ))
127+ if err != nil {
128+ return nil , err
129+ }
130+
131+ images [i ] = image .New (img , p .tmpDirGen , contentTempDir , metadata ... )
132+ }
133+
134+ return image .NewIndex (index , images ), nil
135+ }
0 commit comments