Fix problems signaled by new linter version v1.45.2

PR (linter: upgrade linter version #405) triggered lint job which failed
with many errors generated by various linters. Configurations were added to
golangcilint.yaml and several refactorings were made in order to improve the
results of the linter.

maintidx linter disabled

Signed-off-by: Alex Stan <alexandrustan96@yahoo.ro>
This commit is contained in:
Alex Stan
2022-03-21 17:37:23 +00:00
committed by Ramkumar Chinchani
parent d19a4bf2a1
commit d325c8b5f4
42 changed files with 367 additions and 260 deletions
+1 -1
View File
@@ -24,7 +24,7 @@ jobs:
uses: golangci/golangci-lint-action@v2 uses: golangci/golangci-lint-action@v2
with: with:
# Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version # Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version
version: v1.43.0 version: v1.45.2
# Optional: working directory, useful for monorepos # Optional: working directory, useful for monorepos
# working-directory: somedir # working-directory: somedir
+2 -1
View File
@@ -9,6 +9,7 @@ TOOLSDIR := $(shell pwd)/hack/tools
PATH := bin:$(TOOLSDIR)/bin:$(PATH) PATH := bin:$(TOOLSDIR)/bin:$(PATH)
STACKER := $(shell which stacker) STACKER := $(shell which stacker)
GOLINTER := $(TOOLSDIR)/bin/golangci-lint GOLINTER := $(TOOLSDIR)/bin/golangci-lint
GOLINTER_VERSION := v1.45.2
NOTATION := $(TOOLSDIR)/bin/notation NOTATION := $(TOOLSDIR)/bin/notation
BATS := $(TOOLSDIR)/bin/bats BATS := $(TOOLSDIR)/bin/bats
TESTDATA := $(TOP_LEVEL)/test/data TESTDATA := $(TOP_LEVEL)/test/data
@@ -89,7 +90,7 @@ covhtml:
$(GOLINTER): $(GOLINTER):
mkdir -p $(TOOLSDIR)/bin mkdir -p $(TOOLSDIR)/bin
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(TOOLSDIR)/bin v1.43.0 curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(TOOLSDIR)/bin $(GOLINTER_VERSION)
$(GOLINTER) version $(GOLINTER) version
.PHONY: check .PHONY: check
+8 -4
View File
@@ -38,7 +38,8 @@ func deleteTestRepo(repos []string, url string, client *resty.Client) error {
} }
func pullAndCollect(url string, repos []string, manifestItem manifestStruct, func pullAndCollect(url string, repos []string, manifestItem manifestStruct,
config testConfig, client *resty.Client, statsCh chan statsRecord) []string { config testConfig, client *resty.Client, statsCh chan statsRecord,
) []string {
manifestHash := manifestItem.manifestHash manifestHash := manifestItem.manifestHash
manifestBySizeHash := manifestItem.manifestBySizeHash manifestBySizeHash := manifestItem.manifestBySizeHash
@@ -252,7 +253,8 @@ func pullAndCollect(url string, repos []string, manifestItem manifestStruct,
} }
func pushMonolithImage(workdir, url, trepo string, repos []string, size int, func pushMonolithImage(workdir, url, trepo string, repos []string, size int,
client *resty.Client) (map[string]string, []string, error) { client *resty.Client,
) (map[string]string, []string, error) {
var statusCode int var statusCode int
// key: repository name. value: manifest name // key: repository name. value: manifest name
@@ -398,7 +400,8 @@ func pushMonolithImage(workdir, url, trepo string, repos []string, size int,
func pushMonolithAndCollect(workdir, url, trepo string, count int, func pushMonolithAndCollect(workdir, url, trepo string, count int,
repos []string, config testConfig, client *resty.Client, repos []string, config testConfig, client *resty.Client,
statsCh chan statsRecord) []string { statsCh chan statsRecord,
) []string {
func() { func() {
start := time.Now() start := time.Now()
@@ -618,7 +621,8 @@ func pushMonolithAndCollect(workdir, url, trepo string, count int,
func pushChunkAndCollect(workdir, url, trepo string, count int, func pushChunkAndCollect(workdir, url, trepo string, count int,
repos []string, config testConfig, client *resty.Client, repos []string, config testConfig, client *resty.Client,
statsCh chan statsRecord) []string { statsCh chan statsRecord,
) []string {
func() { func() {
start := time.Now() start := time.Now()
+1
View File
@@ -4,6 +4,7 @@ import "errors"
var ( var (
ErrBadConfig = errors.New("config: invalid config") ErrBadConfig = errors.New("config: invalid config")
ErrCliBadConfig = errors.New("cli: bad config")
ErrRepoNotFound = errors.New("repository: not found") ErrRepoNotFound = errors.New("repository: not found")
ErrRepoIsNotDir = errors.New("repository: not a directory") ErrRepoIsNotDir = errors.New("repository: not a directory")
ErrRepoBadVersion = errors.New("repository: unsupported layout version") ErrRepoBadVersion = errors.New("repository: unsupported layout version")
+14 -1
View File
@@ -5,7 +5,7 @@ run:
linters: linters:
enable-all: true enable-all: true
disable: funlen,gocognit,exhaustivestruct,paralleltest,forbidigo,ireturn,wrapcheck,exhaustive disable: funlen,gocognit,exhaustivestruct,paralleltest,forbidigo,ireturn,wrapcheck,exhaustive,maintidx
linters-settings: linters-settings:
dupl: dupl:
@@ -24,6 +24,19 @@ linters-settings:
- err - err
- ok - ok
- gc - gc
- wg
ignore-decls:
- n int
- i int
- r *os.File
- w *os.File
- to int64
- l *ldap.Conn
wsl:
allow-assign-and-anything: true
enforce-err-cuddling: true
nolintlint:
allow-unused: true
gomnd: gomnd:
settings: settings:
mnd: mnd:
+18 -26
View File
@@ -10,6 +10,7 @@ import (
"crypto/tls" "crypto/tls"
"crypto/x509" "crypto/x509"
"encoding/json" "encoding/json"
goerrors "errors"
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
@@ -1324,7 +1325,8 @@ func (l *testLDAPServer) Bind(bindDN, bindSimplePw string, conn net.Conn) (vldap
} }
func (l *testLDAPServer) Search(boundDN string, req vldap.SearchRequest, func (l *testLDAPServer) Search(boundDN string, req vldap.SearchRequest,
conn net.Conn) (vldap.ServerSearchResult, error) { conn net.Conn,
) (vldap.ServerSearchResult, error) {
check := fmt.Sprintf("(uid=%s)", username) check := fmt.Sprintf("(uid=%s)", username)
if check == req.Filter { if check == req.Filter {
return vldap.ServerSearchResult{ return vldap.ServerSearchResult{
@@ -1893,11 +1895,9 @@ func TestAuthorizationWithBasicAuth(t *testing.T) {
// first let's use global based policies // first let's use global based policies
// add test user to global policy with create perm // add test user to global policy with create perm
conf.AccessControl.Repositories[AuthorizationAllRepos].Policies[0].Users = conf.AccessControl.Repositories[AuthorizationAllRepos].Policies[0].Users = append(conf.AccessControl.Repositories[AuthorizationAllRepos].Policies[0].Users, "test") //nolint:lll // gofumpt conflicts with lll
append(conf.AccessControl.Repositories[AuthorizationAllRepos].Policies[0].Users, "test")
conf.AccessControl.Repositories[AuthorizationAllRepos].Policies[0].Actions = conf.AccessControl.Repositories[AuthorizationAllRepos].Policies[0].Actions = append(conf.AccessControl.Repositories[AuthorizationAllRepos].Policies[0].Actions, "create") //nolint:lll // gofumpt conflicts with lll
append(conf.AccessControl.Repositories[AuthorizationAllRepos].Policies[0].Actions, "create")
// now it should get 202 // now it should get 202
resp, err = resty.R().SetBasicAuth(username, passphrase). resp, err = resty.R().SetBasicAuth(username, passphrase).
@@ -1933,8 +1933,7 @@ func TestAuthorizationWithBasicAuth(t *testing.T) {
So(resp.StatusCode(), ShouldEqual, http.StatusForbidden) So(resp.StatusCode(), ShouldEqual, http.StatusForbidden)
// get tags with read access should get 200 // get tags with read access should get 200
conf.AccessControl.Repositories[AuthorizationAllRepos].Policies[0].Actions = conf.AccessControl.Repositories[AuthorizationAllRepos].Policies[0].Actions = append(conf.AccessControl.Repositories[AuthorizationAllRepos].Policies[0].Actions, "read") //nolint:lll // gofumpt conflicts with lll
append(conf.AccessControl.Repositories[AuthorizationAllRepos].Policies[0].Actions, "read")
resp, err = resty.R().SetBasicAuth(username, passphrase). resp, err = resty.R().SetBasicAuth(username, passphrase).
Get(baseURL + "/v2/" + AuthorizationNamespace + "/tags/list") Get(baseURL + "/v2/" + AuthorizationNamespace + "/tags/list")
@@ -1964,8 +1963,7 @@ func TestAuthorizationWithBasicAuth(t *testing.T) {
So(resp.StatusCode(), ShouldEqual, http.StatusForbidden) So(resp.StatusCode(), ShouldEqual, http.StatusForbidden)
// add delete perm on repo // add delete perm on repo
conf.AccessControl.Repositories[AuthorizationAllRepos].Policies[0].Actions = conf.AccessControl.Repositories[AuthorizationAllRepos].Policies[0].Actions = append(conf.AccessControl.Repositories[AuthorizationAllRepos].Policies[0].Actions, "delete") //nolint:lll // gofumpt conflicts with lll
append(conf.AccessControl.Repositories[AuthorizationAllRepos].Policies[0].Actions, "delete")
// delete blob should get 202 // delete blob should get 202
resp, err = resty.R().SetBasicAuth(username, passphrase). resp, err = resty.R().SetBasicAuth(username, passphrase).
@@ -1987,10 +1985,8 @@ func TestAuthorizationWithBasicAuth(t *testing.T) {
DefaultPolicy: []string{}, DefaultPolicy: []string{},
} }
conf.AccessControl.Repositories[AuthorizationNamespace].Policies[0].Users = conf.AccessControl.Repositories[AuthorizationNamespace].Policies[0].Users = append(conf.AccessControl.Repositories[AuthorizationNamespace].Policies[0].Users, "test") //nolint:lll // gofumpt conflicts with lll
append(conf.AccessControl.Repositories[AuthorizationNamespace].Policies[0].Users, "test") conf.AccessControl.Repositories[AuthorizationNamespace].Policies[0].Actions = append(conf.AccessControl.Repositories[AuthorizationNamespace].Policies[0].Actions, "create") //nolint:lll // gofumpt conflicts with lll
conf.AccessControl.Repositories[AuthorizationNamespace].Policies[0].Actions =
append(conf.AccessControl.Repositories[AuthorizationNamespace].Policies[0].Actions, "create")
// now it should get 202 // now it should get 202
resp, err = resty.R().SetBasicAuth(username, passphrase). resp, err = resty.R().SetBasicAuth(username, passphrase).
@@ -2026,8 +2022,7 @@ func TestAuthorizationWithBasicAuth(t *testing.T) {
So(resp.StatusCode(), ShouldEqual, http.StatusForbidden) So(resp.StatusCode(), ShouldEqual, http.StatusForbidden)
// get tags with read access should get 200 // get tags with read access should get 200
conf.AccessControl.Repositories[AuthorizationNamespace].Policies[0].Actions = conf.AccessControl.Repositories[AuthorizationNamespace].Policies[0].Actions = append(conf.AccessControl.Repositories[AuthorizationNamespace].Policies[0].Actions, "read") //nolint:lll // gofumpt conflicts with lll
append(conf.AccessControl.Repositories[AuthorizationNamespace].Policies[0].Actions, "read")
resp, err = resty.R().SetBasicAuth(username, passphrase). resp, err = resty.R().SetBasicAuth(username, passphrase).
Get(baseURL + "/v2/" + AuthorizationNamespace + "/tags/list") Get(baseURL + "/v2/" + AuthorizationNamespace + "/tags/list")
@@ -2063,8 +2058,7 @@ func TestAuthorizationWithBasicAuth(t *testing.T) {
So(resp.StatusCode(), ShouldEqual, http.StatusForbidden) So(resp.StatusCode(), ShouldEqual, http.StatusForbidden)
// add delete perm on repo // add delete perm on repo
conf.AccessControl.Repositories[AuthorizationNamespace].Policies[0].Actions = conf.AccessControl.Repositories[AuthorizationNamespace].Policies[0].Actions = append(conf.AccessControl.Repositories[AuthorizationNamespace].Policies[0].Actions, "delete") //nolint:lll // gofumpt conflicts with lll
append(conf.AccessControl.Repositories[AuthorizationNamespace].Policies[0].Actions, "delete")
// delete blob should get 202 // delete blob should get 202
resp, err = resty.R().SetBasicAuth(username, passphrase). resp, err = resty.R().SetBasicAuth(username, passphrase).
@@ -2111,8 +2105,7 @@ func TestAuthorizationWithBasicAuth(t *testing.T) {
So(resp.StatusCode(), ShouldEqual, http.StatusForbidden) So(resp.StatusCode(), ShouldEqual, http.StatusForbidden)
// add create perm on repo // add create perm on repo
conf.AccessControl.Repositories["zot-test"].Policies[0].Actions = conf.AccessControl.Repositories["zot-test"].Policies[0].Actions = append(conf.AccessControl.Repositories["zot-test"].Policies[0].Actions, "create") //nolint:lll // gofumpt conflicts with lll
append(conf.AccessControl.Repositories["zot-test"].Policies[0].Actions, "create")
// should get 201 with create perm // should get 201 with create perm
resp, err = resty.R().SetBasicAuth(username, passphrase). resp, err = resty.R().SetBasicAuth(username, passphrase).
@@ -2131,8 +2124,7 @@ func TestAuthorizationWithBasicAuth(t *testing.T) {
So(resp.StatusCode(), ShouldEqual, http.StatusForbidden) So(resp.StatusCode(), ShouldEqual, http.StatusForbidden)
// add update perm on repo // add update perm on repo
conf.AccessControl.Repositories["zot-test"].Policies[0].Actions = conf.AccessControl.Repositories["zot-test"].Policies[0].Actions = append(conf.AccessControl.Repositories["zot-test"].Policies[0].Actions, "update") //nolint:lll // gofumpt conflicts with lll
append(conf.AccessControl.Repositories["zot-test"].Policies[0].Actions, "update")
// update manifest should get 201 with update perm // update manifest should get 201 with update perm
resp, err = resty.R().SetBasicAuth(username, passphrase). resp, err = resty.R().SetBasicAuth(username, passphrase).
@@ -2854,7 +2846,7 @@ func TestParallelRequests(t *testing.T) {
for { for {
nbytes, err := reader.Read(buf) nbytes, err := reader.Read(buf)
if err != nil { if err != nil {
if err == io.EOF { if goerrors.Is(err, io.EOF) {
break break
} }
panic(err) panic(err)
@@ -2879,7 +2871,7 @@ func TestParallelRequests(t *testing.T) {
for { for {
nbytes, err := reader.Read(buf) nbytes, err := reader.Read(buf)
if err != nil { if err != nil {
if err == io.EOF { if goerrors.Is(err, io.EOF) {
break break
} }
panic(err) panic(err)
@@ -4343,7 +4335,7 @@ func TestInjectTooManyOpenFiles(t *testing.T) {
So(digest, ShouldNotBeNil) So(digest, ShouldNotBeNil)
// Testing router path: @Router /v2/{name}/manifests/{reference} [put] // Testing router path: @Router /v2/{name}/manifests/{reference} [put]
// nolint: lll //nolint:lll // gofumpt conflicts with lll
Convey("Uploading an image manifest blob (when injected simulates that PutImageManifest failed due to 'too many open files' error)", func() { Convey("Uploading an image manifest blob (when injected simulates that PutImageManifest failed due to 'too many open files' error)", func() {
injected := test.InjectFailure(1) injected := test.InjectFailure(1)
@@ -4526,7 +4518,7 @@ func TestPeriodicGC(t *testing.T) {
subPaths := make(map[string]config.StorageConfig) subPaths := make(map[string]config.StorageConfig)
subPaths["/a"] = config.StorageConfig{RootDirectory: subDir, GC: true, GCDelay: 1 * time.Second, GCInterval: 24 * time.Hour} // nolint:lll subPaths["/a"] = config.StorageConfig{RootDirectory: subDir, GC: true, GCDelay: 1 * time.Second, GCInterval: 24 * time.Hour} //nolint:lll // gofumpt conflicts with lll
ctlr.Config.Storage.SubPaths = subPaths ctlr.Config.Storage.SubPaths = subPaths
ctlr.Config.Storage.RootDirectory = dir ctlr.Config.Storage.RootDirectory = dir
@@ -4542,7 +4534,7 @@ func TestPeriodicGC(t *testing.T) {
"\"GCDelay\":3600000000000,\"GCInterval\":0,\"RootDirectory\":\""+dir+"\"") "\"GCDelay\":3600000000000,\"GCInterval\":0,\"RootDirectory\":\""+dir+"\"")
// periodic GC is enabled for sub store // periodic GC is enabled for sub store
So(string(data), ShouldContainSubstring, So(string(data), ShouldContainSubstring,
fmt.Sprintf("\"SubPaths\":{\"/a\":{\"RootDirectory\":\"%s\",\"GC\":true,\"Dedupe\":false,\"Commit\":false,\"GCDelay\":1000000000,\"GCInterval\":86400000000000", subDir)) // nolint:lll fmt.Sprintf("\"SubPaths\":{\"/a\":{\"RootDirectory\":\"%s\",\"GC\":true,\"Dedupe\":false,\"Commit\":false,\"GCDelay\":1000000000,\"GCInterval\":86400000000000", subDir)) //nolint:lll // gofumpt conflicts with lll
So(string(data), ShouldContainSubstring, So(string(data), ShouldContainSubstring,
fmt.Sprintf("executing GC of orphaned blobs for %s", ctlr.StoreController.SubStore["/a"].RootDir())) fmt.Sprintf("executing GC of orphaned blobs for %s", ctlr.StoreController.SubStore["/a"].RootDir()))
}) })
+10 -8
View File
@@ -33,8 +33,7 @@ import (
ext "zotregistry.io/zot/pkg/extensions" ext "zotregistry.io/zot/pkg/extensions"
"zotregistry.io/zot/pkg/log" "zotregistry.io/zot/pkg/log"
"zotregistry.io/zot/pkg/storage" "zotregistry.io/zot/pkg/storage"
"zotregistry.io/zot/pkg/test" "zotregistry.io/zot/pkg/test" // nolint: goimports
// as required by swaggo. // as required by swaggo.
_ "zotregistry.io/zot/swagger" _ "zotregistry.io/zot/swagger"
) )
@@ -184,17 +183,17 @@ func (rh *RouteHandler) ListTags(response http.ResponseWriter, request *http.Req
return return
} }
var n1 int64 var nQuery1 int64
var err error var err error
if n1, err = strconv.ParseInt(nQuery[0], 10, 0); err != nil { if nQuery1, err = strconv.ParseInt(nQuery[0], 10, 0); err != nil {
response.WriteHeader(http.StatusBadRequest) response.WriteHeader(http.StatusBadRequest)
return return
} }
numTags = int(n1) numTags = int(nQuery1)
paginate = true paginate = true
} }
@@ -1298,7 +1297,8 @@ func WriteData(w http.ResponseWriter, status int, mediaType string, data []byte)
} }
func WriteDataFromReader(response http.ResponseWriter, status int, length int64, mediaType string, func WriteDataFromReader(response http.ResponseWriter, status int, length int64, mediaType string,
reader io.Reader, logger log.Logger) { reader io.Reader, logger log.Logger,
) {
response.Header().Set("Content-Type", mediaType) response.Header().Set("Content-Type", mediaType)
response.Header().Set("Content-Length", strconv.FormatInt(length, 10)) response.Header().Set("Content-Length", strconv.FormatInt(length, 10))
response.WriteHeader(status) response.WriteHeader(status)
@@ -1325,7 +1325,8 @@ func (rh *RouteHandler) getImageStore(name string) storage.ImageStore {
// will sync on demand if an image is not found, in case sync extensions is enabled. // will sync on demand if an image is not found, in case sync extensions is enabled.
func getImageManifest(routeHandler *RouteHandler, imgStore storage.ImageStore, name, func getImageManifest(routeHandler *RouteHandler, imgStore storage.ImageStore, name,
reference string) ([]byte, string, string, error) { reference string,
) ([]byte, string, string, error) {
content, digest, mediaType, err := imgStore.GetImageManifest(name, reference) content, digest, mediaType, err := imgStore.GetImageManifest(name, reference)
if err != nil { if err != nil {
if errors.Is(err, zerr.ErrRepoNotFound) || errors.Is(err, zerr.ErrManifestNotFound) { if errors.Is(err, zerr.ErrRepoNotFound) || errors.Is(err, zerr.ErrManifestNotFound) {
@@ -1354,7 +1355,8 @@ func getImageManifest(routeHandler *RouteHandler, imgStore storage.ImageStore, n
// will sync referrers on demand if they are not found, in case sync extensions is enabled. // will sync referrers on demand if they are not found, in case sync extensions is enabled.
func getReferrers(routeHandler *RouteHandler, imgStore storage.ImageStore, name, digest, func getReferrers(routeHandler *RouteHandler, imgStore storage.ImageStore, name, digest,
artifactType string) ([]artifactspec.Descriptor, error) { artifactType string,
) ([]artifactspec.Descriptor, error) {
refs, err := imgStore.GetReferrers(name, digest, artifactType) refs, err := imgStore.GetReferrers(name, digest, artifactType)
if err != nil { if err != nil {
if routeHandler.c.Config.Extensions != nil && if routeHandler.c.Config.Extensions != nil &&
+6 -6
View File
@@ -38,7 +38,7 @@ const (
) )
func createHTTPClient(verifyTLS bool, host string) *http.Client { func createHTTPClient(verifyTLS bool, host string) *http.Client {
htr := http.DefaultTransport.(*http.Transport).Clone() htr := http.DefaultTransport.(*http.Transport).Clone() //nolint: forcetypeassert
if !verifyTLS { if !verifyTLS {
htr.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} //nolint: gosec htr.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} //nolint: gosec
@@ -65,7 +65,8 @@ func createHTTPClient(verifyTLS bool, host string) *http.Client {
} }
func makeGETRequest(ctx context.Context, url, username, password string, func makeGETRequest(ctx context.Context, url, username, password string,
verifyTLS bool, resultsPtr interface{}) (http.Header, error) { verifyTLS bool, resultsPtr interface{},
) (http.Header, error) {
req, err := http.NewRequestWithContext(ctx, "GET", url, nil) req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -77,7 +78,8 @@ func makeGETRequest(ctx context.Context, url, username, password string,
} }
func makeGraphQLRequest(ctx context.Context, url, query, username, func makeGraphQLRequest(ctx context.Context, url, query, username,
password string, verifyTLS bool, resultsPtr interface{}) error { password string, verifyTLS bool, resultsPtr interface{},
) error {
req, err := http.NewRequestWithContext(ctx, "GET", url, bytes.NewBufferString(query)) req, err := http.NewRequestWithContext(ctx, "GET", url, bytes.NewBufferString(query))
if err != nil { if err != nil {
return err return err
@@ -201,7 +203,6 @@ type requestsPool struct {
done chan struct{} done chan struct{}
wtgrp *sync.WaitGroup wtgrp *sync.WaitGroup
outputCh chan stringResult outputCh chan stringResult
context context.Context
} }
type manifestJob struct { type manifestJob struct {
@@ -216,7 +217,7 @@ type manifestJob struct {
const rateLimiterBuffer = 5000 const rateLimiterBuffer = 5000
func newSmoothRateLimiter(ctx context.Context, wtgrp *sync.WaitGroup, opch chan stringResult) *requestsPool { func newSmoothRateLimiter(wtgrp *sync.WaitGroup, opch chan stringResult) *requestsPool {
ch := make(chan *manifestJob, rateLimiterBuffer) ch := make(chan *manifestJob, rateLimiterBuffer)
return &requestsPool{ return &requestsPool{
@@ -224,7 +225,6 @@ func newSmoothRateLimiter(ctx context.Context, wtgrp *sync.WaitGroup, opch chan
done: make(chan struct{}), done: make(chan struct{}),
wtgrp: wtgrp, wtgrp: wtgrp,
outputCh: opch, outputCh: opch,
context: ctx,
} }
} }
+6 -1
View File
@@ -150,7 +150,12 @@ func getConfigMapFromFile(filePath string) ([]interface{}, error) {
return nil, zerr.ErrEmptyJSON return nil, zerr.ErrEmptyJSON
} }
return jsonMap["configs"].([]interface{}), nil configs, ok := jsonMap["configs"].([]interface{})
if !ok {
return nil, zerr.ErrCliBadConfig
}
return configs, nil
} }
func saveConfigMapToFile(filePath string, configMap []interface{}) error { func saveConfigMapToFile(filePath string, configMap []interface{}) error {
+13
View File
@@ -79,6 +79,19 @@ func TestConfigCmdMain(t *testing.T) {
So(actualStr, ShouldContainSubstring, "https://test-url.com") So(actualStr, ShouldContainSubstring, "https://test-url.com")
}) })
Convey("Test add config with invalid format", t, func() {
args := []string{"--list"}
configPath := makeConfigFile(`{"configs":{"_name":"configtest","url":"https://test-url.com","showspinner":false}}`)
defer os.Remove(configPath)
cmd := NewConfigCommand()
buff := bytes.NewBufferString("")
cmd.SetOut(buff)
cmd.SetErr(buff)
cmd.SetArgs(args)
err := cmd.Execute()
So(err, ShouldEqual, zotErrors.ErrCliBadConfig)
})
Convey("Test add config with invalid URL", t, func() { Convey("Test add config with invalid URL", t, func() {
args := []string{"add", "configtest1", "test..com"} args := []string{"add", "configtest1", "test..com"}
file := makeConfigFile("") file := makeConfigFile("")
+8 -8
View File
@@ -102,7 +102,7 @@ func TestServeExtensions(t *testing.T) {
WaitTillServerReady(baseURL) WaitTillServerReady(baseURL)
data, err := os.ReadFile(logFile.Name()) data, err := os.ReadFile(logFile.Name())
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(string(data), ShouldContainSubstring, "\"Extensions\":{\"Search\":null,\"Sync\":null,\"Metrics\":null,\"Scrub\":null") // nolint:lll So(string(data), ShouldContainSubstring, "\"Extensions\":{\"Search\":null,\"Sync\":null,\"Metrics\":null,\"Scrub\":null") //nolint:lll // gofumpt conflicts with lll
}) })
} }
@@ -143,7 +143,7 @@ func testWithMetricsEnabled(cfgContentFormat string) {
data, err := os.ReadFile(logFile.Name()) data, err := os.ReadFile(logFile.Name())
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(string(data), ShouldContainSubstring, So(string(data), ShouldContainSubstring,
"\"Extensions\":{\"Search\":null,\"Sync\":null,\"Metrics\":{\"Enable\":true,\"Prometheus\":{\"Path\":\"/metrics\"}},\"Scrub\":null}") // nolint:lll "\"Extensions\":{\"Search\":null,\"Sync\":null,\"Metrics\":{\"Enable\":true,\"Prometheus\":{\"Path\":\"/metrics\"}},\"Scrub\":null}") //nolint:lll // gofumpt conflicts with lll
} }
func TestServeMetricsExtension(t *testing.T) { func TestServeMetricsExtension(t *testing.T) {
@@ -267,7 +267,7 @@ func TestServeMetricsExtension(t *testing.T) {
data, err := os.ReadFile(logFile.Name()) data, err := os.ReadFile(logFile.Name())
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(string(data), ShouldContainSubstring, So(string(data), ShouldContainSubstring,
"\"Extensions\":{\"Search\":null,\"Sync\":null,\"Metrics\":{\"Enable\":false,\"Prometheus\":{\"Path\":\"/metrics\"}},\"Scrub\":null}") // nolint:lll "\"Extensions\":{\"Search\":null,\"Sync\":null,\"Metrics\":{\"Enable\":false,\"Prometheus\":{\"Path\":\"/metrics\"}},\"Scrub\":null}") //nolint:lll // gofumpt conflicts with lll
}) })
} }
@@ -508,7 +508,7 @@ func TestServeScrubExtension(t *testing.T) {
So(err, ShouldBeNil) So(err, ShouldBeNil)
// Even if in config we specified scrub interval=1h, the minimum interval is 2h // Even if in config we specified scrub interval=1h, the minimum interval is 2h
So(string(data), ShouldContainSubstring, So(string(data), ShouldContainSubstring,
"\"Extensions\":{\"Search\":null,\"Sync\":null,\"Metrics\":null,\"Scrub\":{\"Interval\":3600000000000}") // nolint:lll "\"Extensions\":{\"Search\":null,\"Sync\":null,\"Metrics\":null,\"Scrub\":{\"Interval\":3600000000000}") //nolint:lll // gofumpt conflicts with lll
So(string(data), ShouldContainSubstring, "executing scrub to check manifest/blob integrity") So(string(data), ShouldContainSubstring, "executing scrub to check manifest/blob integrity")
So(string(data), ShouldContainSubstring, So(string(data), ShouldContainSubstring,
"Scrub interval set to too-short interval < 2h, changing scrub duration to 2 hours and continuing.") "Scrub interval set to too-short interval < 2h, changing scrub duration to 2 hours and continuing.")
@@ -612,7 +612,7 @@ func TestServeSearchExtension(t *testing.T) {
data, err := os.ReadFile(logFile.Name()) data, err := os.ReadFile(logFile.Name())
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(string(data), ShouldContainSubstring, So(string(data), ShouldContainSubstring,
"\"Extensions\":{\"Search\":{\"CVE\":{\"UpdateInterval\":86400000000000},\"Enable\":true},\"Sync\":null,\"Metrics\":null,\"Scrub\":null}") // nolint:lll "\"Extensions\":{\"Search\":{\"CVE\":{\"UpdateInterval\":86400000000000},\"Enable\":true},\"Sync\":null,\"Metrics\":null,\"Scrub\":null}") //nolint:lll // gofumpt conflicts with lll
So(string(data), ShouldContainSubstring, "updating the CVE database") So(string(data), ShouldContainSubstring, "updating the CVE database")
}) })
@@ -663,7 +663,7 @@ func TestServeSearchExtension(t *testing.T) {
So(err, ShouldBeNil) So(err, ShouldBeNil)
// Even if in config we specified updateInterval=1h, the minimum interval is 2h // Even if in config we specified updateInterval=1h, the minimum interval is 2h
So(string(data), ShouldContainSubstring, So(string(data), ShouldContainSubstring,
"\"Extensions\":{\"Search\":{\"CVE\":{\"UpdateInterval\":3600000000000},\"Enable\":true},\"Sync\":null,\"Metrics\":null,\"Scrub\":null}") // nolint:lll "\"Extensions\":{\"Search\":{\"CVE\":{\"UpdateInterval\":3600000000000},\"Enable\":true},\"Sync\":null,\"Metrics\":null,\"Scrub\":null}") //nolint:lll // gofumpt conflicts with lll
So(string(data), ShouldContainSubstring, "updating the CVE database") So(string(data), ShouldContainSubstring, "updating the CVE database")
So(string(data), ShouldContainSubstring, So(string(data), ShouldContainSubstring,
"CVE update interval set to too-short interval < 2h, changing update duration to 2 hours and continuing.") "CVE update interval set to too-short interval < 2h, changing update duration to 2 hours and continuing.")
@@ -713,7 +713,7 @@ func TestServeSearchExtension(t *testing.T) {
data, err := os.ReadFile(logFile.Name()) data, err := os.ReadFile(logFile.Name())
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(string(data), ShouldContainSubstring, So(string(data), ShouldContainSubstring,
"\"Extensions\":{\"Search\":{\"CVE\":{\"UpdateInterval\":86400000000000},\"Enable\":true},\"Sync\":null,\"Metrics\":null,\"Scrub\":null}") // nolint:lll "\"Extensions\":{\"Search\":{\"CVE\":{\"UpdateInterval\":86400000000000},\"Enable\":true},\"Sync\":null,\"Metrics\":null,\"Scrub\":null}") //nolint:lll // gofumpt conflicts with lll
So(string(data), ShouldContainSubstring, "updating the CVE database") So(string(data), ShouldContainSubstring, "updating the CVE database")
}) })
@@ -764,7 +764,7 @@ func TestServeSearchExtension(t *testing.T) {
data, err := os.ReadFile(logFile.Name()) data, err := os.ReadFile(logFile.Name())
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(string(data), ShouldContainSubstring, So(string(data), ShouldContainSubstring,
"\"Extensions\":{\"Search\":{\"CVE\":{\"UpdateInterval\":10800000000000},\"Enable\":false},\"Sync\":null,\"Metrics\":null,\"Scrub\":null}") // nolint:lll "\"Extensions\":{\"Search\":{\"CVE\":{\"UpdateInterval\":10800000000000},\"Enable\":false},\"Sync\":null,\"Metrics\":null,\"Scrub\":null}") //nolint:lll // gofumpt conflicts with lll
So(string(data), ShouldContainSubstring, "CVE config not provided, skipping CVE update") So(string(data), ShouldContainSubstring, "CVE config not provided, skipping CVE update")
So(string(data), ShouldNotContainSubstring, So(string(data), ShouldNotContainSubstring,
"CVE update interval set to too-short interval < 2h, changing update duration to 2 hours and continuing.") "CVE update interval set to too-short interval < 2h, changing update duration to 2 hours and continuing.")
+2 -1
View File
@@ -116,7 +116,8 @@ func parseBooleanConfig(configPath, configName, configParam string) (bool, error
} }
func setupImageFlags(imageCmd *cobra.Command, searchImageParams map[string]*string, func setupImageFlags(imageCmd *cobra.Command, searchImageParams map[string]*string,
servURL, user, outputFormat *string, verbose *bool) { servURL, user, outputFormat *string, verbose *bool,
) {
searchImageParams["imageName"] = imageCmd.Flags().StringP("name", "n", "", "List image details by name") searchImageParams["imageName"] = imageCmd.Flags().StringP("name", "n", "", "List image details by name")
searchImageParams["digest"] = imageCmd.Flags().StringP("digest", "d", "", searchImageParams["digest"] = imageCmd.Flags().StringP("digest", "d", "",
"List images containing a specific manifest, config, or layer digest") "List images containing a specific manifest, config, or layer digest")
+34 -12
View File
@@ -312,14 +312,18 @@ func TestServerResponse(t *testing.T) {
_ = controller.Server.Shutdown(ctx) _ = controller.Server.Shutdown(ctx)
}(ctlr) }(ctlr)
uploadManifest(url) err := uploadManifest(url)
t.Logf("%s", ctlr.Config.Storage.RootDirectory)
So(err, ShouldBeNil)
Convey("Test all images config url", func() { Convey("Test all images config url", func() {
t.Logf("%s", ctlr.Config.Storage.RootDirectory)
args := []string{"imagetest"} args := []string{"imagetest"}
configPath := makeConfigFile(fmt.Sprintf(`{"configs":[{"_name":"imagetest","url":"%s","showspinner":false}]}`, url)) configPath := makeConfigFile(fmt.Sprintf(`{"configs":[{"_name":"imagetest","url":"%s","showspinner":false}]}`, url))
defer os.Remove(configPath) defer os.Remove(configPath)
cmd := NewImageCommand(new(searchService)) cmd := NewImageCommand(new(searchService))
buff := bytes.NewBufferString("") // buff := bytes.NewBufferString("")
buff := &bytes.Buffer{}
cmd.SetOut(buff) cmd.SetOut(buff)
cmd.SetErr(buff) cmd.SetErr(buff)
cmd.SetArgs(args) cmd.SetArgs(args)
@@ -454,7 +458,7 @@ func TestServerResponse(t *testing.T) {
}) })
} }
func uploadManifest(url string) { func uploadManifest(url string) error {
// create a blob/layer // create a blob/layer
resp, _ := resty.R().Post(url + "/v2/repo7/blobs/uploads/") resp, _ := resty.R().Post(url + "/v2/repo7/blobs/uploads/")
loc := test.Location(url, resp) loc := test.Location(url, resp)
@@ -493,7 +497,12 @@ func uploadManifest(url string) {
}, },
} }
manifest.SchemaVersion = 2 manifest.SchemaVersion = 2
content, _ = json.Marshal(manifest)
content, err := json.Marshal(manifest)
if err != nil {
return err
}
_, _ = resty.R().SetHeader("Content-Type", "application/vnd.oci.image.manifest.v1+json"). _, _ = resty.R().SetHeader("Content-Type", "application/vnd.oci.image.manifest.v1+json").
SetBody(content).Put(url + "/v2/repo7/manifests/test:1.0") SetBody(content).Put(url + "/v2/repo7/manifests/test:1.0")
@@ -515,15 +524,22 @@ func uploadManifest(url string) {
}, },
} }
manifest.SchemaVersion = 2 manifest.SchemaVersion = 2
content, _ = json.Marshal(manifest)
content, err = json.Marshal(manifest)
if err != nil {
return err
}
_, _ = resty.R().SetHeader("Content-Type", "application/vnd.oci.image.manifest.v1+json"). _, _ = resty.R().SetHeader("Content-Type", "application/vnd.oci.image.manifest.v1+json").
SetBody(content).Put(url + "/v2/repo7/manifests/test:2.0") SetBody(content).Put(url + "/v2/repo7/manifests/test:2.0")
return nil
} }
type mockService struct{} type mockService struct{}
func (service mockService) getAllImages(ctx context.Context, config searchConfig, username, password string, func (service mockService) getAllImages(ctx context.Context, config searchConfig, username, password string,
channel chan stringResult, wtgrp *sync.WaitGroup) { channel chan stringResult, wtgrp *sync.WaitGroup,
) {
defer wtgrp.Done() defer wtgrp.Done()
defer close(channel) defer close(channel)
@@ -548,7 +564,8 @@ func (service mockService) getAllImages(ctx context.Context, config searchConfig
} }
func (service mockService) getImageByName(ctx context.Context, config searchConfig, func (service mockService) getImageByName(ctx context.Context, config searchConfig,
username, password, imageName string, channel chan stringResult, wtgrp *sync.WaitGroup) { username, password, imageName string, channel chan stringResult, wtgrp *sync.WaitGroup,
) {
defer wtgrp.Done() defer wtgrp.Done()
defer close(channel) defer close(channel)
@@ -573,7 +590,8 @@ func (service mockService) getImageByName(ctx context.Context, config searchConf
} }
func (service mockService) getCveByImage(ctx context.Context, config searchConfig, username, password, func (service mockService) getCveByImage(ctx context.Context, config searchConfig, username, password,
imageName string, rch chan stringResult, wtgrp *sync.WaitGroup) { imageName string, rch chan stringResult, wtgrp *sync.WaitGroup,
) {
defer wtgrp.Done() defer wtgrp.Done()
defer close(rch) defer close(rch)
@@ -610,22 +628,26 @@ func (service mockService) getCveByImage(ctx context.Context, config searchConfi
} }
func (service mockService) getImagesByCveID(ctx context.Context, config searchConfig, username, password, cvid string, func (service mockService) getImagesByCveID(ctx context.Context, config searchConfig, username, password, cvid string,
rch chan stringResult, wtgrp *sync.WaitGroup) { rch chan stringResult, wtgrp *sync.WaitGroup,
) {
service.getImageByName(ctx, config, username, password, "anImage", rch, wtgrp) service.getImageByName(ctx, config, username, password, "anImage", rch, wtgrp)
} }
func (service mockService) getImagesByDigest(ctx context.Context, config searchConfig, username, func (service mockService) getImagesByDigest(ctx context.Context, config searchConfig, username,
password, digest string, rch chan stringResult, wtgrp *sync.WaitGroup) { password, digest string, rch chan stringResult, wtgrp *sync.WaitGroup,
) {
service.getImageByName(ctx, config, username, password, "anImage", rch, wtgrp) service.getImageByName(ctx, config, username, password, "anImage", rch, wtgrp)
} }
func (service mockService) getImageByNameAndCVEID(ctx context.Context, config searchConfig, username, func (service mockService) getImageByNameAndCVEID(ctx context.Context, config searchConfig, username,
password, imageName, cvid string, rch chan stringResult, wtgrp *sync.WaitGroup) { password, imageName, cvid string, rch chan stringResult, wtgrp *sync.WaitGroup,
) {
service.getImageByName(ctx, config, username, password, imageName, rch, wtgrp) service.getImageByName(ctx, config, username, password, imageName, rch, wtgrp)
} }
func (service mockService) getFixedTagsForCVE(ctx context.Context, config searchConfig, func (service mockService) getFixedTagsForCVE(ctx context.Context, config searchConfig,
username, password, imageName, cvid string, rch chan stringResult, wtgrp *sync.WaitGroup) { username, password, imageName, cvid string, rch chan stringResult, wtgrp *sync.WaitGroup,
) {
service.getImageByName(ctx, config, username, password, imageName, rch, wtgrp) service.getImageByName(ctx, config, username, password, imageName, rch, wtgrp)
} }
+2 -1
View File
@@ -299,7 +299,8 @@ func (search fixedTagsSearcher) search(config searchConfig) (bool, error) {
} }
func collectResults(config searchConfig, wg *sync.WaitGroup, imageErr chan stringResult, func collectResults(config searchConfig, wg *sync.WaitGroup, imageErr chan stringResult,
cancel context.CancelFunc, printHeader printHeader, errCh chan error) { cancel context.CancelFunc, printHeader printHeader, errCh chan error,
) {
var foundResult bool var foundResult bool
defer wg.Done() defer wg.Done()
+26 -16
View File
@@ -44,12 +44,13 @@ func NewSearchService() SearchService {
} }
func (service searchService) getImageByName(ctx context.Context, config searchConfig, func (service searchService) getImageByName(ctx context.Context, config searchConfig,
username, password, imageName string, rch chan stringResult, wtgrp *sync.WaitGroup) { username, password, imageName string, rch chan stringResult, wtgrp *sync.WaitGroup,
) {
defer wtgrp.Done() defer wtgrp.Done()
defer close(rch) defer close(rch)
var localWg sync.WaitGroup var localWg sync.WaitGroup
rlim := newSmoothRateLimiter(ctx, &localWg, rch) rlim := newSmoothRateLimiter(&localWg, rch)
localWg.Add(1) localWg.Add(1)
@@ -62,7 +63,8 @@ func (service searchService) getImageByName(ctx context.Context, config searchCo
} }
func (service searchService) getAllImages(ctx context.Context, config searchConfig, username, password string, func (service searchService) getAllImages(ctx context.Context, config searchConfig, username, password string,
rch chan stringResult, wtgrp *sync.WaitGroup) { rch chan stringResult, wtgrp *sync.WaitGroup,
) {
defer wtgrp.Done() defer wtgrp.Done()
defer close(rch) defer close(rch)
@@ -90,7 +92,7 @@ func (service searchService) getAllImages(ctx context.Context, config searchConf
var localWg sync.WaitGroup var localWg sync.WaitGroup
rlim := newSmoothRateLimiter(ctx, &localWg, rch) rlim := newSmoothRateLimiter(&localWg, rch)
localWg.Add(1) localWg.Add(1)
@@ -106,7 +108,8 @@ func (service searchService) getAllImages(ctx context.Context, config searchConf
} }
func getImage(ctx context.Context, config searchConfig, username, password, imageName string, func getImage(ctx context.Context, config searchConfig, username, password, imageName string,
rch chan stringResult, wtgrp *sync.WaitGroup, pool *requestsPool) { rch chan stringResult, wtgrp *sync.WaitGroup, pool *requestsPool,
) {
defer wtgrp.Done() defer wtgrp.Done()
tagListEndpoint, err := combineServerAndEndpointURL(*config.servURL, fmt.Sprintf("/v2/%s/tags/list", imageName)) tagListEndpoint, err := combineServerAndEndpointURL(*config.servURL, fmt.Sprintf("/v2/%s/tags/list", imageName))
@@ -139,7 +142,8 @@ func getImage(ctx context.Context, config searchConfig, username, password, imag
} }
func (service searchService) getImagesByCveID(ctx context.Context, config searchConfig, username, func (service searchService) getImagesByCveID(ctx context.Context, config searchConfig, username,
password, cvid string, rch chan stringResult, wtgrp *sync.WaitGroup) { password, cvid string, rch chan stringResult, wtgrp *sync.WaitGroup,
) {
defer wtgrp.Done() defer wtgrp.Done()
defer close(rch) defer close(rch)
@@ -176,7 +180,7 @@ func (service searchService) getImagesByCveID(ctx context.Context, config search
var localWg sync.WaitGroup var localWg sync.WaitGroup
rlim := newSmoothRateLimiter(ctx, &localWg, rch) rlim := newSmoothRateLimiter(&localWg, rch)
localWg.Add(1) localWg.Add(1)
go rlim.startRateLimiter(ctx) go rlim.startRateLimiter(ctx)
@@ -193,7 +197,8 @@ func (service searchService) getImagesByCveID(ctx context.Context, config search
} }
func (service searchService) getImagesByDigest(ctx context.Context, config searchConfig, username, func (service searchService) getImagesByDigest(ctx context.Context, config searchConfig, username,
password string, digest string, rch chan stringResult, wtgrp *sync.WaitGroup) { password string, digest string, rch chan stringResult, wtgrp *sync.WaitGroup,
) {
defer wtgrp.Done() defer wtgrp.Done()
defer close(rch) defer close(rch)
@@ -230,7 +235,7 @@ func (service searchService) getImagesByDigest(ctx context.Context, config searc
var localWg sync.WaitGroup var localWg sync.WaitGroup
rlim := newSmoothRateLimiter(ctx, &localWg, rch) rlim := newSmoothRateLimiter(&localWg, rch)
localWg.Add(1) localWg.Add(1)
go rlim.startRateLimiter(ctx) go rlim.startRateLimiter(ctx)
@@ -247,7 +252,8 @@ func (service searchService) getImagesByDigest(ctx context.Context, config searc
} }
func (service searchService) getImageByNameAndCVEID(ctx context.Context, config searchConfig, username, func (service searchService) getImageByNameAndCVEID(ctx context.Context, config searchConfig, username,
password, imageName, cvid string, rch chan stringResult, wtgrp *sync.WaitGroup) { password, imageName, cvid string, rch chan stringResult, wtgrp *sync.WaitGroup,
) {
defer wtgrp.Done() defer wtgrp.Done()
defer close(rch) defer close(rch)
@@ -284,7 +290,7 @@ func (service searchService) getImageByNameAndCVEID(ctx context.Context, config
var localWg sync.WaitGroup var localWg sync.WaitGroup
rlim := newSmoothRateLimiter(ctx, &localWg, rch) rlim := newSmoothRateLimiter(&localWg, rch)
localWg.Add(1) localWg.Add(1)
go rlim.startRateLimiter(ctx) go rlim.startRateLimiter(ctx)
@@ -305,7 +311,8 @@ func (service searchService) getImageByNameAndCVEID(ctx context.Context, config
} }
func (service searchService) getCveByImage(ctx context.Context, config searchConfig, username, password, func (service searchService) getCveByImage(ctx context.Context, config searchConfig, username, password,
imageName string, rch chan stringResult, wtgrp *sync.WaitGroup) { imageName string, rch chan stringResult, wtgrp *sync.WaitGroup,
) {
defer wtgrp.Done() defer wtgrp.Done()
defer close(rch) defer close(rch)
@@ -388,7 +395,8 @@ func isContextDone(ctx context.Context) bool {
} }
func (service searchService) getFixedTagsForCVE(ctx context.Context, config searchConfig, func (service searchService) getFixedTagsForCVE(ctx context.Context, config searchConfig,
username, password, imageName, cvid string, rch chan stringResult, wtgrp *sync.WaitGroup) { username, password, imageName, cvid string, rch chan stringResult, wtgrp *sync.WaitGroup,
) {
defer wtgrp.Done() defer wtgrp.Done()
defer close(rch) defer close(rch)
@@ -425,7 +433,7 @@ func (service searchService) getFixedTagsForCVE(ctx context.Context, config sear
var localWg sync.WaitGroup var localWg sync.WaitGroup
rlim := newSmoothRateLimiter(ctx, &localWg, rch) rlim := newSmoothRateLimiter(&localWg, rch)
localWg.Add(1) localWg.Add(1)
go rlim.startRateLimiter(ctx) go rlim.startRateLimiter(ctx)
@@ -443,7 +451,8 @@ func (service searchService) getFixedTagsForCVE(ctx context.Context, config sear
// errors are returned in the stringResult channel, the unmarshalled payload is in resultPtr. // errors are returned in the stringResult channel, the unmarshalled payload is in resultPtr.
func (service searchService) makeGraphQLQuery(ctx context.Context, config searchConfig, func (service searchService) makeGraphQLQuery(ctx context.Context, config searchConfig,
username, password, query string, username, password, query string,
resultPtr interface{}) error { resultPtr interface{},
) error {
endPoint, err := combineServerAndEndpointURL(*config.servURL, "/query") endPoint, err := combineServerAndEndpointURL(*config.servURL, "/query")
if err != nil { if err != nil {
return err return err
@@ -458,7 +467,8 @@ func (service searchService) makeGraphQLQuery(ctx context.Context, config search
} }
func addManifestCallToPool(ctx context.Context, config searchConfig, pool *requestsPool, func addManifestCallToPool(ctx context.Context, config searchConfig, pool *requestsPool,
username, password, imageName, tagName string, rch chan stringResult, wtgrp *sync.WaitGroup) { username, password, imageName, tagName string, rch chan stringResult, wtgrp *sync.WaitGroup,
) {
defer wtgrp.Done() defer wtgrp.Done()
resultManifest := manifestResponse{} resultManifest := manifestResponse{}
+4 -5
View File
@@ -13,8 +13,7 @@ import (
"testing" "testing"
godigest "github.com/opencontainers/go-digest" godigest "github.com/opencontainers/go-digest"
ispec "github.com/opencontainers/image-spec/specs-go/v1" ispec "github.com/opencontainers/image-spec/specs-go/v1" // nolint: goimports
// nolint:golint,stylecheck,revive // nolint:golint,stylecheck,revive
. "github.com/smartystreets/goconvey/convey" . "github.com/smartystreets/goconvey/convey"
"github.com/smartystreets/goconvey/convey/reporting" "github.com/smartystreets/goconvey/convey/reporting"
@@ -1105,14 +1104,14 @@ func outputJSONExit() {
} }
func validateMinifyRawJSON(rawJSON string) string { func validateMinifyRawJSON(rawJSON string) string {
var j interface{} var jsonData interface{}
err := json.Unmarshal([]byte(rawJSON), &j) err := json.Unmarshal([]byte(rawJSON), &jsonData)
if err != nil { if err != nil {
panic(err) panic(err)
} }
rawJSONBytesMinified, err := json.Marshal(j) rawJSONBytesMinified, err := json.Marshal(jsonData)
if err != nil { if err != nil {
panic(err) panic(err)
} }
+10 -6
View File
@@ -43,7 +43,7 @@ func EnableExtensions(config *config.Config, log log.Logger, rootDir string) {
if config.Extensions.Search.CVE.UpdateInterval < defaultUpdateInterval { if config.Extensions.Search.CVE.UpdateInterval < defaultUpdateInterval {
config.Extensions.Search.CVE.UpdateInterval = defaultUpdateInterval config.Extensions.Search.CVE.UpdateInterval = defaultUpdateInterval
log.Warn().Msg("CVE update interval set to too-short interval < 2h, changing update duration to 2 hours and continuing.") // nolint: lll log.Warn().Msg("CVE update interval set to too-short interval < 2h, changing update duration to 2 hours and continuing.") //nolint:lll // gofumpt conflicts with lll
} }
go func() { go func() {
@@ -72,7 +72,8 @@ func EnableExtensions(config *config.Config, log log.Logger, rootDir string) {
// EnableSyncExtension enables sync extension. // EnableSyncExtension enables sync extension.
func EnableSyncExtension(ctx context.Context, config *config.Config, wg *goSync.WaitGroup, func EnableSyncExtension(ctx context.Context, config *config.Config, wg *goSync.WaitGroup,
storeController storage.StoreController, log log.Logger) { storeController storage.StoreController, log log.Logger,
) {
if config.Extensions.Sync != nil && *config.Extensions.Sync.Enable { if config.Extensions.Sync != nil && *config.Extensions.Sync.Enable {
if err := sync.Run(ctx, *config.Extensions.Sync, storeController, wg, log); err != nil { if err := sync.Run(ctx, *config.Extensions.Sync, storeController, wg, log); err != nil {
log.Error().Err(err).Msg("Error encountered while setting up syncing") log.Error().Err(err).Msg("Error encountered while setting up syncing")
@@ -84,7 +85,8 @@ func EnableSyncExtension(ctx context.Context, config *config.Config, wg *goSync.
// EnableScrubExtension enables scrub extension. // EnableScrubExtension enables scrub extension.
func EnableScrubExtension(config *config.Config, storeController storage.StoreController, func EnableScrubExtension(config *config.Config, storeController storage.StoreController,
log log.Logger) { log log.Logger,
) {
if config.Extensions.Scrub != nil && if config.Extensions.Scrub != nil &&
config.Extensions.Scrub.Interval != 0 { config.Extensions.Scrub.Interval != 0 {
minScrubInterval, _ := time.ParseDuration("2h") minScrubInterval, _ := time.ParseDuration("2h")
@@ -92,7 +94,7 @@ func EnableScrubExtension(config *config.Config, storeController storage.StoreCo
if config.Extensions.Scrub.Interval < minScrubInterval { if config.Extensions.Scrub.Interval < minScrubInterval {
config.Extensions.Scrub.Interval = minScrubInterval config.Extensions.Scrub.Interval = minScrubInterval
log.Warn().Msg("Scrub interval set to too-short interval < 2h, changing scrub duration to 2 hours and continuing.") // nolint: lll log.Warn().Msg("Scrub interval set to too-short interval < 2h, changing scrub duration to 2 hours and continuing.") //nolint:lll // gofumpt conflicts with lll
} }
go func() { go func() {
@@ -108,7 +110,8 @@ func EnableScrubExtension(config *config.Config, storeController storage.StoreCo
// SetupRoutes ... // SetupRoutes ...
func SetupRoutes(config *config.Config, router *mux.Router, storeController storage.StoreController, func SetupRoutes(config *config.Config, router *mux.Router, storeController storage.StoreController,
l log.Logger) { l log.Logger,
) {
// fork a new zerolog child to avoid data race // fork a new zerolog child to avoid data race
log := log.Logger{Logger: l.With().Caller().Timestamp().Logger()} log := log.Logger{Logger: l.With().Caller().Timestamp().Logger()}
log.Info().Msg("setting up extensions routes") log.Info().Msg("setting up extensions routes")
@@ -134,7 +137,8 @@ func SetupRoutes(config *config.Config, router *mux.Router, storeController stor
// SyncOneImage syncs one image. // SyncOneImage syncs one image.
func SyncOneImage(config *config.Config, storeController storage.StoreController, func SyncOneImage(config *config.Config, storeController storage.StoreController,
repoName, reference string, isArtifact bool, log log.Logger) error { repoName, reference string, isArtifact bool, log log.Logger,
) error {
log.Info().Msgf("syncing image %s:%s", repoName, reference) log.Info().Msgf("syncing image %s:%s", repoName, reference)
err := sync.OneImage(*config.Extensions.Sync, storeController, repoName, reference, isArtifact, log) err := sync.OneImage(*config.Extensions.Sync, storeController, repoName, reference, isArtifact, log)
+6 -3
View File
@@ -27,14 +27,16 @@ func EnableExtensions(config *config.Config, log log.Logger, rootDir string) {
// EnableSyncExtension ... // EnableSyncExtension ...
func EnableSyncExtension(ctx context.Context, config *config.Config, wg *goSync.WaitGroup, func EnableSyncExtension(ctx context.Context, config *config.Config, wg *goSync.WaitGroup,
storeController storage.StoreController, log log.Logger) { storeController storage.StoreController, log log.Logger,
) {
log.Warn().Msg("skipping enabling sync extension because given zot binary doesn't support any extensions," + log.Warn().Msg("skipping enabling sync extension because given zot binary doesn't support any extensions," +
"please build zot full binary for this feature") "please build zot full binary for this feature")
} }
// EnableScrubExtension ... // EnableScrubExtension ...
func EnableScrubExtension(config *config.Config, storeController storage.StoreController, func EnableScrubExtension(config *config.Config, storeController storage.StoreController,
log log.Logger) { log log.Logger,
) {
log.Warn().Msg("skipping enabling scrub extension because given zot binary doesn't support any extensions," + log.Warn().Msg("skipping enabling scrub extension because given zot binary doesn't support any extensions," +
"please build zot full binary for this feature") "please build zot full binary for this feature")
} }
@@ -47,7 +49,8 @@ func SetupRoutes(conf *config.Config, router *mux.Router, storeController storag
// SyncOneImage ... // SyncOneImage ...
func SyncOneImage(config *config.Config, storeController storage.StoreController, func SyncOneImage(config *config.Config, storeController storage.StoreController,
repoName, reference string, isArtifact bool, log log.Logger) error { repoName, reference string, isArtifact bool, log log.Logger,
) error {
log.Warn().Msg("skipping syncing on demand because given zot binary doesn't support any extensions," + log.Warn().Msg("skipping syncing on demand because given zot binary doesn't support any extensions," +
"please build zot full binary for this feature") "please build zot full binary for this feature")
+1 -1
View File
@@ -169,7 +169,7 @@ func IncDownloadCounter(ms MetricServer, repo string) {
}) })
} }
func SetStorageUsage(ms MetricServer, rootDir string, repo string) { func SetStorageUsage(ms MetricServer, rootDir, repo string) {
ms.SendMetric(func() { ms.SendMetric(func() {
dir := path.Join(rootDir, repo) dir := path.Join(rootDir, repo)
repoSize, err := getDirSize(dir) repoSize, err := getDirSize(dir)
+3 -3
View File
@@ -235,7 +235,7 @@ func GetHistograms() map[string][]string {
// return true if a metric does not have any labels or if the label // return true if a metric does not have any labels or if the label
// values for searched metric corresponds to the one in the cached slice. // values for searched metric corresponds to the one in the cached slice.
func isMetricMatch(lValues []string, metricValues []string) bool { func isMetricMatch(lValues, metricValues []string) bool {
if len(lValues) == len(metricValues) { if len(lValues) == len(metricValues) {
for i, v := range metricValues { for i, v := range metricValues {
if v != lValues[i] { if v != lValues[i] {
@@ -400,7 +400,7 @@ func (ms *metricServer) HistogramObserve(hv *HistogramValue) {
} }
// nolint: goerr113 // nolint: goerr113
func sanityChecks(name string, knownLabels []string, found bool, labelNames []string, labelValues []string) error { func sanityChecks(name string, knownLabels []string, found bool, labelNames, labelValues []string) error {
if !found { if !found {
return fmt.Errorf("metric %s: not found", name) return fmt.Errorf("metric %s: not found", name)
} }
@@ -479,7 +479,7 @@ func IncUploadCounter(ms MetricServer, repo string) {
ms.SendMetric(uCounter) ms.SendMetric(uCounter)
} }
func SetStorageUsage(ms MetricServer, rootDir string, repo string) { func SetStorageUsage(ms MetricServer, rootDir, repo string) {
dir := path.Join(rootDir, repo) dir := path.Join(rootDir, repo)
repoSize, err := getDirSize(dir) repoSize, err := getDirSize(dir)
+1 -1
View File
@@ -38,7 +38,7 @@ type MetricsClient struct {
} }
func newHTTPMetricsClient() *http.Client { func newHTTPMetricsClient() *http.Client {
defaultTransport := http.DefaultTransport.(*http.Transport).Clone() defaultTransport := http.DefaultTransport.(*http.Transport).Clone() //nolint: forcetypeassert
defaultTransport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} //nolint: gosec defaultTransport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} //nolint: gosec
return &http.Client{ return &http.Client{
+1 -1
View File
@@ -67,7 +67,7 @@ func GetRepo(image string) string {
return image return image
} }
func GetFixedTags(allTags []TagInfo, infectedTags []TagInfo) []TagInfo { func GetFixedTags(allTags, infectedTags []TagInfo) []TagInfo {
sort.Slice(allTags, func(i, j int) bool { sort.Slice(allTags, func(i, j int) bool {
return allTags[i].Timestamp.Before(allTags[j].Timestamp) return allTags[i].Timestamp.Before(allTags[j].Timestamp)
}) })
+3 -2
View File
@@ -139,8 +139,9 @@ func (cveinfo CveInfo) GetTrivyContext(image string) *TrivyCtx {
return trivyCtx return trivyCtx
} }
func (cveinfo CveInfo) GetImageListForCVE(repo string, cvid string, imgStore storage.ImageStore, func (cveinfo CveInfo) GetImageListForCVE(repo, cvid string, imgStore storage.ImageStore,
trivyCtx *TrivyCtx) ([]*string, error) { trivyCtx *TrivyCtx,
) ([]*string, error) {
tags := make([]*string, 0) tags := make([]*string, 0)
tagList, err := imgStore.GetImageTags(repo) tagList, err := imgStore.GetImageTags(repo)
+4 -4
View File
@@ -315,7 +315,7 @@ func generateTestData() error { // nolint: gocyclo
return nil return nil
} }
func makeTestFile(fileName string, content string) error { func makeTestFile(fileName, content string) error {
if err := ioutil.WriteFile(fileName, []byte(content), 0o600); err != nil { if err := ioutil.WriteFile(fileName, []byte(content), 0o600); err != nil {
panic(err) panic(err)
} }
@@ -426,15 +426,15 @@ func TestCVESearch(t *testing.T) {
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp, ShouldNotBeNil) So(resp, ShouldNotBeNil)
So(resp.StatusCode(), ShouldEqual, 401) So(resp.StatusCode(), ShouldEqual, 401)
var e api.Error var apiErr api.Error
err = json.Unmarshal(resp.Body(), &e) err = json.Unmarshal(resp.Body(), &apiErr)
So(err, ShouldBeNil) So(err, ShouldBeNil)
resp, err = resty.R().Get(baseURL + "/query/") resp, err = resty.R().Get(baseURL + "/query/")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp, ShouldNotBeNil) So(resp, ShouldNotBeNil)
So(resp.StatusCode(), ShouldEqual, 401) So(resp.StatusCode(), ShouldEqual, 401)
err = json.Unmarshal(resp.Body(), &e) err = json.Unmarshal(resp.Body(), &apiErr)
So(err, ShouldBeNil) So(err, ShouldBeNil)
// with creds, should get expected status code // with creds, should get expected status code
+1 -1
View File
@@ -23,7 +23,7 @@ func NewDigestInfo(storeController storage.StoreController, log log.Logger) *Dig
} }
// FilterImagesByDigest returns a list of image tags in a repository matching a specific divest. // FilterImagesByDigest returns a list of image tags in a repository matching a specific divest.
func (digestinfo DigestInfo) GetImageTagsByDigest(repo string, digest string) ([]*string, error) { func (digestinfo DigestInfo) GetImageTagsByDigest(repo, digest string) ([]*string, error) {
uniqueTags := []*string{} uniqueTags := []*string{}
manifests, err := digestinfo.LayoutUtils.GetImageManifests(repo) manifests, err := digestinfo.LayoutUtils.GetImageManifests(repo)
+6 -4
View File
@@ -9,7 +9,7 @@ import (
"strings" "strings"
godigest "github.com/opencontainers/go-digest" godigest "github.com/opencontainers/go-digest"
"zotregistry.io/zot/pkg/log" "zotregistry.io/zot/pkg/log" // nolint: gci
"zotregistry.io/zot/pkg/extensions/search/common" "zotregistry.io/zot/pkg/extensions/search/common"
cveinfo "zotregistry.io/zot/pkg/extensions/search/cve" cveinfo "zotregistry.io/zot/pkg/extensions/search/cve"
@@ -247,7 +247,8 @@ func (r *queryResolver) ImageListForCve(ctx context.Context, cvid string) ([]*Im
} }
func (r *queryResolver) getImageListForCVE(repoList []string, cvid string, imgStore storage.ImageStore, func (r *queryResolver) getImageListForCVE(repoList []string, cvid string, imgStore storage.ImageStore,
trivyCtx *cveinfo.TrivyCtx) ([]*ImgResultForCve, error) { trivyCtx *cveinfo.TrivyCtx,
) ([]*ImgResultForCve, error) {
cveResult := []*ImgResultForCve{} cveResult := []*ImgResultForCve{}
for _, repo := range repoList { for _, repo := range repoList {
@@ -270,7 +271,7 @@ func (r *queryResolver) getImageListForCVE(repoList []string, cvid string, imgSt
return cveResult, nil return cveResult, nil
} }
func (r *queryResolver) ImageListWithCVEFixed(ctx context.Context, cvid string, image string) (*ImgResultForFixedCve, error) { // nolint: lll func (r *queryResolver) ImageListWithCVEFixed(ctx context.Context, cvid, image string) (*ImgResultForFixedCve, error) { // nolint: lll
imgResultForFixedCVE := &ImgResultForFixedCve{} imgResultForFixedCVE := &ImgResultForFixedCve{}
r.log.Info().Str("image", image).Msg("extracting list of tags available in image") r.log.Info().Str("image", image).Msg("extracting list of tags available in image")
@@ -396,7 +397,8 @@ func (r *queryResolver) ImageListForDigest(ctx context.Context, digestID string)
} }
func (r *queryResolver) getImageListForDigest(repoList []string, func (r *queryResolver) getImageListForDigest(repoList []string,
digest string) ([]*ImgResultForDigest, error) { digest string,
) ([]*ImgResultForDigest, error) {
imgResultForDigest := []*ImgResultForDigest{} imgResultForDigest := []*ImgResultForDigest{}
var errResult error var errResult error
+7 -4
View File
@@ -44,7 +44,7 @@ func (di *demandedImages) loadOrStoreChan(key string, value chan error) (chan er
return errChannel, found return errChannel, found
} }
func (di *demandedImages) loadOrStoreStr(key string, value string) (string, bool) { func (di *demandedImages) loadOrStoreStr(key, value string) (string, bool) {
val, found := di.syncedMap.LoadOrStore(key, value) val, found := di.syncedMap.LoadOrStore(key, value)
str, _ := val.(string) str, _ := val.(string)
@@ -56,7 +56,8 @@ func (di *demandedImages) delete(key string) {
} }
func OneImage(cfg Config, storeController storage.StoreController, func OneImage(cfg Config, storeController storage.StoreController,
repo, tag string, isArtifact bool, log log.Logger) error { repo, tag string, isArtifact bool, log log.Logger,
) error {
// guard against multiple parallel requests // guard against multiple parallel requests
demandedImage := fmt.Sprintf("%s:%s", repo, tag) demandedImage := fmt.Sprintf("%s:%s", repo, tag)
// loadOrStore image-based channel // loadOrStore image-based channel
@@ -88,7 +89,8 @@ func OneImage(cfg Config, storeController storage.StoreController,
} }
func syncOneImage(imageChannel chan error, cfg Config, storeController storage.StoreController, func syncOneImage(imageChannel chan error, cfg Config, storeController storage.StoreController,
localRepo, tag string, isArtifact bool, log log.Logger) { localRepo, tag string, isArtifact bool, log log.Logger,
) {
var credentialsFile CredentialsFile var credentialsFile CredentialsFile
if cfg.CredentialsFile != "" { if cfg.CredentialsFile != "" {
@@ -267,7 +269,8 @@ func syncOneImage(imageChannel chan error, cfg Config, storeController storage.S
} }
func syncRun(regCfg RegistryConfig, localRepo, remoteRepo, tag string, utils syncContextUtils, func syncRun(regCfg RegistryConfig, localRepo, remoteRepo, tag string, utils syncContextUtils,
log log.Logger) (bool, error) { log log.Logger,
) (bool, error) {
upstreamImageRef, err := getImageRef(utils.upstreamAddr, remoteRepo, tag) upstreamImageRef, err := getImageRef(utils.upstreamAddr, remoteRepo, tag)
if err != nil { if err != nil {
log.Error().Err(err).Msgf("error creating docker reference for repository %s/%s:%s", log.Error().Err(err).Msgf("error creating docker reference for repository %s/%s:%s",
+14 -10
View File
@@ -20,8 +20,9 @@ import (
) )
func getCosignManifest(client *resty.Client, regURL url.URL, repo, digest string, func getCosignManifest(client *resty.Client, regURL url.URL, repo, digest string,
log log.Logger) (*ispec.Manifest, error) { log log.Logger,
var m ispec.Manifest ) (*ispec.Manifest, error) {
var cosignManifest ispec.Manifest
cosignTag := getCosignTagFromImageDigest(digest) cosignTag := getCosignTagFromImageDigest(digest)
@@ -51,7 +52,7 @@ func getCosignManifest(client *resty.Client, regURL url.URL, repo, digest string
return nil, zerr.ErrSyncSignature return nil, zerr.ErrSyncSignature
} }
err = json.Unmarshal(resp.Body(), &m) err = json.Unmarshal(resp.Body(), &cosignManifest)
if err != nil { if err != nil {
log.Error().Err(err).Str("url", getCosignManifestURL.String()). log.Error().Err(err).Str("url", getCosignManifestURL.String()).
Msgf("couldn't unmarshal cosign manifest %s", cosignTag) Msgf("couldn't unmarshal cosign manifest %s", cosignTag)
@@ -59,7 +60,7 @@ func getCosignManifest(client *resty.Client, regURL url.URL, repo, digest string
return nil, err return nil, err
} }
return &m, nil return &cosignManifest, nil
} }
func getNotaryRefs(client *resty.Client, regURL url.URL, repo, digest string, log log.Logger) (ReferenceList, error) { func getNotaryRefs(client *resty.Client, regURL url.URL, repo, digest string, log log.Logger) (ReferenceList, error) {
@@ -195,7 +196,8 @@ func syncCosignSignature(client *resty.Client, imageStore storage.ImageStore,
} }
func syncNotarySignature(client *resty.Client, imageStore storage.ImageStore, func syncNotarySignature(client *resty.Client, imageStore storage.ImageStore,
regURL url.URL, localRepo, remoteRepo, digest string, referrers ReferenceList, log log.Logger) error { regURL url.URL, localRepo, remoteRepo, digest string, referrers ReferenceList, log log.Logger,
) error {
if len(referrers.References) == 0 { if len(referrers.References) == 0 {
return nil return nil
} }
@@ -217,16 +219,16 @@ func syncNotarySignature(client *resty.Client, imageStore storage.ImageStore,
} }
// read manifest // read manifest
var m artifactspec.Manifest var artifactManifest artifactspec.Manifest
err = json.Unmarshal(resp.Body(), &m) err = json.Unmarshal(resp.Body(), &artifactManifest)
if err != nil { if err != nil {
log.Error().Err(err).Msgf("couldn't unmarshal notary manifest: %s", getRefManifestURL.String()) log.Error().Err(err).Msgf("couldn't unmarshal notary manifest: %s", getRefManifestURL.String())
return err return err
} }
for _, blob := range m.Blobs { for _, blob := range artifactManifest.Blobs {
getBlobURL := regURL getBlobURL := regURL
getBlobURL.Path = path.Join(getBlobURL.Path, "v2", remoteRepo, "blobs", blob.Digest.String()) getBlobURL.Path = path.Join(getBlobURL.Path, "v2", remoteRepo, "blobs", blob.Digest.String())
getBlobURL.RawQuery = getBlobURL.Query().Encode() getBlobURL.RawQuery = getBlobURL.Query().Encode()
@@ -270,7 +272,8 @@ func syncNotarySignature(client *resty.Client, imageStore storage.ImageStore,
} }
func canSkipNotarySignature(repo, tag, digest string, refs ReferenceList, imageStore storage.ImageStore, func canSkipNotarySignature(repo, tag, digest string, refs ReferenceList, imageStore storage.ImageStore,
log log.Logger) (bool, error) { log log.Logger,
) (bool, error) {
// check notary signature already synced // check notary signature already synced
if len(refs.References) > 0 { if len(refs.References) > 0 {
localRefs, err := imageStore.GetReferrers(repo, digest, notreg.ArtifactTypeNotation) localRefs, err := imageStore.GetReferrers(repo, digest, notreg.ArtifactTypeNotation)
@@ -297,7 +300,8 @@ func canSkipNotarySignature(repo, tag, digest string, refs ReferenceList, imageS
} }
func canSkipCosignSignature(repo, tag, digest string, cosignManifest *ispec.Manifest, imageStore storage.ImageStore, func canSkipCosignSignature(repo, tag, digest string, cosignManifest *ispec.Manifest, imageStore storage.ImageStore,
log log.Logger) (bool, error) { log log.Logger,
) (bool, error) {
// check cosign signature already synced // check cosign signature already synced
if cosignManifest != nil { if cosignManifest != nil {
var localCosignManifest ispec.Manifest var localCosignManifest ispec.Manifest
+12 -9
View File
@@ -75,7 +75,7 @@ type Tags struct {
// getUpstreamCatalog gets all repos from a registry. // getUpstreamCatalog gets all repos from a registry.
func getUpstreamCatalog(client *resty.Client, upstreamURL string, log log.Logger) (catalog, error) { func getUpstreamCatalog(client *resty.Client, upstreamURL string, log log.Logger) (catalog, error) {
var c catalog var catalog catalog
registryCatalogURL := fmt.Sprintf("%s%s", upstreamURL, "/v2/_catalog") registryCatalogURL := fmt.Sprintf("%s%s", upstreamURL, "/v2/_catalog")
@@ -83,24 +83,24 @@ func getUpstreamCatalog(client *resty.Client, upstreamURL string, log log.Logger
if err != nil { if err != nil {
log.Err(err).Msgf("couldn't query %s", registryCatalogURL) log.Err(err).Msgf("couldn't query %s", registryCatalogURL)
return c, err return catalog, err
} }
if resp.IsError() { if resp.IsError() {
log.Error().Msgf("couldn't query %s, status code: %d, body: %s", registryCatalogURL, log.Error().Msgf("couldn't query %s, status code: %d, body: %s", registryCatalogURL,
resp.StatusCode(), resp.Body()) resp.StatusCode(), resp.Body())
return c, zerr.ErrSyncMissingCatalog return catalog, zerr.ErrSyncMissingCatalog
} }
err = json.Unmarshal(resp.Body(), &c) err = json.Unmarshal(resp.Body(), &catalog)
if err != nil { if err != nil {
log.Err(err).Str("body", string(resp.Body())).Msg("couldn't unmarshal registry's catalog") log.Err(err).Str("body", string(resp.Body())).Msg("couldn't unmarshal registry's catalog")
return c, err return catalog, err
} }
return c, nil return catalog, nil
} }
// getImageTags lists all tags in a repository. // getImageTags lists all tags in a repository.
@@ -189,7 +189,8 @@ func filterImagesBySemver(upstreamReferences *[]types.ImageReference, content Co
// imagesToCopyFromRepos lists all images given a registry name and its repos. // imagesToCopyFromRepos lists all images given a registry name and its repos.
func imagesToCopyFromUpstream(ctx context.Context, registryName string, repos []string, func imagesToCopyFromUpstream(ctx context.Context, registryName string, repos []string,
upstreamCtx *types.SystemContext, content Content, log log.Logger) ([]types.ImageReference, error) { upstreamCtx *types.SystemContext, content Content, log log.Logger,
) ([]types.ImageReference, error) {
var upstreamReferences []types.ImageReference var upstreamReferences []types.ImageReference
for _, repoName := range repos { for _, repoName := range repos {
@@ -286,7 +287,8 @@ func getUpstreamContext(regCfg *RegistryConfig, credentials Credentials) *types.
func syncRegistry(ctx context.Context, regCfg RegistryConfig, upstreamURL string, func syncRegistry(ctx context.Context, regCfg RegistryConfig, upstreamURL string,
storeController storage.StoreController, localCtx *types.SystemContext, storeController storage.StoreController, localCtx *types.SystemContext,
policyCtx *signature.PolicyContext, credentials Credentials, policyCtx *signature.PolicyContext, credentials Credentials,
retryOptions *retry.RetryOptions, log log.Logger) error { retryOptions *retry.RetryOptions, log log.Logger,
) error {
log.Info().Msgf("syncing registry: %s", upstreamURL) log.Info().Msgf("syncing registry: %s", upstreamURL)
var err error var err error
@@ -532,7 +534,8 @@ func getLocalContexts(log log.Logger) (*types.SystemContext, *signature.PolicyCo
} }
func Run(ctx context.Context, cfg Config, storeController storage.StoreController, func Run(ctx context.Context, cfg Config, storeController storage.StoreController,
wtgrp *goSync.WaitGroup, logger log.Logger) error { wtgrp *goSync.WaitGroup, logger log.Logger,
) error {
var credentialsFile CredentialsFile var credentialsFile CredentialsFile
var err error var err error
+33 -33
View File
@@ -1324,13 +1324,13 @@ func TestNoImagesByRegex(t *testing.T) {
So(resp, ShouldNotBeEmpty) So(resp, ShouldNotBeEmpty)
So(resp.StatusCode(), ShouldEqual, 200) So(resp.StatusCode(), ShouldEqual, 200)
var c catalog var catalog catalog
err = json.Unmarshal(resp.Body(), &c) err = json.Unmarshal(resp.Body(), &catalog)
if err != nil { if err != nil {
panic(err) panic(err)
} }
So(c.Repositories, ShouldResemble, []string{}) So(catalog.Repositories, ShouldResemble, []string{})
}) })
} }
@@ -2215,17 +2215,17 @@ func TestPeriodicallySignaturesErr(t *testing.T) {
So(err, ShouldBeNil) So(err, ShouldBeNil)
// read manifest // read manifest
var nm artifactspec.Manifest var artifactManifest artifactspec.Manifest
for _, ref := range referrers.References { for _, ref := range referrers.References {
refPath := path.Join(srcDir, repoName, "blobs", string(ref.Digest.Algorithm()), ref.Digest.Hex()) refPath := path.Join(srcDir, repoName, "blobs", string(ref.Digest.Algorithm()), ref.Digest.Hex())
body, err := ioutil.ReadFile(refPath) body, err := ioutil.ReadFile(refPath)
So(err, ShouldBeNil) So(err, ShouldBeNil)
err = json.Unmarshal(body, &nm) err = json.Unmarshal(body, &artifactManifest)
So(err, ShouldBeNil) So(err, ShouldBeNil)
// triggers perm denied on sig blobs // triggers perm denied on sig blobs
for _, blob := range nm.Blobs { for _, blob := range artifactManifest.Blobs {
blobPath := path.Join(srcDir, repoName, "blobs", string(blob.Digest.Algorithm()), blob.Digest.Hex()) blobPath := path.Join(srcDir, repoName, "blobs", string(blob.Digest.Algorithm()), blob.Digest.Hex())
err := os.Chmod(blobPath, 0o000) err := os.Chmod(blobPath, 0o000)
So(err, ShouldBeNil) So(err, ShouldBeNil)
@@ -2383,17 +2383,17 @@ func TestSignatures(t *testing.T) {
err = os.RemoveAll(path.Join(destDir, repoName)) err = os.RemoveAll(path.Join(destDir, repoName))
So(err, ShouldBeNil) So(err, ShouldBeNil)
var nm artifactspec.Manifest var artifactManifest artifactspec.Manifest
for _, ref := range referrers.References { for _, ref := range referrers.References {
refPath := path.Join(srcDir, repoName, "blobs", string(ref.Digest.Algorithm()), ref.Digest.Hex()) refPath := path.Join(srcDir, repoName, "blobs", string(ref.Digest.Algorithm()), ref.Digest.Hex())
body, err := ioutil.ReadFile(refPath) body, err := ioutil.ReadFile(refPath)
So(err, ShouldBeNil) So(err, ShouldBeNil)
err = json.Unmarshal(body, &nm) err = json.Unmarshal(body, &artifactManifest)
So(err, ShouldBeNil) So(err, ShouldBeNil)
// triggers perm denied on notary sig blobs on downstream // triggers perm denied on notary sig blobs on downstream
for _, blob := range nm.Blobs { for _, blob := range artifactManifest.Blobs {
blobPath := path.Join(destDir, repoName, "blobs", string(blob.Digest.Algorithm()), blob.Digest.Hex()) blobPath := path.Join(destDir, repoName, "blobs", string(blob.Digest.Algorithm()), blob.Digest.Hex())
err := os.MkdirAll(blobPath, 0o755) err := os.MkdirAll(blobPath, 0o755)
So(err, ShouldBeNil) So(err, ShouldBeNil)
@@ -2426,7 +2426,7 @@ func TestSignatures(t *testing.T) {
So(resp.StatusCode(), ShouldEqual, 200) So(resp.StatusCode(), ShouldEqual, 200)
// triggers perm denied on sig blobs // triggers perm denied on sig blobs
for _, blob := range nm.Blobs { for _, blob := range artifactManifest.Blobs {
blobPath := path.Join(srcDir, repoName, "blobs", string(blob.Digest.Algorithm()), blob.Digest.Hex()) blobPath := path.Join(srcDir, repoName, "blobs", string(blob.Digest.Algorithm()), blob.Digest.Hex())
err := os.Chmod(blobPath, 0o000) err := os.Chmod(blobPath, 0o000)
So(err, ShouldBeNil) So(err, ShouldBeNil)
@@ -2449,29 +2449,29 @@ func TestSignatures(t *testing.T) {
mResp, err := resty.R().Get(getCosignManifestURL) mResp, err := resty.R().Get(getCosignManifestURL)
So(err, ShouldBeNil) So(err, ShouldBeNil)
var cm ispec.Manifest var imageManifest ispec.Manifest
err = json.Unmarshal(mResp.Body(), &cm) err = json.Unmarshal(mResp.Body(), &imageManifest)
So(err, ShouldBeNil) So(err, ShouldBeNil)
downstreaamCosignManifest := ispec.Manifest{ downstreaamCosignManifest := ispec.Manifest{
MediaType: cm.MediaType, MediaType: imageManifest.MediaType,
Config: ispec.Descriptor{ Config: ispec.Descriptor{
MediaType: cm.Config.MediaType, MediaType: imageManifest.Config.MediaType,
Size: cm.Config.Size, Size: imageManifest.Config.Size,
Digest: cm.Config.Digest, Digest: imageManifest.Config.Digest,
Annotations: cm.Config.Annotations, Annotations: imageManifest.Config.Annotations,
}, },
Layers: cm.Layers, Layers: imageManifest.Layers,
Versioned: cm.Versioned, Versioned: imageManifest.Versioned,
Annotations: cm.Annotations, Annotations: imageManifest.Annotations,
} }
buf, err := json.Marshal(downstreaamCosignManifest) buf, err := json.Marshal(downstreaamCosignManifest)
So(err, ShouldBeNil) So(err, ShouldBeNil)
cosignManifestDigest := godigest.FromBytes(buf) cosignManifestDigest := godigest.FromBytes(buf)
for _, blob := range cm.Layers { for _, blob := range imageManifest.Layers {
blobPath := path.Join(srcDir, repoName, "blobs", string(blob.Digest.Algorithm()), blob.Digest.Hex()) blobPath := path.Join(srcDir, repoName, "blobs", string(blob.Digest.Algorithm()), blob.Digest.Hex())
err := os.Chmod(blobPath, 0o000) err := os.Chmod(blobPath, 0o000)
So(err, ShouldBeNil) So(err, ShouldBeNil)
@@ -2490,7 +2490,7 @@ func TestSignatures(t *testing.T) {
err = os.RemoveAll(path.Join(destDir, repoName)) err = os.RemoveAll(path.Join(destDir, repoName))
So(err, ShouldBeNil) So(err, ShouldBeNil)
for _, blob := range cm.Layers { for _, blob := range imageManifest.Layers {
srcBlobPath := path.Join(srcDir, repoName, "blobs", string(blob.Digest.Algorithm()), blob.Digest.Hex()) srcBlobPath := path.Join(srcDir, repoName, "blobs", string(blob.Digest.Algorithm()), blob.Digest.Hex())
err := os.Chmod(srcBlobPath, 0o755) err := os.Chmod(srcBlobPath, 0o755)
So(err, ShouldBeNil) So(err, ShouldBeNil)
@@ -2507,7 +2507,7 @@ func TestSignatures(t *testing.T) {
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, 200) So(resp.StatusCode(), ShouldEqual, 200)
for _, blob := range cm.Layers { for _, blob := range imageManifest.Layers {
destBlobPath := path.Join(destDir, repoName, "blobs", string(blob.Digest.Algorithm()), blob.Digest.Hex()) destBlobPath := path.Join(destDir, repoName, "blobs", string(blob.Digest.Algorithm()), blob.Digest.Hex())
err = os.Chmod(destBlobPath, 0o755) err = os.Chmod(destBlobPath, 0o755)
So(err, ShouldBeNil) So(err, ShouldBeNil)
@@ -2516,8 +2516,8 @@ func TestSignatures(t *testing.T) {
} }
// trigger error on upstream config blob // trigger error on upstream config blob
srcConfigBlobPath := path.Join(srcDir, repoName, "blobs", string(cm.Config.Digest.Algorithm()), srcConfigBlobPath := path.Join(srcDir, repoName, "blobs", string(imageManifest.Config.Digest.Algorithm()),
cm.Config.Digest.Hex()) imageManifest.Config.Digest.Hex())
err = os.Chmod(srcConfigBlobPath, 0o000) err = os.Chmod(srcConfigBlobPath, 0o000)
So(err, ShouldBeNil) So(err, ShouldBeNil)
@@ -2538,8 +2538,8 @@ func TestSignatures(t *testing.T) {
err = os.RemoveAll(path.Join(destDir, repoName)) err = os.RemoveAll(path.Join(destDir, repoName))
So(err, ShouldBeNil) So(err, ShouldBeNil)
destConfigBlobPath := path.Join(destDir, repoName, "blobs", string(cm.Config.Digest.Algorithm()), destConfigBlobPath := path.Join(destDir, repoName, "blobs", string(imageManifest.Config.Digest.Algorithm()),
cm.Config.Digest.Hex()) imageManifest.Config.Digest.Hex())
err = os.MkdirAll(destConfigBlobPath, 0o755) err = os.MkdirAll(destConfigBlobPath, 0o755)
So(err, ShouldBeNil) So(err, ShouldBeNil)
@@ -3062,15 +3062,15 @@ func TestSignaturesOnDemand(t *testing.T) {
mResp, err := resty.R().Get(getCosignManifestURL) mResp, err := resty.R().Get(getCosignManifestURL)
So(err, ShouldBeNil) So(err, ShouldBeNil)
var cm ispec.Manifest var imageManifest ispec.Manifest
err = json.Unmarshal(mResp.Body(), &cm) err = json.Unmarshal(mResp.Body(), &imageManifest)
So(err, ShouldBeNil) So(err, ShouldBeNil)
// trigger errors on cosign blobs // trigger errors on cosign blobs
// trigger error on cosign config blob // trigger error on cosign config blob
srcConfigBlobPath := path.Join(srcDir, repoName, "blobs", string(cm.Config.Digest.Algorithm()), srcConfigBlobPath := path.Join(srcDir, repoName, "blobs", string(imageManifest.Config.Digest.Algorithm()),
cm.Config.Digest.Hex()) imageManifest.Config.Digest.Hex())
err = os.Chmod(srcConfigBlobPath, 0o000) err = os.Chmod(srcConfigBlobPath, 0o000)
So(err, ShouldBeNil) So(err, ShouldBeNil)
@@ -3084,8 +3084,8 @@ func TestSignaturesOnDemand(t *testing.T) {
So(resp.StatusCode(), ShouldEqual, 200) So(resp.StatusCode(), ShouldEqual, 200)
// trigger error on cosign layer blob // trigger error on cosign layer blob
srcSignatureBlobPath := path.Join(srcDir, repoName, "blobs", string(cm.Layers[0].Digest.Algorithm()), srcSignatureBlobPath := path.Join(srcDir, repoName, "blobs", string(imageManifest.Layers[0].Digest.Algorithm()),
cm.Layers[0].Digest.Hex()) imageManifest.Layers[0].Digest.Hex())
err = os.Chmod(srcConfigBlobPath, 0o755) err = os.Chmod(srcConfigBlobPath, 0o755)
So(err, ShouldBeNil) So(err, ShouldBeNil)
+4 -2
View File
@@ -206,7 +206,8 @@ func getFileCredentials(filepath string) (CredentialsFile, error) {
} }
func getHTTPClient(regCfg *RegistryConfig, upstreamURL string, credentials Credentials, func getHTTPClient(regCfg *RegistryConfig, upstreamURL string, credentials Credentials,
log log.Logger) (*resty.Client, *url.URL, error) { log log.Logger,
) (*resty.Client, *url.URL, error) {
client := resty.New() client := resty.New()
if !common.Contains(regCfg.URLs, upstreamURL) { if !common.Contains(regCfg.URLs, upstreamURL) {
@@ -262,7 +263,8 @@ func getHTTPClient(regCfg *RegistryConfig, upstreamURL string, credentials Crede
} }
func pushSyncedLocalImage(localRepo, tag, localCachePath string, func pushSyncedLocalImage(localRepo, tag, localCachePath string,
imageStore storage.ImageStore, log log.Logger) error { imageStore storage.ImageStore, log log.Logger,
) error {
log.Info().Msgf("pushing synced local image %s/%s:%s to local registry", localCachePath, localRepo, tag) log.Info().Msgf("pushing synced local image %s/%s:%s to local registry", localCachePath, localRepo, tag)
metrics := monitoring.NewMetricsServer(false, log) metrics := monitoring.NewMetricsServer(false, log)
+2 -2
View File
@@ -21,7 +21,7 @@ func (l Logger) Println(v ...interface{}) {
l.Logger.Error().Msg("panic recovered") l.Logger.Error().Msg("panic recovered")
} }
func NewLogger(level string, output string) Logger { func NewLogger(level, output string) Logger {
zerolog.TimeFieldFormat = time.RFC3339Nano zerolog.TimeFieldFormat = time.RFC3339Nano
lvl, err := zerolog.ParseLevel(level) lvl, err := zerolog.ParseLevel(level)
@@ -46,7 +46,7 @@ func NewLogger(level string, output string) Logger {
return Logger{Logger: log.Hook(goroutineHook{}).With().Caller().Timestamp().Logger()} return Logger{Logger: log.Hook(goroutineHook{}).With().Caller().Timestamp().Logger()}
} }
func NewAuditLogger(level string, audit string) *Logger { func NewAuditLogger(level, audit string) *Logger {
zerolog.TimeFieldFormat = time.RFC3339Nano zerolog.TimeFieldFormat = time.RFC3339Nano
lvl, err := zerolog.ParseLevel(level) lvl, err := zerolog.ParseLevel(level)
+4 -4
View File
@@ -27,7 +27,7 @@ type Blob struct {
Path string Path string
} }
func NewCache(rootDir string, name string, log zlog.Logger) *Cache { func NewCache(rootDir, name string, log zlog.Logger) *Cache {
dbPath := path.Join(rootDir, name+".db") dbPath := path.Join(rootDir, name+".db")
dbOpts := &bbolt.Options{ dbOpts := &bbolt.Options{
Timeout: dbCacheLockCheckTimeout, Timeout: dbCacheLockCheckTimeout,
@@ -60,7 +60,7 @@ func NewCache(rootDir string, name string, log zlog.Logger) *Cache {
return &Cache{rootDir: rootDir, db: cacheDB, log: log} return &Cache{rootDir: rootDir, db: cacheDB, log: log}
} }
func (c *Cache) PutBlob(digest string, path string) error { func (c *Cache) PutBlob(digest, path string) error {
if path == "" { if path == "" {
c.log.Error().Err(errors.ErrEmptyValue).Str("digest", digest).Msg("empty path provided") c.log.Error().Err(errors.ErrEmptyValue).Str("digest", digest).Msg("empty path provided")
@@ -136,7 +136,7 @@ func (c *Cache) GetBlob(digest string) (string, error) {
return blobPath.String(), nil return blobPath.String(), nil
} }
func (c *Cache) HasBlob(digest string, blob string) bool { func (c *Cache) HasBlob(digest, blob string) bool {
if err := c.db.View(func(tx *bbolt.Tx) error { if err := c.db.View(func(tx *bbolt.Tx) error {
root := tx.Bucket([]byte(BlobsCache)) root := tx.Bucket([]byte(BlobsCache))
if root == nil { if root == nil {
@@ -164,7 +164,7 @@ func (c *Cache) HasBlob(digest string, blob string) bool {
return true return true
} }
func (c *Cache) DeleteBlob(digest string, path string) error { func (c *Cache) DeleteBlob(digest, path string) error {
// use only relative (to rootDir) paths on blobs // use only relative (to rootDir) paths on blobs
relp, err := filepath.Rel(c.rootDir, path) relp, err := filepath.Rel(c.rootDir, path)
if err != nil { if err != nil {
+2 -2
View File
@@ -166,7 +166,7 @@ type StorageDriverMock struct {
writerFn func(ctx context.Context, path string, isAppend bool) (driver.FileWriter, error) writerFn func(ctx context.Context, path string, isAppend bool) (driver.FileWriter, error)
statFn func(ctx context.Context, path string) (driver.FileInfo, error) statFn func(ctx context.Context, path string) (driver.FileInfo, error)
listFn func(ctx context.Context, path string) ([]string, error) listFn func(ctx context.Context, path string) ([]string, error)
moveFn func(ctx context.Context, sourcePath string, destPath string) error moveFn func(ctx context.Context, sourcePath, destPath string) error
deleteFn func(ctx context.Context, path string) error deleteFn func(ctx context.Context, path string) error
walkFn func(ctx context.Context, path string, f driver.WalkFn) error walkFn func(ctx context.Context, path string, f driver.WalkFn) error
} }
@@ -227,7 +227,7 @@ func (s *StorageDriverMock) List(ctx context.Context, path string) ([]string, er
return []string{"a"}, nil return []string{"a"}, nil
} }
func (s *StorageDriverMock) Move(ctx context.Context, sourcePath string, destPath string) error { func (s *StorageDriverMock) Move(ctx context.Context, sourcePath, destPath string) error {
if s != nil && s.moveFn != nil { if s != nil && s.moveFn != nil {
return s.moveFn(ctx, sourcePath, destPath) return s.moveFn(ctx, sourcePath, destPath)
} }
+26 -24
View File
@@ -16,7 +16,6 @@ import (
// Add s3 support. // Add s3 support.
"github.com/docker/distribution/registry/storage/driver" "github.com/docker/distribution/registry/storage/driver"
// Load s3 driver. // Load s3 driver.
_ "github.com/docker/distribution/registry/storage/driver/s3-aws" _ "github.com/docker/distribution/registry/storage/driver/s3-aws"
guuid "github.com/gofrs/uuid" guuid "github.com/gofrs/uuid"
@@ -65,7 +64,8 @@ func (is *ObjectStorage) DirExists(d string) bool {
// see https://github.com/docker/docker.github.io/tree/master/registry/storage-drivers // see https://github.com/docker/docker.github.io/tree/master/registry/storage-drivers
func NewImageStore(rootDir string, gc bool, gcDelay time.Duration, dedupe, commit bool, func NewImageStore(rootDir string, gc bool, gcDelay time.Duration, dedupe, commit bool,
log zlog.Logger, metrics monitoring.MetricServer, log zlog.Logger, metrics monitoring.MetricServer,
store driver.StorageDriver) storage.ImageStore { store driver.StorageDriver,
) storage.ImageStore {
imgStore := &ObjectStorage{ imgStore := &ObjectStorage{
rootDir: rootDir, rootDir: rootDir,
store: store, store: store,
@@ -307,7 +307,7 @@ func (is *ObjectStorage) GetImageTags(repo string) ([]string, error) {
} }
// GetImageManifest returns the image manifest of an image in the specific repository. // GetImageManifest returns the image manifest of an image in the specific repository.
func (is *ObjectStorage) GetImageManifest(repo string, reference string) ([]byte, string, string, error) { func (is *ObjectStorage) GetImageManifest(repo, reference string) ([]byte, string, string, error) {
var lockLatency time.Time var lockLatency time.Time
dir := path.Join(is.rootDir, repo) dir := path.Join(is.rootDir, repo)
@@ -381,8 +381,9 @@ func (is *ObjectStorage) GetImageManifest(repo string, reference string) ([]byte
} }
// PutImageManifest adds an image manifest to the repository. // PutImageManifest adds an image manifest to the repository.
func (is *ObjectStorage) PutImageManifest(repo string, reference string, mediaType string, func (is *ObjectStorage) PutImageManifest(repo, reference, mediaType string,
body []byte) (string, error) { body []byte,
) (string, error) {
if err := is.InitRepo(repo); err != nil { if err := is.InitRepo(repo); err != nil {
is.log.Debug().Err(err).Msg("init repo") is.log.Debug().Err(err).Msg("init repo")
@@ -402,20 +403,20 @@ func (is *ObjectStorage) PutImageManifest(repo string, reference string, mediaTy
return "", zerr.ErrBadManifest return "", zerr.ErrBadManifest
} }
var m ispec.Manifest var imageManifest ispec.Manifest
if err := json.Unmarshal(body, &m); err != nil { if err := json.Unmarshal(body, &imageManifest); err != nil {
is.log.Error().Err(err).Msg("unable to unmarshal JSON") is.log.Error().Err(err).Msg("unable to unmarshal JSON")
return "", zerr.ErrBadManifest return "", zerr.ErrBadManifest
} }
if m.SchemaVersion != storage.SchemaVersion { if imageManifest.SchemaVersion != storage.SchemaVersion {
is.log.Error().Int("SchemaVersion", m.SchemaVersion).Msg("invalid manifest") is.log.Error().Int("SchemaVersion", imageManifest.SchemaVersion).Msg("invalid manifest")
return "", zerr.ErrBadManifest return "", zerr.ErrBadManifest
} }
for _, l := range m.Layers { for _, l := range imageManifest.Layers {
digest := l.Digest digest := l.Digest
blobPath := is.BlobPath(repo, digest) blobPath := is.BlobPath(repo, digest)
is.log.Info().Str("blobPath", blobPath).Str("reference", reference).Msg("manifest layers") is.log.Info().Str("blobPath", blobPath).Str("reference", reference).Msg("manifest layers")
@@ -548,7 +549,7 @@ func (is *ObjectStorage) PutImageManifest(repo string, reference string, mediaTy
} }
// DeleteImageManifest deletes the image manifest from the repository. // DeleteImageManifest deletes the image manifest from the repository.
func (is *ObjectStorage) DeleteImageManifest(repo string, reference string) error { func (is *ObjectStorage) DeleteImageManifest(repo, reference string) error {
var lockLatency time.Time var lockLatency time.Time
dir := path.Join(is.rootDir, repo) dir := path.Join(is.rootDir, repo)
@@ -657,7 +658,7 @@ func (is *ObjectStorage) DeleteImageManifest(repo string, reference string) erro
} }
// BlobUploadPath returns the upload path for a blob in this store. // BlobUploadPath returns the upload path for a blob in this store.
func (is *ObjectStorage) BlobUploadPath(repo string, uuid string) string { func (is *ObjectStorage) BlobUploadPath(repo, uuid string) string {
dir := path.Join(is.rootDir, repo) dir := path.Join(is.rootDir, repo)
blobUploadPath := path.Join(dir, storage.BlobUploadDir, uuid) blobUploadPath := path.Join(dir, storage.BlobUploadDir, uuid)
@@ -692,7 +693,7 @@ func (is *ObjectStorage) NewBlobUpload(repo string) (string, error) {
} }
// GetBlobUpload returns the current size of a blob upload. // GetBlobUpload returns the current size of a blob upload.
func (is *ObjectStorage) GetBlobUpload(repo string, uuid string) (int64, error) { func (is *ObjectStorage) GetBlobUpload(repo, uuid string) (int64, error) {
var fileSize int64 var fileSize int64
blobUploadPath := is.BlobUploadPath(repo, uuid) blobUploadPath := is.BlobUploadPath(repo, uuid)
@@ -727,7 +728,7 @@ func (is *ObjectStorage) GetBlobUpload(repo string, uuid string) (int64, error)
// PutBlobChunkStreamed appends another chunk of data to the specified blob. It returns // PutBlobChunkStreamed appends another chunk of data to the specified blob. It returns
// the number of actual bytes to the blob. // the number of actual bytes to the blob.
func (is *ObjectStorage) PutBlobChunkStreamed(repo string, uuid string, body io.Reader) (int64, error) { func (is *ObjectStorage) PutBlobChunkStreamed(repo, uuid string, 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
} }
@@ -769,8 +770,9 @@ func (is *ObjectStorage) PutBlobChunkStreamed(repo string, uuid string, body io.
// PutBlobChunk writes another chunk of data to the specified blob. It returns // PutBlobChunk writes another chunk of data to the specified blob. It returns
// the number of actual bytes to the blob. // the number of actual bytes to the blob.
func (is *ObjectStorage) PutBlobChunk(repo string, uuid string, from int64, to int64, func (is *ObjectStorage) PutBlobChunk(repo, uuid string, from, to int64,
body io.Reader) (int64, error) { 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
} }
@@ -828,7 +830,7 @@ func (is *ObjectStorage) PutBlobChunk(repo string, uuid string, from int64, to i
} }
// BlobUploadInfo returns the current blob size in bytes. // BlobUploadInfo returns the current blob size in bytes.
func (is *ObjectStorage) BlobUploadInfo(repo string, uuid string) (int64, error) { func (is *ObjectStorage) BlobUploadInfo(repo, uuid string) (int64, error) {
var fileSize int64 var fileSize int64
blobUploadPath := is.BlobUploadPath(repo, uuid) blobUploadPath := is.BlobUploadPath(repo, uuid)
@@ -861,7 +863,7 @@ func (is *ObjectStorage) BlobUploadInfo(repo string, uuid string) (int64, error)
} }
// FinishBlobUpload finalizes the blob upload and moves blob the repository. // FinishBlobUpload finalizes the blob upload and moves blob the repository.
func (is *ObjectStorage) FinishBlobUpload(repo string, uuid string, body io.Reader, digest string) error { func (is *ObjectStorage) FinishBlobUpload(repo, uuid string, 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")
@@ -1010,7 +1012,7 @@ func (is *ObjectStorage) RunGCPeriodically(gcInterval time.Duration) {
} }
// DeleteBlobUpload deletes an existing blob upload that is currently in progress. // DeleteBlobUpload deletes an existing blob upload that is currently in progress.
func (is *ObjectStorage) DeleteBlobUpload(repo string, uuid string) error { func (is *ObjectStorage) DeleteBlobUpload(repo, uuid string) error {
blobUploadPath := is.BlobUploadPath(repo, uuid) blobUploadPath := is.BlobUploadPath(repo, uuid)
if err := is.store.Delete(context.Background(), blobUploadPath); err != nil { if err := is.store.Delete(context.Background(), blobUploadPath); err != nil {
is.log.Error().Err(err).Str("blobUploadPath", blobUploadPath).Msg("error deleting blob upload") is.log.Error().Err(err).Str("blobUploadPath", blobUploadPath).Msg("error deleting blob upload")
@@ -1027,7 +1029,7 @@ func (is *ObjectStorage) BlobPath(repo string, digest godigest.Digest) string {
} }
// CheckBlob verifies a blob and returns true if the blob is correct. // CheckBlob verifies a blob and returns true if the blob is correct.
func (is *ObjectStorage) CheckBlob(repo string, digest string) (bool, int64, error) { func (is *ObjectStorage) CheckBlob(repo, digest string) (bool, int64, error) {
var lockLatency time.Time var lockLatency time.Time
dgst, err := godigest.Parse(digest) dgst, err := godigest.Parse(digest)
@@ -1061,7 +1063,7 @@ func (is *ObjectStorage) CheckBlob(repo string, digest string) (bool, int64, err
// GetBlob returns a stream to read the blob. // GetBlob returns a stream to read the blob.
// blob selector instead of directly downloading the blob. // blob selector instead of directly downloading the blob.
func (is *ObjectStorage) GetBlob(repo string, digest string, mediaType string) (io.Reader, int64, error) { func (is *ObjectStorage) GetBlob(repo, digest, mediaType string) (io.Reader, int64, error) {
var lockLatency time.Time var lockLatency time.Time
dgst, err := godigest.Parse(digest) dgst, err := godigest.Parse(digest)
@@ -1093,7 +1095,7 @@ func (is *ObjectStorage) GetBlob(repo string, digest string, mediaType string) (
return blobReader, binfo.Size(), nil return blobReader, binfo.Size(), nil
} }
func (is *ObjectStorage) GetBlobContent(repo string, digest string) ([]byte, error) { func (is *ObjectStorage) GetBlobContent(repo, digest string) ([]byte, error) {
blob, _, err := is.GetBlob(repo, digest, ispec.MediaTypeImageManifest) blob, _, err := is.GetBlob(repo, digest, ispec.MediaTypeImageManifest)
if err != nil { if err != nil {
return []byte{}, err return []byte{}, err
@@ -1111,7 +1113,7 @@ func (is *ObjectStorage) GetBlobContent(repo string, digest string) ([]byte, err
return buf.Bytes(), nil return buf.Bytes(), nil
} }
func (is *ObjectStorage) GetReferrers(repo, digest string, mediaType string) ([]artifactspec.Descriptor, error) { func (is *ObjectStorage) GetReferrers(repo, digest, mediaType string) ([]artifactspec.Descriptor, error) {
return nil, zerr.ErrMethodNotSupported return nil, zerr.ErrMethodNotSupported
} }
@@ -1134,7 +1136,7 @@ func (is *ObjectStorage) GetIndexContent(repo string) ([]byte, error) {
} }
// DeleteBlob removes the blob from the repository. // DeleteBlob removes the blob from the repository.
func (is *ObjectStorage) DeleteBlob(repo string, digest string) error { func (is *ObjectStorage) DeleteBlob(repo, digest string) error {
var lockLatency time.Time var lockLatency time.Time
dgst, err := godigest.Parse(digest) dgst, err := godigest.Parse(digest)
+1 -2
View File
@@ -126,8 +126,7 @@ func checkRepo(imageName string, imgStore ImageStore) ([]ScrubImageResult, error
return results, nil return results, nil
} }
func checkIntegrity(ctx context.Context, imageName, tagName string, oci casext.Engine, manifest ispec.Descriptor, func checkIntegrity(ctx context.Context, imageName, tagName string, oci casext.Engine, manifest ispec.Descriptor, dir string) ScrubImageResult { // nolint: lll
dir string) ScrubImageResult {
// check manifest and config // check manifest and config
stat, err := umoci.Stat(ctx, oci, manifest) stat, err := umoci.Stat(ctx, oci, manifest)
+2 -1
View File
@@ -117,7 +117,8 @@ func TestCheckAllBlobsIntegrity(t *testing.T) {
} }
mnfst.SchemaVersion = 2 mnfst.SchemaVersion = 2
mb, _ := json.Marshal(mnfst) mb, err := json.Marshal(mnfst)
So(err, ShouldBeNil)
manifest, err = imgStore.PutImageManifest(repoName, tag, ispec.MediaTypeImageManifest, mb) manifest, err = imgStore.PutImageManifest(repoName, tag, ispec.MediaTypeImageManifest, mb)
So(err, ShouldBeNil) So(err, ShouldBeNil)
+13 -13
View File
@@ -24,23 +24,23 @@ type ImageStore interface {
ValidateRepo(name string) (bool, error) ValidateRepo(name string) (bool, error)
GetRepositories() ([]string, error) GetRepositories() ([]string, error)
GetImageTags(repo string) ([]string, error) GetImageTags(repo string) ([]string, error)
GetImageManifest(repo string, reference string) ([]byte, string, string, error) GetImageManifest(repo, reference string) ([]byte, string, string, error)
PutImageManifest(repo string, reference string, mediaType string, body []byte) (string, error) PutImageManifest(repo, reference, mediaType string, body []byte) (string, error)
DeleteImageManifest(repo string, reference string) error DeleteImageManifest(repo, reference string) error
BlobUploadPath(repo string, uuid string) string BlobUploadPath(repo, uuid string) string
NewBlobUpload(repo string) (string, error) NewBlobUpload(repo string) (string, error)
GetBlobUpload(repo string, uuid string) (int64, error) GetBlobUpload(repo, uuid string) (int64, error)
PutBlobChunkStreamed(repo string, uuid string, body io.Reader) (int64, error) PutBlobChunkStreamed(repo, uuid string, body io.Reader) (int64, error)
PutBlobChunk(repo string, uuid string, from int64, to int64, body io.Reader) (int64, error) PutBlobChunk(repo, uuid string, from, to int64, body io.Reader) (int64, error)
BlobUploadInfo(repo string, uuid string) (int64, error) BlobUploadInfo(repo, uuid string) (int64, error)
FinishBlobUpload(repo string, uuid string, body io.Reader, digest string) error FinishBlobUpload(repo, uuid string, body io.Reader, digest string) error
FullBlobUpload(repo string, body io.Reader, digest string) (string, int64, error) FullBlobUpload(repo string, body io.Reader, digest string) (string, int64, error)
DedupeBlob(src string, dstDigest digest.Digest, dst string) error DedupeBlob(src string, dstDigest digest.Digest, dst string) error
DeleteBlobUpload(repo string, uuid string) error DeleteBlobUpload(repo, uuid string) error
BlobPath(repo string, digest digest.Digest) string BlobPath(repo string, digest digest.Digest) string
CheckBlob(repo string, digest string) (bool, int64, error) CheckBlob(repo, digest string) (bool, int64, error)
GetBlob(repo string, digest string, mediaType string) (io.Reader, int64, error) GetBlob(repo, digest, mediaType string) (io.Reader, int64, error)
DeleteBlob(repo string, digest string) error DeleteBlob(repo, digest string) error
GetIndexContent(repo string) ([]byte, error) GetIndexContent(repo string) ([]byte, error)
GetBlobContent(repo, digest string) ([]byte, error) GetBlobContent(repo, digest string) ([]byte, error)
GetReferrers(repo, digest string, mediaType string) ([]artifactspec.Descriptor, error) GetReferrers(repo, digest string, mediaType string) ([]artifactspec.Descriptor, error)
+24 -21
View File
@@ -106,7 +106,8 @@ func (sc StoreController) GetImageStore(name string) ImageStore {
// NewImageStore returns a new image store backed by a file storage. // NewImageStore returns a new image store backed by a file storage.
func NewImageStore(rootDir string, gc bool, gcDelay time.Duration, dedupe, commit bool, func NewImageStore(rootDir string, gc bool, gcDelay time.Duration, dedupe, commit bool,
log zlog.Logger, metrics monitoring.MetricServer) ImageStore { log zlog.Logger, metrics monitoring.MetricServer,
) ImageStore {
if _, err := os.Stat(rootDir); os.IsNotExist(err) { if _, err := os.Stat(rootDir); os.IsNotExist(err) {
if err := os.MkdirAll(rootDir, DefaultDirPerms); err != nil { if err := os.MkdirAll(rootDir, DefaultDirPerms); err != nil {
log.Error().Err(err).Str("rootDir", rootDir).Msg("unable to create root dir") log.Error().Err(err).Str("rootDir", rootDir).Msg("unable to create root dir")
@@ -387,7 +388,7 @@ func (is *ImageStoreFS) GetImageTags(repo string) ([]string, error) {
} }
// GetImageManifest returns the image manifest of an image in the specific repository. // GetImageManifest returns the image manifest of an image in the specific repository.
func (is *ImageStoreFS) GetImageManifest(repo string, reference string) ([]byte, string, string, error) { func (is *ImageStoreFS) GetImageManifest(repo, reference string) ([]byte, string, string, error) {
var lockLatency time.Time var lockLatency time.Time
dir := path.Join(is.rootDir, repo) dir := path.Join(is.rootDir, repo)
@@ -471,7 +472,7 @@ func (is *ImageStoreFS) GetImageManifest(repo string, reference string) ([]byte,
return buf, digest.String(), mediaType, nil return buf, digest.String(), mediaType, nil
} }
func (is *ImageStoreFS) validateOCIManifest(repo string, reference string, manifest *ispec.Manifest) (string, error) { func (is *ImageStoreFS) validateOCIManifest(repo, reference string, manifest *ispec.Manifest) (string, error) {
if manifest.SchemaVersion != SchemaVersion { if manifest.SchemaVersion != SchemaVersion {
is.log.Error().Int("SchemaVersion", manifest.SchemaVersion).Msg("invalid manifest") is.log.Error().Int("SchemaVersion", manifest.SchemaVersion).Msg("invalid manifest")
@@ -526,8 +527,9 @@ func (is *ImageStoreFS) validateOCIManifest(repo string, reference string, manif
} }
// PutImageManifest adds an image manifest to the repository. // PutImageManifest adds an image manifest to the repository.
func (is *ImageStoreFS) PutImageManifest(repo string, reference string, mediaType string, func (is *ImageStoreFS) PutImageManifest(repo, reference, mediaType string,
body []byte) (string, error) { body []byte,
) (string, error) {
if err := is.InitRepo(repo); err != nil { if err := is.InitRepo(repo); err != nil {
is.log.Debug().Err(err).Msg("init repo") is.log.Debug().Err(err).Msg("init repo")
@@ -703,7 +705,7 @@ func (is *ImageStoreFS) PutImageManifest(repo string, reference string, mediaTyp
} }
// DeleteImageManifest deletes the image manifest from the repository. // DeleteImageManifest deletes the image manifest from the repository.
func (is *ImageStoreFS) DeleteImageManifest(repo string, reference string) error { func (is *ImageStoreFS) DeleteImageManifest(repo, reference string) error {
var lockLatency time.Time var lockLatency time.Time
dir := path.Join(is.rootDir, repo) dir := path.Join(is.rootDir, repo)
@@ -815,7 +817,7 @@ func (is *ImageStoreFS) DeleteImageManifest(repo string, reference string) error
} }
// BlobUploadPath returns the upload path for a blob in this store. // BlobUploadPath returns the upload path for a blob in this store.
func (is *ImageStoreFS) BlobUploadPath(repo string, uuid string) string { func (is *ImageStoreFS) BlobUploadPath(repo, uuid string) string {
dir := path.Join(is.rootDir, repo) dir := path.Join(is.rootDir, repo)
blobUploadPath := path.Join(dir, BlobUploadDir, uuid) blobUploadPath := path.Join(dir, BlobUploadDir, uuid)
@@ -849,7 +851,7 @@ func (is *ImageStoreFS) NewBlobUpload(repo string) (string, error) {
} }
// GetBlobUpload returns the current size of a blob upload. // GetBlobUpload returns the current size of a blob upload.
func (is *ImageStoreFS) GetBlobUpload(repo string, uuid string) (int64, error) { func (is *ImageStoreFS) GetBlobUpload(repo, uuid string) (int64, error) {
blobUploadPath := is.BlobUploadPath(repo, uuid) blobUploadPath := is.BlobUploadPath(repo, uuid)
binfo, err := os.Stat(blobUploadPath) binfo, err := os.Stat(blobUploadPath)
@@ -866,7 +868,7 @@ func (is *ImageStoreFS) GetBlobUpload(repo string, uuid string) (int64, error) {
// PutBlobChunkStreamed appends another chunk of data to the specified blob. It returns // PutBlobChunkStreamed appends another chunk of data to the specified blob. It returns
// the number of actual bytes to the blob. // the number of actual bytes to the blob.
func (is *ImageStoreFS) PutBlobChunkStreamed(repo string, uuid string, body io.Reader) (int64, error) { func (is *ImageStoreFS) PutBlobChunkStreamed(repo, uuid string, 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
} }
@@ -906,8 +908,9 @@ func (is *ImageStoreFS) PutBlobChunkStreamed(repo string, uuid string, body io.R
// PutBlobChunk writes another chunk of data to the specified blob. It returns // PutBlobChunk writes another chunk of data to the specified blob. It returns
// the number of actual bytes to the blob. // the number of actual bytes to the blob.
func (is *ImageStoreFS) PutBlobChunk(repo string, uuid string, from int64, to int64, func (is *ImageStoreFS) PutBlobChunk(repo, uuid string, from, to int64,
body io.Reader) (int64, error) { 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
} }
@@ -953,7 +956,7 @@ func (is *ImageStoreFS) PutBlobChunk(repo string, uuid string, from int64, to in
} }
// BlobUploadInfo returns the current blob size in bytes. // BlobUploadInfo returns the current blob size in bytes.
func (is *ImageStoreFS) BlobUploadInfo(repo string, uuid string) (int64, error) { func (is *ImageStoreFS) BlobUploadInfo(repo, uuid string) (int64, error) {
blobUploadPath := is.BlobUploadPath(repo, uuid) blobUploadPath := is.BlobUploadPath(repo, uuid)
binfo, err := os.Stat(blobUploadPath) binfo, err := os.Stat(blobUploadPath)
@@ -969,7 +972,7 @@ func (is *ImageStoreFS) BlobUploadInfo(repo string, uuid string) (int64, error)
} }
// FinishBlobUpload finalizes the blob upload and moves blob the repository. // FinishBlobUpload finalizes the blob upload and moves blob the repository.
func (is *ImageStoreFS) FinishBlobUpload(repo string, uuid string, body io.Reader, digest string) error { func (is *ImageStoreFS) FinishBlobUpload(repo, uuid string, 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")
@@ -1169,7 +1172,7 @@ retry:
is.log.Error().Err(err).Str("blobPath", dstRecord).Msg("dedupe: unable to stat") is.log.Error().Err(err).Str("blobPath", dstRecord).Msg("dedupe: unable to stat")
// the actual blob on disk may have been removed by GC, so sync the cache // the actual blob on disk may have been removed by GC, so sync the cache
if err := is.cache.DeleteBlob(dstDigest.String(), dstRecord); err != nil { if err := is.cache.DeleteBlob(dstDigest.String(), dstRecord); err != nil {
// nolint:lll //nolint:lll // gofumpt conflicts with lll
is.log.Error().Err(err).Str("dstDigest", dstDigest.String()).Str("dst", dst).Msg("dedupe: unable to delete blob record") is.log.Error().Err(err).Str("dstDigest", dstDigest.String()).Str("dst", dst).Msg("dedupe: unable to delete blob record")
return err return err
@@ -1215,7 +1218,7 @@ retry:
} }
// DeleteBlobUpload deletes an existing blob upload that is currently in progress. // DeleteBlobUpload deletes an existing blob upload that is currently in progress.
func (is *ImageStoreFS) DeleteBlobUpload(repo string, uuid string) error { func (is *ImageStoreFS) DeleteBlobUpload(repo, uuid string) error {
blobUploadPath := is.BlobUploadPath(repo, uuid) blobUploadPath := is.BlobUploadPath(repo, uuid)
if err := os.Remove(blobUploadPath); err != nil { if err := os.Remove(blobUploadPath); err != nil {
is.log.Error().Err(err).Str("blobUploadPath", blobUploadPath).Msg("error deleting blob upload") is.log.Error().Err(err).Str("blobUploadPath", blobUploadPath).Msg("error deleting blob upload")
@@ -1232,7 +1235,7 @@ func (is *ImageStoreFS) BlobPath(repo string, digest godigest.Digest) string {
} }
// CheckBlob verifies a blob and returns true if the blob is correct. // CheckBlob verifies a blob and returns true if the blob is correct.
func (is *ImageStoreFS) CheckBlob(repo string, digest string) (bool, int64, error) { func (is *ImageStoreFS) CheckBlob(repo, digest string) (bool, int64, error) {
var lockLatency time.Time var lockLatency time.Time
parsedDigest, err := godigest.Parse(digest) parsedDigest, err := godigest.Parse(digest)
@@ -1301,7 +1304,7 @@ func (is *ImageStoreFS) checkCacheBlob(digest string) (string, error) {
return dstRecord, nil return dstRecord, nil
} }
func (is *ImageStoreFS) copyBlob(repo string, blobPath string, dstRecord string) (int64, error) { func (is *ImageStoreFS) copyBlob(repo, blobPath, dstRecord string) (int64, error) {
if err := is.initRepo(repo); err != nil { if err := is.initRepo(repo); err != nil {
is.log.Error().Err(err).Str("repo", repo).Msg("unable to initialize an empty repo") is.log.Error().Err(err).Str("repo", repo).Msg("unable to initialize an empty repo")
@@ -1326,7 +1329,7 @@ func (is *ImageStoreFS) copyBlob(repo string, blobPath string, dstRecord string)
// GetBlob returns a stream to read the blob. // GetBlob returns a stream to read the blob.
// blob selector instead of directly downloading the blob. // blob selector instead of directly downloading the blob.
func (is *ImageStoreFS) GetBlob(repo string, digest string, mediaType string) (io.Reader, int64, error) { func (is *ImageStoreFS) GetBlob(repo, digest, mediaType string) (io.Reader, int64, error) {
var lockLatency time.Time var lockLatency time.Time
parsedDigest, err := godigest.Parse(digest) parsedDigest, err := godigest.Parse(digest)
@@ -1358,7 +1361,7 @@ func (is *ImageStoreFS) GetBlob(repo string, digest string, mediaType string) (i
return blobReader, binfo.Size(), nil return blobReader, binfo.Size(), nil
} }
func (is *ImageStoreFS) GetBlobContent(repo string, digest string) ([]byte, error) { func (is *ImageStoreFS) GetBlobContent(repo, digest string) ([]byte, error) {
blob, _, err := is.GetBlob(repo, digest, ispec.MediaTypeImageManifest) blob, _, err := is.GetBlob(repo, digest, ispec.MediaTypeImageManifest)
if err != nil { if err != nil {
return []byte{}, err return []byte{}, err
@@ -1401,7 +1404,7 @@ func (is *ImageStoreFS) GetIndexContent(repo string) ([]byte, error) {
} }
// DeleteBlob removes the blob from the repository. // DeleteBlob removes the blob from the repository.
func (is *ImageStoreFS) DeleteBlob(repo string, digest string) error { func (is *ImageStoreFS) DeleteBlob(repo, digest string) error {
var lockLatency time.Time var lockLatency time.Time
dgst, err := godigest.Parse(digest) dgst, err := godigest.Parse(digest)
@@ -1440,7 +1443,7 @@ func (is *ImageStoreFS) DeleteBlob(repo string, digest string) error {
return nil return nil
} }
func (is *ImageStoreFS) GetReferrers(repo, digest string, mediaType string) ([]artifactspec.Descriptor, error) { func (is *ImageStoreFS) GetReferrers(repo, digest, mediaType string) ([]artifactspec.Descriptor, error) {
var lockLatency time.Time var lockLatency time.Time
dir := path.Join(is.rootDir, repo) dir := path.Join(is.rootDir, repo)
+16 -8
View File
@@ -84,7 +84,8 @@ func TestStorageFSAPIs(t *testing.T) {
} }
manifest.SchemaVersion = 2 manifest.SchemaVersion = 2
manifestBuf, _ := json.Marshal(manifest) manifestBuf, err := json.Marshal(manifest)
So(err, ShouldBeNil)
digest = godigest.FromBytes(manifestBuf) digest = godigest.FromBytes(manifestBuf)
err = os.Chmod(path.Join(imgStore.RootDir(), repoName, "index.json"), 0o000) err = os.Chmod(path.Join(imgStore.RootDir(), repoName, "index.json"), 0o000)
@@ -217,7 +218,8 @@ func TestDedupeLinks(t *testing.T) {
}, },
} }
manifest.SchemaVersion = 2 manifest.SchemaVersion = 2
manifestBuf, _ := json.Marshal(manifest) manifestBuf, err := json.Marshal(manifest)
So(err, ShouldBeNil)
digest = godigest.FromBytes(manifestBuf) digest = godigest.FromBytes(manifestBuf)
_, err = imgStore.PutImageManifest("dedupe1", digest.String(), ispec.MediaTypeImageManifest, manifestBuf) _, err = imgStore.PutImageManifest("dedupe1", digest.String(), ispec.MediaTypeImageManifest, manifestBuf)
So(err, ShouldBeNil) So(err, ShouldBeNil)
@@ -273,7 +275,8 @@ func TestDedupeLinks(t *testing.T) {
}, },
} }
manifest.SchemaVersion = 2 manifest.SchemaVersion = 2
manifestBuf, _ = json.Marshal(manifest) manifestBuf, err = json.Marshal(manifest)
So(err, ShouldBeNil)
digest = godigest.FromBytes(manifestBuf) digest = godigest.FromBytes(manifestBuf)
_, err = imgStore.PutImageManifest("dedupe2", "1.0", ispec.MediaTypeImageManifest, manifestBuf) _, err = imgStore.PutImageManifest("dedupe2", "1.0", ispec.MediaTypeImageManifest, manifestBuf)
So(err, ShouldBeNil) So(err, ShouldBeNil)
@@ -779,7 +782,8 @@ func TestGarbageCollect(t *testing.T) {
} }
manifest.SchemaVersion = 2 manifest.SchemaVersion = 2
manifestBuf, _ := json.Marshal(manifest) manifestBuf, err := json.Marshal(manifest)
So(err, ShouldBeNil)
digest := godigest.FromBytes(manifestBuf) digest := godigest.FromBytes(manifestBuf)
_, err = imgStore.PutImageManifest(repoName, tag, ispec.MediaTypeImageManifest, manifestBuf) _, err = imgStore.PutImageManifest(repoName, tag, ispec.MediaTypeImageManifest, manifestBuf)
@@ -866,7 +870,8 @@ func TestGarbageCollect(t *testing.T) {
} }
manifest.SchemaVersion = 2 manifest.SchemaVersion = 2
manifestBuf, _ := json.Marshal(manifest) manifestBuf, err := json.Marshal(manifest)
So(err, ShouldBeNil)
digest := godigest.FromBytes(manifestBuf) digest := godigest.FromBytes(manifestBuf)
_, err = imgStore.PutImageManifest(repoName, tag, ispec.MediaTypeImageManifest, manifestBuf) _, err = imgStore.PutImageManifest(repoName, tag, ispec.MediaTypeImageManifest, manifestBuf)
@@ -945,7 +950,8 @@ func TestGarbageCollect(t *testing.T) {
} }
manifest.SchemaVersion = 2 manifest.SchemaVersion = 2
manifestBuf, _ := json.Marshal(manifest) manifestBuf, err := json.Marshal(manifest)
So(err, ShouldBeNil)
_, err = imgStore.PutImageManifest(repo1Name, tag, ispec.MediaTypeImageManifest, manifestBuf) _, err = imgStore.PutImageManifest(repo1Name, tag, ispec.MediaTypeImageManifest, manifestBuf)
So(err, ShouldBeNil) So(err, ShouldBeNil)
@@ -1007,7 +1013,8 @@ func TestGarbageCollect(t *testing.T) {
} }
manifest.SchemaVersion = 2 manifest.SchemaVersion = 2
manifestBuf, _ = json.Marshal(manifest) manifestBuf, err = json.Marshal(manifest)
So(err, ShouldBeNil)
_, err = imgStore.PutImageManifest(repo2Name, tag, ispec.MediaTypeImageManifest, manifestBuf) _, err = imgStore.PutImageManifest(repo2Name, tag, ispec.MediaTypeImageManifest, manifestBuf)
So(err, ShouldBeNil) So(err, ShouldBeNil)
@@ -1062,7 +1069,8 @@ func TestGarbageCollect(t *testing.T) {
} }
manifest.SchemaVersion = 2 manifest.SchemaVersion = 2
manifestBuf, _ = json.Marshal(manifest) manifestBuf, err = json.Marshal(manifest)
So(err, ShouldBeNil)
digest := godigest.FromBytes(manifestBuf) digest := godigest.FromBytes(manifestBuf)
_, err = imgStore.PutImageManifest(repo2Name, tag, ispec.MediaTypeImageManifest, manifestBuf) _, err = imgStore.PutImageManifest(repo2Name, tag, ispec.MediaTypeImageManifest, manifestBuf)
+15 -7
View File
@@ -235,7 +235,8 @@ func TestStorageAPIs(t *testing.T) {
manifest := ispec.Manifest{} manifest := ispec.Manifest{}
manifest.SchemaVersion = 2 manifest.SchemaVersion = 2
manifestBuf, _ := json.Marshal(manifest) manifestBuf, err := json.Marshal(manifest)
So(err, ShouldBeNil)
Convey("Bad image manifest", func() { Convey("Bad image manifest", func() {
_, err = imgStore.PutImageManifest("test", digest.String(), "application/json", _, err = imgStore.PutImageManifest("test", digest.String(), "application/json",
@@ -289,12 +290,14 @@ func TestStorageAPIs(t *testing.T) {
} }
manifest.SchemaVersion = 2 manifest.SchemaVersion = 2
manifestBuf, _ = json.Marshal(manifest) manifestBuf, err = json.Marshal(manifest)
So(err, ShouldBeNil)
digest := godigest.FromBytes(manifestBuf) digest := godigest.FromBytes(manifestBuf)
// bad manifest // bad manifest
manifest.Layers[0].Digest = godigest.FromBytes([]byte("inexistent")) manifest.Layers[0].Digest = godigest.FromBytes([]byte("inexistent"))
badMb, _ := json.Marshal(manifest) badMb, err := json.Marshal(manifest)
So(err, ShouldBeNil)
_, err = imgStore.PutImageManifest("test", "1.0", ispec.MediaTypeImageManifest, badMb) _, err = imgStore.PutImageManifest("test", "1.0", ispec.MediaTypeImageManifest, badMb)
So(err, ShouldNotBeNil) So(err, ShouldNotBeNil)
@@ -428,7 +431,8 @@ func TestStorageAPIs(t *testing.T) {
manifest := ispec.Manifest{} manifest := ispec.Manifest{}
manifest.SchemaVersion = 2 manifest.SchemaVersion = 2
manifestBuf, _ := json.Marshal(manifest) manifestBuf, err := json.Marshal(manifest)
So(err, ShouldBeNil)
Convey("Bad digests", func() { Convey("Bad digests", func() {
_, _, err := imgStore.FullBlobUpload("test", bytes.NewBuffer([]byte{}), "inexistent") _, _, err := imgStore.FullBlobUpload("test", bytes.NewBuffer([]byte{}), "inexistent")
@@ -473,7 +477,8 @@ func TestStorageAPIs(t *testing.T) {
}, },
} }
manifest.SchemaVersion = 2 manifest.SchemaVersion = 2
manifestBuf, _ = json.Marshal(manifest) manifestBuf, err = json.Marshal(manifest)
So(err, ShouldBeNil)
digest := godigest.FromBytes(manifestBuf) digest := godigest.FromBytes(manifestBuf)
_, err = imgStore.PutImageManifest("test", digest.String(), ispec.MediaTypeImageManifest, manifestBuf) _, err = imgStore.PutImageManifest("test", digest.String(), ispec.MediaTypeImageManifest, manifestBuf)
So(err, ShouldBeNil) So(err, ShouldBeNil)
@@ -567,7 +572,9 @@ func TestStorageAPIs(t *testing.T) {
}, },
} }
manifest.SchemaVersion = 2 manifest.SchemaVersion = 2
manifestBuf, _ := json.Marshal(manifest) manifestBuf, err := json.Marshal(manifest)
So(err, ShouldBeNil)
digest = godigest.FromBytes(manifestBuf) digest = godigest.FromBytes(manifestBuf)
_, err = imgStore.PutImageManifest("replace", "1.0", ispec.MediaTypeImageManifest, manifestBuf) _, err = imgStore.PutImageManifest("replace", "1.0", ispec.MediaTypeImageManifest, manifestBuf)
So(err, ShouldBeNil) So(err, ShouldBeNil)
@@ -617,7 +624,8 @@ func TestStorageAPIs(t *testing.T) {
}, },
} }
manifest.SchemaVersion = 2 manifest.SchemaVersion = 2
manifestBuf, _ = json.Marshal(manifest) manifestBuf, err = json.Marshal(manifest)
So(err, ShouldBeNil)
_ = godigest.FromBytes(manifestBuf) _ = godigest.FromBytes(manifestBuf)
_, err = imgStore.PutImageManifest("replace", "1.0", ispec.MediaTypeImageManifest, manifestBuf) _, err = imgStore.PutImageManifest("replace", "1.0", ispec.MediaTypeImageManifest, manifestBuf)
So(err, ShouldBeNil) So(err, ShouldBeNil)
+1 -1
View File
@@ -85,7 +85,7 @@ func Location(baseURL string, resp *resty.Response) string {
return baseURL + path return baseURL + path
} }
func CopyFiles(sourceDir string, destDir string) error { func CopyFiles(sourceDir, destDir string) error {
sourceMeta, err := os.Stat(sourceDir) sourceMeta, err := os.Stat(sourceDir)
if err != nil { if err != nil {
return fmt.Errorf("CopyFiles os.Stat failed: %w", err) return fmt.Errorf("CopyFiles os.Stat failed: %w", err)