package handler import ( "strconv" "strings" "gitea.loveuer.com/loveuer/cluster/controller" "gitea.loveuer.com/loveuer/cluster/internal/registry/storage" "github.com/gofiber/fiber/v3" ) // GetManifest 获取 manifest func GetManifest(store storage.Storage) fiber.Handler { return func(c fiber.Ctx) error { repo := c.Locals("repo_name") repoStr := "" if repo != nil { repoStr = repo.(string) } if repoStr == "" { repoStr = strings.TrimPrefix(c.Params("name"), "/") } reference := c.Locals("reference") referenceStr := "" if reference != nil { referenceStr = reference.(string) } data, mediaType, digest, err := controller.GetManifest(store, repoStr, referenceStr) if err != nil { return c.Status(fiber.StatusNotFound).JSON(fiber.Map{ "errors": []fiber.Map{ { "code": "MANIFEST_UNKNOWN", "message": err.Error(), }, }, }) } c.Set("Content-Type", mediaType) c.Set("Content-Length", strconv.FormatInt(int64(len(data)), 10)) c.Set("Docker-Content-Digest", digest) return c.Send(data) } } // PutManifest 推送 manifest func PutManifest(store storage.Storage) fiber.Handler { return func(c fiber.Ctx) error { repo := c.Locals("repo_name") repoStr := "" if repo != nil { repoStr = repo.(string) } if repoStr == "" { repoStr = c.Params("name") } reference := c.Locals("reference") referenceStr := "" if reference != nil { referenceStr = reference.(string) } // 读取请求体 data := c.Body() // 获取 Content-Type mediaType := c.Get("Content-Type") if mediaType == "" { mediaType = "application/vnd.docker.distribution.manifest.v2+json" } digest, err := controller.PutManifest(store, repoStr, referenceStr, data, mediaType) if err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "errors": []fiber.Map{ { "code": "INTERNAL_ERROR", "message": err.Error(), }, }, }) } // 返回 Location 和 Digest c.Set("Location", c.Path()) c.Set("Docker-Content-Digest", digest) return c.SendStatus(fiber.StatusCreated) } } // DeleteManifest 删除 manifest func DeleteManifest(store storage.Storage) fiber.Handler { return func(c fiber.Ctx) error { repo := c.Locals("repo_name") repoStr := "" if repo != nil { repoStr = repo.(string) } if repoStr == "" { repoStr = c.Params("name") } reference := c.Locals("reference") referenceStr := "" if reference != nil { referenceStr = reference.(string) } if err := controller.DeleteManifest(store, repoStr, referenceStr); err != nil { return c.Status(fiber.StatusNotFound).JSON(fiber.Map{ "errors": []fiber.Map{ { "code": "MANIFEST_UNKNOWN", "message": err.Error(), }, }, }) } return c.SendStatus(fiber.StatusAccepted) } } // HeadManifest 检查 manifest 是否存在 func HeadManifest(store storage.Storage) fiber.Handler { return func(c fiber.Ctx) error { repo := c.Locals("repo_name") repoStr := "" if repo != nil { repoStr = repo.(string) } if repoStr == "" { repoStr = strings.TrimPrefix(c.Params("name"), "/") } reference := c.Locals("reference") referenceStr := "" if reference != nil { referenceStr = reference.(string) } exists, data, mediaType, digest, err := controller.HeadManifest(store, repoStr, referenceStr) if err != nil || !exists { return c.SendStatus(fiber.StatusNotFound) } c.Set("Content-Type", mediaType) c.Set("Content-Length", strconv.FormatInt(int64(len(data)), 10)) c.Set("Docker-Content-Digest", digest) return c.SendStatus(fiber.StatusOK) } }