1
15 package content
16
17 import (
18 "encoding/json"
19 "sort"
20
21 "github.com/opencontainers/go-digest"
22 specs "github.com/opencontainers/image-spec/specs-go"
23 ocispec "github.com/opencontainers/image-spec/specs-go/v1"
24 artifact "oras.land/oras-go/pkg/artifact"
25 )
26
27
28
29 func GenerateManifest(config *ocispec.Descriptor, annotations map[string]string, descs ...ocispec.Descriptor) ([]byte, ocispec.Descriptor, error) {
30
31 if config == nil {
32 _, configGen, err := GenerateConfig(nil)
33 if err != nil {
34 return nil, ocispec.Descriptor{}, err
35 }
36 config = &configGen
37 }
38 return pack(*config, annotations, descs)
39 }
40
41
42 func GenerateConfig(annotations map[string]string) ([]byte, ocispec.Descriptor, error) {
43 configBytes := []byte("{}")
44 dig := digest.FromBytes(configBytes)
45 config := ocispec.Descriptor{
46 MediaType: artifact.UnknownConfigMediaType,
47 Digest: dig,
48 Size: int64(len(configBytes)),
49 Annotations: annotations,
50 }
51 return configBytes, config, nil
52 }
53
54
55 func GenerateManifestAndConfig(manifestAnnotations map[string]string, configAnnotations map[string]string, descs ...ocispec.Descriptor) (manifest []byte, manifestDesc ocispec.Descriptor, config []byte, configDesc ocispec.Descriptor, err error) {
56 config, configDesc, err = GenerateConfig(configAnnotations)
57 if err != nil {
58 return nil, ocispec.Descriptor{}, nil, ocispec.Descriptor{}, err
59 }
60 manifest, manifestDesc, err = GenerateManifest(&configDesc, manifestAnnotations, descs...)
61 if err != nil {
62 return nil, ocispec.Descriptor{}, nil, ocispec.Descriptor{}, err
63 }
64 return
65 }
66
67
68 func pack(config ocispec.Descriptor, annotations map[string]string, descriptors []ocispec.Descriptor) ([]byte, ocispec.Descriptor, error) {
69 if descriptors == nil {
70 descriptors = []ocispec.Descriptor{}
71 }
72
73 sort.Slice(descriptors, func(i, j int) bool {
74 return descriptors[i].Digest < descriptors[j].Digest
75 })
76 manifest := ocispec.Manifest{
77 Versioned: specs.Versioned{
78 SchemaVersion: 2,
79 },
80 Config: config,
81 Layers: descriptors,
82 Annotations: annotations,
83 }
84 manifestBytes, err := json.Marshal(manifest)
85 if err != nil {
86 return nil, ocispec.Descriptor{}, err
87 }
88 manifestDescriptor := ocispec.Descriptor{
89 MediaType: ocispec.MediaTypeImageManifest,
90 Digest: digest.FromBytes(manifestBytes),
91 Size: int64(len(manifestBytes)),
92 }
93
94 return manifestBytes, manifestDescriptor, nil
95 }
96
View as plain text