feat: as docker mirror registry
feat: add global proxy config upgrade: upgrade front(angular) to 19 chore: deployment staff 1. Dockerfile: build frontend, backend, and run in nginx base image
This commit is contained in:
@ -3,17 +3,18 @@ package handler
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/loveuer/nf"
|
||||
"github.com/sirupsen/logrus"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"nf-repo/internal/model"
|
||||
"nf-repo/internal/opt"
|
||||
"nf-repo/internal/util/rerr"
|
||||
"nf-repo/internal/verify"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"nf-repo/internal/model"
|
||||
"nf-repo/internal/opt"
|
||||
"nf-repo/internal/tool/rerr"
|
||||
"nf-repo/internal/verify"
|
||||
|
||||
"github.com/loveuer/nf"
|
||||
"github.com/loveuer/nf/nft/log"
|
||||
)
|
||||
|
||||
func handleBlobs(c *nf.Ctx) error {
|
||||
@ -39,15 +40,8 @@ func handleBlobs(c *nf.Ctx) error {
|
||||
rangeHeader := c.Get("Range")
|
||||
repo := c.Request.URL.Host + path.Join(elem[1:len(elem)-2]...)
|
||||
|
||||
logrus.
|
||||
WithField("handler", "handleBlob").
|
||||
WithField("path", c.Path()).
|
||||
WithField("method", c.Method()).
|
||||
WithField("target", target).
|
||||
WithField("service", service).
|
||||
WithField("repo", repo).
|
||||
WithField("digest", digest).
|
||||
Debug()
|
||||
log.Debug("handleBlob: path = %s, method = %s, target = %s, service = %s, repo = %s, digest = %s",
|
||||
c.Path(), c.Method(), target, service, repo, digest)
|
||||
|
||||
switch c.Method() {
|
||||
case http.MethodHead:
|
||||
@ -68,7 +62,7 @@ func handleBlobs(c *nf.Ctx) error {
|
||||
} else if err != nil {
|
||||
var re model.RedirectError
|
||||
if errors.As(err, &re) {
|
||||
http.Redirect(c.RawWriter(), c.Request, re.Location, re.Code)
|
||||
http.Redirect(c.Writer, c.Request, re.Location, re.Code)
|
||||
return nil
|
||||
}
|
||||
return rerr.Error(c, rerr.ErrInternal(err))
|
||||
@ -93,11 +87,12 @@ func handleBlobs(c *nf.Ctx) error {
|
||||
|
||||
size, err = b.blobHandler.Stat(c.Request.Context(), repo, h)
|
||||
if errors.Is(err, opt.ErrNotFound) {
|
||||
log.Error("handleBlobs: mirror registry get repo not found, repo = %s", repo)
|
||||
return rerr.Error(c, rerr.ErrBlobUnknown)
|
||||
} else if err != nil {
|
||||
var re model.RedirectError
|
||||
if errors.As(err, &re) {
|
||||
http.Redirect(c.RawWriter(), c.Request, re.Location, re.Code)
|
||||
http.Redirect(c.Writer, c.Request, re.Location, re.Code)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -110,7 +105,7 @@ func handleBlobs(c *nf.Ctx) error {
|
||||
} else if err != nil {
|
||||
var re model.RedirectError
|
||||
if errors.As(err, &re) {
|
||||
http.Redirect(c.RawWriter(), c.Request, re.Location, re.Code)
|
||||
http.Redirect(c.Writer, c.Request, re.Location, re.Code)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -162,7 +157,7 @@ func handleBlobs(c *nf.Ctx) error {
|
||||
c.Status(http.StatusOK)
|
||||
}
|
||||
|
||||
_, err = io.Copy(c.RawWriter(), r)
|
||||
_, err = io.Copy(c.Writer, r)
|
||||
return err
|
||||
|
||||
case http.MethodPost:
|
||||
@ -190,7 +185,7 @@ func handleBlobs(c *nf.Ctx) error {
|
||||
|
||||
if err = b.blobHandler.Put(c.Request.Context(), repo, h, vrc); err != nil {
|
||||
if errors.As(err, &verify.Error{}) {
|
||||
log.Printf("Digest mismatch: %v", err)
|
||||
log.Info("Digest mismatch: %v", err)
|
||||
return rerr.Error(c, rerr.ErrDigestMismatch)
|
||||
}
|
||||
return rerr.Error(c, rerr.ErrInternal(err))
|
||||
|
@ -1,12 +1,14 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"github.com/loveuer/nf"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"nf-repo/internal/interfaces"
|
||||
"nf-repo/internal/model"
|
||||
"nf-repo/internal/util/rerr"
|
||||
"strconv"
|
||||
"nf-repo/internal/tool/rerr"
|
||||
|
||||
"github.com/loveuer/nf"
|
||||
)
|
||||
|
||||
func handleCatalog(ctx *nf.Ctx, m interfaces.ManifestHandler) error {
|
||||
|
@ -2,30 +2,30 @@ package handler
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/loveuer/nf"
|
||||
"github.com/sirupsen/logrus"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"nf-repo/internal/controller"
|
||||
"nf-repo/internal/interfaces"
|
||||
"nf-repo/internal/model"
|
||||
"nf-repo/internal/util/rerr"
|
||||
"strings"
|
||||
"nf-repo/internal/tool/rerr"
|
||||
|
||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||
"github.com/loveuer/nf"
|
||||
"github.com/loveuer/nf/nft/log"
|
||||
)
|
||||
|
||||
func handleManifest(ctx *nf.Ctx, m interfaces.ManifestHandler) error {
|
||||
func handleManifest(ctx *nf.Ctx, m interfaces.ManifestHandler, blobHandler interfaces.BlobHandler) error {
|
||||
elem := strings.Split(ctx.Path(), "/")
|
||||
elem = elem[1:]
|
||||
target := elem[len(elem)-1]
|
||||
repo := strings.Join(elem[1:len(elem)-2], "/")
|
||||
|
||||
logrus.
|
||||
WithField("handler", "handleManifest").
|
||||
WithField("path", ctx.Path()).
|
||||
WithField("method", ctx.Method()).
|
||||
WithField("repo", repo).
|
||||
WithField("target", target).
|
||||
Debug()
|
||||
log.Debug("handleManifest: path = %s, method = %s, repo = %s, target = %s",
|
||||
ctx.Path(), ctx.Method(), repo, target)
|
||||
|
||||
switch ctx.Method() {
|
||||
case http.MethodGet:
|
||||
@ -38,6 +38,22 @@ func handleManifest(ctx *nf.Ctx, m interfaces.ManifestHandler) error {
|
||||
)
|
||||
|
||||
if reader, contentType, re = m.Get(ctx.Request.Context(), repo, target); re != nil {
|
||||
if re.Status == 404 {
|
||||
log.Debug("handleManifest: repo not found, start pull, repo = %s, tag = %s", repo, target)
|
||||
var manifest *v1.Manifest
|
||||
if manifest, err = controller.PullRepo(ctx.Context(), repo, target, "", m, blobHandler); err != nil {
|
||||
return rerr.Error(ctx, &rerr.RepositoryError{
|
||||
Status: http.StatusInternalServerError,
|
||||
Code: "INTERNAL_SERVER_ERROR",
|
||||
Message: err.Error(),
|
||||
})
|
||||
}
|
||||
|
||||
contentType = string(manifest.MediaType)
|
||||
bs, _ = json.Marshal(manifest)
|
||||
goto RETURN_GET
|
||||
}
|
||||
|
||||
return rerr.Error(ctx, re)
|
||||
}
|
||||
|
||||
@ -49,6 +65,8 @@ func handleManifest(ctx *nf.Ctx, m interfaces.ManifestHandler) error {
|
||||
})
|
||||
}
|
||||
|
||||
RETURN_GET:
|
||||
|
||||
h, _, _ := model.SHA256(bytes.NewReader(bs))
|
||||
ctx.Set("Docker-Content-Digest", h.String())
|
||||
ctx.Set("Content-Type", contentType)
|
||||
@ -107,16 +125,8 @@ func handleManifest(ctx *nf.Ctx, m interfaces.ManifestHandler) error {
|
||||
ContentType: ctx.Get("Content-Type"),
|
||||
}
|
||||
|
||||
logrus.
|
||||
WithField("handler", "handleManifest").
|
||||
WithField("path", ctx.Path()).
|
||||
WithField("method", ctx.Method()).
|
||||
WithField("repo", repo).
|
||||
WithField("target", target).
|
||||
WithField("digest", digest).
|
||||
WithField("content-type", ctx.Get("Content-Type")).
|
||||
WithField("content", buf.String()).
|
||||
Debug()
|
||||
log.Debug("handleManifest: path = %s, method = %s, repo = %s, target = %s, digest = %s, content-type = %s, content = %s",
|
||||
ctx.Path(), ctx.Method(), repo, target, digest, ctx.Get("Content-Type"), buf.String())
|
||||
|
||||
if err := m.Put(ctx.Request.Context(), repo, target, digest, &mf); err != nil {
|
||||
return rerr.Error(ctx, err)
|
||||
|
@ -4,14 +4,16 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/loveuer/nf"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"nf-repo/internal/interfaces"
|
||||
"nf-repo/internal/model"
|
||||
"nf-repo/internal/model/types"
|
||||
"nf-repo/internal/util/rerr"
|
||||
"strings"
|
||||
"nf-repo/internal/tool/rerr"
|
||||
|
||||
"github.com/loveuer/nf"
|
||||
)
|
||||
|
||||
func handleReferrers(ctx *nf.Ctx, m interfaces.ManifestHandler) error {
|
||||
@ -51,7 +53,7 @@ func handleReferrers(ctx *nf.Ctx, m interfaces.ManifestHandler) error {
|
||||
ctx.Set("Content-Length", fmt.Sprint(len(msg)))
|
||||
ctx.Set("Content-Type", string(types.OCIImageIndex))
|
||||
ctx.Status(http.StatusOK)
|
||||
_, err = io.Copy(ctx.RawWriter(), bytes.NewReader(msg))
|
||||
_, err = io.Copy(ctx.Writer, bytes.NewReader(msg))
|
||||
|
||||
return err
|
||||
}
|
||||
|
@ -4,25 +4,28 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/google/go-containerregistry/pkg/name"
|
||||
"github.com/google/go-containerregistry/pkg/v1"
|
||||
"github.com/google/go-containerregistry/pkg/v1/remote"
|
||||
"github.com/loveuer/nf"
|
||||
"github.com/sirupsen/logrus"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"nf-repo/internal/interfaces"
|
||||
"nf-repo/internal/model"
|
||||
"nf-repo/internal/opt"
|
||||
"nf-repo/internal/util/r"
|
||||
"nf-repo/internal/util/rerr"
|
||||
"strings"
|
||||
"nf-repo/internal/tool/r"
|
||||
"nf-repo/internal/tool/rerr"
|
||||
|
||||
"github.com/google/go-containerregistry/pkg/name"
|
||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||
"github.com/google/go-containerregistry/pkg/v1/remote"
|
||||
"github.com/loveuer/nf"
|
||||
"github.com/loveuer/nf/nft/log"
|
||||
"github.com/loveuer/nf/nft/resp"
|
||||
)
|
||||
|
||||
func RepoSettings(c *nf.Ctx) error {
|
||||
return r.Resp200(c, nf.Map{
|
||||
"base_address": opt.BaseAddress,
|
||||
return resp.Resp200(c, nf.Map{
|
||||
"repo_name": opt.Cfg.RepoName,
|
||||
})
|
||||
}
|
||||
|
||||
@ -42,7 +45,7 @@ func RepoList(mh interfaces.ManifestHandler) nf.HandlerFunc {
|
||||
)
|
||||
|
||||
if err = c.QueryParser(req); err != nil {
|
||||
return r.Resp400(c, err.Error())
|
||||
return resp.Resp400(c, err.Error())
|
||||
}
|
||||
|
||||
if req.N == 0 {
|
||||
@ -50,14 +53,14 @@ func RepoList(mh interfaces.ManifestHandler) nf.HandlerFunc {
|
||||
}
|
||||
|
||||
if req.N > 1000 {
|
||||
return r.Resp400(c, "limit invalid: too big")
|
||||
return resp.Resp400(c, "limit invalid: too big")
|
||||
}
|
||||
|
||||
if catalog, re = mh.Catalog(c.Request.Context(), req.N, req.Last, req.Keyword); re != nil {
|
||||
return r.Resp(c, uint32(re.Status), "", re.Code, re.Message)
|
||||
return resp.Resp(c, uint32(re.Status), "", re.Code, re.Message)
|
||||
}
|
||||
|
||||
return r.Resp200(c, nf.Map{"list": catalog.Repos, "total": 0})
|
||||
return resp.Resp200(c, nf.Map{"list": catalog.Repos, "total": 0})
|
||||
}
|
||||
}
|
||||
|
||||
@ -127,7 +130,7 @@ func ProxyDownloadImage(mh interfaces.ManifestHandler, bh interfaces.BlobHandler
|
||||
manifest *v1.Manifest
|
||||
bs []byte
|
||||
mhash model.Hash
|
||||
//progressCh = make(chan v1.Update, 16)
|
||||
// progressCh = make(chan v1.Update, 16)
|
||||
)
|
||||
|
||||
if err = c.BodyParser(req); err != nil {
|
||||
@ -144,21 +147,18 @@ func ProxyDownloadImage(mh interfaces.ManifestHandler, bh interfaces.BlobHandler
|
||||
}
|
||||
|
||||
repo, tag := repoTags[0], repoTags[1]
|
||||
repo = strings.TrimPrefix(repo, opt.BaseAddress)
|
||||
repo = strings.TrimPrefix(repo, opt.Cfg.RepoName)
|
||||
repo = strings.Trim(repo, "/")
|
||||
|
||||
if req.Source == "" {
|
||||
return r.Resp400(c, "source invalid")
|
||||
}
|
||||
|
||||
imageName := fmt.Sprintf("%s/%s:%s", opt.BaseAddress, repo, tag)
|
||||
_ = imageName
|
||||
log.Debug("ProxyDownloadImage: req = %#v, repo = %s", *req, repo)
|
||||
|
||||
logrus.
|
||||
WithField("path", "handler.ProxyDownloadImage").
|
||||
WithField("req", *req).
|
||||
WithField("repo", repo).
|
||||
Debug()
|
||||
if opt.Proxy != nil {
|
||||
transport.Proxy = http.ProxyURL(opt.Proxy)
|
||||
}
|
||||
|
||||
if req.Proxy != "" {
|
||||
var pu *url.URL
|
||||
|
@ -1,11 +1,12 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"github.com/loveuer/nf"
|
||||
"github.com/sirupsen/logrus"
|
||||
"nf-repo/internal/interfaces"
|
||||
"nf-repo/internal/opt"
|
||||
"nf-repo/internal/util/rerr"
|
||||
"nf-repo/internal/tool/rerr"
|
||||
|
||||
"github.com/loveuer/nf"
|
||||
"github.com/loveuer/nf/nft/log"
|
||||
)
|
||||
|
||||
type blob struct {
|
||||
@ -13,9 +14,7 @@ type blob struct {
|
||||
uploadHandler interfaces.UploadHandler
|
||||
}
|
||||
|
||||
var (
|
||||
b = &blob{}
|
||||
)
|
||||
var b = &blob{}
|
||||
|
||||
func Root(bh interfaces.BlobHandler, uh interfaces.UploadHandler, mh interfaces.ManifestHandler) nf.HandlerFunc {
|
||||
b.blobHandler = bh
|
||||
@ -26,7 +25,7 @@ func Root(bh interfaces.BlobHandler, uh interfaces.UploadHandler, mh interfaces.
|
||||
}
|
||||
|
||||
if isManifest(c) {
|
||||
return handleManifest(c, mh)
|
||||
return handleManifest(c, mh, bh)
|
||||
}
|
||||
|
||||
if isTags(c) {
|
||||
@ -43,11 +42,7 @@ func Root(bh interfaces.BlobHandler, uh interfaces.UploadHandler, mh interfaces.
|
||||
|
||||
c.SetHeader("Docker-Distribution-API-Version", "registry/2.0")
|
||||
|
||||
logrus.
|
||||
WithField("path", c.Path()).
|
||||
WithField("method", c.Method()).
|
||||
WithField("headers", c.Request.Header).
|
||||
Warn()
|
||||
log.Warn("root.go Root: path = %s, method = %s, headers = %v", c.Path(), c.Method(), c.Request.Header)
|
||||
|
||||
return rerr.Error(c, rerr.ErrUnauthorized)
|
||||
}
|
||||
|
@ -1,12 +1,14 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"github.com/loveuer/nf"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"nf-repo/internal/interfaces"
|
||||
"nf-repo/internal/model"
|
||||
"nf-repo/internal/util/rerr"
|
||||
"strings"
|
||||
"nf-repo/internal/tool/rerr"
|
||||
|
||||
"github.com/loveuer/nf"
|
||||
)
|
||||
|
||||
func handleTags(ctx *nf.Ctx, m interfaces.ManifestHandler) error {
|
||||
|
Reference in New Issue
Block a user