mirror of
https://github.com/goharbor/harbor.git
synced 2025-01-20 06:31:55 +01:00
Merge pull request #8541 from ywk253100/190802_retention_repo
Remove the retention job for deleting repository
This commit is contained in:
commit
93070067be
@ -32,6 +32,4 @@ const (
|
|||||||
ReplicationScheduler = "IMAGE_REPLICATE"
|
ReplicationScheduler = "IMAGE_REPLICATE"
|
||||||
// Retention : the name of the retention job
|
// Retention : the name of the retention job
|
||||||
Retention = "RETENTION"
|
Retention = "RETENTION"
|
||||||
// RetentionDel is the name of retention deletion job
|
|
||||||
RetentionDel = "RETENTION_DEL"
|
|
||||||
)
|
)
|
||||||
|
@ -247,7 +247,6 @@ func (bs *Bootstrap) loadAndRunRedisWorkerPool(
|
|||||||
job.Replication: (*replication.Replication)(nil),
|
job.Replication: (*replication.Replication)(nil),
|
||||||
job.ReplicationScheduler: (*replication.Scheduler)(nil),
|
job.ReplicationScheduler: (*replication.Scheduler)(nil),
|
||||||
job.Retention: (*retention.Job)(nil),
|
job.Retention: (*retention.Job)(nil),
|
||||||
job.RetentionDel: (*retention.DelRepoJob)(nil),
|
|
||||||
scheduler.JobNameScheduler: (*scheduler.PeriodicJob)(nil),
|
scheduler.JobNameScheduler: (*scheduler.PeriodicJob)(nil),
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
// exit
|
// exit
|
||||||
|
@ -1,114 +0,0 @@
|
|||||||
// Copyright Project Harbor Authors
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package retention
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/goharbor/harbor/src/jobservice/job"
|
|
||||||
"github.com/goharbor/harbor/src/jobservice/logger"
|
|
||||||
"github.com/goharbor/harbor/src/pkg/retention/dep"
|
|
||||||
"github.com/goharbor/harbor/src/pkg/retention/res"
|
|
||||||
"github.com/olekukonko/tablewriter"
|
|
||||||
)
|
|
||||||
|
|
||||||
// DelRepoJob tries to delete the whole given repository
|
|
||||||
type DelRepoJob struct{}
|
|
||||||
|
|
||||||
// MaxFails of the job
|
|
||||||
func (drj *DelRepoJob) MaxFails() uint {
|
|
||||||
return 3
|
|
||||||
}
|
|
||||||
|
|
||||||
// ShouldRetry indicates job can be retried if failed
|
|
||||||
func (drj *DelRepoJob) ShouldRetry() bool {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate the parameters
|
|
||||||
func (drj *DelRepoJob) Validate(params job.Parameters) (err error) {
|
|
||||||
if _, err = getParamRepo(params); err == nil {
|
|
||||||
_, err = getParamDryRun(params)
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run the job
|
|
||||||
func (drj *DelRepoJob) Run(ctx job.Context, params job.Parameters) error {
|
|
||||||
// logger for logging
|
|
||||||
myLogger := ctx.GetLogger()
|
|
||||||
|
|
||||||
// Parameters have been validated, ignore error checking
|
|
||||||
repo, _ := getParamRepo(params)
|
|
||||||
isDryRun, _ := getParamDryRun(params)
|
|
||||||
|
|
||||||
// Log stage: start
|
|
||||||
repoPath := fmt.Sprintf("%s/%s", repo.Namespace, repo.Name)
|
|
||||||
myLogger.Infof("Run retention process.\n Repository: %s \n Dry Run: %v", repoPath, isDryRun)
|
|
||||||
|
|
||||||
// For printing retention log
|
|
||||||
allArtifacts, err := dep.DefaultClient.GetCandidates(repo)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stop check point:
|
|
||||||
if isStopped(ctx) {
|
|
||||||
logStop(myLogger)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete the repository
|
|
||||||
if !isDryRun {
|
|
||||||
if err := dep.DefaultClient.DeleteRepository(repo); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Log deletions
|
|
||||||
logDeletions(myLogger, allArtifacts)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func logDeletions(logger logger.Interface, all []*res.Candidate) {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
|
|
||||||
data := make([][]string, len(all))
|
|
||||||
for _, c := range all {
|
|
||||||
row := []string{
|
|
||||||
arn(c),
|
|
||||||
c.Kind,
|
|
||||||
strings.Join(c.Labels, ","),
|
|
||||||
t(c.PushedTime),
|
|
||||||
t(c.PulledTime),
|
|
||||||
t(c.CreationTime),
|
|
||||||
actionMarkDeletion,
|
|
||||||
}
|
|
||||||
data = append(data, row)
|
|
||||||
}
|
|
||||||
|
|
||||||
table := tablewriter.NewWriter(&buf)
|
|
||||||
table.SetHeader([]string{"Artifact", "Kind", "labels", "PushedTime", "PulledTime", "CreatedTime", "Retention"})
|
|
||||||
table.SetBorders(tablewriter.Border{Left: true, Top: false, Right: true, Bottom: false})
|
|
||||||
table.SetCenterSeparator("|")
|
|
||||||
table.AppendBulk(data)
|
|
||||||
table.Render()
|
|
||||||
|
|
||||||
logger.Infof("\n%s", buf.String())
|
|
||||||
}
|
|
@ -1,69 +0,0 @@
|
|||||||
// Copyright Project Harbor Authors
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package retention
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/goharbor/harbor/src/jobservice/job"
|
|
||||||
"github.com/goharbor/harbor/src/pkg/retention/dep"
|
|
||||||
"github.com/goharbor/harbor/src/pkg/retention/res"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"github.com/stretchr/testify/suite"
|
|
||||||
)
|
|
||||||
|
|
||||||
// DelRepoJobSuite tests the del repository job
|
|
||||||
type DelRepoJobSuite struct {
|
|
||||||
suite.Suite
|
|
||||||
|
|
||||||
oldClient dep.Client
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestJob is entry of running JobTestSuite
|
|
||||||
func TestDelRepoJob(t *testing.T) {
|
|
||||||
suite.Run(t, new(DelRepoJobSuite))
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetupSuite ...
|
|
||||||
func (suite *DelRepoJobSuite) SetupSuite() {
|
|
||||||
suite.oldClient = dep.DefaultClient
|
|
||||||
dep.DefaultClient = &fakeRetentionClient{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TearDownSuite ...
|
|
||||||
func (suite *DelRepoJobSuite) TearDownSuite() {
|
|
||||||
dep.DefaultClient = suite.oldClient
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestRun ...
|
|
||||||
func (suite *DelRepoJobSuite) TestRun() {
|
|
||||||
params := make(job.Parameters)
|
|
||||||
params[ParamDryRun] = false
|
|
||||||
repository := &res.Repository{
|
|
||||||
Namespace: "library",
|
|
||||||
Name: "harbor",
|
|
||||||
Kind: res.Image,
|
|
||||||
}
|
|
||||||
repoJSON, err := repository.ToJSON()
|
|
||||||
require.NoError(suite.T(), err)
|
|
||||||
params[ParamRepo] = repoJSON
|
|
||||||
|
|
||||||
j := &DelRepoJob{}
|
|
||||||
err = j.Validate(params)
|
|
||||||
require.NoError(suite.T(), err)
|
|
||||||
|
|
||||||
err = j.Run(&fakeJobContext{}, params)
|
|
||||||
require.NoError(suite.T(), err)
|
|
||||||
}
|
|
@ -111,7 +111,6 @@ func (l *launcher) Launch(ply *policy.Metadata, executionID int64, isDryRun bool
|
|||||||
if scope == nil {
|
if scope == nil {
|
||||||
return 0, launcherError(fmt.Errorf("the scope of policy is nil"))
|
return 0, launcherError(fmt.Errorf("the scope of policy is nil"))
|
||||||
}
|
}
|
||||||
allRepositories := make(map[res.Repository]struct{}, 0)
|
|
||||||
repositoryRules := make(map[res.Repository]*lwp.Metadata, 0)
|
repositoryRules := make(map[res.Repository]*lwp.Metadata, 0)
|
||||||
level := scope.Level
|
level := scope.Level
|
||||||
var allProjects []*res.Candidate
|
var allProjects []*res.Candidate
|
||||||
@ -154,12 +153,6 @@ func (l *launcher) Launch(ply *policy.Metadata, executionID int64, isDryRun bool
|
|||||||
return 0, launcherError(err)
|
return 0, launcherError(err)
|
||||||
}
|
}
|
||||||
for _, repository := range repositories {
|
for _, repository := range repositories {
|
||||||
repo := res.Repository{
|
|
||||||
Namespace: repository.Namespace,
|
|
||||||
Name: repository.Repository,
|
|
||||||
Kind: repository.Kind,
|
|
||||||
}
|
|
||||||
allRepositories[repo] = struct{}{}
|
|
||||||
repositoryCandidates = append(repositoryCandidates, repository)
|
repositoryCandidates = append(repositoryCandidates, repository)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -193,7 +186,7 @@ func (l *launcher) Launch(ply *policy.Metadata, executionID int64, isDryRun bool
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create job data list
|
// create job data list
|
||||||
jobDatas, err := createJobs(allRepositories, repositoryRules, isDryRun)
|
jobDatas, err := createJobs(repositoryRules, isDryRun)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, launcherError(err)
|
return 0, launcherError(err)
|
||||||
}
|
}
|
||||||
@ -217,8 +210,7 @@ func (l *launcher) Launch(ply *policy.Metadata, executionID int64, isDryRun bool
|
|||||||
return int64(len(jobDatas)), nil
|
return int64(len(jobDatas)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createJobs(allRepositories map[res.Repository]struct{},
|
func createJobs(repositoryRules map[res.Repository]*lwp.Metadata, isDryRun bool) ([]*jobData, error) {
|
||||||
repositoryRules map[res.Repository]*lwp.Metadata, isDryRun bool) ([]*jobData, error) {
|
|
||||||
jobDatas := []*jobData{}
|
jobDatas := []*jobData{}
|
||||||
for repository, policy := range repositoryRules {
|
for repository, policy := range repositoryRules {
|
||||||
jobData := &jobData{
|
jobData := &jobData{
|
||||||
@ -242,25 +234,6 @@ func createJobs(allRepositories map[res.Repository]struct{},
|
|||||||
jobData.JobParams[ParamMeta] = policyJSON
|
jobData.JobParams[ParamMeta] = policyJSON
|
||||||
jobDatas = append(jobDatas, jobData)
|
jobDatas = append(jobDatas, jobData)
|
||||||
}
|
}
|
||||||
for repository := range allRepositories {
|
|
||||||
if _, exist := repositoryRules[repository]; exist {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
jobData := &jobData{
|
|
||||||
Repository: repository,
|
|
||||||
JobName: job.RetentionDel,
|
|
||||||
JobParams: make(map[string]interface{}, 2),
|
|
||||||
}
|
|
||||||
// set dry run
|
|
||||||
jobData.JobParams[ParamDryRun] = isDryRun
|
|
||||||
// set repository
|
|
||||||
repoJSON, err := repository.ToJSON()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
jobData.JobParams[ParamRepo] = repoJSON
|
|
||||||
jobDatas = append(jobDatas, jobData)
|
|
||||||
}
|
|
||||||
return jobDatas, nil
|
return jobDatas, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user