diff --git a/src/common/dao/artifact.go b/src/common/dao/artifact.go index 6edef8773..c66930876 100644 --- a/src/common/dao/artifact.go +++ b/src/common/dao/artifact.go @@ -88,6 +88,21 @@ func ListArtifacts(query *models.ArtifactQuery) ([]*models.Artifact, error) { return afs, err } +// GetArtifact by repository and tag +func GetArtifact(repo, tag string) (*models.Artifact, error) { + artifact := &models.Artifact{} + err := GetOrmer().QueryTable(&models.Artifact{}). + Filter("Repo", repo). + Filter("Tag", tag).One(artifact) + if err != nil { + if err == orm.ErrNoRows { + return nil, nil + } + return nil, err + } + return artifact, nil +} + // GetTotalOfArtifacts returns total of artifacts func GetTotalOfArtifacts(query ...*models.ArtifactQuery) (int64, error) { var qs orm.QuerySeter diff --git a/src/common/dao/artifact_test.go b/src/common/dao/artifact_test.go index 31f2770a1..a7889375c 100644 --- a/src/common/dao/artifact_test.go +++ b/src/common/dao/artifact_test.go @@ -40,6 +40,16 @@ func TestAddArtifact(t *testing.T) { } +func TestGetArtifact(t *testing.T) { + repo := "hello-world" + tag := "latest" + artifact, err := GetArtifact(repo, tag) + require.Nil(t, err) + require.NotNil(t, artifact) + assert.Equal(t, repo, artifact.Repo) + assert.Equal(t, tag, artifact.Tag) +} + func TestUpdateArtifactDigest(t *testing.T) { af := &models.Artifact{ PID: 1, diff --git a/src/common/models/repo.go b/src/common/models/repo.go index 15954450e..9993fbcc6 100644 --- a/src/common/models/repo.go +++ b/src/common/models/repo.go @@ -57,6 +57,8 @@ type TagResp struct { Signature *model.Target `json:"signature"` ScanOverview *ImgScanOverview `json:"scan_overview,omitempty"` Labels []*Label `json:"labels"` + PushTime time.Time `json:"push_time"` + PullTime time.Time `json:"pull_time"` } // TagDetail ... diff --git a/src/core/api/repository.go b/src/core/api/repository.go index b7c718552..dd88c3ebb 100644 --- a/src/core/api/repository.go +++ b/src/core/api/repository.go @@ -649,6 +649,20 @@ func assembleTag(c chan *models.TagResp, client *registry.Repository, } } } + + // pull/push time + artifact, err := dao.GetArtifact(repository, tag) + if err != nil { + log.Errorf("failed to get artifact %s:%s: %v", repository, tag, err) + } else { + if artifact == nil { + log.Warningf("artifact %s:%s not found", repository, tag) + } else { + item.PullTime = artifact.PullTime + item.PushTime = artifact.PushTime + } + } + c <- item } diff --git a/src/pkg/retention/dep/client.go b/src/pkg/retention/dep/client.go index ef878c447..9ccb951f7 100644 --- a/src/pkg/retention/dep/client.go +++ b/src/pkg/retention/dep/client.go @@ -17,9 +17,7 @@ package dep import ( "errors" "fmt" - "math/rand" "net/http" - "time" "github.com/goharbor/harbor/src/common/http/modifier/auth" "github.com/goharbor/harbor/src/jobservice/config" @@ -113,8 +111,8 @@ func (bc *basicClient) GetCandidates(repository *res.Repository) ([]*res.Candida Tag: image.Name, Labels: labels, CreationTime: image.Created.Unix(), - PulledTime: time.Now().Unix() - (int64)(rand.Int31n(4)*3600), - PushedTime: time.Now().Unix() - (int64)((rand.Int31n(5)+5)*3600), + PulledTime: image.PullTime.Unix(), + PushedTime: image.PushTime.Unix(), } candidates = append(candidates, candidate) }