@@ -60,44 +60,26 @@ func NewLiveClient(hc *http.Client, host string, l *ioconfig.Handler) *LiveClien
6060 }
6161}
6262
63- func (c * LiveClient ) BuildRepoAndDigestURL (repo , digest string ) string {
64- repo = strings .Trim (repo , "/" )
65- return fmt .Sprintf (GetAttestationByRepoAndSubjectDigestPath , repo , digest )
66- }
67-
6863// GetByRepoAndDigest fetches the attestation by repo and digest
6964func (c * LiveClient ) GetByRepoAndDigest (repo , digest string , limit int ) ([]* Attestation , error ) {
70- url := c .BuildRepoAndDigestURL (repo , digest )
71- attestations , err := c .getAttestations (url , repo , digest , limit )
72- if err != nil {
73- return nil , err
74- }
75-
76- bundles , err := c .fetchBundleFromAttestations (attestations )
77- if err != nil {
78- return nil , fmt .Errorf ("failed to fetch bundle with URL: %w" , err )
79- }
80-
81- return bundles , nil
82- }
83-
84- func (c * LiveClient ) BuildOwnerAndDigestURL (owner , digest string ) string {
85- owner = strings .Trim (owner , "/" )
86- return fmt .Sprintf (GetAttestationByOwnerAndSubjectDigestPath , owner , digest )
65+ c .logger .VerbosePrintf ("Fetching attestations for artifact digest %s\n \n " , digest )
66+ url := fmt .Sprintf (GetAttestationByRepoAndSubjectDigestPath , repo , digest )
67+ return c .getByURL (url , limit )
8768}
8869
8970// GetByOwnerAndDigest fetches attestation by owner and digest
9071func (c * LiveClient ) GetByOwnerAndDigest (owner , digest string , limit int ) ([]* Attestation , error ) {
91- url := c .BuildOwnerAndDigestURL (owner , digest )
92- attestations , err := c .getAttestations (url , owner , digest , limit )
72+ c .logger .VerbosePrintf ("Fetching attestations for artifact digest %s\n \n " , digest )
73+ url := fmt .Sprintf (GetAttestationByOwnerAndSubjectDigestPath , owner , digest )
74+ return c .getByURL (url , limit )
75+ }
76+
77+ func (c * LiveClient ) getByURL (url string , limit int ) ([]* Attestation , error ) {
78+ attestations , err := c .getAttestations (url , limit )
9379 if err != nil {
9480 return nil , err
9581 }
9682
97- if len (attestations ) == 0 {
98- return nil , newErrNoAttestations (owner , digest )
99- }
100-
10183 bundles , err := c .fetchBundleFromAttestations (attestations )
10284 if err != nil {
10385 return nil , fmt .Errorf ("failed to fetch bundle with URL: %w" , err )
@@ -112,9 +94,7 @@ func (c *LiveClient) GetTrustDomain() (string, error) {
11294 return c .getTrustDomain (MetaPath )
11395}
11496
115- func (c * LiveClient ) getAttestations (url , name , digest string , limit int ) ([]* Attestation , error ) {
116- c .logger .VerbosePrintf ("Fetching attestations for artifact digest %s\n \n " , digest )
117-
97+ func (c * LiveClient ) getAttestations (url string , limit int ) ([]* Attestation , error ) {
11898 perPage := limit
11999 if perPage <= 0 || perPage > maxLimitForFlag {
120100 return nil , fmt .Errorf ("limit must be greater than 0 and less than or equal to %d" , maxLimitForFlag )
@@ -157,7 +137,7 @@ func (c *LiveClient) getAttestations(url, name, digest string, limit int) ([]*At
157137 }
158138
159139 if len (attestations ) == 0 {
160- return nil , newErrNoAttestations ( name , digest )
140+ return nil , ErrNoAttestationsFound
161141 }
162142
163143 if len (attestations ) > limit {
@@ -176,23 +156,22 @@ func (c *LiveClient) fetchBundleFromAttestations(attestations []*Attestation) ([
176156 return fmt .Errorf ("attestation has no bundle or bundle URL" )
177157 }
178158
179- // If the bundle field is nil, try to fetch the bundle with the provided URL
180- if a .Bundle == nil {
181- c .logger .VerbosePrintf ("Bundle field is empty. Trying to fetch with bundle URL\n \n " )
182- b , err := c .GetBundle (a .BundleURL )
183- if err != nil {
184- return fmt .Errorf ("failed to fetch bundle with URL: %w" , err )
185- }
159+ // for now, we fall back to the bundle field if the bundle URL is empty
160+ if a .BundleURL == "" {
161+ c .logger .VerbosePrintf ("Bundle URL is empty. Falling back to bundle field\n \n " )
186162 fetched [i ] = & Attestation {
187- Bundle : b ,
163+ Bundle : a . Bundle ,
188164 }
189165 return nil
190166 }
191167
192- // otherwise fall back to the bundle field
193- c .logger .VerbosePrintf ("Fetching bundle from Bundle field\n \n " )
168+ // otherwise fetch the bundle with the provided URL
169+ b , err := c .getBundle (a .BundleURL )
170+ if err != nil {
171+ return fmt .Errorf ("failed to fetch bundle with URL: %w" , err )
172+ }
194173 fetched [i ] = & Attestation {
195- Bundle : a . Bundle ,
174+ Bundle : b ,
196175 }
197176
198177 return nil
@@ -206,38 +185,49 @@ func (c *LiveClient) fetchBundleFromAttestations(attestations []*Attestation) ([
206185 return fetched , nil
207186}
208187
209- func (c * LiveClient ) GetBundle (url string ) (* bundle.Bundle , error ) {
188+ func (c * LiveClient ) getBundle (url string ) (* bundle.Bundle , error ) {
210189 c .logger .VerbosePrintf ("Fetching attestation bundle with bundle URL\n \n " )
211190
212- resp , err := c .httpClient .Get (url )
213- if err != nil {
214- return nil , err
215- }
191+ var sgBundle * bundle.Bundle
192+ bo := backoff .NewConstantBackOff (getAttestationRetryInterval )
193+ err := backoff .Retry (func () error {
194+ resp , err := c .httpClient .Get (url )
195+ if err != nil {
196+ return fmt .Errorf ("request to fetch bundle from URL failed: %w" , err )
197+ }
216198
217- defer resp .Body .Close ()
218- if resp .StatusCode != http .StatusOK {
219- return nil , fmt .Errorf ("unexpected status code: %d" , resp .StatusCode )
220- }
199+ if resp .StatusCode >= 500 && resp .StatusCode <= 599 {
200+ return fmt .Errorf ("attestation bundle with URL %s returned status code %d" , url , resp .StatusCode )
201+ }
221202
222- body , err := io .ReadAll (resp .Body )
223- if err != nil {
224- return nil , fmt .Errorf ("failed to read blob storage response body: %w" , err )
225- }
203+ defer resp .Body .Close ()
204+ body , err := io .ReadAll (resp .Body )
205+ if err != nil {
206+ return fmt .Errorf ("failed to read blob storage response body: %w" , err )
207+ }
226208
227- var out []byte
228- decompressed , err := snappy .Decode (out , body )
229- if err != nil {
230- return nil , fmt .Errorf ("failed to decompress with snappy: %w" , err )
231- }
209+ var out []byte
210+ decompressed , err := snappy .Decode (out , body )
211+ if err != nil {
212+ return backoff . Permanent ( fmt .Errorf ("failed to decompress with snappy: %w" , err ) )
213+ }
232214
233- var pbBundle v1.Bundle
234- if err = protojson .Unmarshal (decompressed , & pbBundle ); err != nil {
235- return nil , fmt .Errorf ("failed to unmarshal to bundle: %w" , err )
236- }
215+ var pbBundle v1.Bundle
216+ if err = protojson .Unmarshal (decompressed , & pbBundle ); err != nil {
217+ return backoff . Permanent ( fmt .Errorf ("failed to unmarshal to bundle: %w" , err ) )
218+ }
237219
238- c .logger .VerbosePrintf ("Successfully fetched bundle\n \n " )
220+ c .logger .VerbosePrintf ("Successfully fetched bundle\n \n " )
221+
222+ sgBundle , err = bundle .NewBundle (& pbBundle )
223+ if err != nil {
224+ return backoff .Permanent (fmt .Errorf ("failed to create new bundle: %w" , err ))
225+ }
226+
227+ return nil
228+ }, backoff .WithMaxRetries (bo , 3 ))
239229
240- return bundle . NewBundle ( & pbBundle )
230+ return sgBundle , err
241231}
242232
243233func shouldRetry (err error ) bool {
0 commit comments