@@ -6,6 +6,7 @@ package uriget
6
6
7
7
import (
8
8
"context"
9
+ "encoding/json"
9
10
"fmt"
10
11
"io"
11
12
"log"
@@ -17,8 +18,7 @@ import (
17
18
"strings"
18
19
"time"
19
20
20
- "oras.land/oras-go/v2"
21
- "oras.land/oras-go/v2/content/oci"
21
+ v1 "github.com/opencontainers/image-spec/specs-go/v1"
22
22
"oras.land/oras-go/v2/registry"
23
23
"oras.land/oras-go/v2/registry/remote"
24
24
)
@@ -244,25 +244,52 @@ func (o *options) getGit(ctx context.Context, u *url.URL) ([]byte, error) {
244
244
func (o * options ) getOci (ctx context.Context , u * url.URL ) ([]byte , error ) {
245
245
ref , err := registry .ParseReference (u .Host + u .Path )
246
246
if err != nil {
247
- return nil , fmt .Errorf ("can't parse artifact URL into a valid reference : %w" , err )
247
+ return nil , fmt .Errorf ("invalid artifact URL: %w" , err )
248
248
}
249
- store , err := oci .New (o .tempDir )
250
- if err != nil {
251
- return nil , fmt .Errorf ("failed to create OCI layout store: %w" , err )
249
+ if ref .Reference == "" {
250
+ ref .Reference = "latest"
252
251
}
252
+ specifiedFile := strings .TrimPrefix (u .Fragment , "#" )
253
253
remoteRepo , err := remote .NewRepository (ref .String ())
254
254
if err != nil {
255
- return nil , fmt .Errorf ("failed to connect to remote repository: %w" , err )
255
+ return nil , fmt .Errorf ("connection to remote repository failed: %w" , err )
256
+ }
257
+ _ , rc , err := remoteRepo .Manifests ().FetchReference (ctx , ref .Reference )
258
+ if err != nil {
259
+ return nil , fmt .Errorf ("manifest fetch failed: %w" , err )
260
+ }
261
+ defer rc .Close ()
262
+ var manifest v1.Manifest
263
+ if err = json .NewDecoder (rc ).Decode (& manifest ); err != nil {
264
+ return nil , fmt .Errorf ("manifest decode failed: %w" , err )
265
+ }
266
+ var selectedLayer * v1.Descriptor
267
+ yamlFileCount := 0
268
+ for _ , layer := range manifest .Layers {
269
+ title := layer .Annotations [v1 .AnnotationTitle ]
270
+ if strings .HasSuffix (title , ".yaml" ) {
271
+ yamlFileCount ++
272
+ if specifiedFile == "" && yamlFileCount > 1 {
273
+ return nil , fmt .Errorf ("manifest contains %d .yaml files; specify a specific file in the URL fragment" , yamlFileCount )
274
+ }
275
+ if specifiedFile == "" || title == specifiedFile {
276
+ selectedLayer = & layer
277
+ break
278
+ }
279
+ }
256
280
}
257
- tag := "latest"
258
- if ref .Reference != "" {
259
- tag = ref .Reference
281
+ if selectedLayer == nil {
282
+ return nil , fmt .Errorf ("no matching .yaml file found in layers" )
260
283
}
261
- manifestDescriptor , err := oras . Copy ( ctx , remoteRepo , tag , store , tag , oras . DefaultCopyOptions )
284
+ _ , rc , err = remoteRepo . Blobs (). FetchReference ( ctx , selectedLayer . Digest . String () )
262
285
if err != nil {
263
- return nil , fmt .Errorf ("failed to pull OCI image : %w" , err )
286
+ return nil , fmt .Errorf ("blob fetch failed : %w" , err )
264
287
}
265
-
266
- o .logger .Printf ("Pulled OCI image: %s with manifest descriptor: %v" , u .String (), manifestDescriptor .Digest )
267
- return []byte (manifestDescriptor .Digest ), nil
288
+ defer rc .Close ()
289
+ buff , err := readLimited (rc , o .limit )
290
+ if err != nil {
291
+ return nil , fmt .Errorf ("blob read failed: %w" , err )
292
+ }
293
+ o .logger .Printf ("Read %d bytes from %s" , len (buff ), specifiedFile )
294
+ return buff , nil
268
295
}
0 commit comments