MCPcopy
hub / github.com/docker/compose / generateManifest

Function generateManifest

internal/oci/push.go:162–223  ·  view source on GitHub ↗
(layers []v1.Descriptor, ociCompat api.OCIVersion)

Source from the content-addressed store, hash-verified

160}
161
162func generateManifest(layers []v1.Descriptor, ociCompat api.OCIVersion) (v1.Descriptor, []v1.Descriptor, error) {
163 var toPush []v1.Descriptor
164 var config v1.Descriptor
165 var artifactType string
166 switch ociCompat {
167 case api.OCIVersion1_0:
168 // "Content other than OCI container images MAY be packaged using the image manifest.
169 // When this is done, the config.mediaType value MUST be set to a value specific to
170 // the artifact type or the empty value."
171 // Source: https://github.com/opencontainers/image-spec/blob/main/manifest.md#guidelines-for-artifact-usage
172 //
173 // The `ComposeEmptyConfigMediaType` is used specifically for this purpose:
174 // there is no config, and an empty descriptor is used for OCI 1.1 in
175 // conjunction with the `ArtifactType`, but for OCI 1.0 compatibility,
176 // tooling falls back to the config media type, so this is used to
177 // indicate that it's not a container image but custom content.
178 configData := []byte("{}")
179 config = v1.Descriptor{
180 MediaType: ComposeEmptyConfigMediaType,
181 Digest: digest.FromBytes(configData),
182 Size: int64(len(configData)),
183 Data: configData,
184 }
185 // N.B. OCI 1.0 does NOT support specifying the artifact type, so it's
186 // left as an empty string to omit it from the marshaled JSON
187 artifactType = ""
188 toPush = append(toPush, config)
189 case api.OCIVersion1_1:
190 config = v1.DescriptorEmptyJSON
191 artifactType = ComposeProjectArtifactType
192 toPush = append(toPush, config)
193 default:
194 return v1.Descriptor{}, nil, fmt.Errorf("unsupported OCI version: %s", ociCompat)
195 }
196
197 manifest, err := json.Marshal(v1.Manifest{
198 Versioned: specs.Versioned{SchemaVersion: 2},
199 MediaType: v1.MediaTypeImageManifest,
200 ArtifactType: artifactType,
201 Config: config,
202 Layers: layers,
203 Annotations: map[string]string{
204 "org.opencontainers.image.created": time.Now().Format(time.RFC3339),
205 },
206 })
207 if err != nil {
208 return v1.Descriptor{}, nil, err
209 }
210
211 manifestDescriptor := v1.Descriptor{
212 MediaType: v1.MediaTypeImageManifest,
213 Digest: digest.FromString(string(manifest)),
214 Size: int64(len(manifest)),
215 Annotations: map[string]string{
216 "com.docker.compose.version": api.ComposeVersion,
217 },
218 ArtifactType: artifactType,
219 Data: manifest,

Callers 1

createAndPushManifestFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected