Files
cluster/handler/registry.go
2025-11-09 15:19:11 +08:00

114 lines
2.4 KiB
Go

package handler
import (
"log"
"strings"
"gitea.loveuer.com/loveuer/cluster/controller"
"gitea.loveuer.com/loveuer/cluster/internal/registry/storage"
"github.com/gofiber/fiber/v3"
)
func isBlob(c fiber.Ctx) bool {
elem := strings.Split(c.Path(), "/")
elem = elem[1:]
if elem[len(elem)-1] == "" {
elem = elem[:len(elem)-1]
}
if len(elem) < 3 {
return false
}
return elem[len(elem)-2] == "blobs" || (elem[len(elem)-3] == "blobs" &&
elem[len(elem)-2] == "uploads")
}
func isManifest(c fiber.Ctx) bool {
elems := strings.Split(c.Path(), "/")
elems = elems[1:]
if len(elems) < 4 {
return false
}
return elems[len(elems)-2] == "manifests"
}
func isTags(c fiber.Ctx) bool {
elems := strings.Split(c.Path(), "/")
elems = elems[1:]
if len(elems) < 4 {
return false
}
return elems[len(elems)-2] == "tags"
}
func isCatalog(c fiber.Ctx) bool {
elems := strings.Split(c.Path(), "/")
elems = elems[1:]
if len(elems) < 2 {
return false
}
return elems[len(elems)-1] == "_catalog"
}
func isReferrers(c fiber.Ctx) bool {
elems := strings.Split(c.Path(), "/")
elems = elems[1:]
if len(elems) < 4 {
return false
}
return elems[len(elems)-2] == "referrers"
}
// RegistryV2 handles all OCI Registry API v2 requests
func RegistryV2(store storage.Storage) fiber.Handler {
// Initialize handlers
blobHandler = NewBlobHandler(store)
uploadHandler = NewUploadHandler()
m = NewManifestHandler(store)
return func(c fiber.Ctx) error {
if isBlob(c) {
return handleBlobs(c)
}
if isManifest(c) {
return handleManifest(c)
}
if isTags(c) {
return handleTags(c)
}
if isCatalog(c) {
return handleCatalog(c)
}
if isReferrers(c) {
return handleReferrers(c)
}
// Handle root v2 endpoint
if c.Path() == "/v2/" {
c.Set("Docker-Distribution-API-Version", "registry/2.0")
return c.SendStatus(200)
}
c.Set("Docker-Distribution-API-Version", "registry/2.0")
log.Printf("[WARN] RegistryV2: unknown endpoint - path = %s, method = %s", c.Path(), c.Method())
return c.Status(404).JSON(fiber.Map{
"errors": []fiber.Map{{"code": "NOT_FOUND", "message": "endpoint not found"}},
})
}
}
// ListImages 返回所有仓库列表
func ListImages(c fiber.Ctx) error {
repos, err := controller.ListImages()
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
}
return c.JSON(fiber.Map{"images": repos})
}