-
-
Save 02strich/9917a31f407f0419fa762735c9770dca to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package tools | |
import ( | |
"context" | |
"fmt" | |
"os" | |
"strings" | |
"github.com/Masterminds/semver/v3" | |
"github.com/chkk-io/addon-hub/pkg/addons/addonsiface" | |
"github.com/chkk-io/addon-hub/pkg/addons/sources" | |
"github.com/chkk-io/common-go/pkg/utils" | |
"github.com/google/go-containerregistry/pkg/authn" | |
"github.com/google/go-containerregistry/pkg/name" | |
"github.com/google/go-containerregistry/pkg/v1/remote" | |
log "github.com/sirupsen/logrus" | |
) | |
func CollectHashes(ctx context.Context, logger *log.Entry, addonDefinitions []sources.RegisteredSource) (string, error) { | |
remoteOpts := []remote.Option{ | |
remote.WithAuthFromKeychain(authn.DefaultKeychain), | |
} | |
for _, addon := range addonDefinitions { | |
digests := make(map[string]*addonsiface.ImageDetails) | |
for _, registry := range addon.SourceDefinition.PublicRegistries { | |
repo, err := name.NewRepository(registry.URL) | |
if err != nil { | |
log.WithError(err).Errorf("Failed to create repository reference for %s", registry.URL) | |
continue | |
} | |
puller, err := remote.NewPuller(remoteOpts...) | |
if err != nil { | |
log.WithError(err).Errorf("Failed to pull repository %s", registry.URL) | |
continue | |
} | |
lister, err := puller.Lister(ctx, repo) | |
if err != nil { | |
log.WithError(err).Errorf("Failed to list tags for %s", registry.URL) | |
continue | |
} | |
for lister.HasNext() { | |
tags, err := lister.Next(ctx) | |
if err != nil { | |
log.WithError(err).Error("failed to get next entry") | |
} else { | |
for _, tag := range tags.Tags { | |
name, err := name.ParseReference(fmt.Sprintf("%s:%s", registry.URL, tag)) | |
if err != nil { | |
log.WithError(err).Error("Failed to parse image reference") | |
continue | |
} | |
descr, err := puller.Get(ctx, name) | |
if err != nil { | |
log.WithError(err).Errorf("Failed to retrieve image details for %s", name) | |
continue | |
} | |
// parse version | |
parsedVersion := "" | |
v, err := semver.NewVersion(tag) | |
if err == nil { | |
parsedVersion = fmt.Sprintf("%d.%d.%d", v.Major(), v.Minor(), v.Patch()) | |
} | |
// create new object or add to an existing one | |
var currentDigest *addonsiface.ImageDetails | |
if _, ok := digests[descr.Digest.Hex]; ok { | |
currentDigest = digests[descr.Digest.Hex] | |
currentDigest.Names = append(currentDigest.Names, name.String()) | |
if !utils.ContainsStringArray(currentDigest.Versions, parsedVersion) { | |
currentDigest.Versions = append(currentDigest.Versions, parsedVersion) | |
} | |
} else { | |
currentDigest = &addonsiface.ImageDetails{Names: []string{name.String()}, Versions: []string{parsedVersion}, Digest: descr.Digest.Hex, Size: descr.Size, Layers: make([]addonsiface.ImageLayer, 0), SubManifests: make([]addonsiface.ImageSubManifestReference, 0)} | |
digests[descr.Digest.Hex] = currentDigest | |
} | |
// see whether we got an index file | |
index, err := descr.ImageIndex() | |
if index != nil { | |
indexManifest, err := index.IndexManifest() | |
if err != nil { | |
log.WithError(err).Errorf("Failed to parse index manifest data") | |
continue | |
} | |
for _, manifestReference := range indexManifest.Manifests { | |
submanifestReference := addonsiface.ImageSubManifestReference{ | |
Digest: manifestReference.Digest.Hex, | |
Size: manifestReference.Size, | |
} | |
if manifestReference.Platform != nil { | |
submanifestReference.PlatformArchitecture = manifestReference.Platform.Architecture | |
submanifestReference.PlatformOs = manifestReference.Platform.OS | |
submanifestReference.PlatformOsVersion = manifestReference.Platform.OSVersion | |
} | |
currentDigest.SubManifests = append(currentDigest.SubManifests, submanifestReference) | |
} | |
} else { | |
// just an image | |
image, err := descr.Image() | |
if err != nil { | |
log.WithError(err).Errorf("Failed to parse image data") | |
continue | |
} | |
imageManifest, err := image.Manifest() | |
if err != nil { | |
log.WithError(err).Errorf("Failed to parse image manifest data") | |
continue | |
} | |
for _, layer := range imageManifest.Layers { | |
currentDigest.Layers = append(currentDigest.Layers, addonsiface.ImageLayer{ | |
Digest: layer.Digest.Hex, | |
Size: layer.Size, | |
}) | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
return "", nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment