harbor/src/pkg/artifact/manager.go
Wenkai Yin(尹文开) 8984979bd2
Relocate/rename some packages (#11183)
Fixes #11016
1. src/pkg/q->src/internal/q
2. src/internal->src/lib (internal is a reserved package name of golang)
3. src/api->src/controller

Signed-off-by: Wenkai Yin <yinw@vmware.com>
2020-03-24 20:45:45 +08:00

164 lines
5.0 KiB
Go

// 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 artifact
import (
"context"
"github.com/goharbor/harbor/src/lib/q"
"github.com/goharbor/harbor/src/pkg/artifact/dao"
)
var (
// Mgr is a global artifact manager instance
Mgr = NewManager()
)
// Manager is the only interface of artifact module to provide the management functions for artifacts
type Manager interface {
// Count returns the total count of artifacts according to the query.
// The artifacts that referenced by others and without tags are not counted
Count(ctx context.Context, query *q.Query) (total int64, err error)
// List artifacts according to the query. The artifacts that referenced by others and
// without tags are not returned
List(ctx context.Context, query *q.Query) (artifacts []*Artifact, err error)
// Get the artifact specified by the ID
Get(ctx context.Context, id int64) (artifact *Artifact, err error)
// GetByDigest returns the artifact specified by repository and digest
GetByDigest(ctx context.Context, repository, digest string) (artifact *Artifact, err error)
// Create the artifact. If the artifact is an index, make sure all the artifacts it references
// already exist
Create(ctx context.Context, artifact *Artifact) (id int64, err error)
// Delete just deletes the artifact record. The underlying data of registry will be
// removed during garbage collection
Delete(ctx context.Context, id int64) (err error)
// Update the artifact. Only the properties specified by "props" will be updated if it is set
Update(ctx context.Context, artifact *Artifact, props ...string) (err error)
// ListReferences according to the query
ListReferences(ctx context.Context, query *q.Query) (references []*Reference, err error)
// DeleteReference specified by ID
DeleteReference(ctx context.Context, id int64) (err error)
}
// NewManager returns an instance of the default manager
func NewManager() Manager {
return &manager{
dao.New(),
}
}
var _ Manager = &manager{}
type manager struct {
dao dao.DAO
}
func (m *manager) Count(ctx context.Context, query *q.Query) (int64, error) {
return m.dao.Count(ctx, query)
}
func (m *manager) List(ctx context.Context, query *q.Query) ([]*Artifact, error) {
arts, err := m.dao.List(ctx, query)
if err != nil {
return nil, err
}
var artifacts []*Artifact
for _, art := range arts {
artifact, err := m.assemble(ctx, art)
if err != nil {
return nil, err
}
artifacts = append(artifacts, artifact)
}
return artifacts, nil
}
func (m *manager) Get(ctx context.Context, id int64) (*Artifact, error) {
art, err := m.dao.Get(ctx, id)
if err != nil {
return nil, err
}
return m.assemble(ctx, art)
}
func (m *manager) GetByDigest(ctx context.Context, repository, digest string) (*Artifact, error) {
art, err := m.dao.GetByDigest(ctx, repository, digest)
if err != nil {
return nil, err
}
return m.assemble(ctx, art)
}
func (m *manager) Create(ctx context.Context, artifact *Artifact) (int64, error) {
id, err := m.dao.Create(ctx, artifact.To())
if err != nil {
return 0, err
}
for _, reference := range artifact.References {
reference.ParentID = id
if _, err = m.dao.CreateReference(ctx, reference.To()); err != nil {
return 0, err
}
}
return id, nil
}
func (m *manager) Delete(ctx context.Context, id int64) error {
// delete references
if err := m.dao.DeleteReferences(ctx, id); err != nil {
return err
}
// delete artifact
return m.dao.Delete(ctx, id)
}
func (m *manager) Update(ctx context.Context, artifact *Artifact, props ...string) (err error) {
return m.dao.Update(ctx, artifact.To(), props...)
}
func (m *manager) ListReferences(ctx context.Context, query *q.Query) ([]*Reference, error) {
references, err := m.dao.ListReferences(ctx, query)
if err != nil {
return nil, err
}
var refs []*Reference
for _, reference := range references {
ref := &Reference{}
ref.From(reference)
refs = append(refs, ref)
}
return refs, nil
}
func (m *manager) DeleteReference(ctx context.Context, id int64) error {
return m.dao.DeleteReference(ctx, id)
}
// assemble the artifact with references populated
func (m *manager) assemble(ctx context.Context, art *dao.Artifact) (*Artifact, error) {
artifact := &Artifact{}
// convert from database object
artifact.From(art)
// populate the references
if artifact.IsImageIndex() {
references, err := m.ListReferences(ctx, q.New(q.KeyWords{"ParentID": artifact.ID}))
if err != nil {
return nil, err
}
artifact.References = references
}
return artifact, nil
}