107 lines
3.0 KiB
Go
107 lines
3.0 KiB
Go
package handler
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"io"
|
|
|
|
"gitea.loveuer.com/loveuer/cluster/internal/database"
|
|
"gitea.loveuer.com/loveuer/cluster/internal/model"
|
|
"gitea.loveuer.com/loveuer/cluster/internal/rerr"
|
|
"gitea.loveuer.com/loveuer/cluster/internal/registry/storage"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type manifestHandlerImpl struct {
|
|
store storage.Storage
|
|
}
|
|
|
|
// NewManifestHandler creates a new manifest handler
|
|
func NewManifestHandler(store storage.Storage) ManifestHandler {
|
|
return &manifestHandlerImpl{store: store}
|
|
}
|
|
|
|
func (m *manifestHandlerImpl) Get(ctx context.Context, repo, tag string) (io.ReadCloser, string, *rerr.RepositoryError) {
|
|
data, mediaType, err := m.store.GetManifest(repo, tag)
|
|
if err != nil {
|
|
return nil, "", &rerr.RepositoryError{
|
|
Status: 404,
|
|
Code: "MANIFEST_UNKNOWN",
|
|
Message: "manifest not found",
|
|
}
|
|
}
|
|
return io.NopCloser(bytes.NewReader(data)), mediaType, nil
|
|
}
|
|
|
|
func (m *manifestHandlerImpl) Put(ctx context.Context, repo, tag, digest string, mf *model.RepoSimpleManifest) error {
|
|
return m.store.PutManifest(repo, tag, mf.Blob, mf.ContentType)
|
|
}
|
|
|
|
func (m *manifestHandlerImpl) Delete(ctx context.Context, repo, tag string) error {
|
|
return m.store.DeleteManifest(repo, tag)
|
|
}
|
|
|
|
func (m *manifestHandlerImpl) Tags(ctx context.Context, repo string, n, last int, prefix string) (*model.Tag, *rerr.RepositoryError) {
|
|
var repository model.RegistryRepository
|
|
if err := database.DB.Where("name = ?", repo).First(&repository).Error; err != nil {
|
|
if err == gorm.ErrRecordNotFound {
|
|
return &model.Tag{Name: repo, Tags: []string{}}, nil
|
|
}
|
|
return nil, rerr.ErrInternal(err)
|
|
}
|
|
|
|
var tags []model.RegistryTag
|
|
query := database.DB.Where("repository_id = ?", repository.ID)
|
|
if prefix != "" {
|
|
query = query.Where("name LIKE ?", prefix+"%")
|
|
}
|
|
if last > 0 {
|
|
query = query.Where("id > ?", last)
|
|
}
|
|
query = query.Order("id ASC").Limit(n)
|
|
|
|
if err := query.Find(&tags).Error; err != nil {
|
|
return nil, rerr.ErrInternal(err)
|
|
}
|
|
|
|
tagNames := make([]string, len(tags))
|
|
for i, tag := range tags {
|
|
tagNames[i] = tag.Name
|
|
}
|
|
|
|
return &model.Tag{Name: repo, Tags: tagNames}, nil
|
|
}
|
|
|
|
func (m *manifestHandlerImpl) Catalog(ctx context.Context, n, last int, prefix string) (*model.Catalog, *rerr.RepositoryError) {
|
|
var repositories []model.RegistryRepository
|
|
query := database.DB
|
|
if prefix != "" {
|
|
query = query.Where("name LIKE ?", prefix+"%")
|
|
}
|
|
if last > 0 {
|
|
query = query.Where("id > ?", last)
|
|
}
|
|
query = query.Order("id ASC").Limit(n)
|
|
|
|
if err := query.Find(&repositories).Error; err != nil {
|
|
return nil, rerr.ErrInternal(err)
|
|
}
|
|
|
|
repoNames := make([]string, len(repositories))
|
|
for i, repo := range repositories {
|
|
repoNames[i] = repo.Name
|
|
}
|
|
|
|
return &model.Catalog{Repositories: repoNames}, nil
|
|
}
|
|
|
|
func (m *manifestHandlerImpl) Referrers(ctx context.Context, repo, target string) (*model.IndexManifest, *rerr.RepositoryError) {
|
|
// For now, return an empty index manifest
|
|
return &model.IndexManifest{
|
|
SchemaVersion: 2,
|
|
MediaType: "application/vnd.oci.image.index.v1+json",
|
|
Manifests: []model.IndexManifestEntry{},
|
|
}, nil
|
|
}
|