Skip to content

Commit c884e00

Browse files
committed
refactor: refine image tag created time fetch
1 parent daedee1 commit c884e00

File tree

2 files changed

+37
-44
lines changed

2 files changed

+37
-44
lines changed

handlers.go

Lines changed: 2 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,8 @@ package main
33
import (
44
"bytes"
55
"context"
6-
"encoding/json"
7-
"errors"
86
"fmt"
9-
"github.com/distribution/distribution/v3/manifest/ocischema"
107
"github.com/labstack/echo/v4"
11-
ociv1 "github.com/opencontainers/image-spec/specs-go/v1"
128
"html/template"
139
"io/ioutil"
1410
"net/http"
@@ -198,47 +194,9 @@ func (rc *registryController) generateTagsTemplate(ctx context.Context, repo str
198194
// get the image creat time, for v2 or oci image,
199195
// maybe someday we can get it from `org.opencontainers.image.created` annotation
200196
// ref https://github.com/opencontainers/image-spec/blob/main/annotations.md#pre-defined-annotation-keys
201-
m1, err := rc.reg.ManifestV1(ctx, repo, tag)
202-
var createdDate *time.Time
203-
var imageType string
197+
createdDate, imageType, err := rc.reg.TagCreatedDate(ctx, repo, tag)
204198
if err != nil {
205-
// skip htp error
206-
logrus.Warnf("getting v1 manifest for %s:%s failed: %v, try v2 and oci", repo, tag, err)
207-
if errors.Is(err, registry.ErrResourceNotFound) {
208-
manifest, descriptor, err := rc.reg.Manifest(ctx, repo, tag)
209-
if err != nil {
210-
logrus.Errorf("getting v2 or oci manifest for %s:%s failed: %v", repo, tag, err)
211-
} else if descriptor.MediaType == ociv1.MediaTypeImageManifest {
212-
if ocimanifest, ok := manifest.(*ocischema.DeserializedManifest); ok && ocimanifest.Annotations != nil {
213-
if created, ok := ocimanifest.Annotations["org.opencontainers.image.created"]; ok {
214-
if t, err := time.Parse(time.RFC3339, created); err == nil {
215-
createdDate = &t
216-
}
217-
}
218-
}
219-
imageType = "OCI"
220-
} else {
221-
logrus.Warnf("can not get created time, unsupported manifest type %s for %s:%s",
222-
descriptor.MediaType, repo, tag)
223-
imageType = "Docker V2"
224-
}
225-
if createdDate == nil {
226-
if created, err := rc.reg.CreatedDate(ctx, repo, manifest.References()[0].Digest); err == nil {
227-
createdDate = created
228-
}
229-
}
230-
}
231-
} else {
232-
for _, h := range m1.History {
233-
var comp v1Compatibility
234-
235-
if err := json.Unmarshal([]byte(h.V1Compatibility), &comp); err != nil {
236-
return nil, fmt.Errorf("unmarshal v1 manifest for %s:%s failed: %v", repo, tag, err)
237-
}
238-
createdDate = &comp.Created
239-
imageType = "Docker V1"
240-
break
241-
}
199+
logrus.Warnf("getting created date for %s:%s failed: %v", repo, tag, err)
242200
}
243201

244202
repoURI := fmt.Sprintf("%s/%s", rc.reg.Domain, repo)

registry/tags.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ package registry
22

33
import (
44
"context"
5+
"github.com/distribution/distribution/v3/manifest/ocischema"
6+
"github.com/distribution/distribution/v3/manifest/schema2"
57
"github.com/opencontainers/go-digest"
8+
ociv1 "github.com/opencontainers/image-spec/specs-go/v1"
69
"github.com/sirupsen/logrus"
710
"time"
811
)
@@ -37,3 +40,35 @@ func (r *Registry) CreatedDate(ctx context.Context, repository string, configDig
3740
logrus.Infof("Got created time from config layer: %v", configBase.Created)
3841
return configBase.Created, nil
3942
}
43+
44+
func (r *Registry) TagCreatedDate(ctx context.Context, repo, tag string) (createdDate *time.Time, imageType string, retErr error) {
45+
imageType = "Docker v1"
46+
manifest, descriptor, err := r.Manifest(ctx, repo, tag)
47+
if err != nil {
48+
logrus.Errorf("getting v2 or oci manifest for %s:%s failed: %v", repo, tag, err)
49+
retErr = err
50+
return
51+
} else if descriptor.MediaType == ociv1.MediaTypeImageManifest {
52+
if ocimanifest, ok := manifest.(*ocischema.DeserializedManifest); ok && ocimanifest.Annotations != nil {
53+
if created, ok := ocimanifest.Annotations["org.opencontainers.image.created"]; ok {
54+
if t, err := time.Parse(time.RFC3339, created); err == nil {
55+
createdDate = &t
56+
}
57+
}
58+
}
59+
imageType = "OCI"
60+
} else if descriptor.MediaType == schema2.MediaTypeManifest {
61+
imageType = "Docker V2"
62+
}
63+
64+
if createdDate == nil {
65+
if created, err := r.CreatedDate(ctx, repo, manifest.References()[0].Digest); err == nil {
66+
createdDate = created
67+
} else {
68+
logrus.Errorf("getting created time from config layer for %s:%s failed: %v", repo, tag, err)
69+
retErr = err
70+
return
71+
}
72+
}
73+
return
74+
}

0 commit comments

Comments
 (0)