github.com/docker/cnab-to-oci@v0.3.0-beta4/remotes/pull_test.go (about) 1 package remotes 2 3 import ( 4 "bytes" 5 "context" 6 "encoding/json" 7 "fmt" 8 "os" 9 "testing" 10 11 "github.com/docker/cnab-to-oci/tests" 12 "github.com/docker/distribution/reference" 13 ocischemav1 "github.com/opencontainers/image-spec/specs-go/v1" 14 "gotest.tools/assert" 15 ) 16 17 func TestPull(t *testing.T) { 18 index := tests.MakeTestOCIIndex() 19 bufBundleManifest, err := json.Marshal(index) 20 assert.NilError(t, err) 21 22 bundleConfigManifestDescriptor := []byte(`{ 23 "schemaVersion": 2, 24 "mediaType": "application/vnd.docker.distribution.manifest.v2+json", 25 "config": { 26 "mediaType": "application/vnd.docker.container.image.v1+json", 27 "size": 315, 28 "digest": "sha256:e2337974e94637d3fab7004f87501e605b08bca3adf9ecd356909a9329da128a" 29 }, 30 "layers": null 31 }`) 32 33 b := tests.MakeTestBundle() 34 bufBundle, err := json.Marshal(b) 35 assert.NilError(t, err) 36 37 fetcher := &mockFetcher{indexBuffers: []*bytes.Buffer{ 38 // Bundle index 39 bytes.NewBuffer(bufBundleManifest), 40 // Bundle config manifest 41 bytes.NewBuffer(bundleConfigManifestDescriptor), 42 // Bundle config 43 bytes.NewBuffer(bufBundle), 44 }} 45 resolver := &mockResolver{ 46 fetcher: fetcher, 47 resolvedDescriptors: []ocischemav1.Descriptor{ 48 // Bundle index descriptor 49 {MediaType: ocischemav1.MediaTypeImageIndex}, 50 // Bundle config manifest descriptor 51 { 52 MediaType: ocischemav1.MediaTypeDescriptor, 53 Digest: "sha256:d59a1aa7866258751a261bae525a1842c7ff0662d4f34a355d5f36826abc0341", 54 }, 55 // Bundle config descriptor 56 {MediaType: ocischemav1.MediaTypeImageIndex}, 57 }, 58 } 59 ref, err := reference.ParseNamed("my.registry/namespace/my-app:my-tag") 60 assert.NilError(t, err) 61 62 // Pull the CNAB and get the bundle 63 b, _, err = Pull(context.Background(), ref, resolver) 64 assert.NilError(t, err) 65 expectedBundle := tests.MakeTestBundle() 66 assert.DeepEqual(t, expectedBundle, b) 67 } 68 69 // nolint: lll 70 func ExamplePull() { 71 // Use remotes.CreateResolver for creating your remotes.Resolver 72 resolver := createExampleResolver() 73 ref, err := reference.ParseNamed("my.registry/namespace/my-app:my-tag") 74 if err != nil { 75 panic(err) 76 } 77 78 // Pull the CNAB, get the bundle and the associated relocation map 79 resultBundle, relocationMap, err := Pull(context.Background(), ref, resolver) 80 if err != nil { 81 panic(err) 82 } 83 84 resultBundle.WriteTo(os.Stdout) //nolint:errcheck 85 buf, err := json.Marshal(relocationMap) 86 if err != nil { 87 panic(err) 88 } 89 fmt.Printf("\n") 90 fmt.Println(string(buf)) 91 // Output: 92 //{"actions":{"action-1":{"modifies":true}},"credentials":{"cred-1":{"env":"env-var","path":"/some/path"}},"custom":{"my-key":"my-value"},"definitions":{"output1Type":{"type":"string"},"param1Type":{"default":"hello","enum":["value1",true,1],"type":["string","boolean","number"]}},"description":"description","images":{"another-image":{"contentDigest":"sha256:d59a1aa7866258751a261bae525a1842c7ff0662d4f34a355d5f36826abc0342","description":"","image":"my.registry/namespace/another-image","imageType":"oci","mediaType":"application/vnd.oci.image.manifest.v1+json","size":507},"image-1":{"contentDigest":"sha256:d59a1aa7866258751a261bae525a1842c7ff0662d4f34a355d5f36826abc0341","description":"","image":"my.registry/namespace/image-1","imageType":"oci","mediaType":"application/vnd.oci.image.manifest.v1+json","size":507}},"invocationImages":[{"contentDigest":"sha256:d59a1aa7866258751a261bae525a1842c7ff0662d4f34a355d5f36826abc0343","image":"my.registry/namespace/my-app-invoc","imageType":"docker","mediaType":"application/vnd.docker.distribution.manifest.v2+json","size":506}],"keywords":["keyword1","keyword2"],"maintainers":[{"email":"docker@docker.com","name":"docker","url":"docker.com"}],"name":"my-app","outputs":{"output1":{"applyTo":["install"],"definition":"output1Type","description":"magic","path":"/cnab/app/outputs/magic"}},"parameters":{"param1":{"definition":"param1Type","destination":{"env":"env_var","path":"/some/path"}}},"schemaVersion":"v1.0.0","version":"0.1.0"} 93 //{"my.registry/namespace/image-1":"my.registry/namespace/my-app@sha256:d59a1aa7866258751a261bae525a1842c7ff0662d4f34a355d5f36826abc0341","my.registry/namespace/my-app-invoc":"my.registry/namespace/my-app@sha256:d59a1aa7866258751a261bae525a1842c7ff0662d4f34a355d5f36826abc0341"} 94 } 95 96 const ( 97 bufBundleManifest = `{ 98 "schemaVersion": 1, 99 "manifests": [ 100 { 101 "mediaType": "application/vnd.oci.image.manifest.v1+json", 102 "digest": "sha256:d59a1aa7866258751a261bae525a1842c7ff0662d4f34a355d5f36826abc0341", 103 "size": 315, 104 "annotations": { 105 "io.cnab.manifest.type": "config" 106 } 107 }, 108 { 109 "mediaType": "application/vnd.docker.distribution.manifest.v2+json", 110 "digest": "sha256:d59a1aa7866258751a261bae525a1842c7ff0662d4f34a355d5f36826abc0341", 111 "size": 506, 112 "annotations": { 113 "io.cnab.manifest.type": "invocation" 114 } 115 }, 116 { 117 "mediaType": "application/vnd.oci.image.manifest.v1+json", 118 "digest": "sha256:d59a1aa7866258751a261bae525a1842c7ff0662d4f34a355d5f36826abc0341", 119 "size": 507, 120 "annotations": { 121 "io.cnab.component.name": "image-1", 122 "io.cnab.manifest.type": "component" 123 } 124 } 125 ], 126 "annotations": { 127 "io.cnab.keywords": "[\"keyword1\",\"keyword2\"]", 128 "io.cnab.runtime_version": "v1.0.0", 129 "io.docker.app.format": "cnab", 130 "io.docker.type": "app", 131 "org.opencontainers.image.authors": "[{\"name\":\"docker\",\"email\":\"docker@docker.com\",\"url\":\"docker.com\"}]", 132 "org.opencontainers.image.description": "description", 133 "org.opencontainers.image.title": "my-app", 134 "org.opencontainers.image.version": "0.1.0" 135 } 136 }` 137 138 bundleConfigManifestDescriptor = `{ 139 "schemaVersion": 2, 140 "config": { 141 "mediaType": "application/vnd.cnab.config.v1+json", 142 "size": 315, 143 "digest": "sha256:e2337974e94637d3fab7004f87501e605b08bca3adf9ecd356909a9329da128a" 144 }, 145 "layers": null 146 }` 147 ) 148 149 func createExampleResolver() *mockResolver { 150 b := tests.MakeTestBundle() 151 bufBundleConfig, err := json.Marshal(b) 152 if err != nil { 153 panic(err) 154 } 155 buf := []*bytes.Buffer{ 156 // Bundle index 157 bytes.NewBuffer([]byte(bufBundleManifest)), 158 // Bundle config manifest 159 bytes.NewBuffer([]byte(bundleConfigManifestDescriptor)), 160 // Bundle config 161 bytes.NewBuffer(bufBundleConfig), 162 } 163 fetcher := &mockFetcher{indexBuffers: buf} 164 pusher := &mockPusher{} 165 return &mockResolver{ 166 pusher: pusher, 167 fetcher: fetcher, 168 resolvedDescriptors: []ocischemav1.Descriptor{ 169 // Bundle index descriptor 170 { 171 MediaType: ocischemav1.MediaTypeImageIndex, 172 Digest: "sha256:d59a1aa7866258751a261bae525a1842c7ff0662d4f34a355d5f36826abc0341", 173 Size: int64(len(bufBundleManifest)), 174 }, 175 // Bundle config manifest descriptor 176 { 177 MediaType: ocischemav1.MediaTypeDescriptor, 178 Digest: "sha256:d59a1aa7866258751a261bae525a1842c7ff0662d4f34a355d5f36826abc0341", 179 Size: int64(len(bundleConfigManifestDescriptor)), 180 }, 181 // Bundle config descriptor 182 { 183 MediaType: ocischemav1.MediaTypeImageConfig, 184 Digest: "sha256:d59a1aa7866258751a261bae525a1842c7ff0662d4f34a355d5f36826abc0341", 185 Size: int64(len(bufBundleConfig)), 186 }, 187 }, 188 } 189 }