mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-07-20 17:49:10 +00:00
fix merging indexes in pkg manifest command
Signed-off-by: Avi Deitcher <avi@deitcher.net>
This commit is contained in:
parent
4c14831d6b
commit
4e75efc8aa
@ -94,6 +94,11 @@ func PushManifest(img string, options ...remote.Option) (hash string, length int
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return hash, length, fmt.Errorf("getting index digest: %w", err)
|
return hash, length, fmt.Errorf("getting index digest: %w", err)
|
||||||
}
|
}
|
||||||
|
// if it is unchanged, do nothing
|
||||||
|
if desc != nil && desc.Digest == dig {
|
||||||
|
log.Debugf("not pushing manifest list for %s, unchanged", img)
|
||||||
|
return dig.String(), size, nil
|
||||||
|
}
|
||||||
log.Debugf("pushing manifest list for %s -> %#v", img, index)
|
log.Debugf("pushing manifest list for %s -> %#v", img, index)
|
||||||
err = remote.WriteIndex(baseRef, index, options...)
|
err = remote.WriteIndex(baseRef, index, options...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||||
|
"github.com/google/go-containerregistry/pkg/v1/mutate"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -14,12 +15,15 @@ const (
|
|||||||
AnnotationSPDXDoc = "https://spdx.dev/Document"
|
AnnotationSPDXDoc = "https://spdx.dev/Document"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AppendIndex appends the elements of secondary ImageIndex into primary ImageIndex,
|
// AppendIndex creates a new ImageIndex composed of the merge of the elements of secondary ImageIndex
|
||||||
// returning the updated primary ImageIndex.
|
// and primary ImageIndex.
|
||||||
// In the case of conflicts, the primary ImageIndex wins.
|
// In the case of conflicts, the primary ImageIndex wins.
|
||||||
// For example, if both have a manifest for a specific platform, then use the one from primary.
|
// For example, if both have a manifest for a specific platform, then use the one from primary.
|
||||||
// The append is aware of the buildkit-style attestations, and will keep any attestations that point to a valid
|
// The append is aware of the buildkit-style attestations, and will keep any attestations that point to a valid
|
||||||
// manifest in the list, discarding any that do not.
|
// manifest in the list, discarding any that do not.
|
||||||
|
// If either of the two ImageIndexes is nil, the other is returned.
|
||||||
|
// If the secondary ImageIndex is a precise superset of primary,
|
||||||
|
// then the returned new ImageIndex is an identical copy of the secondary ImageIndex.
|
||||||
func AppendIndex(primary, secondary v1.ImageIndex) (v1.ImageIndex, error) {
|
func AppendIndex(primary, secondary v1.ImageIndex) (v1.ImageIndex, error) {
|
||||||
primaryManifest, err := primary.IndexManifest()
|
primaryManifest, err := primary.IndexManifest()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -35,10 +39,14 @@ func AppendIndex(primary, secondary v1.ImageIndex) (v1.ImageIndex, error) {
|
|||||||
// 2. attestation - after all platforms, does it point to something in the updated index?
|
// 2. attestation - after all platforms, does it point to something in the updated index?
|
||||||
// If not, remove
|
// If not, remove
|
||||||
|
|
||||||
|
if indexSuperset(primaryManifest, secondaryManifest) {
|
||||||
|
return secondary, nil
|
||||||
|
}
|
||||||
// make a map of all the digests already in the index, so we can know what is there
|
// make a map of all the digests already in the index, so we can know what is there
|
||||||
var (
|
var (
|
||||||
manifestMap = map[v1.Hash]bool{}
|
manifestMap = map[v1.Hash]bool{}
|
||||||
platformMap = map[string]bool{}
|
platformMap = map[string]bool{}
|
||||||
|
adds []mutate.IndexAddendum
|
||||||
)
|
)
|
||||||
for _, m := range primaryManifest.Manifests {
|
for _, m := range primaryManifest.Manifests {
|
||||||
if m.Platform == nil || m.Platform.Architecture == "" {
|
if m.Platform == nil || m.Platform.Architecture == "" {
|
||||||
@ -63,7 +71,15 @@ func AppendIndex(primary, secondary v1.ImageIndex) (v1.ImageIndex, error) {
|
|||||||
// we already have this one, so we can skip it
|
// we already have this one, so we can skip it
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
primaryManifest.Manifests = append(primaryManifest.Manifests, m)
|
img, err := secondary.Image(m.Digest)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("could not get image %s: %v", m.Digest, err)
|
||||||
|
}
|
||||||
|
adds = append(adds, mutate.IndexAddendum{
|
||||||
|
Add: img,
|
||||||
|
Descriptor: m,
|
||||||
|
})
|
||||||
|
// want to add manifest "m"
|
||||||
manifestMap[m.Digest] = true
|
manifestMap[m.Digest] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,7 +89,7 @@ func AppendIndex(primary, secondary v1.ImageIndex) (v1.ImageIndex, error) {
|
|||||||
// we either add them to the local index, or remove them if they are no longer valid
|
// we either add them to the local index, or remove them if they are no longer valid
|
||||||
// we assume the ones in the local index are valid because they would have been generated now
|
// we assume the ones in the local index are valid because they would have been generated now
|
||||||
for _, m := range secondaryManifest.Manifests {
|
for _, m := range secondaryManifest.Manifests {
|
||||||
if m.Platform == nil || m.Platform.Architecture != "unknown" || m.Platform.OS == "unknown" || m.Annotations == nil || m.Annotations[AnnotationDockerReferenceDigest] == "" {
|
if m.Platform == nil || m.Platform.Architecture != "unknown" || m.Platform.OS != "unknown" || m.Annotations == nil || m.Annotations[AnnotationDockerReferenceDigest] == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// if we already have this one, we are good
|
// if we already have this one, we are good
|
||||||
@ -90,8 +106,34 @@ func AppendIndex(primary, secondary v1.ImageIndex) (v1.ImageIndex, error) {
|
|||||||
if _, ok := manifestMap[dig]; !ok {
|
if _, ok := manifestMap[dig]; !ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
primaryManifest.Manifests = append(primaryManifest.Manifests, m)
|
img, err := secondary.Image(m.Digest)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("could not get image %s: %v", m.Digest, err)
|
||||||
|
}
|
||||||
|
adds = append(adds, mutate.IndexAddendum{
|
||||||
|
Add: img,
|
||||||
|
Descriptor: m,
|
||||||
|
})
|
||||||
|
// want to add manifest "m"
|
||||||
manifestMap[m.Digest] = true
|
manifestMap[m.Digest] = true
|
||||||
}
|
}
|
||||||
return primary, nil
|
ret := mutate.AppendManifests(primary, adds...)
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func indexSuperset(inner, outer *v1.IndexManifest) bool {
|
||||||
|
var manifestMap = map[v1.Hash]bool{}
|
||||||
|
if len(inner.Manifests) > len(outer.Manifests) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for _, m := range outer.Manifests {
|
||||||
|
manifestMap[m.Digest] = true
|
||||||
|
}
|
||||||
|
for _, m := range inner.Manifests {
|
||||||
|
if _, ok := manifestMap[m.Digest]; !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user