harbor/src/api/repository/controller.go

111 lines
3.4 KiB
Go
Raw Normal View History

// 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 repository
import (
"context"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/common/utils"
ierror "github.com/goharbor/harbor/src/internal/error"
"github.com/goharbor/harbor/src/pkg/project"
"github.com/goharbor/harbor/src/pkg/q"
"github.com/goharbor/harbor/src/pkg/repository"
)
var (
// Ctl is a global repository controller instance
Ctl = NewController()
)
// Controller defines the operations related with repositories
type Controller interface {
// Ensure the repository specified by the "name" exists, creates it if it doesn't exist.
// The "name" should contain the namespace part. The "created" will be set as true
// when the repository is created
Ensure(ctx context.Context, name string) (created bool, id int64, err error)
// List repositories according to the query
List(ctx context.Context, query *q.Query) (total int64, repositories []*models.RepoRecord, err error)
// Get the repository specified by ID
Get(ctx context.Context, id int64) (repository *models.RepoRecord, err error)
// GetByName gets the repository specified by name
GetByName(ctx context.Context, name string) (repository *models.RepoRecord, err error)
}
// NewController creates an instance of the default repository controller
func NewController() Controller {
return &controller{
proMgr: project.Mgr,
repoMgr: repository.Mgr,
}
}
type controller struct {
proMgr project.Manager
repoMgr repository.Manager
}
func (c *controller) Ensure(ctx context.Context, name string) (bool, int64, error) {
query := &q.Query{
Keywords: map[string]interface{}{
"name": name,
},
}
_, repositories, err := c.repoMgr.List(ctx, query)
if err != nil {
return false, 0, err
}
// the repository already exists, return directly
if len(repositories) > 0 {
return false, repositories[0].RepositoryID, nil
}
// the repository doesn't exist, create it first
projectName, _ := utils.ParseRepository(name)
project, err := c.proMgr.Get(projectName)
if err != nil {
return false, 0, err
}
id, err := c.repoMgr.Create(ctx, &models.RepoRecord{
ProjectID: project.ProjectID,
Name: name,
})
if err != nil {
// if got conflict error, try to get again
if ierror.IsConflictErr(err) {
_, repositories, err = c.repoMgr.List(ctx, query)
if err != nil {
return false, 0, err
}
if len(repositories) > 0 {
return false, repositories[0].RepositoryID, nil
}
}
return false, 0, err
}
return true, id, nil
}
func (c *controller) List(ctx context.Context, query *q.Query) (int64, []*models.RepoRecord, error) {
return c.repoMgr.List(ctx, query)
}
func (c *controller) Get(ctx context.Context, id int64) (*models.RepoRecord, error) {
return c.repoMgr.Get(ctx, id)
}
func (c *controller) GetByName(ctx context.Context, name string) (*models.RepoRecord, error) {
return c.repoMgr.GetByName(ctx, name)
}