mirror of
https://github.com/project-zot/zot.git
synced 2026-06-16 04:17:55 +08:00
Fixing all the issues with upgrading to golangci-lint 1.21.0
This commit is contained in:
@@ -5,6 +5,7 @@ run:
|
|||||||
|
|
||||||
linters:
|
linters:
|
||||||
enable-all: true
|
enable-all: true
|
||||||
|
disable: funlen,godox,gocognit
|
||||||
|
|
||||||
output:
|
output:
|
||||||
format: colored-line-number
|
format: colored-line-number
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ test:
|
|||||||
|
|
||||||
.PHONY: check
|
.PHONY: check
|
||||||
check: .bazel/golangcilint.yaml
|
check: .bazel/golangcilint.yaml
|
||||||
golangci-lint --version || curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s v1.17.1
|
golangci-lint --version || curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s v1.21.0
|
||||||
golangci-lint --config .bazel/golangcilint.yaml run --enable-all ./cmd/... ./pkg/...
|
golangci-lint --config .bazel/golangcilint.yaml run --enable-all ./cmd/... ./pkg/...
|
||||||
|
|
||||||
docs/docs.go:
|
docs/docs.go:
|
||||||
swag -v || go install github.com/swaggo/swag/cmd/swag
|
swag -v || go install github.com/swaggo/swag/cmd/swag
|
||||||
|
|||||||
@@ -82,13 +82,18 @@ func (c *Config) Sanitize() *Config {
|
|||||||
if err := deepcopy.Copy(s, c); err != nil {
|
if err := deepcopy.Copy(s, c); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
s.HTTP.Auth.LDAP = &LDAPConfig{}
|
s.HTTP.Auth.LDAP = &LDAPConfig{}
|
||||||
|
|
||||||
if err := deepcopy.Copy(s.HTTP.Auth.LDAP, c.HTTP.Auth.LDAP); err != nil {
|
if err := deepcopy.Copy(s.HTTP.Auth.LDAP, c.HTTP.Auth.LDAP); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
s.HTTP.Auth.LDAP.BindPassword = "******"
|
s.HTTP.Auth.LDAP.BindPassword = "******"
|
||||||
|
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,5 +106,6 @@ func (c *Config) Validate(log log.Logger) error {
|
|||||||
return errors.ErrLDAPConfig
|
return errors.ErrLDAPConfig
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ func (c *Controller) Run() error {
|
|||||||
engine := mux.NewRouter()
|
engine := mux.NewRouter()
|
||||||
engine.Use(log.SessionLogger(c.Log), handlers.RecoveryHandler(handlers.RecoveryLogger(c.Log),
|
engine.Use(log.SessionLogger(c.Log), handlers.RecoveryHandler(handlers.RecoveryLogger(c.Log),
|
||||||
handlers.PrintRecoveryStack(false)))
|
handlers.PrintRecoveryStack(false)))
|
||||||
|
|
||||||
c.Router = engine
|
c.Router = engine
|
||||||
_ = NewRouteHandler(c)
|
_ = NewRouteHandler(c)
|
||||||
|
|
||||||
@@ -66,10 +67,13 @@ func (c *Controller) Run() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
caCertPool := x509.NewCertPool()
|
caCertPool := x509.NewCertPool()
|
||||||
|
|
||||||
if !caCertPool.AppendCertsFromPEM(caCert) {
|
if !caCertPool.AppendCertsFromPEM(caCert) {
|
||||||
panic(errors.ErrBadCACert)
|
panic(errors.ErrBadCACert)
|
||||||
}
|
}
|
||||||
|
|
||||||
server.TLSConfig = &tls.Config{
|
server.TLSConfig = &tls.Config{
|
||||||
ClientAuth: clientAuth,
|
ClientAuth: clientAuth,
|
||||||
ClientCAs: caCertPool,
|
ClientCAs: caCertPool,
|
||||||
@@ -81,5 +85,6 @@ func (c *Controller) Run() error {
|
|||||||
|
|
||||||
return server.ServeTLS(l, c.Config.HTTP.TLS.Cert, c.Config.HTTP.TLS.Key)
|
return server.ServeTLS(l, c.Config.HTTP.TLS.Cert, c.Config.HTTP.TLS.Key)
|
||||||
}
|
}
|
||||||
|
|
||||||
return server.Serve(l)
|
return server.Serve(l)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -637,21 +637,25 @@ func newTestLDAPServer() *testLDAPServer {
|
|||||||
server.SearchFunc("", l)
|
server.SearchFunc("", l)
|
||||||
l.server = server
|
l.server = server
|
||||||
l.quitCh = quitCh
|
l.quitCh = quitCh
|
||||||
|
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *testLDAPServer) Start() {
|
func (l *testLDAPServer) Start() {
|
||||||
addr := fmt.Sprintf("%s:%d", LDAPAddress, LDAPPort)
|
addr := fmt.Sprintf("%s:%d", LDAPAddress, LDAPPort)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
if err := l.server.ListenAndServe(addr); err != nil {
|
if err := l.server.ListenAndServe(addr); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
_, err := net.Dial("tcp", addr)
|
_, err := net.Dial("tcp", addr)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
time.Sleep(10 * time.Millisecond)
|
time.Sleep(10 * time.Millisecond)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -664,10 +668,12 @@ func (l *testLDAPServer) Bind(bindDN, bindSimplePw string, conn net.Conn) (vldap
|
|||||||
if bindDN == "" || bindSimplePw == "" {
|
if bindDN == "" || bindSimplePw == "" {
|
||||||
return vldap.LDAPResultInappropriateAuthentication, errors.New("ldap: bind creds required")
|
return vldap.LDAPResultInappropriateAuthentication, errors.New("ldap: bind creds required")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bindDN == LDAPBindDN && bindSimplePw == LDAPBindPassword) ||
|
if (bindDN == LDAPBindDN && bindSimplePw == LDAPBindPassword) ||
|
||||||
(bindDN == fmt.Sprintf("cn=%s,%s", username, LDAPBaseDN) && bindSimplePw == passphrase) {
|
(bindDN == fmt.Sprintf("cn=%s,%s", username, LDAPBaseDN) && bindSimplePw == passphrase) {
|
||||||
return vldap.LDAPResultSuccess, nil
|
return vldap.LDAPResultSuccess, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return vldap.LDAPResultInvalidCredentials, errors.New("ldap: invalid credentials")
|
return vldap.LDAPResultInvalidCredentials, errors.New("ldap: invalid credentials")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -682,6 +688,7 @@ func (l *testLDAPServer) Search(boundDN string, req vldap.SearchRequest,
|
|||||||
ResultCode: vldap.LDAPResultSuccess,
|
ResultCode: vldap.LDAPResultSuccess,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return vldap.ServerSearchResult{}, nil
|
return vldap.ServerSearchResult{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -35,7 +35,6 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewError(code ErrorCode, detail ...interface{}) Error {
|
func NewError(code ErrorCode, detail ...interface{}) Error {
|
||||||
|
|
||||||
var errMap = map[ErrorCode]Error{
|
var errMap = map[ErrorCode]Error{
|
||||||
BLOB_UNKNOWN: {
|
BLOB_UNKNOWN: {
|
||||||
Message: "blob unknown to registry",
|
Message: "blob unknown to registry",
|
||||||
@@ -138,5 +137,6 @@ func NewError(code ErrorCode, detail ...interface{}) Error {
|
|||||||
|
|
||||||
e.Code = code
|
e.Code = code
|
||||||
e.Detail = detail
|
e.Detail = detail
|
||||||
|
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,8 +40,11 @@ type LDAPClient struct {
|
|||||||
func (lc *LDAPClient) Connect() error {
|
func (lc *LDAPClient) Connect() error {
|
||||||
if lc.Conn == nil {
|
if lc.Conn == nil {
|
||||||
var l *goldap.Conn
|
var l *goldap.Conn
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
address := fmt.Sprintf("%s:%d", lc.Host, lc.Port)
|
address := fmt.Sprintf("%s:%d", lc.Host, lc.Port)
|
||||||
|
|
||||||
if !lc.UseSSL {
|
if !lc.UseSSL {
|
||||||
l, err = goldap.Dial("tcp", address)
|
l, err = goldap.Dial("tcp", address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -59,7 +62,9 @@ func (lc *LDAPClient) Connect() error {
|
|||||||
config.Certificates = lc.ClientCertificates
|
config.Certificates = lc.ClientCertificates
|
||||||
config.BuildNameToCertificate()
|
config.BuildNameToCertificate()
|
||||||
}
|
}
|
||||||
|
|
||||||
err = l.StartTLS(config)
|
err = l.StartTLS(config)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
lc.Log.Error().Err(err).Str("address", address).Msg("TLS connection failed")
|
lc.Log.Error().Err(err).Str("address", address).Msg("TLS connection failed")
|
||||||
return err
|
return err
|
||||||
@@ -84,6 +89,7 @@ func (lc *LDAPClient) Connect() error {
|
|||||||
|
|
||||||
lc.Conn = l
|
lc.Conn = l
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,10 +107,12 @@ func sleepAndRetry(retries, maxRetries int) bool {
|
|||||||
if retries > maxRetries {
|
if retries > maxRetries {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if retries < maxRetries {
|
if retries < maxRetries {
|
||||||
time.Sleep(time.Duration(retries) * time.Second) // gradually backoff
|
time.Sleep(time.Duration(retries) * time.Second) // gradually backoff
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,9 +138,11 @@ func (lc *LDAPClient) Authenticate(username, password string) (bool, map[string]
|
|||||||
// clean up the cached conn, so we can retry
|
// clean up the cached conn, so we can retry
|
||||||
lc.Conn.Close()
|
lc.Conn.Close()
|
||||||
lc.Conn = nil
|
lc.Conn = nil
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
connected = true
|
connected = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,6 +154,7 @@ func (lc *LDAPClient) Authenticate(username, password string) (bool, map[string]
|
|||||||
|
|
||||||
attributes := append(lc.Attributes, "dn")
|
attributes := append(lc.Attributes, "dn")
|
||||||
searchScope := goldap.ScopeSingleLevel
|
searchScope := goldap.ScopeSingleLevel
|
||||||
|
|
||||||
if lc.SubtreeSearch {
|
if lc.SubtreeSearch {
|
||||||
searchScope = goldap.ScopeWholeSubtree
|
searchScope = goldap.ScopeWholeSubtree
|
||||||
}
|
}
|
||||||
@@ -161,6 +172,7 @@ func (lc *LDAPClient) Authenticate(username, password string) (bool, map[string]
|
|||||||
fmt.Printf("%v\n", err)
|
fmt.Printf("%v\n", err)
|
||||||
lc.Log.Error().Err(err).Str("bindDN", lc.BindDN).Str("username", username).
|
lc.Log.Error().Err(err).Str("bindDN", lc.BindDN).Str("username", username).
|
||||||
Str("baseDN", lc.Base).Msg("search failed")
|
Str("baseDN", lc.Base).Msg("search failed")
|
||||||
|
|
||||||
return false, nil, err
|
return false, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,6 +180,7 @@ func (lc *LDAPClient) Authenticate(username, password string) (bool, map[string]
|
|||||||
err := errors.ErrBadUser
|
err := errors.ErrBadUser
|
||||||
lc.Log.Error().Err(err).Str("bindDN", lc.BindDN).Str("username", username).
|
lc.Log.Error().Err(err).Str("bindDN", lc.BindDN).Str("username", username).
|
||||||
Str("baseDN", lc.Base).Msg("entries not found")
|
Str("baseDN", lc.Base).Msg("entries not found")
|
||||||
|
|
||||||
return false, nil, err
|
return false, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,11 +188,13 @@ func (lc *LDAPClient) Authenticate(username, password string) (bool, map[string]
|
|||||||
err := errors.ErrEntriesExceeded
|
err := errors.ErrEntriesExceeded
|
||||||
lc.Log.Error().Err(err).Str("bindDN", lc.BindDN).Str("username", username).
|
lc.Log.Error().Err(err).Str("bindDN", lc.BindDN).Str("username", username).
|
||||||
Str("baseDN", lc.Base).Msg("too many entries")
|
Str("baseDN", lc.Base).Msg("too many entries")
|
||||||
|
|
||||||
return false, nil, err
|
return false, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
userDN := sr.Entries[0].DN
|
userDN := sr.Entries[0].DN
|
||||||
user := map[string]string{}
|
user := map[string]string{}
|
||||||
|
|
||||||
for _, attr := range lc.Attributes {
|
for _, attr := range lc.Attributes {
|
||||||
user[attr] = sr.Entries[0].GetAttributeValue(attr)
|
user[attr] = sr.Entries[0].GetAttributeValue(attr)
|
||||||
}
|
}
|
||||||
@@ -217,12 +232,16 @@ func (lc *LDAPClient) GetGroupsOfUser(username string) ([]string, error) {
|
|||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
sr, err := lc.Conn.Search(searchRequest)
|
sr, err := lc.Conn.Search(searchRequest)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
groups := []string{}
|
groups := []string{}
|
||||||
|
|
||||||
for _, entry := range sr.Entries {
|
for _, entry := range sr.Entries {
|
||||||
groups = append(groups, entry.GetAttributeValue("cn"))
|
groups = append(groups, entry.GetAttributeValue("cn"))
|
||||||
}
|
}
|
||||||
|
|
||||||
return groups, nil
|
return groups, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ type RouteHandler struct {
|
|||||||
func NewRouteHandler(c *Controller) *RouteHandler {
|
func NewRouteHandler(c *Controller) *RouteHandler {
|
||||||
rh := &RouteHandler{c: c}
|
rh := &RouteHandler{c: c}
|
||||||
rh.SetupRoutes()
|
rh.SetupRoutes()
|
||||||
|
|
||||||
return rh
|
return rh
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,6 +117,7 @@ type ImageTags struct {
|
|||||||
func (rh *RouteHandler) ListTags(w http.ResponseWriter, r *http.Request) {
|
func (rh *RouteHandler) ListTags(w http.ResponseWriter, r *http.Request) {
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
name, ok := vars["name"]
|
name, ok := vars["name"]
|
||||||
|
|
||||||
if !ok || name == "" {
|
if !ok || name == "" {
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
return
|
return
|
||||||
@@ -145,6 +147,7 @@ func (rh *RouteHandler) ListTags(w http.ResponseWriter, r *http.Request) {
|
|||||||
func (rh *RouteHandler) CheckManifest(w http.ResponseWriter, r *http.Request) {
|
func (rh *RouteHandler) CheckManifest(w http.ResponseWriter, r *http.Request) {
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
name, ok := vars["name"]
|
name, ok := vars["name"]
|
||||||
|
|
||||||
if !ok || name == "" {
|
if !ok || name == "" {
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
return
|
return
|
||||||
@@ -165,6 +168,7 @@ func (rh *RouteHandler) CheckManifest(w http.ResponseWriter, r *http.Request) {
|
|||||||
rh.c.Log.Error().Err(err).Msg("unexpected error")
|
rh.c.Log.Error().Err(err).Msg("unexpected error")
|
||||||
WriteJSON(w, http.StatusInternalServerError, NewError(MANIFEST_INVALID, map[string]string{"reference": reference}))
|
WriteJSON(w, http.StatusInternalServerError, NewError(MANIFEST_INVALID, map[string]string{"reference": reference}))
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,6 +197,7 @@ type ImageManifest struct {
|
|||||||
func (rh *RouteHandler) GetManifest(w http.ResponseWriter, r *http.Request) {
|
func (rh *RouteHandler) GetManifest(w http.ResponseWriter, r *http.Request) {
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
name, ok := vars["name"]
|
name, ok := vars["name"]
|
||||||
|
|
||||||
if !ok || name == "" {
|
if !ok || name == "" {
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
return
|
return
|
||||||
@@ -217,6 +222,7 @@ func (rh *RouteHandler) GetManifest(w http.ResponseWriter, r *http.Request) {
|
|||||||
rh.c.Log.Error().Err(err).Msg("unexpected error")
|
rh.c.Log.Error().Err(err).Msg("unexpected error")
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,6 +246,7 @@ func (rh *RouteHandler) GetManifest(w http.ResponseWriter, r *http.Request) {
|
|||||||
func (rh *RouteHandler) UpdateManifest(w http.ResponseWriter, r *http.Request) {
|
func (rh *RouteHandler) UpdateManifest(w http.ResponseWriter, r *http.Request) {
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
name, ok := vars["name"]
|
name, ok := vars["name"]
|
||||||
|
|
||||||
if !ok || name == "" {
|
if !ok || name == "" {
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
return
|
return
|
||||||
@@ -278,6 +285,7 @@ func (rh *RouteHandler) UpdateManifest(w http.ResponseWriter, r *http.Request) {
|
|||||||
rh.c.Log.Error().Err(err).Msg("unexpected error")
|
rh.c.Log.Error().Err(err).Msg("unexpected error")
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,6 +306,7 @@ func (rh *RouteHandler) UpdateManifest(w http.ResponseWriter, r *http.Request) {
|
|||||||
func (rh *RouteHandler) DeleteManifest(w http.ResponseWriter, r *http.Request) {
|
func (rh *RouteHandler) DeleteManifest(w http.ResponseWriter, r *http.Request) {
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
name, ok := vars["name"]
|
name, ok := vars["name"]
|
||||||
|
|
||||||
if !ok || name == "" {
|
if !ok || name == "" {
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
return
|
return
|
||||||
@@ -320,6 +329,7 @@ func (rh *RouteHandler) DeleteManifest(w http.ResponseWriter, r *http.Request) {
|
|||||||
rh.c.Log.Error().Err(err).Msg("unexpected error")
|
rh.c.Log.Error().Err(err).Msg("unexpected error")
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -339,6 +349,7 @@ func (rh *RouteHandler) DeleteManifest(w http.ResponseWriter, r *http.Request) {
|
|||||||
func (rh *RouteHandler) CheckBlob(w http.ResponseWriter, r *http.Request) {
|
func (rh *RouteHandler) CheckBlob(w http.ResponseWriter, r *http.Request) {
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
name, ok := vars["name"]
|
name, ok := vars["name"]
|
||||||
|
|
||||||
if !ok || name == "" {
|
if !ok || name == "" {
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
return
|
return
|
||||||
@@ -365,6 +376,7 @@ func (rh *RouteHandler) CheckBlob(w http.ResponseWriter, r *http.Request) {
|
|||||||
rh.c.Log.Error().Err(err).Msg("unexpected error")
|
rh.c.Log.Error().Err(err).Msg("unexpected error")
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -391,6 +403,7 @@ func (rh *RouteHandler) CheckBlob(w http.ResponseWriter, r *http.Request) {
|
|||||||
func (rh *RouteHandler) GetBlob(w http.ResponseWriter, r *http.Request) {
|
func (rh *RouteHandler) GetBlob(w http.ResponseWriter, r *http.Request) {
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
name, ok := vars["name"]
|
name, ok := vars["name"]
|
||||||
|
|
||||||
if !ok || name == "" {
|
if !ok || name == "" {
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
return
|
return
|
||||||
@@ -417,6 +430,7 @@ func (rh *RouteHandler) GetBlob(w http.ResponseWriter, r *http.Request) {
|
|||||||
rh.c.Log.Error().Err(err).Msg("unexpected error")
|
rh.c.Log.Error().Err(err).Msg("unexpected error")
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -438,6 +452,7 @@ func (rh *RouteHandler) GetBlob(w http.ResponseWriter, r *http.Request) {
|
|||||||
func (rh *RouteHandler) DeleteBlob(w http.ResponseWriter, r *http.Request) {
|
func (rh *RouteHandler) DeleteBlob(w http.ResponseWriter, r *http.Request) {
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
name, ok := vars["name"]
|
name, ok := vars["name"]
|
||||||
|
|
||||||
if !ok || name == "" {
|
if !ok || name == "" {
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
return
|
return
|
||||||
@@ -462,6 +477,7 @@ func (rh *RouteHandler) DeleteBlob(w http.ResponseWriter, r *http.Request) {
|
|||||||
rh.c.Log.Error().Err(err).Msg("unexpected error")
|
rh.c.Log.Error().Err(err).Msg("unexpected error")
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -483,6 +499,7 @@ func (rh *RouteHandler) DeleteBlob(w http.ResponseWriter, r *http.Request) {
|
|||||||
func (rh *RouteHandler) CreateBlobUpload(w http.ResponseWriter, r *http.Request) {
|
func (rh *RouteHandler) CreateBlobUpload(w http.ResponseWriter, r *http.Request) {
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
name, ok := vars["name"]
|
name, ok := vars["name"]
|
||||||
|
|
||||||
if !ok || name == "" {
|
if !ok || name == "" {
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
return
|
return
|
||||||
@@ -497,6 +514,7 @@ func (rh *RouteHandler) CreateBlobUpload(w http.ResponseWriter, r *http.Request)
|
|||||||
rh.c.Log.Error().Err(err).Msg("unexpected error")
|
rh.c.Log.Error().Err(err).Msg("unexpected error")
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -521,6 +539,7 @@ func (rh *RouteHandler) CreateBlobUpload(w http.ResponseWriter, r *http.Request)
|
|||||||
func (rh *RouteHandler) GetBlobUpload(w http.ResponseWriter, r *http.Request) {
|
func (rh *RouteHandler) GetBlobUpload(w http.ResponseWriter, r *http.Request) {
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
name, ok := vars["name"]
|
name, ok := vars["name"]
|
||||||
|
|
||||||
if !ok || name == "" {
|
if !ok || name == "" {
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
return
|
return
|
||||||
@@ -547,6 +566,7 @@ func (rh *RouteHandler) GetBlobUpload(w http.ResponseWriter, r *http.Request) {
|
|||||||
rh.c.Log.Error().Err(err).Msg("unexpected error")
|
rh.c.Log.Error().Err(err).Msg("unexpected error")
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -575,10 +595,12 @@ func (rh *RouteHandler) PatchBlobUpload(w http.ResponseWriter, r *http.Request)
|
|||||||
rh.c.Log.Info().Interface("headers", r.Header).Msg("request headers")
|
rh.c.Log.Info().Interface("headers", r.Header).Msg("request headers")
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
name, ok := vars["name"]
|
name, ok := vars["name"]
|
||||||
|
|
||||||
if !ok || name == "" {
|
if !ok || name == "" {
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
uuid, ok := vars["uuid"]
|
uuid, ok := vars["uuid"]
|
||||||
if !ok || uuid == "" {
|
if !ok || uuid == "" {
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
@@ -586,10 +608,13 @@ func (rh *RouteHandler) PatchBlobUpload(w http.ResponseWriter, r *http.Request)
|
|||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
var contentLength int64
|
var contentLength int64
|
||||||
|
|
||||||
if contentLength, err = strconv.ParseInt(r.Header.Get("Content-Length"), 10, 64); err != nil {
|
if contentLength, err = strconv.ParseInt(r.Header.Get("Content-Length"), 10, 64); err != nil {
|
||||||
rh.c.Log.Warn().Str("actual", r.Header.Get("Content-Length")).Msg("invalid content length")
|
rh.c.Log.Warn().Str("actual", r.Header.Get("Content-Length")).Msg("invalid content length")
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -597,6 +622,7 @@ func (rh *RouteHandler) PatchBlobUpload(w http.ResponseWriter, r *http.Request)
|
|||||||
if contentRange == "" {
|
if contentRange == "" {
|
||||||
rh.c.Log.Warn().Str("actual", r.Header.Get("Content-Range")).Msg("invalid content range")
|
rh.c.Log.Warn().Str("actual", r.Header.Get("Content-Range")).Msg("invalid content range")
|
||||||
w.WriteHeader(http.StatusRequestedRangeNotSatisfiable)
|
w.WriteHeader(http.StatusRequestedRangeNotSatisfiable)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -609,6 +635,7 @@ func (rh *RouteHandler) PatchBlobUpload(w http.ResponseWriter, r *http.Request)
|
|||||||
if contentType := r.Header.Get("Content-Type"); contentType != "application/octet-stream" {
|
if contentType := r.Header.Get("Content-Type"); contentType != "application/octet-stream" {
|
||||||
rh.c.Log.Warn().Str("actual", contentType).Str("expected", "application/octet-stream").Msg("invalid media type")
|
rh.c.Log.Warn().Str("actual", contentType).Str("expected", "application/octet-stream").Msg("invalid media type")
|
||||||
w.WriteHeader(http.StatusUnsupportedMediaType)
|
w.WriteHeader(http.StatusUnsupportedMediaType)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -625,6 +652,7 @@ func (rh *RouteHandler) PatchBlobUpload(w http.ResponseWriter, r *http.Request)
|
|||||||
rh.c.Log.Error().Err(err).Msg("unexpected error")
|
rh.c.Log.Error().Err(err).Msg("unexpected error")
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -652,6 +680,7 @@ func (rh *RouteHandler) PatchBlobUpload(w http.ResponseWriter, r *http.Request)
|
|||||||
func (rh *RouteHandler) UpdateBlobUpload(w http.ResponseWriter, r *http.Request) {
|
func (rh *RouteHandler) UpdateBlobUpload(w http.ResponseWriter, r *http.Request) {
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
name, ok := vars["name"]
|
name, ok := vars["name"]
|
||||||
|
|
||||||
if !ok || name == "" {
|
if !ok || name == "" {
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
return
|
return
|
||||||
@@ -668,14 +697,18 @@ func (rh *RouteHandler) UpdateBlobUpload(w http.ResponseWriter, r *http.Request)
|
|||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
digest := digests[0]
|
digest := digests[0]
|
||||||
|
|
||||||
contentPresent := true
|
contentPresent := true
|
||||||
contentLen, err := strconv.ParseInt(r.Header.Get("Content-Length"), 10, 64)
|
contentLen, err := strconv.ParseInt(r.Header.Get("Content-Length"), 10, 64)
|
||||||
|
|
||||||
if err != nil || contentLen == 0 {
|
if err != nil || contentLen == 0 {
|
||||||
contentPresent = false
|
contentPresent = false
|
||||||
}
|
}
|
||||||
|
|
||||||
contentRangePresent := true
|
contentRangePresent := true
|
||||||
|
|
||||||
if r.Header.Get("Content-Range") == "" {
|
if r.Header.Get("Content-Range") == "" {
|
||||||
contentRangePresent = false
|
contentRangePresent = false
|
||||||
}
|
}
|
||||||
@@ -698,10 +731,12 @@ func (rh *RouteHandler) UpdateBlobUpload(w http.ResponseWriter, r *http.Request)
|
|||||||
contentRange := r.Header.Get("Content-Range")
|
contentRange := r.Header.Get("Content-Range")
|
||||||
if contentRange == "" { // monolithic upload
|
if contentRange == "" { // monolithic upload
|
||||||
from = 0
|
from = 0
|
||||||
|
|
||||||
if contentLen == 0 {
|
if contentLen == 0 {
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
to = contentLen
|
to = contentLen
|
||||||
} else if from, to, err = getContentRange(r); err != nil { // finish chunked upload
|
} else if from, to, err = getContentRange(r); err != nil { // finish chunked upload
|
||||||
w.WriteHeader(http.StatusRequestedRangeNotSatisfiable)
|
w.WriteHeader(http.StatusRequestedRangeNotSatisfiable)
|
||||||
@@ -721,6 +756,7 @@ func (rh *RouteHandler) UpdateBlobUpload(w http.ResponseWriter, r *http.Request)
|
|||||||
rh.c.Log.Error().Err(err).Msg("unexpected error")
|
rh.c.Log.Error().Err(err).Msg("unexpected error")
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -740,6 +776,7 @@ func (rh *RouteHandler) UpdateBlobUpload(w http.ResponseWriter, r *http.Request)
|
|||||||
rh.c.Log.Error().Err(err).Msg("unexpected error")
|
rh.c.Log.Error().Err(err).Msg("unexpected error")
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -763,6 +800,7 @@ func (rh *RouteHandler) UpdateBlobUpload(w http.ResponseWriter, r *http.Request)
|
|||||||
func (rh *RouteHandler) DeleteBlobUpload(w http.ResponseWriter, r *http.Request) {
|
func (rh *RouteHandler) DeleteBlobUpload(w http.ResponseWriter, r *http.Request) {
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
name, ok := vars["name"]
|
name, ok := vars["name"]
|
||||||
|
|
||||||
if !ok || name == "" {
|
if !ok || name == "" {
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
return
|
return
|
||||||
@@ -784,6 +822,7 @@ func (rh *RouteHandler) DeleteBlobUpload(w http.ResponseWriter, r *http.Request)
|
|||||||
rh.c.Log.Error().Err(err).Msg("unexpected error")
|
rh.c.Log.Error().Err(err).Msg("unexpected error")
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -820,25 +859,31 @@ func getContentRange(r *http.Request) (int64 /* from */, int64 /* to */, error)
|
|||||||
contentRange := r.Header.Get("Content-Range")
|
contentRange := r.Header.Get("Content-Range")
|
||||||
tokens := strings.Split(contentRange, "-")
|
tokens := strings.Split(contentRange, "-")
|
||||||
from, err := strconv.ParseInt(tokens[0], 10, 64)
|
from, err := strconv.ParseInt(tokens[0], 10, 64)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, -1, errors.ErrBadUploadRange
|
return -1, -1, errors.ErrBadUploadRange
|
||||||
}
|
}
|
||||||
|
|
||||||
to, err := strconv.ParseInt(tokens[1], 10, 64)
|
to, err := strconv.ParseInt(tokens[1], 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, -1, errors.ErrBadUploadRange
|
return -1, -1, errors.ErrBadUploadRange
|
||||||
}
|
}
|
||||||
|
|
||||||
if from > to {
|
if from > to {
|
||||||
return -1, -1, errors.ErrBadUploadRange
|
return -1, -1, errors.ErrBadUploadRange
|
||||||
}
|
}
|
||||||
|
|
||||||
return from, to, nil
|
return from, to, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func WriteJSON(w http.ResponseWriter, status int, data interface{}) {
|
func WriteJSON(w http.ResponseWriter, status int, data interface{}) {
|
||||||
var json = jsoniter.ConfigCompatibleWithStandardLibrary
|
var json = jsoniter.ConfigCompatibleWithStandardLibrary
|
||||||
body, err := json.Marshal(data)
|
body, err := json.Marshal(data)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteData(w, status, DefaultMediaType, body)
|
WriteData(w, status, DefaultMediaType, body)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -853,6 +898,7 @@ func WriteDataFromReader(w http.ResponseWriter, status int, length int64, mediaT
|
|||||||
w.Header().Set("Content-Length", strconv.FormatInt(length, 10))
|
w.Header().Set("Content-Length", strconv.FormatInt(length, 10))
|
||||||
|
|
||||||
const maxSize = 10 * 1024 * 1024
|
const maxSize = 10 * 1024 * 1024
|
||||||
|
|
||||||
for {
|
for {
|
||||||
size, err := io.CopyN(w, reader, maxSize)
|
size, err := io.CopyN(w, reader, maxSize)
|
||||||
if size == 0 {
|
if size == 0 {
|
||||||
@@ -860,6 +906,7 @@ func WriteDataFromReader(w http.ResponseWriter, status int, length int64, mediaT
|
|||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ func NewRootCmd() *cobra.Command {
|
|||||||
|
|
||||||
gcCmd.Flags().StringVarP(&config.Storage.RootDirectory, "storage-root-dir", "r", "",
|
gcCmd.Flags().StringVarP(&config.Storage.RootDirectory, "storage-root-dir", "r", "",
|
||||||
"Use specified directory for filestore backing image data")
|
"Use specified directory for filestore backing image data")
|
||||||
|
|
||||||
_ = gcCmd.MarkFlagRequired("storage-root-dir")
|
_ = gcCmd.MarkFlagRequired("storage-root-dir")
|
||||||
gcCmd.Flags().BoolVarP(&gcDelUntagged, "delete-untagged", "m", false,
|
gcCmd.Flags().BoolVarP(&gcDelUntagged, "delete-untagged", "m", false,
|
||||||
"delete manifests that are not currently referenced via tag")
|
"delete manifests that are not currently referenced via tag")
|
||||||
@@ -106,14 +107,18 @@ func NewRootCmd() *cobra.Command {
|
|||||||
|
|
||||||
complianceCmd.Flags().StringVarP(&complianceConfig.Address, "address", "H", "",
|
complianceCmd.Flags().StringVarP(&complianceConfig.Address, "address", "H", "",
|
||||||
"Registry server address")
|
"Registry server address")
|
||||||
|
|
||||||
if err := complianceCmd.MarkFlagRequired("address"); err != nil {
|
if err := complianceCmd.MarkFlagRequired("address"); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
complianceCmd.Flags().StringVarP(&complianceConfig.Port, "port", "P", "",
|
complianceCmd.Flags().StringVarP(&complianceConfig.Port, "port", "P", "",
|
||||||
"Registry server port")
|
"Registry server port")
|
||||||
|
|
||||||
if err := complianceCmd.MarkFlagRequired("port"); err != nil {
|
if err := complianceCmd.MarkFlagRequired("port"); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
complianceCmd.Flags().StringVarP(&complianceConfig.Version, "version", "V", "all",
|
complianceCmd.Flags().StringVarP(&complianceConfig.Version, "version", "V", "all",
|
||||||
"OCI dist-spec version to check")
|
"OCI dist-spec version to check")
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
|
|
||||||
func TestUsage(t *testing.T) {
|
func TestUsage(t *testing.T) {
|
||||||
oldArgs := os.Args
|
oldArgs := os.Args
|
||||||
|
|
||||||
defer func() { os.Args = oldArgs }()
|
defer func() { os.Args = oldArgs }()
|
||||||
|
|
||||||
Convey("Test usage", t, func(c C) {
|
Convey("Test usage", t, func(c C) {
|
||||||
@@ -28,6 +29,7 @@ func TestUsage(t *testing.T) {
|
|||||||
|
|
||||||
func TestServe(t *testing.T) {
|
func TestServe(t *testing.T) {
|
||||||
oldArgs := os.Args
|
oldArgs := os.Args
|
||||||
|
|
||||||
defer func() { os.Args = oldArgs }()
|
defer func() { os.Args = oldArgs }()
|
||||||
|
|
||||||
Convey("Test serve help", t, func(c C) {
|
Convey("Test serve help", t, func(c C) {
|
||||||
@@ -64,6 +66,7 @@ func TestServe(t *testing.T) {
|
|||||||
|
|
||||||
func TestGC(t *testing.T) {
|
func TestGC(t *testing.T) {
|
||||||
oldArgs := os.Args
|
oldArgs := os.Args
|
||||||
|
|
||||||
defer func() { os.Args = oldArgs }()
|
defer func() { os.Args = oldArgs }()
|
||||||
|
|
||||||
Convey("Test gc", t, func(c C) {
|
Convey("Test gc", t, func(c C) {
|
||||||
|
|||||||
@@ -29,11 +29,13 @@ func TestMain(m *testing.M) {
|
|||||||
config.HTTP.Port = Port
|
config.HTTP.Port = Port
|
||||||
c := api.NewController(config)
|
c := api.NewController(config)
|
||||||
dir, err := ioutil.TempDir("", "oci-repo-test")
|
dir, err := ioutil.TempDir("", "oci-repo-test")
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
//defer os.RemoveAll(dir)
|
//defer os.RemoveAll(dir)
|
||||||
c.Config.Storage.RootDirectory = dir
|
c.Config.Storage.RootDirectory = dir
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
// this blocks
|
// this blocks
|
||||||
if err := c.Run(); err != nil {
|
if err := c.Run(); err != nil {
|
||||||
@@ -42,16 +44,20 @@ func TestMain(m *testing.M) {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
BaseURL := fmt.Sprintf("http://%s:%s", Address, Port)
|
BaseURL := fmt.Sprintf("http://%s:%s", Address, Port)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
// poll until ready
|
// poll until ready
|
||||||
resp, _ := resty.R().Get(BaseURL)
|
resp, _ := resty.R().Get(BaseURL)
|
||||||
if resp.StatusCode() == 404 {
|
if resp.StatusCode() == 404 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
}
|
}
|
||||||
|
|
||||||
status := m.Run()
|
status := m.Run()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
_ = c.Server.Shutdown(ctx)
|
_ = c.Server.Shutdown(ctx)
|
||||||
|
|
||||||
os.Exit(status)
|
os.Exit(status)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,11 +21,15 @@ func (l Logger) Println(v ...interface{}) {
|
|||||||
func NewLogger(level string, output string) Logger {
|
func NewLogger(level string, output string) Logger {
|
||||||
zerolog.TimeFieldFormat = time.RFC3339Nano
|
zerolog.TimeFieldFormat = time.RFC3339Nano
|
||||||
lvl, err := zerolog.ParseLevel(level)
|
lvl, err := zerolog.ParseLevel(level)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
zerolog.SetGlobalLevel(lvl)
|
zerolog.SetGlobalLevel(lvl)
|
||||||
|
|
||||||
var log zerolog.Logger
|
var log zerolog.Logger
|
||||||
|
|
||||||
if output == "" {
|
if output == "" {
|
||||||
log = zerolog.New(os.Stdout)
|
log = zerolog.New(os.Stdout)
|
||||||
} else {
|
} else {
|
||||||
@@ -35,6 +39,7 @@ func NewLogger(level string, output string) Logger {
|
|||||||
}
|
}
|
||||||
log = zerolog.New(file)
|
log = zerolog.New(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
return Logger{Logger: log.With().Timestamp().Logger()}
|
return Logger{Logger: log.With().Timestamp().Logger()}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,13 +58,16 @@ func (w *statusWriter) Write(b []byte) (int, error) {
|
|||||||
if w.status == 0 {
|
if w.status == 0 {
|
||||||
w.status = 200
|
w.status = 200
|
||||||
}
|
}
|
||||||
|
|
||||||
n, err := w.ResponseWriter.Write(b)
|
n, err := w.ResponseWriter.Write(b)
|
||||||
w.length += n
|
w.length += n
|
||||||
|
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func SessionLogger(log Logger) mux.MiddlewareFunc {
|
func SessionLogger(log Logger) mux.MiddlewareFunc {
|
||||||
l := log.With().Str("module", "http").Logger()
|
l := log.With().Str("module", "http").Logger()
|
||||||
|
|
||||||
return func(next http.Handler) http.Handler {
|
return func(next http.Handler) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
// Start timer
|
// Start timer
|
||||||
|
|||||||
+55
-13
@@ -39,6 +39,7 @@ func NewImageStore(rootDir string, log zlog.Logger) *ImageStore {
|
|||||||
blobUploads: make(map[string]BlobUpload),
|
blobUploads: make(map[string]BlobUpload),
|
||||||
log: log.With().Caller().Logger(),
|
log: log.With().Caller().Logger(),
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := os.Stat(rootDir); os.IsNotExist(err) {
|
if _, err := os.Stat(rootDir); os.IsNotExist(err) {
|
||||||
_ = os.MkdirAll(rootDir, 0700)
|
_ = os.MkdirAll(rootDir, 0700)
|
||||||
}
|
}
|
||||||
@@ -69,9 +70,11 @@ func (is *ImageStore) InitRepo(name string) error {
|
|||||||
if _, err := os.Stat(ilPath); err != nil {
|
if _, err := os.Stat(ilPath); err != nil {
|
||||||
il := ispec.ImageLayout{Version: ispec.ImageLayoutVersion}
|
il := ispec.ImageLayout{Version: ispec.ImageLayoutVersion}
|
||||||
buf, err := json.Marshal(il)
|
buf, err := json.Marshal(il)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
is.log.Panic().Err(err).Msg("unable to marshal JSON")
|
is.log.Panic().Err(err).Msg("unable to marshal JSON")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := ioutil.WriteFile(ilPath, buf, 0644); err != nil {
|
if err := ioutil.WriteFile(ilPath, buf, 0644); err != nil {
|
||||||
is.log.Panic().Err(err).Str("file", ilPath).Msg("unable to write file")
|
is.log.Panic().Err(err).Str("file", ilPath).Msg("unable to write file")
|
||||||
}
|
}
|
||||||
@@ -83,9 +86,11 @@ func (is *ImageStore) InitRepo(name string) error {
|
|||||||
index := ispec.Index{}
|
index := ispec.Index{}
|
||||||
index.SchemaVersion = 2
|
index.SchemaVersion = 2
|
||||||
buf, err := json.Marshal(index)
|
buf, err := json.Marshal(index)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
is.log.Panic().Err(err).Msg("unable to marshal JSON")
|
is.log.Panic().Err(err).Msg("unable to marshal JSON")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := ioutil.WriteFile(indexPath, buf, 0644); err != nil {
|
if err := ioutil.WriteFile(indexPath, buf, 0644); err != nil {
|
||||||
is.log.Panic().Err(err).Str("file", indexPath).Msg("unable to write file")
|
is.log.Panic().Err(err).Str("file", indexPath).Msg("unable to write file")
|
||||||
}
|
}
|
||||||
@@ -124,6 +129,7 @@ func (is *ImageStore) ValidateRepo(name string) (bool, error) {
|
|||||||
if file.Name() == "blobs" && !file.IsDir() {
|
if file.Name() == "blobs" && !file.IsDir() {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
found[file.Name()] = true
|
found[file.Name()] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,7 +198,9 @@ func (is *ImageStore) GetImageTags(repo string) ([]string, error) {
|
|||||||
if !dirExists(dir) {
|
if !dirExists(dir) {
|
||||||
return nil, errors.ErrRepoNotFound
|
return nil, errors.ErrRepoNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
buf, err := ioutil.ReadFile(path.Join(dir, "index.json"))
|
buf, err := ioutil.ReadFile(path.Join(dir, "index.json"))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
is.log.Error().Err(err).Str("dir", dir).Msg("failed to read index.json")
|
is.log.Error().Err(err).Str("dir", dir).Msg("failed to read index.json")
|
||||||
return nil, errors.ErrRepoNotFound
|
return nil, errors.ErrRepoNotFound
|
||||||
@@ -221,7 +229,9 @@ func (is *ImageStore) GetImageManifest(repo string, reference string) ([]byte, s
|
|||||||
if !dirExists(dir) {
|
if !dirExists(dir) {
|
||||||
return nil, "", "", errors.ErrRepoNotFound
|
return nil, "", "", errors.ErrRepoNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
buf, err := ioutil.ReadFile(path.Join(dir, "index.json"))
|
buf, err := ioutil.ReadFile(path.Join(dir, "index.json"))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
is.log.Error().Err(err).Str("dir", dir).Msg("failed to read index.json")
|
is.log.Error().Err(err).Str("dir", dir).Msg("failed to read index.json")
|
||||||
return nil, "", "", err
|
return nil, "", "", err
|
||||||
@@ -234,13 +244,17 @@ func (is *ImageStore) GetImageManifest(repo string, reference string) ([]byte, s
|
|||||||
}
|
}
|
||||||
|
|
||||||
found := false
|
found := false
|
||||||
|
|
||||||
var digest godigest.Digest
|
var digest godigest.Digest
|
||||||
|
|
||||||
mediaType := ""
|
mediaType := ""
|
||||||
|
|
||||||
for _, m := range index.Manifests {
|
for _, m := range index.Manifests {
|
||||||
if reference == m.Digest.String() {
|
if reference == m.Digest.String() {
|
||||||
digest = m.Digest
|
digest = m.Digest
|
||||||
mediaType = m.MediaType
|
mediaType = m.MediaType
|
||||||
found = true
|
found = true
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,6 +263,7 @@ func (is *ImageStore) GetImageManifest(repo string, reference string) ([]byte, s
|
|||||||
digest = m.Digest
|
digest = m.Digest
|
||||||
mediaType = m.MediaType
|
mediaType = m.MediaType
|
||||||
found = true
|
found = true
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -276,9 +291,7 @@ func (is *ImageStore) GetImageManifest(repo string, reference string) ([]byte, s
|
|||||||
return buf, digest.String(), mediaType, nil
|
return buf, digest.String(), mediaType, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (is *ImageStore) PutImageManifest(repo string, reference string,
|
func (is *ImageStore) PutImageManifest(repo string, reference string, mediaType string, body []byte) (string, error) {
|
||||||
mediaType string, body []byte) (string, error) {
|
|
||||||
|
|
||||||
if err := is.InitRepo(repo); err != nil {
|
if err := is.InitRepo(repo); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@@ -299,6 +312,7 @@ func (is *ImageStore) PutImageManifest(repo string, reference string,
|
|||||||
for _, l := range m.Layers {
|
for _, l := range m.Layers {
|
||||||
digest := l.Digest
|
digest := l.Digest
|
||||||
blobPath := is.BlobPath(repo, digest)
|
blobPath := is.BlobPath(repo, digest)
|
||||||
|
|
||||||
if _, err := os.Stat(blobPath); err != nil {
|
if _, err := os.Stat(blobPath); err != nil {
|
||||||
return digest.String(), errors.ErrBlobNotFound
|
return digest.String(), errors.ErrBlobNotFound
|
||||||
}
|
}
|
||||||
@@ -307,17 +321,20 @@ func (is *ImageStore) PutImageManifest(repo string, reference string,
|
|||||||
mDigest := godigest.FromBytes(body)
|
mDigest := godigest.FromBytes(body)
|
||||||
refIsDigest := false
|
refIsDigest := false
|
||||||
d, err := godigest.Parse(reference)
|
d, err := godigest.Parse(reference)
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if d.String() != mDigest.String() {
|
if d.String() != mDigest.String() {
|
||||||
is.log.Error().Str("actual", mDigest.String()).Str("expected", d.String()).
|
is.log.Error().Str("actual", mDigest.String()).Str("expected", d.String()).
|
||||||
Msg("manifest digest is not valid")
|
Msg("manifest digest is not valid")
|
||||||
return "", errors.ErrBadManifest
|
return "", errors.ErrBadManifest
|
||||||
}
|
}
|
||||||
|
|
||||||
refIsDigest = true
|
refIsDigest = true
|
||||||
}
|
}
|
||||||
|
|
||||||
dir := path.Join(is.rootDir, repo)
|
dir := path.Join(is.rootDir, repo)
|
||||||
buf, err := ioutil.ReadFile(path.Join(dir, "index.json"))
|
buf, err := ioutil.ReadFile(path.Join(dir, "index.json"))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
is.log.Error().Err(err).Str("dir", dir).Msg("failed to read index.json")
|
is.log.Error().Err(err).Str("dir", dir).Msg("failed to read index.json")
|
||||||
return "", err
|
return "", err
|
||||||
@@ -342,6 +359,7 @@ func (is *ImageStore) PutImageManifest(repo string, reference string,
|
|||||||
// nothing changed, so don't update
|
// nothing changed, so don't update
|
||||||
desc = m
|
desc = m
|
||||||
updateIndex = false
|
updateIndex = false
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -351,12 +369,15 @@ func (is *ImageStore) PutImageManifest(repo string, reference string,
|
|||||||
// nothing changed, so don't update
|
// nothing changed, so don't update
|
||||||
desc = m
|
desc = m
|
||||||
updateIndex = false
|
updateIndex = false
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
// manifest contents have changed for the same tag
|
// manifest contents have changed for the same tag
|
||||||
desc = m
|
desc = m
|
||||||
desc.Digest = mDigest
|
desc.Digest = mDigest
|
||||||
|
|
||||||
index.Manifests = append(index.Manifests[:i], index.Manifests[i+1:]...)
|
index.Manifests = append(index.Manifests[:i], index.Manifests[i+1:]...)
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -371,6 +392,7 @@ func (is *ImageStore) PutImageManifest(repo string, reference string,
|
|||||||
dir = path.Join(dir, mDigest.Algorithm().String())
|
dir = path.Join(dir, mDigest.Algorithm().String())
|
||||||
_ = os.MkdirAll(dir, 0755)
|
_ = os.MkdirAll(dir, 0755)
|
||||||
file := path.Join(dir, mDigest.Encoded())
|
file := path.Join(dir, mDigest.Encoded())
|
||||||
|
|
||||||
if err := ioutil.WriteFile(file, body, 0644); err != nil {
|
if err := ioutil.WriteFile(file, body, 0644); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@@ -380,9 +402,11 @@ func (is *ImageStore) PutImageManifest(repo string, reference string,
|
|||||||
dir = path.Join(is.rootDir, repo)
|
dir = path.Join(is.rootDir, repo)
|
||||||
file = path.Join(dir, "index.json")
|
file = path.Join(dir, "index.json")
|
||||||
buf, err = json.Marshal(index)
|
buf, err = json.Marshal(index)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := ioutil.WriteFile(file, buf, 0644); err != nil {
|
if err := ioutil.WriteFile(file, buf, 0644); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@@ -395,7 +419,9 @@ func (is *ImageStore) DeleteImageManifest(repo string, reference string) error {
|
|||||||
if !dirExists(dir) {
|
if !dirExists(dir) {
|
||||||
return errors.ErrRepoNotFound
|
return errors.ErrRepoNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
buf, err := ioutil.ReadFile(path.Join(dir, "index.json"))
|
buf, err := ioutil.ReadFile(path.Join(dir, "index.json"))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
is.log.Error().Err(err).Str("dir", dir).Msg("failed to read index.json")
|
is.log.Error().Err(err).Str("dir", dir).Msg("failed to read index.json")
|
||||||
return err
|
return err
|
||||||
@@ -408,13 +434,18 @@ func (is *ImageStore) DeleteImageManifest(repo string, reference string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
found := false
|
found := false
|
||||||
|
|
||||||
var digest godigest.Digest
|
var digest godigest.Digest
|
||||||
|
|
||||||
var i int
|
var i int
|
||||||
|
|
||||||
var m ispec.Descriptor
|
var m ispec.Descriptor
|
||||||
|
|
||||||
for i, m = range index.Manifests {
|
for i, m = range index.Manifests {
|
||||||
if reference == m.Digest.String() {
|
if reference == m.Digest.String() {
|
||||||
digest = m.Digest
|
digest = m.Digest
|
||||||
found = true
|
found = true
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -422,6 +453,7 @@ func (is *ImageStore) DeleteImageManifest(repo string, reference string) error {
|
|||||||
if ok && v == reference {
|
if ok && v == reference {
|
||||||
digest = m.Digest
|
digest = m.Digest
|
||||||
found = true
|
found = true
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -438,9 +470,11 @@ func (is *ImageStore) DeleteImageManifest(repo string, reference string) error {
|
|||||||
dir = path.Join(is.rootDir, repo)
|
dir = path.Join(is.rootDir, repo)
|
||||||
file := path.Join(dir, "index.json")
|
file := path.Join(dir, "index.json")
|
||||||
buf, err = json.Marshal(index)
|
buf, err = json.Marshal(index)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := ioutil.WriteFile(file, buf, 0644); err != nil {
|
if err := ioutil.WriteFile(file, buf, 0644); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -458,6 +492,7 @@ func (is *ImageStore) BlobUploadPath(repo string, uuid string) string {
|
|||||||
dir := path.Join(is.rootDir, repo)
|
dir := path.Join(is.rootDir, repo)
|
||||||
blobUploadPath := path.Join(dir, BlobUploadDir)
|
blobUploadPath := path.Join(dir, BlobUploadDir)
|
||||||
blobUploadPath = path.Join(blobUploadPath, uuid)
|
blobUploadPath = path.Join(blobUploadPath, uuid)
|
||||||
|
|
||||||
return blobUploadPath
|
return blobUploadPath
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -474,6 +509,7 @@ func (is *ImageStore) NewBlobUpload(repo string) (string, error) {
|
|||||||
u := uuid.String()
|
u := uuid.String()
|
||||||
blobUploadPath := is.BlobUploadPath(repo, u)
|
blobUploadPath := is.BlobUploadPath(repo, u)
|
||||||
file, err := os.OpenFile(blobUploadPath, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0600)
|
file, err := os.OpenFile(blobUploadPath, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0600)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.ErrRepoNotFound
|
return "", errors.ErrRepoNotFound
|
||||||
}
|
}
|
||||||
@@ -485,19 +521,19 @@ func (is *ImageStore) NewBlobUpload(repo string) (string, error) {
|
|||||||
func (is *ImageStore) GetBlobUpload(repo string, uuid string) (int64, error) {
|
func (is *ImageStore) GetBlobUpload(repo string, uuid string) (int64, error) {
|
||||||
blobUploadPath := is.BlobUploadPath(repo, uuid)
|
blobUploadPath := is.BlobUploadPath(repo, uuid)
|
||||||
fi, err := os.Stat(blobUploadPath)
|
fi, err := os.Stat(blobUploadPath)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
return -1, errors.ErrUploadNotFound
|
return -1, errors.ErrUploadNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1, err
|
return -1, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return fi.Size(), nil
|
return fi.Size(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (is *ImageStore) PutBlobChunk(repo string, uuid string,
|
func (is *ImageStore) PutBlobChunk(repo string, uuid string, from int64, to int64, body io.Reader) (int64, error) {
|
||||||
from int64, to int64, body io.Reader) (int64, error) {
|
|
||||||
|
|
||||||
if err := is.InitRepo(repo); err != nil {
|
if err := is.InitRepo(repo); err != nil {
|
||||||
return -1, err
|
return -1, err
|
||||||
}
|
}
|
||||||
@@ -508,6 +544,7 @@ func (is *ImageStore) PutBlobChunk(repo string, uuid string,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, errors.ErrUploadNotFound
|
return -1, errors.ErrUploadNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
if from != fi.Size() {
|
if from != fi.Size() {
|
||||||
is.log.Error().Int64("expected", from).Int64("actual", fi.Size()).
|
is.log.Error().Int64("expected", from).Int64("actual", fi.Size()).
|
||||||
Msg("invalid range start for blob upload")
|
Msg("invalid range start for blob upload")
|
||||||
@@ -529,23 +566,25 @@ func (is *ImageStore) PutBlobChunk(repo string, uuid string,
|
|||||||
}
|
}
|
||||||
|
|
||||||
n, err := io.Copy(file, body)
|
n, err := io.Copy(file, body)
|
||||||
|
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (is *ImageStore) BlobUploadInfo(repo string, uuid string) (int64, error) {
|
func (is *ImageStore) BlobUploadInfo(repo string, uuid string) (int64, error) {
|
||||||
blobUploadPath := is.BlobUploadPath(repo, uuid)
|
blobUploadPath := is.BlobUploadPath(repo, uuid)
|
||||||
fi, err := os.Stat(blobUploadPath)
|
fi, err := os.Stat(blobUploadPath)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
is.log.Error().Err(err).Str("blob", blobUploadPath).Msg("failed to stat blob")
|
is.log.Error().Err(err).Str("blob", blobUploadPath).Msg("failed to stat blob")
|
||||||
return -1, err
|
return -1, err
|
||||||
}
|
}
|
||||||
|
|
||||||
size := fi.Size()
|
size := fi.Size()
|
||||||
|
|
||||||
return size, nil
|
return size, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (is *ImageStore) FinishBlobUpload(repo string, uuid string,
|
func (is *ImageStore) FinishBlobUpload(repo string, uuid string, body io.Reader, digest string) error {
|
||||||
body io.Reader, digest string) error {
|
|
||||||
|
|
||||||
dstDigest, err := godigest.Parse(digest)
|
dstDigest, err := godigest.Parse(digest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
is.log.Error().Err(err).Str("digest", digest).Msg("failed to parse digest")
|
is.log.Error().Err(err).Str("digest", digest).Msg("failed to parse digest")
|
||||||
@@ -565,8 +604,10 @@ func (is *ImageStore) FinishBlobUpload(repo string, uuid string,
|
|||||||
is.log.Error().Err(err).Str("blob", src).Msg("failed to open blob")
|
is.log.Error().Err(err).Str("blob", src).Msg("failed to open blob")
|
||||||
return errors.ErrUploadNotFound
|
return errors.ErrUploadNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
srcDigest, err := godigest.FromReader(f)
|
srcDigest, err := godigest.FromReader(f)
|
||||||
f.Close()
|
f.Close()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
is.log.Error().Err(err).Str("blob", src).Msg("failed to open blob")
|
is.log.Error().Err(err).Str("blob", src).Msg("failed to open blob")
|
||||||
return errors.ErrBadBlobDigest
|
return errors.ErrBadBlobDigest
|
||||||
@@ -593,6 +634,7 @@ func (is *ImageStore) FinishBlobUpload(repo string, uuid string,
|
|||||||
func (is *ImageStore) DeleteBlobUpload(repo string, uuid string) error {
|
func (is *ImageStore) DeleteBlobUpload(repo string, uuid string) error {
|
||||||
blobUploadPath := is.BlobUploadPath(repo, uuid)
|
blobUploadPath := is.BlobUploadPath(repo, uuid)
|
||||||
_ = os.Remove(blobUploadPath)
|
_ = os.Remove(blobUploadPath)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -601,12 +643,12 @@ func (is *ImageStore) BlobPath(repo string, digest godigest.Digest) string {
|
|||||||
blobPath := path.Join(dir, "blobs")
|
blobPath := path.Join(dir, "blobs")
|
||||||
blobPath = path.Join(blobPath, digest.Algorithm().String())
|
blobPath = path.Join(blobPath, digest.Algorithm().String())
|
||||||
blobPath = path.Join(blobPath, digest.Encoded())
|
blobPath = path.Join(blobPath, digest.Encoded())
|
||||||
|
|
||||||
return blobPath
|
return blobPath
|
||||||
}
|
}
|
||||||
|
|
||||||
func (is *ImageStore) CheckBlob(repo string, digest string,
|
func (is *ImageStore) CheckBlob(repo string, digest string,
|
||||||
mediaType string) (bool, int64, error) {
|
mediaType string) (bool, int64, error) {
|
||||||
|
|
||||||
d, err := godigest.Parse(digest)
|
d, err := godigest.Parse(digest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
is.log.Error().Err(err).Str("digest", digest).Msg("failed to parse digest")
|
is.log.Error().Err(err).Str("digest", digest).Msg("failed to parse digest")
|
||||||
@@ -626,9 +668,7 @@ func (is *ImageStore) CheckBlob(repo string, digest string,
|
|||||||
|
|
||||||
// FIXME: we should probably parse the manifest and use (digest, mediaType) as a
|
// FIXME: we should probably parse the manifest and use (digest, mediaType) as a
|
||||||
// blob selector instead of directly downloading the blob
|
// blob selector instead of directly downloading the blob
|
||||||
func (is *ImageStore) GetBlob(repo string, digest string,
|
func (is *ImageStore) GetBlob(repo string, digest string, mediaType string) (io.Reader, int64, error) {
|
||||||
mediaType string) (io.Reader, int64, error) {
|
|
||||||
|
|
||||||
d, err := godigest.Parse(digest)
|
d, err := godigest.Parse(digest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
is.log.Error().Err(err).Str("digest", digest).Msg("failed to parse digest")
|
is.log.Error().Err(err).Str("digest", digest).Msg("failed to parse digest")
|
||||||
@@ -687,9 +727,11 @@ func dirExists(d string) bool {
|
|||||||
if err != nil && os.IsNotExist(err) {
|
if err != nil && os.IsNotExist(err) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if !fi.IsDir() {
|
if !fi.IsDir() {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ func TestAPIs(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer os.RemoveAll(dir)
|
defer os.RemoveAll(dir)
|
||||||
|
|
||||||
il := storage.NewImageStore(dir, log.Logger{Logger: zerolog.New(os.Stdout)})
|
il := storage.NewImageStore(dir, log.Logger{Logger: zerolog.New(os.Stdout)})
|
||||||
|
|||||||
Reference in New Issue
Block a user