mirror of
https://github.com/Quiq/docker-registry-ui.git
synced 2026-07-17 02:01:01 +00:00
Fetch image/tag creation date from annotations to support cosign
This commit is contained in:
@@ -204,6 +204,12 @@ func (c *Client) GetImageInfo(imageRef string) (ImageInfo, error) {
|
||||
return ImageInfo{}, err
|
||||
}
|
||||
|
||||
// Performance notes:
|
||||
// puller.Get() → 1 API call (fetches manifest)
|
||||
// descr.Image() → 0 API calls (type conversion)
|
||||
// img.ConfigFile() → 1 API call (fetches config blob)
|
||||
// img.Manifest() → 0 API calls (already fetched on puller.Get())
|
||||
//
|
||||
if ii.IsImage {
|
||||
img, err := descr.Image()
|
||||
if err != nil {
|
||||
@@ -216,6 +222,9 @@ func (c *Client) GetImageInfo(imageRef string) (ImageInfo, error) {
|
||||
return ImageInfo{}, err
|
||||
}
|
||||
ii.Created = cfg.Created.Time
|
||||
if cfg.Created.Time.IsZero() {
|
||||
ii.Created = extractCreatedFromAnnotations(img)
|
||||
}
|
||||
ii.Platforms = getPlatform(cfg.Platform())
|
||||
ii.ConfigFile = structToMap(cfg)
|
||||
// ImageID is what is shown in the terminal when doing "docker images".
|
||||
@@ -289,9 +298,28 @@ func (c *Client) GetImageCreated(imageRef string) time.Time {
|
||||
c.logger.Errorf("Cannot fetch ConfigFile for image reference %s: %s", imageRef, err)
|
||||
return *zeroTime
|
||||
}
|
||||
if cfg.Created.Time.IsZero() {
|
||||
return extractCreatedFromAnnotations(img)
|
||||
}
|
||||
|
||||
return cfg.Created.Time
|
||||
}
|
||||
|
||||
func extractCreatedFromAnnotations(img v1.Image) time.Time {
|
||||
// cosign pushes images with zero time in the image config file.
|
||||
// However, when cosign is used with --record-creation-timestamp it sets creation time
|
||||
// into Manifest > annotations > org.opencontainers.image.created which can be used.
|
||||
zeroTime := new(time.Time)
|
||||
if mf, err := img.Manifest(); err == nil && mf.Annotations != nil {
|
||||
if createdStr, ok := mf.Annotations["org.opencontainers.image.created"]; ok {
|
||||
if createdTime, err := time.Parse(time.RFC3339, createdStr); err == nil {
|
||||
return createdTime
|
||||
}
|
||||
}
|
||||
}
|
||||
return *zeroTime
|
||||
}
|
||||
|
||||
// SubRepoTagCounts return map with tag counts according to the provided list of repos/sub-repos etc.
|
||||
func (c *Client) SubRepoTagCounts(repoPath string, repos []string) map[string]int {
|
||||
counts := map[string]int{}
|
||||
|
||||
@@ -105,7 +105,7 @@ func PurgeOldTags(client *Client, purgeDryRun bool, purgeIncludeRepos, purgeExcl
|
||||
created := client.GetImageCreated(imageRef)
|
||||
if created.IsZero() {
|
||||
// Image manifest with zero creation time, e.g. cosign w/o --record-creation-timestamp
|
||||
logger.Debugf("[%s] tag with zero creation time: %s", repo, tag)
|
||||
logger.Warnf("[%s] tag with zero creation time: %s", repo, tag)
|
||||
continue
|
||||
}
|
||||
repos[repo] = append(repos[repo], TagData{name: tag, created: created})
|
||||
|
||||
Reference in New Issue
Block a user