Files
mstore/app/handler/manifest.go
T

239 lines
6.5 KiB
Go

/*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*/
package handler
import (
"net/http"
"mstore/app/imageoper"
"mstore/app/router"
"mstore/pkg/terms"
)
func (hand *Handler) ManifestExists(rctx *router.Context) {
name, _ := rctx.GetSubpath("name")
reference, _ := rctx.GetSubpath("reference")
hand.DumpHeaders("ManigestExists:\n", rctx)
params := &imageoper.ManifestExistsParams{
Name: name,
Reference: reference,
}
// Rigth checking
operatorID, _ := rctx.GetString(userTag)
opEnable, err := hand.CheckRight(rctx.Ctx, operatorID, terms.RightReadImages, params.Name)
if err != nil {
rctx.SetStatus(http.StatusInternalServerError)
return
}
if !opEnable {
rctx.SetStatus(http.StatusMethodNotAllowed)
return
}
// Execution of the operation
ctx := rctx.GetContext()
res, code, err := hand.imop.ManifestExists(ctx, params)
if err != nil {
hand.logg.Errorf("ManifestExist error: %v", err)
} else if code == http.StatusOK {
rctx.SetHeader("Content-Length", res.ContentLength)
rctx.SetHeader("Content-Type", res.ContentType)
rctx.SetHeader("Docker-Content-Digest", res.DockerContentDigest)
}
hand.logg.Debugf(res.ContentType)
hand.logg.Debugf(res.DockerContentDigest)
rctx.SetStatus(code)
}
// PUT /v2/<name>/manifests/<reference> 201 404
func (hand *Handler) PutManifest(rctx *router.Context) {
//hand.DumpHeaders("PutManifest headers", rctx)
contentType := rctx.GetHeader("Content-Type")
contentLength := rctx.GetHeader("Content-Length")
name, _ := rctx.GetSubpath("name")
reference, _ := rctx.GetSubpath("reference")
params := &imageoper.PutManifestParams{
ContentType: contentType,
ContentLength: contentLength,
Name: name,
Reference: reference,
Reader: rctx.Request.Body,
}
// Rigth checking
operatorID, _ := rctx.GetString(userTag)
opEnable, err := hand.CheckRight(rctx.Ctx, operatorID, terms.RightWriteImages, params.Name)
if err != nil {
rctx.SetStatus(http.StatusInternalServerError)
return
}
if !opEnable {
rctx.SetStatus(http.StatusMethodNotAllowed)
return
}
// Execution of the operation
ctx := rctx.GetContext()
res, code, err := hand.imop.PutManifest(ctx, params)
if err != nil {
hand.logg.Errorf("PutManifest error: %v", err)
} else {
rctx.SetHeader("Location", res.Location)
}
rctx.SetStatus(code)
}
// GET /v2/<name>/manifests/<reference> 200 404
func (hand *Handler) GetManifest(rctx *router.Context) {
name, _ := rctx.GetSubpath("name")
reference, _ := rctx.GetSubpath("reference")
//hand.DumpHeaders("GetManigest", rctx)
params := &imageoper.GetManifestParams{
Name: name,
Reference: reference,
}
// Rigth checking
operatorID, _ := rctx.GetString(userTag)
opEnable, err := hand.CheckRight(rctx.Ctx, operatorID, terms.RightReadImages, params.Name)
if err != nil {
rctx.SetStatus(http.StatusInternalServerError)
return
}
if !opEnable {
rctx.SetStatus(http.StatusMethodNotAllowed)
return
}
// Execution of the operation
ctx := rctx.GetContext()
res, code, err := hand.imop.GetManifest(ctx, params)
if err != nil {
hand.logg.Errorf("GetManifest error: %v", err)
rctx.SetStatus(code)
return
}
if code == http.StatusOK {
//hand.logg.Debugf("GetManifest type: %s", res.ContentType)
//hand.logg.Debugf("GetManifest payload: %s", res.Payload)
rctx.SetHeader("Content-Length", res.ContentLength)
//rctx.SetHeader("Content-Type", res.ContentType)
rctx.SetHeader("Docker-Content-Digest", res.DockerContentDigest)
rctx.SendBytes(code, res.ContentType, []byte(res.Payload))
return
}
rctx.SetStatus(code)
}
// DELETE /v2/<name>/manifests/<reference> 200 404
func (hand *Handler) DeleteManifest(rctx *router.Context) {
name, _ := rctx.GetSubpath("name")
reference, _ := rctx.GetSubpath("reference")
params := &imageoper.DeleteManifestParams{
Name: name,
Reference: reference,
}
// Rigth checking
operatorID, _ := rctx.GetString(userTag)
opEnable, err := hand.CheckRight(rctx.Ctx, operatorID, terms.RightWriteImages, params.Name)
if err != nil {
rctx.SetStatus(http.StatusInternalServerError)
return
}
if !opEnable {
rctx.SetStatus(http.StatusMethodNotAllowed)
return
}
// Execution of the operation
ctx := rctx.GetContext()
_, code, err := hand.imop.DeleteManifest(ctx, params)
if err != nil {
hand.logg.Errorf("DeleteManifest error: %v", err)
}
rctx.SetStatus(code)
}
// GET /v2/<name>/referrers/<digest> 200 404/400
// GET /v2/<name>/referrers/<digest>?artifactType=<artifactType> 200 404/400
func (hand *Handler) GetReferer(rctx *router.Context) {
name, _ := rctx.GetSubpath("name")
digest, _ := rctx.GetSubpath("digest")
params := &imageoper.GetRefererParams{
Name: name,
Digest: digest,
}
// Rigth checking
operatorID, _ := rctx.GetString(userTag)
opEnable, err := hand.CheckRight(rctx.Ctx, operatorID, terms.RightReadImages, params.Name)
if err != nil {
rctx.SetStatus(http.StatusInternalServerError)
return
}
if !opEnable {
rctx.SetStatus(http.StatusMethodNotAllowed)
return
}
// Execution of the operation
res, code, err := hand.imop.GetReferer(rctx.Ctx, params)
if err != nil {
hand.logg.Errorf("GetReferer error: %v", err)
}
rctx.SendText(code, res.Reference)
}
// GET /v2/<name>/tags/list 200 404
// GET /v2/<name>/tags/list?n=<integer>&last=<integer>
func (hand *Handler) GetTags(rctx *router.Context) {
name, _ := rctx.GetSubpath("name")
params := &imageoper.GetTagsParams{
Name: name,
}
// Rigth checking
operatorID, _ := rctx.GetString(userTag)
opEnable, err := hand.CheckRight(rctx.Ctx, operatorID, terms.RightReadImages, params.Name)
if err != nil {
rctx.SetStatus(http.StatusInternalServerError)
return
}
if !opEnable {
rctx.SetStatus(http.StatusMethodNotAllowed)
return
}
// Execution of the operation
ctx := rctx.GetContext()
res, code, err := hand.imop.GetTags(ctx, params)
if err != nil {
hand.logg.Errorf("GetTags error: %v", err)
}
rctx.SendJSON(code, res.TagDescr)
}
// GET /v2/_catalog?n=1000 200 404
func (hand *Handler) ListManifests(rctx *router.Context) {
params := &imageoper.ListManifestsParams{}
// Rigth checking
operatorID, _ := rctx.GetString(userTag)
opEnable, err := hand.CheckRight(rctx.Ctx, operatorID, terms.RightReadImages, "_catalog")
if err != nil {
rctx.SetStatus(http.StatusInternalServerError)
return
}
if !opEnable {
rctx.SetStatus(http.StatusMethodNotAllowed)
return
}
// Execution of the operation
ctx := rctx.GetContext()
res, code, err := hand.imop.ListManifests(ctx, params)
if err != nil {
hand.logg.Errorf("ListManifests error: %v", err)
}
rctx.SendJSON(code, res.Repositories)
}