mirror of
https://github.com/project-zot/zot.git
synced 2026-06-16 12:28:01 +08:00
fix(lastUpdated): fix image lastUpdated timestamp logic (#863)
The lastUpdated field was picked from the first entry in image history Now it is the created time of the image, or the last entry in image history, if created time is unavailable Signed-off-by: Andrei Aaron <andaaron@cisco.com>
This commit is contained in:
@@ -75,6 +75,27 @@ func GetImageDirAndTag(imageName string) (string, string) {
|
||||
return imageDir, imageTag
|
||||
}
|
||||
|
||||
// GetImageLastUpdated This method will return last updated timestamp.
|
||||
// The Created timestamp is used, but if it is missing, look at the
|
||||
// history field and, if provided, return the timestamp of last entry in history.
|
||||
func GetImageLastUpdated(imageInfo ispec.Image) time.Time {
|
||||
timeStamp := imageInfo.Created
|
||||
|
||||
if timeStamp != nil && !timeStamp.IsZero() {
|
||||
return *timeStamp
|
||||
}
|
||||
|
||||
if len(imageInfo.History) > 0 {
|
||||
timeStamp = imageInfo.History[len(imageInfo.History)-1].Created
|
||||
}
|
||||
|
||||
if timeStamp == nil {
|
||||
timeStamp = &time.Time{}
|
||||
}
|
||||
|
||||
return *timeStamp
|
||||
}
|
||||
|
||||
func GetFixedTags(allTags, vulnerableTags []TagInfo) []TagInfo {
|
||||
sort.Slice(allTags, func(i, j int) bool {
|
||||
return allTags[i].Timestamp.Before(allTags[j].Timestamp)
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"fmt"
|
||||
"path"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||
notreg "github.com/notaryproject/notation-go/registry"
|
||||
@@ -24,7 +23,6 @@ type OciLayoutUtils interface { //nolint: interfacebloat
|
||||
GetImageBlobManifest(imageDir string, digest godigest.Digest) (v1.Manifest, error)
|
||||
GetImageInfo(imageDir string, hash v1.Hash) (ispec.Image, error)
|
||||
GetImageTagsWithTimestamp(repo string) ([]TagInfo, error)
|
||||
GetImageLastUpdated(imageInfo ispec.Image) time.Time
|
||||
GetImagePlatform(imageInfo ispec.Image) (string, string)
|
||||
GetImageManifestSize(repo string, manifestDigest godigest.Digest) int64
|
||||
GetRepoLastUpdated(repo string) (TagInfo, error)
|
||||
@@ -189,13 +187,7 @@ func (olu BaseOciLayoutUtils) GetImageTagsWithTimestamp(repo string) ([]TagInfo,
|
||||
return tagsInfo, err
|
||||
}
|
||||
|
||||
var timeStamp time.Time
|
||||
|
||||
if len(imageInfo.History) != 0 {
|
||||
timeStamp = *imageInfo.History[0].Created
|
||||
} else {
|
||||
timeStamp = time.Time{}
|
||||
}
|
||||
timeStamp := GetImageLastUpdated(imageInfo)
|
||||
|
||||
tagsInfo = append(tagsInfo, TagInfo{Name: val, Timestamp: timeStamp, Digest: digest.String()})
|
||||
}
|
||||
@@ -250,18 +242,6 @@ func (olu BaseOciLayoutUtils) CheckManifestSignature(name string, digest godiges
|
||||
return true
|
||||
}
|
||||
|
||||
func (olu BaseOciLayoutUtils) GetImageLastUpdated(imageInfo ispec.Image) time.Time {
|
||||
var timeStamp time.Time
|
||||
|
||||
if len(imageInfo.History) != 0 {
|
||||
timeStamp = *imageInfo.History[0].Created
|
||||
} else {
|
||||
timeStamp = time.Time{}
|
||||
}
|
||||
|
||||
return timeStamp
|
||||
}
|
||||
|
||||
func (olu BaseOciLayoutUtils) GetImagePlatform(imageConfig ispec.Image) (
|
||||
string, string,
|
||||
) {
|
||||
@@ -413,7 +393,7 @@ func (olu BaseOciLayoutUtils) GetExpandedRepoInfo(name string) (RepoInfo, error)
|
||||
size := strconv.Itoa(int(imageSize))
|
||||
manifestDigest := man.Digest.Hex()
|
||||
configDigest := manifest.Config.Digest.Hex
|
||||
lastUpdated := olu.GetImageLastUpdated(imageConfigInfo)
|
||||
lastUpdated := GetImageLastUpdated(imageConfigInfo)
|
||||
score := 0
|
||||
|
||||
imageSummary := ImageSummary{
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/99designs/gqlgen/graphql"
|
||||
glob "github.com/bmatcuk/doublestar/v4" //nolint:gci
|
||||
@@ -211,7 +210,7 @@ func repoListWithNewestImage(
|
||||
manifestDigest := manifest.Digest.Hex()
|
||||
configDigest := imageBlobManifest.Config.Digest.Hex
|
||||
isSigned := olu.CheckManifestSignature(repo, manifest.Digest)
|
||||
lastUpdated := olu.GetImageLastUpdated(imageConfigInfo)
|
||||
lastUpdated := common.GetImageLastUpdated(imageConfigInfo)
|
||||
score := 0
|
||||
|
||||
imageSummary := gql_generated.ImageSummary{
|
||||
@@ -371,7 +370,7 @@ func globalSearch(repoList []string, name, tag string, olu common.OciLayoutUtils
|
||||
// update matching score
|
||||
score := calculateImageMatchingScore(repo, index, matchesTag)
|
||||
|
||||
lastUpdated := olu.GetImageLastUpdated(imageConfigInfo)
|
||||
lastUpdated := common.GetImageLastUpdated(imageConfigInfo)
|
||||
os, arch := olu.GetImagePlatform(imageConfigInfo)
|
||||
osArch := &gql_generated.OsArch{
|
||||
Os: &os,
|
||||
@@ -569,13 +568,7 @@ func BuildImageInfo(repo string, tag string, manifestDigest godigest.Digest,
|
||||
allHistory := []*gql_generated.LayerHistory{}
|
||||
formattedManifestDigest := manifestDigest.Hex()
|
||||
annotations := common.GetAnnotations(manifest.Annotations, imageConfig.Config.Labels)
|
||||
|
||||
lastUpdated := imageConfig.Created
|
||||
|
||||
if (lastUpdated == nil || *lastUpdated == (time.Time{})) &&
|
||||
len(imageConfig.History) > 0 {
|
||||
lastUpdated = imageConfig.History[len(imageConfig.History)-1].Created
|
||||
}
|
||||
lastUpdated := common.GetImageLastUpdated(imageConfig)
|
||||
|
||||
history := imageConfig.History
|
||||
if len(history) == 0 {
|
||||
@@ -617,7 +610,7 @@ func BuildImageInfo(repo string, tag string, manifestDigest godigest.Digest,
|
||||
Licenses: &annotations.Licenses,
|
||||
Labels: &annotations.Labels,
|
||||
Source: &annotations.Source,
|
||||
LastUpdated: lastUpdated,
|
||||
LastUpdated: &lastUpdated,
|
||||
IsSigned: &isSigned,
|
||||
Platform: &gql_generated.OsArch{
|
||||
Os: &imageConfig.OS,
|
||||
@@ -666,7 +659,7 @@ func BuildImageInfo(repo string, tag string, manifestDigest godigest.Digest,
|
||||
Licenses: &annotations.Licenses,
|
||||
Labels: &annotations.Labels,
|
||||
Source: &annotations.Source,
|
||||
LastUpdated: lastUpdated,
|
||||
LastUpdated: &lastUpdated,
|
||||
IsSigned: &isSigned,
|
||||
Platform: &gql_generated.OsArch{
|
||||
Os: &imageConfig.OS,
|
||||
@@ -711,7 +704,7 @@ func BuildImageInfo(repo string, tag string, manifestDigest godigest.Digest,
|
||||
Licenses: &annotations.Licenses,
|
||||
Labels: &annotations.Labels,
|
||||
Source: &annotations.Source,
|
||||
LastUpdated: lastUpdated,
|
||||
LastUpdated: &lastUpdated,
|
||||
IsSigned: &isSigned,
|
||||
Platform: &gql_generated.OsArch{
|
||||
Os: &imageConfig.OS,
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package mocks
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||
godigest "github.com/opencontainers/go-digest"
|
||||
ispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
@@ -15,7 +13,6 @@ type OciLayoutUtilsMock struct {
|
||||
GetImageBlobManifestFn func(imageDir string, digest godigest.Digest) (v1.Manifest, error)
|
||||
GetImageInfoFn func(imageDir string, hash v1.Hash) (ispec.Image, error)
|
||||
GetImageTagsWithTimestampFn func(repo string) ([]common.TagInfo, error)
|
||||
GetImageLastUpdatedFn func(imageInfo ispec.Image) time.Time
|
||||
GetImagePlatformFn func(imageInfo ispec.Image) (string, string)
|
||||
GetImageVendorFn func(imageInfo ispec.Image) string
|
||||
GetImageManifestSizeFn func(repo string, manifestDigest godigest.Digest) int64
|
||||
@@ -75,14 +72,6 @@ func (olum OciLayoutUtilsMock) GetImageTagsWithTimestamp(repo string) ([]common.
|
||||
return []common.TagInfo{}, nil
|
||||
}
|
||||
|
||||
func (olum OciLayoutUtilsMock) GetImageLastUpdated(imageInfo ispec.Image) time.Time {
|
||||
if olum.GetImageLastUpdatedFn != nil {
|
||||
return olum.GetImageLastUpdatedFn(imageInfo)
|
||||
}
|
||||
|
||||
return time.Time{}
|
||||
}
|
||||
|
||||
func (olum OciLayoutUtilsMock) GetImagePlatform(imageInfo ispec.Image) (string, string) {
|
||||
if olum.GetImagePlatformFn != nil {
|
||||
return olum.GetImagePlatformFn(imageInfo)
|
||||
|
||||
Reference in New Issue
Block a user