feat(sync,s3): added s3 logic for ORAS and OCI artifacts (#985)

added sync logic for OCI artifacts

Signed-off-by: Petu Eusebiu <peusebiu@cisco.com>
This commit is contained in:
peusebiu
2022-11-15 08:21:49 +02:00
committed by GitHub
parent fb3e4ec2ef
commit e96c80c344
15 changed files with 1243 additions and 423 deletions
+2 -182
View File
@@ -1341,192 +1341,12 @@ func (is *ImageStoreLocal) DeleteBlob(repo string, digest godigest.Digest) error
func (is *ImageStoreLocal) GetReferrers(repo string, gdigest godigest.Digest, artifactType string,
) (ispec.Index, error) {
var lockLatency time.Time
nilIndex := ispec.Index{}
if err := gdigest.Validate(); err != nil {
return nilIndex, err
}
dir := path.Join(is.rootDir, repo)
if !is.DirExists(dir) {
return nilIndex, zerr.ErrRepoNotFound
}
index, err := storage.GetIndex(is, repo, is.log)
if err != nil {
return nilIndex, err
}
is.RLock(&lockLatency)
defer is.RUnlock(&lockLatency)
found := false
result := []ispec.Descriptor{}
for _, manifest := range index.Manifests {
if manifest.Digest == gdigest {
continue
}
p := path.Join(dir, "blobs", manifest.Digest.Algorithm().String(), manifest.Digest.Encoded())
buf, err := os.ReadFile(p)
if err != nil {
is.log.Error().Err(err).Str("blob", p).Msg("failed to read manifest")
if os.IsNotExist(err) {
return nilIndex, zerr.ErrManifestNotFound
}
return nilIndex, err
}
if manifest.MediaType == ispec.MediaTypeImageManifest {
var mfst ispec.Manifest
if err := json.Unmarshal(buf, &mfst); err != nil {
return nilIndex, err
}
if mfst.Subject == nil || mfst.Subject.Digest != gdigest {
continue
}
// filter by artifact type
if artifactType != "" && mfst.Config.MediaType != artifactType {
continue
}
result = append(result, ispec.Descriptor{
MediaType: manifest.MediaType,
ArtifactType: mfst.Config.MediaType,
Size: manifest.Size,
Digest: manifest.Digest,
Annotations: mfst.Annotations,
})
} else if manifest.MediaType == ispec.MediaTypeArtifactManifest {
var art ispec.Artifact
if err := json.Unmarshal(buf, &art); err != nil {
return nilIndex, err
}
if art.Subject == nil || art.Subject.Digest != gdigest {
continue
}
// filter by artifact type
if artifactType != "" && art.ArtifactType != artifactType {
continue
}
result = append(result, ispec.Descriptor{
MediaType: manifest.MediaType,
ArtifactType: art.ArtifactType,
Size: manifest.Size,
Digest: manifest.Digest,
Annotations: art.Annotations,
})
}
found = true
}
if !found {
return nilIndex, zerr.ErrManifestNotFound
}
index = ispec.Index{
Versioned: imeta.Versioned{SchemaVersion: defaultSchemaVersion},
MediaType: ispec.MediaTypeImageIndex,
Manifests: result,
Annotations: map[string]string{},
}
// response was filtered by artifactType
if artifactType != "" {
index.Annotations[storageConstants.ReferrerFilterAnnotation] = artifactType
}
return index, nil
return storage.GetReferrers(is, repo, gdigest, artifactType, is.log)
}
func (is *ImageStoreLocal) GetOrasReferrers(repo string, gdigest godigest.Digest, artifactType string,
) ([]oras.Descriptor, error) {
var lockLatency time.Time
if err := gdigest.Validate(); err != nil {
return nil, err
}
dir := path.Join(is.rootDir, repo)
if !is.DirExists(dir) {
return nil, zerr.ErrRepoNotFound
}
index, err := storage.GetIndex(is, repo, is.log)
if err != nil {
return nil, err
}
is.RLock(&lockLatency)
defer is.RUnlock(&lockLatency)
found := false
result := []oras.Descriptor{}
for _, manifest := range index.Manifests {
if manifest.MediaType != oras.MediaTypeArtifactManifest {
continue
}
p := path.Join(dir, "blobs", manifest.Digest.Algorithm().String(), manifest.Digest.Encoded())
buf, err := os.ReadFile(p)
if err != nil {
is.log.Error().Err(err).Str("blob", p).Msg("failed to read manifest")
if os.IsNotExist(err) {
return nil, zerr.ErrManifestNotFound
}
return nil, err
}
var artManifest oras.Manifest
if err := json.Unmarshal(buf, &artManifest); err != nil {
is.log.Error().Err(err).Str("dir", dir).Msg("invalid JSON")
return nil, err
}
if artManifest.Subject.Digest != gdigest {
continue
}
// filter by artifact type
if artifactType != "" && artManifest.ArtifactType != artifactType {
continue
}
result = append(result, oras.Descriptor{
MediaType: manifest.MediaType,
ArtifactType: artManifest.ArtifactType,
Digest: manifest.Digest,
Size: manifest.Size,
Annotations: manifest.Annotations,
})
found = true
}
if !found {
return nil, zerr.ErrManifestNotFound
}
return result, nil
return storage.GetOrasReferrers(is, repo, gdigest, artifactType, is.log)
}
func (is *ImageStoreLocal) writeFile(filename string, data []byte) error {