|
7 | 7 | "github.com/docker/cli/cli/manifest/types" |
8 | 8 | "github.com/docker/distribution" |
9 | 9 | "github.com/docker/distribution/manifest/manifestlist" |
| 10 | + "github.com/docker/distribution/manifest/ocischema" |
10 | 11 | "github.com/docker/distribution/manifest/schema2" |
11 | 12 | "github.com/docker/distribution/reference" |
12 | 13 | "github.com/docker/distribution/registry/api/errcode" |
@@ -35,6 +36,12 @@ func fetchManifest(ctx context.Context, repo distribution.Repository, ref refere |
35 | 36 | return types.ImageManifest{}, err |
36 | 37 | } |
37 | 38 | return imageManifest, nil |
| 39 | + case *ocischema.DeserializedManifest: |
| 40 | + imageManifest, err := pullManifestOCISchema(ctx, ref, repo, *v) |
| 41 | + if err != nil { |
| 42 | + return types.ImageManifest{}, err |
| 43 | + } |
| 44 | + return imageManifest, nil |
38 | 45 | case *manifestlist.DeserializedManifestList: |
39 | 46 | return types.ImageManifest{}, errors.Errorf("%s is a manifest list", ref) |
40 | 47 | } |
@@ -94,6 +101,28 @@ func pullManifestSchemaV2(ctx context.Context, ref reference.Named, repo distrib |
94 | 101 | return types.NewImageManifest(ref, manifestDesc, &mfst), nil |
95 | 102 | } |
96 | 103 |
|
| 104 | +func pullManifestOCISchema(ctx context.Context, ref reference.Named, repo distribution.Repository, mfst ocischema.DeserializedManifest) (types.ImageManifest, error) { |
| 105 | + manifestDesc, err := validateManifestDigest(ref, mfst) |
| 106 | + if err != nil { |
| 107 | + return types.ImageManifest{}, err |
| 108 | + } |
| 109 | + configJSON, err := pullManifestSchemaV2ImageConfig(ctx, mfst.Target().Digest, repo) |
| 110 | + if err != nil { |
| 111 | + return types.ImageManifest{}, err |
| 112 | + } |
| 113 | + |
| 114 | + if manifestDesc.Platform == nil { |
| 115 | + manifestDesc.Platform = &ocispec.Platform{} |
| 116 | + } |
| 117 | + |
| 118 | + // Fill in os and architecture fields from config JSON |
| 119 | + if err := json.Unmarshal(configJSON, manifestDesc.Platform); err != nil { |
| 120 | + return types.ImageManifest{}, err |
| 121 | + } |
| 122 | + |
| 123 | + return types.NewOCIImageManifest(ref, manifestDesc, &mfst), nil |
| 124 | +} |
| 125 | + |
97 | 126 | func pullManifestSchemaV2ImageConfig(ctx context.Context, dgst digest.Digest, repo distribution.Repository) ([]byte, error) { |
98 | 127 | blobs := repo.Blobs(ctx) |
99 | 128 | configJSON, err := blobs.Get(ctx, dgst) |
@@ -153,16 +182,21 @@ func pullManifestList(ctx context.Context, ref reference.Named, repo distributio |
153 | 182 | if err != nil { |
154 | 183 | return nil, err |
155 | 184 | } |
156 | | - v, ok := manifest.(*schema2.DeserializedManifest) |
157 | | - if !ok { |
158 | | - return nil, errors.Errorf("unsupported manifest format: %v", v) |
159 | | - } |
160 | 185 |
|
161 | 186 | manifestRef, err := reference.WithDigest(ref, manifestDescriptor.Digest) |
162 | 187 | if err != nil { |
163 | 188 | return nil, err |
164 | 189 | } |
165 | | - imageManifest, err := pullManifestSchemaV2(ctx, manifestRef, repo, *v) |
| 190 | + |
| 191 | + var imageManifest types.ImageManifest |
| 192 | + switch v := manifest.(type) { |
| 193 | + case *schema2.DeserializedManifest: |
| 194 | + imageManifest, err = pullManifestSchemaV2(ctx, manifestRef, repo, *v) |
| 195 | + case *ocischema.DeserializedManifest: |
| 196 | + imageManifest, err = pullManifestOCISchema(ctx, manifestRef, repo, *v) |
| 197 | + default: |
| 198 | + err = errors.Errorf("unsupported manifest type: %T", manifest) |
| 199 | + } |
166 | 200 | if err != nil { |
167 | 201 | return nil, err |
168 | 202 | } |
|
0 commit comments