File: list.go

package info (click to toggle)
golang-github-containers-image 5.28.0-4
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 5,104 kB
  • sloc: sh: 194; makefile: 73
file content (131 lines) | stat: -rw-r--r-- 5,312 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package manifest

import (
	"fmt"

	compression "github.com/containers/image/v5/pkg/compression/types"
	"github.com/containers/image/v5/types"
	digest "github.com/opencontainers/go-digest"
	imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1"
)

// ListPublic is a subset of List which is a part of the public API;
// so no methods can be added, removed or changed.
//
// Internal users should usually use List instead.
type ListPublic interface {
	// MIMEType returns the MIME type of this particular manifest list.
	MIMEType() string

	// Instances returns a list of the manifests that this list knows of, other than its own.
	Instances() []digest.Digest

	// Update information about the list's instances.  The length of the passed-in slice must
	// match the length of the list of instances which the list already contains, and every field
	// must be specified.
	UpdateInstances([]ListUpdate) error

	// Instance returns the size and MIME type of a particular instance in the list.
	Instance(digest.Digest) (ListUpdate, error)

	// ChooseInstance selects which manifest is most appropriate for the platform described by the
	// SystemContext, or for the current platform if the SystemContext doesn't specify any details.
	ChooseInstance(ctx *types.SystemContext) (digest.Digest, error)

	// Serialize returns the list in a blob format.
	// NOTE: Serialize() does not in general reproduce the original blob if this object was loaded
	// from, even if no modifications were made!
	Serialize() ([]byte, error)

	// ConvertToMIMEType returns the list rebuilt to the specified MIME type, or an error.
	ConvertToMIMEType(mimeType string) (ListPublic, error)

	// Clone returns a deep copy of this list and its contents.
	Clone() ListPublic
}

// List is an interface for parsing, modifying lists of image manifests.
// Callers can either use this abstract interface without understanding the details of the formats,
// or instantiate a specific implementation (e.g. manifest.OCI1Index) and access the public members
// directly.
type List interface {
	ListPublic
	// CloneInternal returns a deep copy of this list and its contents.
	CloneInternal() List
	// ChooseInstanceInstanceByCompression selects which manifest is most appropriate for the platform and compression described by the
	// SystemContext ( or for the current platform if the SystemContext doesn't specify any detail ) and preferGzip for compression which
	// when configured to OptionalBoolTrue and chooses best available compression when it is OptionalBoolFalse or left OptionalBoolUndefined.
	ChooseInstanceByCompression(ctx *types.SystemContext, preferGzip types.OptionalBool) (digest.Digest, error)
	// Edit information about the list's instances. Contains Slice of ListEdit where each element
	// is responsible for either Modifying or Adding a new instance to the Manifest. Operation is
	// selected on the basis of configured ListOperation field.
	EditInstances([]ListEdit) error
}

// ListUpdate includes the fields which a List's UpdateInstances() method will modify.
// This is publicly visible as c/image/manifest.ListUpdate.
type ListUpdate struct {
	Digest    digest.Digest
	Size      int64
	MediaType string
	// ReadOnly fields: may be set by Instance(), ignored by UpdateInstance()
	ReadOnly struct {
		Platform                  *imgspecv1.Platform
		Annotations               map[string]string
		CompressionAlgorithmNames []string
	}
}

type ListOp int

const (
	listOpInvalid ListOp = iota
	ListOpAdd
	ListOpUpdate
)

// ListEdit includes the fields which a List's EditInstances() method will modify.
type ListEdit struct {
	ListOperation ListOp

	// if Op == ListEditUpdate (basically the previous UpdateInstances). All fields must be set.
	UpdateOldDigest             digest.Digest
	UpdateDigest                digest.Digest
	UpdateSize                  int64
	UpdateMediaType             string
	UpdateAffectAnnotations     bool
	UpdateAnnotations           map[string]string
	UpdateCompressionAlgorithms []compression.Algorithm

	// If Op = ListEditAdd. All fields must be set.
	AddDigest                digest.Digest
	AddSize                  int64
	AddMediaType             string
	AddPlatform              *imgspecv1.Platform
	AddAnnotations           map[string]string
	AddCompressionAlgorithms []compression.Algorithm
}

// ListPublicFromBlob parses a list of manifests.
// This is publicly visible as c/image/manifest.ListFromBlob.
func ListPublicFromBlob(manifest []byte, manifestMIMEType string) (ListPublic, error) {
	list, err := ListFromBlob(manifest, manifestMIMEType)
	if err != nil {
		return nil, err
	}
	return list, nil
}

// ListFromBlob parses a list of manifests.
func ListFromBlob(manifest []byte, manifestMIMEType string) (List, error) {
	normalized := NormalizedMIMEType(manifestMIMEType)
	switch normalized {
	case DockerV2ListMediaType:
		return Schema2ListFromManifest(manifest)
	case imgspecv1.MediaTypeImageIndex:
		return OCI1IndexFromManifest(manifest)
	case DockerV2Schema1MediaType, DockerV2Schema1SignedMediaType, imgspecv1.MediaTypeImageManifest, DockerV2Schema2MediaType:
		return nil, fmt.Errorf("Treating single images as manifest lists is not implemented")
	}
	return nil, fmt.Errorf("Unimplemented manifest list MIME type %s (normalized as %s)", manifestMIMEType, normalized)
}