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}) }