0
Fork 0
mirror of https://github.com/project-zot/zot.git synced 2025-03-25 02:32:57 -05:00

routes: lock everything that modifies blobs

Now that we're GCing blobs on delete/update manifest, we should lock the
blob queries so that they don't race with each other.

This is a pretty coarse grained lock, there's probably a better way to do
this.

Signed-off-by: Tycho Andersen <tycho@tycho.ws>
This commit is contained in:
Tycho Andersen 2020-03-05 17:46:19 -07:00 committed by Ramkumar Chinchani
parent 95d4a7ce04
commit 94afc30661

View file

@ -20,6 +20,7 @@ import (
"sort"
"strconv"
"strings"
"sync"
_ "github.com/anuvu/zot/docs" // nolint (golint) - as required by swaggo
"github.com/anuvu/zot/errors"
@ -40,16 +41,25 @@ const (
)
type RouteHandler struct {
c *Controller
c *Controller
blobLock sync.Mutex
}
func NewRouteHandler(c *Controller) *RouteHandler {
rh := &RouteHandler{c: c}
rh := &RouteHandler{c: c, blobLock: sync.Mutex{}}
rh.SetupRoutes()
return rh
}
func (rh *RouteHandler) blobLockWrapper(f func (w http.ResponseWriter, r *http.Request)) func (w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
rh.blobLock.Lock()
f(w, r)
rh.blobLock.Unlock()
}
}
func (rh *RouteHandler) SetupRoutes() {
rh.c.Router.Use(AuthHandler(rh.c))
g := rh.c.Router.PathPrefix(RoutePrefix).Subrouter()
@ -61,25 +71,25 @@ func (rh *RouteHandler) SetupRoutes() {
g.HandleFunc(fmt.Sprintf("/{name:%s}/manifests/{reference}", NameRegexp.String()),
rh.GetManifest).Methods("GET")
g.HandleFunc(fmt.Sprintf("/{name:%s}/manifests/{reference}", NameRegexp.String()),
rh.UpdateManifest).Methods("PUT")
rh.blobLockWrapper(rh.UpdateManifest)).Methods("PUT")
g.HandleFunc(fmt.Sprintf("/{name:%s}/manifests/{reference}", NameRegexp.String()),
rh.DeleteManifest).Methods("DELETE")
rh.blobLockWrapper(rh.DeleteManifest)).Methods("DELETE")
g.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/{digest}", NameRegexp.String()),
rh.CheckBlob).Methods("HEAD")
g.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/{digest}", NameRegexp.String()),
rh.GetBlob).Methods("GET")
g.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/{digest}", NameRegexp.String()),
rh.DeleteBlob).Methods("DELETE")
rh.blobLockWrapper(rh.DeleteBlob)).Methods("DELETE")
g.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/uploads/", NameRegexp.String()),
rh.CreateBlobUpload).Methods("POST")
rh.blobLockWrapper(rh.CreateBlobUpload)).Methods("POST")
g.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/uploads/{session_id}", NameRegexp.String()),
rh.GetBlobUpload).Methods("GET")
g.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/uploads/{session_id}", NameRegexp.String()),
rh.PatchBlobUpload).Methods("PATCH")
rh.blobLockWrapper(rh.PatchBlobUpload)).Methods("PATCH")
g.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/uploads/{session_id}", NameRegexp.String()),
rh.UpdateBlobUpload).Methods("PUT")
rh.blobLockWrapper(rh.UpdateBlobUpload)).Methods("PUT")
g.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/uploads/{session_id}", NameRegexp.String()),
rh.DeleteBlobUpload).Methods("DELETE")
rh.blobLockWrapper(rh.DeleteBlobUpload)).Methods("DELETE")
g.HandleFunc("/_catalog",
rh.ListRepositories).Methods("GET")
g.HandleFunc("/",