0
Fork 0
mirror of https://github.com/project-zot/zot.git synced 2025-02-10 23:39:39 -05:00
zot/pkg/extensions/search/digest/digest.go
Andrei Aaron 519ea75d9a Implement a way to search for an image by manifest, config or layer digest
```
Usage:
  zot images [config-name] [flags]

Flags:
  -d, --digest string   List images containing a specific manifest, config, or layer digest
[...]
```
2021-06-24 12:15:25 -07:00

88 lines
2.6 KiB
Go

package digestinfo
import (
"strings"
"github.com/anuvu/zot/errors"
"github.com/anuvu/zot/pkg/extensions/search/common"
"github.com/anuvu/zot/pkg/log"
"github.com/anuvu/zot/pkg/storage"
ispec "github.com/opencontainers/image-spec/specs-go/v1"
)
// DigestInfo implements searching by manifes/config/layer digest.
type DigestInfo struct {
Log log.Logger
LayoutUtils *common.OciLayoutUtils
}
// NewDigestInfo initializes a new DigestInfo object.
func NewDigestInfo(storeController storage.StoreController, log log.Logger) *DigestInfo {
layoutUtils := common.NewOciLayoutUtils(storeController, log)
return &DigestInfo{Log: log, LayoutUtils: layoutUtils}
}
// FilterImagesByDigest returns a list of image tags in a repository matching a specific divest.
func (digestinfo DigestInfo) GetImageTagsByDigest(repo string, digest string) ([]*string, error) {
uniqueTags := []*string{}
imagePath := digestinfo.LayoutUtils.GetImageRepoPath(repo)
if !common.DirExists(imagePath) {
return nil, errors.ErrRepoNotFound
}
manifests, err := digestinfo.LayoutUtils.GetImageManifests(imagePath)
if err != nil {
digestinfo.Log.Error().Err(err).Msg("unable to read image manifests")
return uniqueTags, err
}
for _, manifest := range manifests {
imageDigest := manifest.Digest
v, ok := manifest.Annotations[ispec.AnnotationRefName]
if ok {
imageBlobManifest, err := digestinfo.LayoutUtils.GetImageBlobManifest(imagePath, imageDigest)
if err != nil {
digestinfo.Log.Error().Err(err).Msg("unable to read image blob manifest")
return uniqueTags, err
}
tags := []*string{}
// Check the image manigest in index.json matches the search digest
// This is a blob with mediaType application/vnd.oci.image.manifest.v1+json
if strings.Contains(manifest.Digest.String(), digest) {
tags = append(tags, &v)
}
// Check the image config matches the search digest
// This is a blob with mediaType application/vnd.oci.image.config.v1+json
if strings.Contains(imageBlobManifest.Config.Digest.Algorithm+":"+imageBlobManifest.Config.Digest.Hex, digest) {
tags = append(tags, &v)
}
// Check to see if the individual layers in the oci image manifest match the digest
// These are blobs with mediaType application/vnd.oci.image.layer.v1.tar+gzip
for _, layer := range imageBlobManifest.Layers {
if strings.Contains(layer.Digest.Algorithm+":"+layer.Digest.Hex, digest) {
tags = append(tags, &v)
}
}
keys := make(map[string]bool)
for _, entry := range tags {
if _, value := keys[*entry]; !value {
uniqueTags = append(uniqueTags, entry)
keys[*entry] = true
}
}
}
}
return uniqueTags, nil
}