1
- // Copyright (c) 2018-2022 , Sylabs Inc. All rights reserved.
1
+ // Copyright (c) 2018-2023 , Sylabs Inc. All rights reserved.
2
2
// This software is licensed under a 3-clause BSD license. Please consult the
3
3
// LICENSE.md file distributed with the sources of this project regarding your
4
4
// rights to use or distribute this software.
@@ -30,8 +30,12 @@ const mediaTypeSIFLayer = "application/vnd.sylabs.sif.layer.v1.sif"
30
30
// ociRegistryAuth uses Cloud Library endpoint to determine if artifact can be pulled
31
31
// directly from OCI registry.
32
32
//
33
- // Returns url and credentials (if applicable) for that url.
34
- func (c * Client ) ociRegistryAuth (ctx context.Context , name string , accessTypes []accessType ) (* url.URL , * bearerTokenCredentials , error ) {
33
+ // Returns url, credentials (if applicable) for that url, and mapped name.
34
+ //
35
+ // The mapped name can be the same value as 'name' or mapped to a fully-qualified name
36
+ // (ie. from "alpine" to "library/default/alpine") if supported by cloud library server.
37
+ // It will never be an empty string ("")
38
+ func (c * Client ) ociRegistryAuth (ctx context.Context , name string , accessTypes []accessType ) (* url.URL , * bearerTokenCredentials , string , error ) {
35
39
// Build raw query string to get token for specified namespace and access
36
40
v := url.Values {}
37
41
v .Set ("namespace" , name )
@@ -45,7 +49,7 @@ func (c *Client) ociRegistryAuth(ctx context.Context, name string, accessTypes [
45
49
46
50
req , err := c .newRequest (ctx , http .MethodGet , "v1/oci-redirect" , v .Encode (), nil )
47
51
if err != nil {
48
- return nil , nil , err
52
+ return nil , nil , "" , err
49
53
}
50
54
51
55
if c .UserAgent != "" {
@@ -54,30 +58,35 @@ func (c *Client) ociRegistryAuth(ctx context.Context, name string, accessTypes [
54
58
55
59
res , err := c .HTTPClient .Do (req )
56
60
if err != nil {
57
- return nil , nil , fmt .Errorf ("error determining direct OCI registry access: %w" , err )
61
+ return nil , nil , "" , fmt .Errorf ("error determining direct OCI registry access: %w" , err )
58
62
}
59
63
defer res .Body .Close ()
60
64
61
65
if res .StatusCode != http .StatusOK {
62
- return nil , nil , fmt .Errorf ("error determining direct OCI registry access: %w" , err )
66
+ return nil , nil , "" , fmt .Errorf ("error determining direct OCI registry access: %w" , err )
63
67
}
64
68
65
69
type ociDownloadRedirectResponse struct {
66
70
Token string `json:"token"`
67
71
RegistryURI string `json:"url"`
72
+ Name string `json:"name"`
68
73
}
69
74
70
75
var ociArtifactSpec ociDownloadRedirectResponse
71
76
72
77
if err := json .NewDecoder (res .Body ).Decode (& ociArtifactSpec ); err != nil {
73
- return nil , nil , fmt .Errorf ("error decoding direct OCI registry access response: %w" , err )
78
+ return nil , nil , "" , fmt .Errorf ("error decoding direct OCI registry access response: %w" , err )
79
+ }
80
+
81
+ if ociArtifactSpec .Name != "" && ociArtifactSpec .Name != name {
82
+ name = ociArtifactSpec .Name
74
83
}
75
84
76
85
endpoint , err := url .Parse (ociArtifactSpec .RegistryURI )
77
86
if err != nil {
78
- return nil , nil , fmt .Errorf ("malformed OCI registry URI %v: %v" , ociArtifactSpec .RegistryURI , err )
87
+ return nil , nil , "" , fmt .Errorf ("malformed OCI registry URI %v: %v" , ociArtifactSpec .RegistryURI , err )
79
88
}
80
- return endpoint , & bearerTokenCredentials {authToken : ociArtifactSpec .Token }, nil
89
+ return endpoint , & bearerTokenCredentials {authToken : ociArtifactSpec .Token }, name , nil
81
90
}
82
91
83
92
const (
@@ -621,21 +630,27 @@ func (r *ociRegistry) getImageConfig(ctx context.Context, creds credentials, nam
621
630
622
631
var errOCIDownloadNotSupported = errors .New ("not supported" )
623
632
624
- func (c * Client ) newOCIRegistry (ctx context.Context , name string , accessTypes []accessType ) (* ociRegistry , * bearerTokenCredentials , error ) {
633
+ func (c * Client ) newOCIRegistry (ctx context.Context , name string , accessTypes []accessType ) (* ociRegistry , * bearerTokenCredentials , string , error ) {
625
634
// Attempt to obtain (direct) OCI registry auth token
626
- registryURI , creds , err := c .ociRegistryAuth (ctx , name , accessTypes )
635
+ originalName := name
636
+
637
+ registryURI , creds , name , err := c .ociRegistryAuth (ctx , name , accessTypes )
627
638
if err != nil {
628
- return nil , nil , errOCIDownloadNotSupported
639
+ return nil , nil , "" , errOCIDownloadNotSupported
629
640
}
630
641
631
642
// Download directly from OCI registry
632
643
c .Logger .Logf ("Using OCI registry endpoint %v" , registryURI )
633
644
634
- return & ociRegistry {baseURL : registryURI , httpClient : c .HTTPClient , logger : c .Logger }, creds , nil
645
+ if name != "" && originalName != name {
646
+ c .Logger .Logf ("OCI artifact name \" %v\" mapped to \" %v\" " , originalName , name )
647
+ }
648
+
649
+ return & ociRegistry {baseURL : registryURI , httpClient : c .HTTPClient , logger : c .Logger }, creds , name , nil
635
650
}
636
651
637
652
func (c * Client ) ociDownloadImage (ctx context.Context , arch , name , tag string , w io.WriterAt , spec * Downloader , pb ProgressBar ) error {
638
- reg , creds , err := c .newOCIRegistry (ctx , name , []accessType {accessTypePull })
653
+ reg , creds , name , err := c .newOCIRegistry (ctx , name , []accessType {accessTypePull })
639
654
if err != nil {
640
655
return err
641
656
}
@@ -663,7 +678,7 @@ func (e *unexpectedImageDigest) Error() string {
663
678
}
664
679
665
680
func (c * Client ) ociUploadImage (ctx context.Context , r io.Reader , size int64 , name , arch string , tags []string , description , hash string , callback UploadCallback ) error {
666
- reg , creds , err := c .newOCIRegistry (ctx , name , []accessType {accessTypePull , accessTypePush })
681
+ reg , creds , name , err := c .newOCIRegistry (ctx , name , []accessType {accessTypePull , accessTypePush })
667
682
if err != nil {
668
683
return err
669
684
}
0 commit comments