mirror of
https://github.com/project-zot/zot.git
synced 2026-06-15 20:07:55 +08:00
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 [...] ```
This commit is contained in:
committed by
Ramkumar Chinchani
parent
97628e69c9
commit
519ea75d9a
@@ -0,0 +1,152 @@
|
||||
// Package common ...
|
||||
package common
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/anuvu/zot/errors"
|
||||
"github.com/anuvu/zot/pkg/log"
|
||||
"github.com/anuvu/zot/pkg/storage"
|
||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||
godigest "github.com/opencontainers/go-digest"
|
||||
ispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
// CveInfo ...
|
||||
type OciLayoutUtils struct {
|
||||
Log log.Logger
|
||||
StoreController storage.StoreController
|
||||
}
|
||||
|
||||
// NewOciLayoutUtils initializes a new OciLayoutUtils object.
|
||||
func NewOciLayoutUtils(storeController storage.StoreController, log log.Logger) *OciLayoutUtils {
|
||||
return &OciLayoutUtils{Log: log, StoreController: storeController}
|
||||
}
|
||||
|
||||
// Below method will return image path including root dir, root dir is determined by splitting.
|
||||
func (olu OciLayoutUtils) GetImageRepoPath(image string) string {
|
||||
var rootDir string
|
||||
|
||||
prefixName := GetRoutePrefix(image)
|
||||
|
||||
subStore := olu.StoreController.SubStore
|
||||
|
||||
if subStore != nil {
|
||||
imgStore, ok := olu.StoreController.SubStore[prefixName]
|
||||
if ok {
|
||||
rootDir = imgStore.RootDir()
|
||||
} else {
|
||||
rootDir = olu.StoreController.DefaultStore.RootDir()
|
||||
}
|
||||
} else {
|
||||
rootDir = olu.StoreController.DefaultStore.RootDir()
|
||||
}
|
||||
|
||||
return path.Join(rootDir, image)
|
||||
}
|
||||
|
||||
func (olu OciLayoutUtils) GetImageManifests(imagePath string) ([]ispec.Descriptor, error) {
|
||||
buf, err := ioutil.ReadFile(path.Join(imagePath, "index.json"))
|
||||
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
olu.Log.Error().Err(err).Msg("index.json doesn't exist")
|
||||
|
||||
return nil, errors.ErrRepoNotFound
|
||||
}
|
||||
|
||||
olu.Log.Error().Err(err).Msg("unable to open index.json")
|
||||
|
||||
return nil, errors.ErrRepoNotFound
|
||||
}
|
||||
|
||||
var index ispec.Index
|
||||
|
||||
if err := json.Unmarshal(buf, &index); err != nil {
|
||||
olu.Log.Error().Err(err).Str("dir", imagePath).Msg("invalid JSON")
|
||||
return nil, errors.ErrRepoNotFound
|
||||
}
|
||||
|
||||
return index.Manifests, nil
|
||||
}
|
||||
|
||||
func (olu OciLayoutUtils) GetImageBlobManifest(imageDir string, digest godigest.Digest) (v1.Manifest, error) {
|
||||
var blobIndex v1.Manifest
|
||||
|
||||
blobBuf, err := ioutil.ReadFile(path.Join(imageDir, "blobs", digest.Algorithm().String(), digest.Encoded()))
|
||||
if err != nil {
|
||||
olu.Log.Error().Err(err).Msg("unable to open image metadata file")
|
||||
|
||||
return blobIndex, err
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(blobBuf, &blobIndex); err != nil {
|
||||
olu.Log.Error().Err(err).Msg("unable to marshal blob index")
|
||||
|
||||
return blobIndex, err
|
||||
}
|
||||
|
||||
return blobIndex, nil
|
||||
}
|
||||
|
||||
func (olu OciLayoutUtils) GetImageInfo(imageDir string, hash v1.Hash) (ispec.Image, error) {
|
||||
var imageInfo ispec.Image
|
||||
|
||||
blobBuf, err := ioutil.ReadFile(path.Join(imageDir, "blobs", hash.Algorithm, hash.Hex))
|
||||
if err != nil {
|
||||
olu.Log.Error().Err(err).Msg("unable to open image layers file")
|
||||
|
||||
return imageInfo, err
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(blobBuf, &imageInfo); err != nil {
|
||||
olu.Log.Error().Err(err).Msg("unable to marshal blob index")
|
||||
|
||||
return imageInfo, err
|
||||
}
|
||||
|
||||
return imageInfo, err
|
||||
}
|
||||
|
||||
func GetRoutePrefix(name string) string {
|
||||
names := strings.SplitN(name, "/", 2)
|
||||
|
||||
if len(names) != 2 { // nolint: gomnd
|
||||
// it means route is of global storage e.g "centos:latest"
|
||||
if len(names) == 1 {
|
||||
return "/"
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Sprintf("/%s", names[0])
|
||||
}
|
||||
|
||||
func DirExists(d string) bool {
|
||||
fi, err := os.Stat(d)
|
||||
if err != nil && os.IsNotExist(err) {
|
||||
return false
|
||||
}
|
||||
|
||||
return fi.IsDir()
|
||||
}
|
||||
|
||||
func GetImageDirAndTag(imageName string) (string, string) {
|
||||
var imageDir string
|
||||
|
||||
var imageTag string
|
||||
|
||||
if strings.Contains(imageName, ":") {
|
||||
splitImageName := strings.Split(imageName, ":")
|
||||
imageDir = splitImageName[0]
|
||||
imageTag = splitImageName[1]
|
||||
} else {
|
||||
imageDir = imageName
|
||||
}
|
||||
|
||||
return imageDir, imageTag
|
||||
}
|
||||
Reference in New Issue
Block a user