@@ -18,6 +18,7 @@ import (
18
18
"bytes"
19
19
"context"
20
20
"encoding/json"
21
+ "errors"
21
22
"fmt"
22
23
"io"
23
24
"net/http"
@@ -38,14 +39,18 @@ import (
38
39
)
39
40
40
41
const (
41
- exampleRepositoryName = "example"
42
- exampleTag = "latest"
43
- exampleConfig = "Example config content"
44
- exampleLayer = "Example layer content"
45
- exampleUploadUUid = "0bc84d80-837c-41d9-824e-1907463c53b3"
46
- ManifestDigest = "sha256:0b696106ecd0654e031f19e0a8cbd1aee4ad457d7c9cea881f07b12a930cd307"
47
- ReferenceManifestDigest = "sha256:6983f495f7ee70d43e571657ae8b39ca3d3ca1b0e77270fd4fbddfb19832a1cf"
48
- _ = ExampleUnplayable
42
+ exampleRepositoryName = "example"
43
+ exampleTag = "latest"
44
+ exampleConfig = "Example config content"
45
+ exampleLayer = "Example layer content"
46
+ exampleUploadUUid = "0bc84d80-837c-41d9-824e-1907463c53b3"
47
+ ManifestDigest = "sha256:0b696106ecd0654e031f19e0a8cbd1aee4ad457d7c9cea881f07b12a930cd307"
48
+ ReferenceManifestDigest = "sha256:6983f495f7ee70d43e571657ae8b39ca3d3ca1b0e77270fd4fbddfb19832a1cf"
49
+ referrersAPIUnavailableRepositoryName = "no-referrers-api"
50
+ referrerDigest = "sha256:21c623eb8ccd273f2702efd74a0abb455dd06a99987f413c2114fb00961ebfe7"
51
+ referrersTag = "sha256-c824a9aa7d2e3471306648c6d4baa1abbcb97ff0276181ab4722ca27127cdba0"
52
+ referrerIndexDigest = "sha256:7baac5147dd58d56fdbaad5a888fa919235a3a90cb71aaa8b56ee5d19f4cd838"
53
+ _ = ExampleUnplayable
49
54
)
50
55
51
56
var (
@@ -99,6 +104,15 @@ var (
99
104
ArtifactType : "example/manifest" ,
100
105
Digest : digest .FromBytes (exampleManifestWithBlobs ),
101
106
Size : int64 (len (exampleManifestWithBlobs ))}
107
+ subjectDescriptor = content .NewDescriptorFromBytes (ocispec .MediaTypeImageManifest , []byte (`{"layers":[]}` ))
108
+ referrerManifestContent , _ = json .Marshal (ocispec.Manifest {
109
+ MediaType : ocispec .MediaTypeImageManifest ,
110
+ Subject : & subjectDescriptor ,
111
+ })
112
+ referrerDescriptor = content .NewDescriptorFromBytes (ocispec .MediaTypeImageManifest , referrerManifestContent )
113
+ referrerIndex , _ = json .Marshal (ocispec.Index {
114
+ Manifests : []ocispec.Descriptor {},
115
+ })
102
116
)
103
117
104
118
var host string
@@ -205,6 +219,20 @@ func TestMain(m *testing.M) {
205
219
if m == "GET" {
206
220
w .Write ([]byte (resultBlob ))
207
221
}
222
+ case p == fmt .Sprintf ("/v2/%s/referrers/%s" , referrersAPIUnavailableRepositoryName , "sha256:0000000000000000000000000000000000000000000000000000000000000000" ):
223
+ w .WriteHeader (http .StatusNotFound )
224
+ case p == fmt .Sprintf ("/v2/%s/manifests/%s" , referrersAPIUnavailableRepositoryName , referrerDigest ) && m == http .MethodPut :
225
+ w .WriteHeader (http .StatusCreated )
226
+ case p == fmt .Sprintf ("/v2/%s/manifests/%s" , referrersAPIUnavailableRepositoryName , referrersTag ) && m == http .MethodGet :
227
+ w .Write (referrerIndex )
228
+ w .Header ().Set ("Content-Type" , ocispec .MediaTypeImageIndex )
229
+ w .Header ().Set ("Content-Length" , strconv .Itoa (len (referrerIndex )))
230
+ w .Header ().Set ("Docker-Content-Digest" , digest .Digest (string (referrerIndex )).String ())
231
+ w .WriteHeader (http .StatusCreated )
232
+ case p == fmt .Sprintf ("/v2/%s/manifests/%s" , referrersAPIUnavailableRepositoryName , referrersTag ) && m == http .MethodPut :
233
+ w .WriteHeader (http .StatusCreated )
234
+ case p == fmt .Sprintf ("/v2/%s/manifests/%s" , referrersAPIUnavailableRepositoryName , referrerIndexDigest ) && m == http .MethodDelete :
235
+ w .WriteHeader (http .StatusMethodNotAllowed )
208
236
}
209
237
210
238
}))
@@ -785,3 +813,28 @@ func Example_tagReference() {
785
813
// Output:
786
814
// Tagged sha256:b53dc03a49f383ba230d8ac2b78a9c4aec132e4a9f36cc96524df98163202cc7 as latest
787
815
}
816
+
817
+ // Example_pushAndIgnoreReferrersIndexError gives example snippets on how to
818
+ // ignore referrer index deletion error during push a referrer manifest.
819
+ func Example_pushAndIgnoreReferrersIndexError () {
820
+ repo , err := remote .NewRepository (fmt .Sprintf ("%s/%s" , host , referrersAPIUnavailableRepositoryName ))
821
+ if err != nil {
822
+ panic (err )
823
+ }
824
+ ctx := context .Background ()
825
+
826
+ // push a referrer manifest and ignore cleaning up error
827
+ err = repo .Push (ctx , referrerDescriptor , bytes .NewReader (referrerManifestContent ))
828
+ if err != nil {
829
+ var re * remote.ReferrersError
830
+ if ! errors .As (err , & re ) || ! re .IsReferrersIndexDelete () {
831
+ panic (err )
832
+ }
833
+ fmt .Println ("ignoring error occurred during cleaning obsolete referrers index" )
834
+ }
835
+ fmt .Println ("Push finished" )
836
+
837
+ // Output:
838
+ // ignoring error occurred during cleaning obsolete referrers index
839
+ // Push finished
840
+ }
0 commit comments