package registry import ( "context" "log" "strings" registry "gitea.loveuer.com/loveuer/cluster/pkg/model/registry" "gitea.loveuer.com/loveuer/cluster/pkg/resp" "gitea.loveuer.com/loveuer/cluster/pkg/store" "github.com/gofiber/fiber/v3" "gorm.io/gorm" ) func Registry(ctx context.Context, db *gorm.DB, store store.Store) fiber.Handler { if err := db.AutoMigrate( ®istry.Repository{}, ®istry.Blob{}, ®istry.Manifest{}, ®istry.Tag{}, ®istry.BlobUpload{}, ®istry.RegistryConfig{}, ); err != nil { log.Fatalf("failed to migrate database: %v", err) } if err := store.CreatePartition(ctx, "registry"); err != nil { log.Fatalf("failed to create registry partition: %v", err) } return func(c fiber.Ctx) error { if isBlob(c) { return HandleBlobs(c, db, store) } if isManifest(c) { return HandleManifest(c, db, store) } if isTags(c) { return HandleTags(c, db, store) } if isCatalog(c) { return HandleCatalog(c, db, store) } if isReferrers(c) { return HandleReferrers(c, db, store) } // 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] Registry: unknown endpoint - path = %s, method = %s, headers = %v", c.Path(), c.Method(), &c.Request().Header) return resp.R404(c, "UNKNOWN_ENDPOINT", nil, "endpoint not found") } } 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" }