0
Fork 0
mirror of https://github.com/project-zot/zot.git synced 2024-12-16 21:56:37 -05:00

chore(trivy): update trivy version and enforce OCI compliant repo names in local image storage (#1068)

1. chore(trivy): update trivy library version

The trivy team switched github.com/urfave/cli for viper so
there are some other code changes as well.

Since we don't use github.com/urfave/cli directly in our software
we needed to add a tools.go in order for "go mod tidy" to not delete it.
See this pattern explained in:
- https://github.com/99designs/gqlgen#quick-start
- https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module
- https://github.com/go-modules-by-example/index/blob/master/010_tools/README.md#walk-through

The jobs using "go get -u" have been updated to use "go install", since go get
modifies the go.mod by upgrading some of the packages, but downgrading trivy to an older
version with broken dependencies

2. fix(storage) Update local storage to ignore folder names not compliant with dist spec
Also updated trivy to download the DB and cache results under the rootDir/_trivy folder

3. fix(s3): one of the s3 tests was missing the skipIt call
This caused a failure when running locally without s3 being available

4. make sure the offline scanning is enabled, and zot only downloads the trivy DB
on the regular schedule, and doesn't download the DB on every image scan

ci: increase build and test timeout as tests are reaching the limit more often

Signed-off-by: Andrei Aaron <aaaron@luxoft.com>
This commit is contained in:
Andrei Aaron 2023-01-18 18:24:44 +02:00 committed by GitHub
parent 9294ebb0ec
commit fac1d1d05d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 968 additions and 796 deletions

View file

@ -87,7 +87,7 @@ jobs:
AWS_ACCESS_KEY_ID: fake AWS_ACCESS_KEY_ID: fake
AWS_SECRET_ACCESS_KEY: fake AWS_SECRET_ACCESS_KEY: fake
- name: Run build and test - name: Run build and test
timeout-minutes: 60 timeout-minutes: 70
run: | run: |
echo "Building for $OS:$ARCH" echo "Building for $OS:$ARCH"
cd $GITHUB_WORKSPACE cd $GITHUB_WORKSPACE

View file

@ -34,7 +34,7 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: | run: |
cd $GITHUB_WORKSPACE cd $GITHUB_WORKSPACE
go get -u github.com/swaggo/swag/cmd/swag go install github.com/swaggo/swag/cmd/swag
go mod download go mod download
sudo apt-get update sudo apt-get update
sudo apt-get -y install rpm uidmap sudo apt-get -y install rpm uidmap

View file

@ -23,7 +23,7 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: | run: |
cd $GITHUB_WORKSPACE cd $GITHUB_WORKSPACE
go get -u github.com/swaggo/swag/cmd/swag go install github.com/swaggo/swag/cmd/swag
go mod download go mod download
sudo apt-get update sudo apt-get update
sudo apt-get install libgpgme-dev libassuan-dev libbtrfs-dev libdevmapper-dev pkg-config rpm uidmap sudo apt-get install libgpgme-dev libassuan-dev libbtrfs-dev libdevmapper-dev pkg-config rpm uidmap

View file

@ -45,7 +45,7 @@ var (
ErrEmptyValue = errors.New("cache: empty value") ErrEmptyValue = errors.New("cache: empty value")
ErrEmptyRepoList = errors.New("search: no repository found") ErrEmptyRepoList = errors.New("search: no repository found")
ErrCVESearchDisabled = errors.New("search: CVE search is disabled") ErrCVESearchDisabled = errors.New("search: CVE search is disabled")
ErrInvalidRepositoryName = errors.New("routes: not a repository name") ErrInvalidRepositoryName = errors.New("repository: not a valid repository name")
ErrSyncMissingCatalog = errors.New("sync: couldn't fetch upstream registry's catalog") ErrSyncMissingCatalog = errors.New("sync: couldn't fetch upstream registry's catalog")
ErrMethodNotSupported = errors.New("storage: method not supported") ErrMethodNotSupported = errors.New("storage: method not supported")
ErrInvalidMetric = errors.New("metrics: invalid metric func") ErrInvalidMetric = errors.New("metrics: invalid metric func")

169
go.mod
View file

@ -7,7 +7,7 @@ require (
github.com/Masterminds/semver v1.5.0 github.com/Masterminds/semver v1.5.0
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751
github.com/apex/log v1.9.0 github.com/apex/log v1.9.0
github.com/aquasecurity/trivy-db v0.0.0-20210916043317-726b7b72a47b github.com/aquasecurity/trivy-db v0.0.0-20220627104749-930461748b63
github.com/bmatcuk/doublestar/v4 v4.6.0 github.com/bmatcuk/doublestar/v4 v4.6.0
github.com/briandowns/spinner v1.20.0 github.com/briandowns/spinner v1.20.0
github.com/chartmuseum/auth v0.5.0 github.com/chartmuseum/auth v0.5.0
@ -42,7 +42,6 @@ require (
github.com/spf13/viper v1.14.0 github.com/spf13/viper v1.14.0
github.com/stretchr/testify v1.8.1 github.com/stretchr/testify v1.8.1
github.com/swaggo/swag v1.8.9 github.com/swaggo/swag v1.8.9
github.com/urfave/cli/v2 v2.23.7
github.com/vektah/gqlparser/v2 v2.5.1 github.com/vektah/gqlparser/v2 v2.5.1
go.etcd.io/bbolt v1.3.6 go.etcd.io/bbolt v1.3.6
golang.org/x/crypto v0.5.0 golang.org/x/crypto v0.5.0
@ -51,7 +50,7 @@ require (
) )
require ( require (
github.com/aquasecurity/trivy v0.0.0-00010101000000-000000000000 github.com/aquasecurity/trivy v0.35.0
github.com/aws/aws-sdk-go-v2/service/dynamodb v1.18.0 github.com/aws/aws-sdk-go-v2/service/dynamodb v1.18.0
github.com/containers/image/v5 v5.23.0 github.com/containers/image/v5 v5.23.0
github.com/gobwas/glob v0.2.3 github.com/gobwas/glob v0.2.3
@ -62,9 +61,102 @@ require (
) )
require ( require (
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/CycloneDX/cyclonedx-go v0.6.0 // indirect
github.com/MakeNowJust/heredoc v1.0.0 // indirect
github.com/Masterminds/semver/v3 v3.1.1 // indirect
github.com/Masterminds/sprig/v3 v3.2.2 // indirect
github.com/Masterminds/squirrel v1.5.3 // indirect
github.com/Microsoft/hcsshim v0.9.4 // indirect
github.com/alecthomas/chroma v0.10.0 // indirect
github.com/aquasecurity/defsec v0.82.0 // indirect
github.com/aquasecurity/memoryfs v1.4.4 // indirect
github.com/aquasecurity/table v1.8.0 // indirect
github.com/aquasecurity/tml v0.6.1 // indirect
github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.14.0 // indirect github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.14.0 // indirect
github.com/aws/aws-sdk-go-v2/service/ebs v1.15.19 // indirect
github.com/aws/aws-sdk-go-v2/service/ec2 v1.63.1 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.7.21 // indirect github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.7.21 // indirect
github.com/chai2010/gettext-go v1.0.2 // indirect
github.com/containerd/cgroups v1.0.4 // indirect
github.com/containerd/containerd v1.6.8 // indirect
github.com/containerd/continuity v0.3.0 // indirect
github.com/containerd/fifo v1.0.0 // indirect
github.com/containerd/ttrpc v1.1.1-0.20220420014843-944ef4a40df3 // indirect
github.com/dlclark/regexp2 v1.4.0 // indirect
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect
github.com/docker/libnetwork v0.8.0-dev.2.0.20200917202933-d0951081b35f // indirect
github.com/emicklei/go-restful/v3 v3.8.0 // indirect
github.com/evanphx/json-patch v5.6.0+incompatible // indirect
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect
github.com/go-errors/errors v1.0.1 // indirect
github.com/go-gorp/gorp/v3 v3.0.2 // indirect
github.com/gogo/googleapis v1.4.1 // indirect
github.com/google/gnostic v0.5.7-v3refs // indirect
github.com/google/licenseclassifier/v2 v2.0.0-pre6 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/gosuri/uitable v0.0.4 // indirect
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect
github.com/jmoiron/sqlx v1.3.5 // indirect
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
github.com/liamg/iamgo v0.0.9 // indirect
github.com/liamg/jfather v0.0.7 // indirect
github.com/liamg/memoryfs v1.4.3 // indirect
github.com/lib/pq v1.10.6 // indirect
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 // indirect
github.com/masahiro331/go-disk v0.0.0-20220919035250-c8da316f91ac // indirect
github.com/masahiro331/go-ebs-file v0.0.0-20221125181850-09c63351e38c // indirect
github.com/masahiro331/go-ext4-filesystem v0.0.0-20221016160854-4b40d7ee6193 // indirect
github.com/masahiro331/go-vmdk-parser v0.0.0-20221124162251-5eeffd974e5a // indirect
github.com/masahiro331/go-xfs-filesystem v0.0.0-20221127135739-051c25f1becd // indirect
github.com/microsoft/go-rustaudit v0.0.0-20220808201409-204dfee52032 // indirect
github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect
github.com/moby/locker v1.0.1 // indirect
github.com/moby/spdystream v0.2.0 // indirect
github.com/moby/sys/signal v0.7.0 // indirect
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/opencontainers/selinux v1.10.2 // indirect
github.com/owenrumney/go-sarif/v2 v2.1.2 // indirect
github.com/package-url/packageurl-go v0.1.1-0.20220203205134-d70459300c8a // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
github.com/rubenv/sql-migrate v1.1.2 // indirect
github.com/russross/blackfriday v1.6.0 // indirect
github.com/samber/lo v1.33.0 // indirect
github.com/shopspring/decimal v1.2.0 // indirect
github.com/spdx/tools-golang v0.3.0 // indirect
github.com/tetratelabs/wazero v1.0.0-pre.3 // indirect
github.com/urfave/cli/v2 v2.8.1 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
github.com/xlab/treeprint v1.1.0 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect
helm.sh/helm/v3 v3.10.0 // indirect
k8s.io/apiextensions-apiserver v0.25.0 // indirect
k8s.io/apiserver v0.25.0 // indirect
k8s.io/cli-runtime v0.25.3 // indirect
k8s.io/component-base v0.25.3 // indirect
k8s.io/kubectl v0.25.3 // indirect
lukechampine.com/uint128 v1.1.1 // indirect
modernc.org/cc/v3 v3.36.0 // indirect
modernc.org/ccgo/v3 v3.16.6 // indirect
modernc.org/libc v1.16.7 // indirect
modernc.org/mathutil v1.4.1 // indirect
modernc.org/memory v1.1.1 // indirect
modernc.org/opt v0.1.1 // indirect
modernc.org/sqlite v1.17.3 // indirect
modernc.org/strutil v1.1.1 // indirect
modernc.org/token v1.0.0 // indirect
oras.land/oras-go v1.2.0 // indirect
sigs.k8s.io/kustomize/api v0.12.1 // indirect
sigs.k8s.io/kustomize/kyaml v0.13.9 // indirect
) )
require ( require (
@ -88,10 +180,9 @@ require (
github.com/Azure/go-autorest/tracing v0.6.0 // indirect github.com/Azure/go-autorest/tracing v0.6.0 // indirect
github.com/Azure/go-ntlmssp v0.0.0-20220621081337-cb9428e4ac1e // indirect github.com/Azure/go-ntlmssp v0.0.0-20220621081337-cb9428e4ac1e // indirect
github.com/BurntSushi/toml v1.2.1 // indirect github.com/BurntSushi/toml v1.2.1 // indirect
github.com/GoogleCloudPlatform/docker-credential-gcr v1.5.0 // indirect github.com/GoogleCloudPlatform/docker-credential-gcr v2.0.5+incompatible // indirect
github.com/KyleBanks/depth v1.2.1 // indirect github.com/KyleBanks/depth v1.2.1 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/sprig v2.22.0+incompatible // indirect
github.com/Microsoft/go-winio v0.6.0 // indirect github.com/Microsoft/go-winio v0.6.0 // indirect
github.com/OneOfOne/xxhash v1.2.8 // indirect github.com/OneOfOne/xxhash v1.2.8 // indirect
github.com/ProtonMail/go-crypto v0.0.0-20220407094043-a94812496cf5 // indirect github.com/ProtonMail/go-crypto v0.0.0-20220407094043-a94812496cf5 // indirect
@ -99,7 +190,7 @@ require (
github.com/VividCortex/ewma v1.2.0 // indirect github.com/VividCortex/ewma v1.2.0 // indirect
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d // indirect github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d // indirect
github.com/acomagu/bufpipe v1.0.3 // indirect github.com/acomagu/bufpipe v1.0.3 // indirect
github.com/agext/levenshtein v1.2.2 // indirect github.com/agext/levenshtein v1.2.3 // indirect
github.com/agnivade/levenshtein v1.1.1 // indirect github.com/agnivade/levenshtein v1.1.1 // indirect
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4 // indirect github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4 // indirect
github.com/alibabacloud-go/cr-20160607 v1.0.1 // indirect github.com/alibabacloud-go/cr-20160607 v1.0.1 // indirect
@ -114,15 +205,13 @@ require (
github.com/aliyun/credentials-go v1.2.3 // indirect github.com/aliyun/credentials-go v1.2.3 // indirect
github.com/apparentlymart/go-cidr v1.1.0 // indirect github.com/apparentlymart/go-cidr v1.1.0 // indirect
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
github.com/aquasecurity/fanal v0.0.0-20211005172059-69527b46560c // indirect github.com/aquasecurity/go-dep-parser v0.0.0-20221114145626-35ef808901e8 // indirect
github.com/aquasecurity/go-dep-parser v0.0.0-20210919151457-76db061b9305 // indirect
github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce // indirect github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce // indirect
github.com/aquasecurity/go-npm-version v0.0.0-20201110091526-0b796d180798 // indirect github.com/aquasecurity/go-npm-version v0.0.0-20201110091526-0b796d180798 // indirect
github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46 // indirect github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46 // indirect
github.com/aquasecurity/go-version v0.0.0-20210121072130-637058cfe492 // indirect github.com/aquasecurity/go-version v0.0.0-20210121072130-637058cfe492 // indirect
github.com/aquasecurity/tfsec v0.58.11 // indirect
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect
github.com/aws/aws-sdk-go v1.44.114 github.com/aws/aws-sdk-go v1.44.136
github.com/aws/aws-sdk-go-v2 v1.17.3 github.com/aws/aws-sdk-go-v2 v1.17.3
github.com/aws/aws-sdk-go-v2/config v1.18.8 github.com/aws/aws-sdk-go-v2/config v1.18.8
github.com/aws/aws-sdk-go-v2/credentials v1.13.8 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.13.8 // indirect
@ -131,7 +220,7 @@ require (
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.27 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.27 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.21 // indirect github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.21 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.28 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.3.28 // indirect
github.com/aws/aws-sdk-go-v2/service/ecr v1.15.0 // indirect github.com/aws/aws-sdk-go-v2/service/ecr v1.17.18 // indirect
github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.12.0 // indirect github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.12.0 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.21 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.21 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.12.0 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.12.0 // indirect
@ -145,12 +234,12 @@ require (
github.com/bgentry/speakeasy v0.1.0 // indirect github.com/bgentry/speakeasy v0.1.0 // indirect
github.com/blang/semver v3.5.1+incompatible // indirect github.com/blang/semver v3.5.1+incompatible // indirect
github.com/bmatcuk/doublestar v1.3.4 // indirect github.com/bmatcuk/doublestar v1.3.4 // indirect
github.com/caarlos0/env/v6 v6.0.0 // indirect github.com/caarlos0/env/v6 v6.10.1 // indirect
github.com/cenkalti/backoff v2.2.1+incompatible // indirect github.com/cenkalti/backoff v2.2.1+incompatible // indirect
github.com/cenkalti/backoff/v4 v4.1.3 // indirect github.com/cenkalti/backoff/v4 v4.1.3 // indirect
github.com/census-instrumentation/opencensus-proto v0.3.0 // indirect github.com/census-instrumentation/opencensus-proto v0.3.0 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/cheggaaa/pb/v3 v3.0.3 // indirect github.com/cheggaaa/pb/v3 v3.1.0 // indirect
github.com/chrismellard/docker-credential-acr-env v0.0.0-20220119192733-fe33c00cee21 // indirect github.com/chrismellard/docker-credential-acr-env v0.0.0-20220119192733-fe33c00cee21 // indirect
github.com/clbanning/mxj/v2 v2.5.6 // indirect github.com/clbanning/mxj/v2 v2.5.6 // indirect
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4 // indirect github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4 // indirect
@ -205,9 +294,8 @@ require (
github.com/go-pkgz/expirable-cache v0.0.3 // indirect github.com/go-pkgz/expirable-cache v0.0.3 // indirect
github.com/go-playground/locales v0.14.0 // indirect github.com/go-playground/locales v0.14.0 // indirect
github.com/go-playground/universal-translator v0.18.0 // indirect github.com/go-playground/universal-translator v0.18.0 // indirect
github.com/go-playground/validator/v10 v10.11.0 // indirect github.com/go-playground/validator/v10 v10.11.1 // indirect
github.com/go-redis/redis/v8 v8.11.5 // indirect github.com/go-redis/redis/v8 v8.11.5 // indirect
github.com/go-restruct/restruct v0.0.0-20191227155143-5734170a48a1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
github.com/golang-jwt/jwt/v4 v4.4.2 // indirect github.com/golang-jwt/jwt/v4 v4.4.2 // indirect
@ -219,7 +307,6 @@ require (
github.com/google/btree v1.1.2 // indirect github.com/google/btree v1.1.2 // indirect
github.com/google/certificate-transparency-go v1.1.3 // indirect github.com/google/certificate-transparency-go v1.1.3 // indirect
github.com/google/go-cmp v0.5.9 // indirect github.com/google/go-cmp v0.5.9 // indirect
github.com/google/go-github/v33 v33.0.0 // indirect
github.com/google/go-github/v45 v45.2.0 // indirect github.com/google/go-github/v45 v45.2.0 // indirect
github.com/google/go-querystring v1.1.0 // indirect github.com/google/go-querystring v1.1.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect github.com/google/gofuzz v1.2.0 // indirect
@ -227,7 +314,6 @@ require (
github.com/google/wire v0.5.0 // indirect github.com/google/wire v0.5.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.2.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.2.0 // indirect
github.com/googleapis/gax-go/v2 v2.6.0 // indirect github.com/googleapis/gax-go/v2 v2.6.0 // indirect
github.com/googleapis/gnostic v0.5.5 // indirect
github.com/googleapis/go-type-adapters v1.0.0 // indirect github.com/googleapis/go-type-adapters v1.0.0 // indirect
github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 // indirect github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 // indirect
github.com/gorilla/websocket v1.5.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect
@ -237,7 +323,7 @@ require (
github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-getter v1.5.2 // indirect github.com/hashicorp/go-getter v1.6.2 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-retryablehttp v0.7.1 // indirect github.com/hashicorp/go-retryablehttp v0.7.1 // indirect
github.com/hashicorp/go-safetemp v1.0.0 // indirect github.com/hashicorp/go-safetemp v1.0.0 // indirect
@ -245,10 +331,10 @@ require (
github.com/hashicorp/go-version v1.6.0 // indirect github.com/hashicorp/go-version v1.6.0 // indirect
github.com/hashicorp/golang-lru v0.5.4 github.com/hashicorp/golang-lru v0.5.4
github.com/hashicorp/hcl v1.0.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hashicorp/hcl/v2 v2.10.1 // indirect github.com/hashicorp/hcl/v2 v2.14.1 // indirect
github.com/huandu/xstrings v1.3.2 // indirect github.com/huandu/xstrings v1.3.2 // indirect
github.com/imdario/mergo v0.3.13 // indirect github.com/imdario/mergo v0.3.13 // indirect
github.com/in-toto/in-toto-golang v0.3.4-0.20220709202702-fa494aaa0add // indirect github.com/in-toto/in-toto-golang v0.5.0 // indirect
github.com/inconshreveable/mousetrap v1.0.1 // indirect github.com/inconshreveable/mousetrap v1.0.1 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/jedisct1/go-minisign v0.0.0-20211028175153-1c139d1cc84b // indirect github.com/jedisct1/go-minisign v0.0.0-20211028175153-1c139d1cc84b // indirect
@ -263,8 +349,8 @@ require (
github.com/klauspost/pgzip v1.2.5 // indirect github.com/klauspost/pgzip v1.2.5 // indirect
github.com/knqyf263/go-apk-version v0.0.0-20200609155635-041fdbb8563f // indirect github.com/knqyf263/go-apk-version v0.0.0-20200609155635-041fdbb8563f // indirect
github.com/knqyf263/go-deb-version v0.0.0-20190517075300-09fca494f03d // indirect github.com/knqyf263/go-deb-version v0.0.0-20190517075300-09fca494f03d // indirect
github.com/knqyf263/go-rpm-version v0.0.0-20170716094938-74609b86c936 // indirect github.com/knqyf263/go-rpm-version v0.0.0-20220614171824-631e686d1075 // indirect
github.com/knqyf263/go-rpmdb v0.0.0-20210911072402-73bd0ce46c49 // indirect github.com/knqyf263/go-rpmdb v0.0.0-20221030142135-919c8a52f04f // indirect
github.com/knqyf263/nested v0.0.1 // indirect github.com/knqyf263/nested v0.0.1 // indirect
github.com/leodido/go-urn v1.2.1 // indirect github.com/leodido/go-urn v1.2.1 // indirect
github.com/letsencrypt/boulder v0.0.0-20220929215747-76583552c2be // indirect github.com/letsencrypt/boulder v0.0.0-20220929215747-76583552c2be // indirect
@ -279,9 +365,9 @@ require (
github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect
github.com/mitchellh/go-wordwrap v1.0.0 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/moby/buildkit v0.8.1 // indirect github.com/moby/buildkit v0.10.4 // indirect
github.com/moby/sys/mountinfo v0.6.2 // indirect github.com/moby/sys/mountinfo v0.6.2 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect
@ -292,9 +378,9 @@ require (
github.com/oklog/ulid v1.3.1 // indirect github.com/oklog/ulid v1.3.1 // indirect
github.com/open-policy-agent/opa v0.45.0 // indirect github.com/open-policy-agent/opa v0.45.0 // indirect
github.com/opencontainers/runc v1.1.4 // indirect github.com/opencontainers/runc v1.1.4 // indirect
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 // indirect github.com/opencontainers/runtime-spec v1.0.3-0.20220311020903-6969a0a09ab1 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/owenrumney/squealer v0.2.28 // indirect github.com/owenrumney/squealer v1.0.1-0.20220510063705-c0be93f0edea // indirect
github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml v1.9.5 // indirect
github.com/pelletier/go-toml/v2 v2.0.5 // indirect github.com/pelletier/go-toml/v2 v2.0.5 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
@ -313,7 +399,7 @@ require (
github.com/sergi/go-diff v1.2.0 // indirect github.com/sergi/go-diff v1.2.0 // indirect
github.com/shibumi/go-pathspec v1.3.0 // indirect github.com/shibumi/go-pathspec v1.3.0 // indirect
github.com/sigstore/fulcio v0.6.0 // indirect github.com/sigstore/fulcio v0.6.0 // indirect
github.com/sigstore/rekor v0.12.1-0.20220915152154-4bb6f441c1b2 // indirect github.com/sigstore/rekor v1.0.0 // indirect
github.com/sigstore/sigstore v1.4.4 // indirect github.com/sigstore/sigstore v1.4.4 // indirect
github.com/sirupsen/logrus v1.9.0 // indirect github.com/sirupsen/logrus v1.9.0 // indirect
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect
@ -337,9 +423,8 @@ require (
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 // indirect github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 // indirect
github.com/tjfoc/gmsm v1.3.2 // indirect github.com/tjfoc/gmsm v1.3.2 // indirect
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 // indirect github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 // indirect
github.com/tmccombs/hcl2json v0.3.1 // indirect
github.com/transparency-dev/merkle v0.0.1 // indirect github.com/transparency-dev/merkle v0.0.1 // indirect
github.com/twitchtv/twirp v8.1.0+incompatible // indirect github.com/twitchtv/twirp v8.1.2+incompatible // indirect
github.com/ulikunitz/xz v0.5.10 // indirect github.com/ulikunitz/xz v0.5.10 // indirect
github.com/urfave/cli v1.22.7 // indirect github.com/urfave/cli v1.22.7 // indirect
github.com/vbatts/go-mtree v0.5.0 // indirect github.com/vbatts/go-mtree v0.5.0 // indirect
@ -350,9 +435,8 @@ require (
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
github.com/yashtewari/glob-intersection v0.1.0 // indirect github.com/yashtewari/glob-intersection v0.1.0 // indirect
github.com/zclconf/go-cty v1.9.1 // indirect github.com/zclconf/go-cty v1.10.0 // indirect
github.com/zclconf/go-cty-yaml v1.0.2 // indirect github.com/zclconf/go-cty-yaml v1.0.2 // indirect
github.com/zeebo/errs v1.2.2 // indirect github.com/zeebo/errs v1.2.2 // indirect
go.etcd.io/etcd/api/v3 v3.6.0-alpha.0 // indirect go.etcd.io/etcd/api/v3 v3.6.0-alpha.0 // indirect
@ -369,7 +453,7 @@ require (
go.mongodb.org/mongo-driver v1.10.0 // indirect go.mongodb.org/mongo-driver v1.10.0 // indirect
go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 // indirect go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 // indirect
go.opencensus.io v0.23.0 // indirect go.opencensus.io v0.23.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.28.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.29.0 // indirect
go.opentelemetry.io/otel v1.7.0 // indirect go.opentelemetry.io/otel v1.7.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.7.0 // indirect go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.7.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.7.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.7.0 // indirect
@ -389,7 +473,7 @@ require (
golang.org/x/term v0.4.0 // indirect golang.org/x/term v0.4.0 // indirect
golang.org/x/text v0.6.0 // indirect golang.org/x/text v0.6.0 // indirect
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af // indirect golang.org/x/time v0.0.0-20220922220347-f3bd1da661af // indirect
golang.org/x/tools v0.1.12 // indirect golang.org/x/tools v0.2.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/api v0.102.0 // indirect google.golang.org/api v0.102.0 // indirect
google.golang.org/appengine v1.6.7 // indirect google.golang.org/appengine v1.6.7 // indirect
@ -403,23 +487,20 @@ require (
gopkg.in/square/go-jose.v2 v2.6.0 // indirect gopkg.in/square/go-jose.v2 v2.6.0 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/api v0.23.5 // indirect k8s.io/api v0.25.3 // indirect
k8s.io/apimachinery v0.23.5 // indirect k8s.io/apimachinery v0.25.3 // indirect
k8s.io/client-go v0.23.5 // indirect k8s.io/client-go v0.25.3 // indirect
k8s.io/klog/v2 v2.60.1-0.20220317184644-43cc75f9ae89 // indirect k8s.io/klog/v2 v2.70.1 // indirect
k8s.io/kube-openapi v0.0.0-20220124234850-424119656bbf // indirect k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 // indirect
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed // indirect
oras.land/oras-go/v2 v2.0.0-rc.3 // indirect oras.land/oras-go/v2 v2.0.0-rc.3 // indirect
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
sigs.k8s.io/release-utils v0.7.3 // indirect sigs.k8s.io/release-utils v0.7.3 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect sigs.k8s.io/yaml v1.3.0 // indirect
) )
replace ( replace (
github.com/aquasecurity/fanal => github.com/project-zot/fanal v0.0.0-20211007194926-d0c577a014df
github.com/aquasecurity/trivy => github.com/project-zot/trivy v0.9.2-0.20211013001708-27408aa50da3
github.com/aquasecurity/trivy-db => github.com/project-zot/trivy-db v0.0.0-20211007191113-44f7e57b689c
github.com/containers/image/v5 => github.com/anuvu/image/v5 v5.0.0-20220520105616-e594853d6471 github.com/containers/image/v5 => github.com/anuvu/image/v5 v5.0.0-20220520105616-e594853d6471
github.com/hashicorp/go-getter => github.com/hashicorp/go-getter v1.6.1 github.com/hashicorp/go-getter => github.com/hashicorp/go-getter v1.6.1
github.com/open-policy-agent/opa => github.com/open-policy-agent/opa v0.44.0 github.com/open-policy-agent/opa => github.com/open-policy-agent/opa v0.44.0

958
go.sum

File diff suppressed because it is too large Load diff

View file

@ -6117,7 +6117,7 @@ func TestInjectTooManyOpenFiles(t *testing.T) {
func TestGCSignaturesAndUntaggedManifests(t *testing.T) { func TestGCSignaturesAndUntaggedManifests(t *testing.T) {
Convey("Make controller", t, func() { Convey("Make controller", t, func() {
repoName := "testrepo" repoName := "testrepo" //nolint:goconst
tag := "0.0.1" tag := "0.0.1"
port := test.GetFreePort() port := test.GetFreePort()
@ -6369,7 +6369,7 @@ func TestGCSignaturesAndUntaggedManifests(t *testing.T) {
func TestPeriodicGC(t *testing.T) { func TestPeriodicGC(t *testing.T) {
Convey("Periodic gc enabled for default store", t, func() { Convey("Periodic gc enabled for default store", t, func() {
repoName := "testRepo" repoName := "testrepo" //nolint:goconst
port := test.GetFreePort() port := test.GetFreePort()
conf := config.New() conf := config.New()
@ -6445,7 +6445,7 @@ func TestPeriodicGC(t *testing.T) {
}) })
Convey("Periodic gc error", t, func() { Convey("Periodic gc error", t, func() {
repoName := "testRepo" repoName := "testrepo" //nolint:goconst
port := test.GetFreePort() port := test.GetFreePort()
conf := config.New() conf := config.New()
@ -6505,7 +6505,7 @@ func TestSearchRoutes(t *testing.T) {
cm.StartAndWait(port) cm.StartAndWait(port)
defer cm.StopServer() defer cm.StopServer()
repoName := "testrepo" repoName := "testrepo" //nolint:goconst
inaccessibleRepo := "inaccessible" inaccessibleRepo := "inaccessible"
cfg, layers, manifest, err := test.GetImageComponents(10000) cfg, layers, manifest, err := test.GetImageComponents(10000)

View file

@ -36,6 +36,7 @@ import (
"zotregistry.io/zot/pkg/extensions/sync" "zotregistry.io/zot/pkg/extensions/sync"
"zotregistry.io/zot/pkg/log" "zotregistry.io/zot/pkg/log"
repoDBUpdate "zotregistry.io/zot/pkg/meta/repodb/update" repoDBUpdate "zotregistry.io/zot/pkg/meta/repodb/update"
zreg "zotregistry.io/zot/pkg/regexp"
localCtx "zotregistry.io/zot/pkg/requestcontext" localCtx "zotregistry.io/zot/pkg/requestcontext"
"zotregistry.io/zot/pkg/storage" "zotregistry.io/zot/pkg/storage"
"zotregistry.io/zot/pkg/test" //nolint:goimports "zotregistry.io/zot/pkg/test" //nolint:goimports
@ -73,34 +74,34 @@ func (rh *RouteHandler) SetupRoutes() {
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#endpoints // https://github.com/opencontainers/distribution-spec/blob/main/spec.md#endpoints
prefixedRouter := rh.c.Router.PathPrefix(constants.RoutePrefix).Subrouter() prefixedRouter := rh.c.Router.PathPrefix(constants.RoutePrefix).Subrouter()
{ {
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/tags/list", NameRegexp.String()), prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/tags/list", zreg.NameRegexp.String()),
rh.ListTags).Methods(allowedMethods("GET")...) rh.ListTags).Methods(allowedMethods("GET")...)
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/manifests/{reference}", NameRegexp.String()), prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/manifests/{reference}", zreg.NameRegexp.String()),
rh.CheckManifest).Methods(allowedMethods("HEAD")...) rh.CheckManifest).Methods(allowedMethods("HEAD")...)
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/manifests/{reference}", NameRegexp.String()), prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/manifests/{reference}", zreg.NameRegexp.String()),
rh.GetManifest).Methods(allowedMethods("GET")...) rh.GetManifest).Methods(allowedMethods("GET")...)
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/manifests/{reference}", NameRegexp.String()), prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/manifests/{reference}", zreg.NameRegexp.String()),
rh.UpdateManifest).Methods("PUT") rh.UpdateManifest).Methods("PUT")
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/manifests/{reference}", NameRegexp.String()), prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/manifests/{reference}", zreg.NameRegexp.String()),
rh.DeleteManifest).Methods("DELETE") rh.DeleteManifest).Methods("DELETE")
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/{digest}", NameRegexp.String()), prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/{digest}", zreg.NameRegexp.String()),
rh.CheckBlob).Methods("HEAD") rh.CheckBlob).Methods("HEAD")
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/{digest}", NameRegexp.String()), prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/{digest}", zreg.NameRegexp.String()),
rh.GetBlob).Methods("GET") rh.GetBlob).Methods("GET")
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/{digest}", NameRegexp.String()), prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/{digest}", zreg.NameRegexp.String()),
rh.DeleteBlob).Methods("DELETE") rh.DeleteBlob).Methods("DELETE")
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/uploads/", NameRegexp.String()), prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/uploads/", zreg.NameRegexp.String()),
rh.CreateBlobUpload).Methods("POST") rh.CreateBlobUpload).Methods("POST")
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/uploads/{session_id}", NameRegexp.String()), prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/uploads/{session_id}", zreg.NameRegexp.String()),
rh.GetBlobUpload).Methods("GET") rh.GetBlobUpload).Methods("GET")
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/uploads/{session_id}", NameRegexp.String()), prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/uploads/{session_id}", zreg.NameRegexp.String()),
rh.PatchBlobUpload).Methods("PATCH") rh.PatchBlobUpload).Methods("PATCH")
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/uploads/{session_id}", NameRegexp.String()), prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/uploads/{session_id}", zreg.NameRegexp.String()),
rh.UpdateBlobUpload).Methods("PUT") rh.UpdateBlobUpload).Methods("PUT")
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/uploads/{session_id}", NameRegexp.String()), prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/uploads/{session_id}", zreg.NameRegexp.String()),
rh.DeleteBlobUpload).Methods("DELETE") rh.DeleteBlobUpload).Methods("DELETE")
// support for OCI artifact references // support for OCI artifact references
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/referrers/{digest}", NameRegexp.String()), prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/referrers/{digest}", zreg.NameRegexp.String()),
rh.GetReferrers).Methods(allowedMethods("GET")...) rh.GetReferrers).Methods(allowedMethods("GET")...)
prefixedRouter.HandleFunc(constants.ExtCatalogPrefix, prefixedRouter.HandleFunc(constants.ExtCatalogPrefix,
rh.ListRepositories).Methods(allowedMethods("GET")...) rh.ListRepositories).Methods(allowedMethods("GET")...)
@ -112,7 +113,7 @@ func (rh *RouteHandler) SetupRoutes() {
// support for ORAS artifact reference types (alpha 1) - image signature use case // support for ORAS artifact reference types (alpha 1) - image signature use case
rh.c.Router.HandleFunc(fmt.Sprintf("%s/{name:%s}/manifests/{digest}/referrers", rh.c.Router.HandleFunc(fmt.Sprintf("%s/{name:%s}/manifests/{digest}/referrers",
constants.ArtifactSpecRoutePrefix, NameRegexp.String()), rh.GetOrasReferrers).Methods("GET") constants.ArtifactSpecRoutePrefix, zreg.NameRegexp.String()), rh.GetOrasReferrers).Methods("GET")
// swagger // swagger
debug.SetupSwaggerRoutes(rh.c.Config, rh.c.Router, rh.c.Log) debug.SetupSwaggerRoutes(rh.c.Config, rh.c.Router, rh.c.Log)

View file

@ -1298,7 +1298,7 @@ func TestScrub(t *testing.T) {
dir := t.TempDir() dir := t.TempDir()
repoName := "badIndex" repoName := "badindex"
repo, err := os.MkdirTemp(dir, repoName) repo, err := os.MkdirTemp(dir, repoName)
if err != nil { if err != nil {

View file

@ -555,9 +555,14 @@ func TestRepoListWithNewestImage(t *testing.T) {
ShouldBeGreaterThan, ShouldBeGreaterThan,
0, 0,
) )
// This really depends on the test data, but with the current test images it's CRITICAL if repo.Name == "zot-cve-test" {
// This really depends on the test data, but with the current test image it's HIGH
So(vulnerabilities.MaxSeverity, ShouldEqual, "HIGH")
} else if repo.Name == "zot-test" {
// This really depends on the test data, but with the current test image it's CRITICAL
So(vulnerabilities.MaxSeverity, ShouldEqual, "CRITICAL") So(vulnerabilities.MaxSeverity, ShouldEqual, "CRITICAL")
} }
}
}) })
} }

View file

@ -1,20 +1,19 @@
package trivy package trivy
import ( import (
"context"
"encoding/json" "encoding/json"
"flag"
"path" "path"
"strings"
"sync" "sync"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types" dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
"github.com/aquasecurity/trivy/pkg/commands/artifact" "github.com/aquasecurity/trivy/pkg/commands/artifact"
"github.com/aquasecurity/trivy/pkg/commands/operation" "github.com/aquasecurity/trivy/pkg/commands/operation"
"github.com/aquasecurity/trivy/pkg/flag"
"github.com/aquasecurity/trivy/pkg/types" "github.com/aquasecurity/trivy/pkg/types"
regTypes "github.com/google/go-containerregistry/pkg/v1/types" regTypes "github.com/google/go-containerregistry/pkg/v1/types"
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"
"github.com/urfave/cli/v2"
zerr "zotregistry.io/zot/errors" zerr "zotregistry.io/zot/errors"
"zotregistry.io/zot/pkg/extensions/search/common" "zotregistry.io/zot/pkg/extensions/search/common"
@ -24,51 +23,44 @@ import (
"zotregistry.io/zot/pkg/storage" "zotregistry.io/zot/pkg/storage"
) )
type trivyCtx struct { const dbRepository = "ghcr.io/aquasecurity/trivy-db"
Input string
Ctx *cli.Context
}
// newTrivyContext set some trivy configuration value and return a context. // getNewScanOptions sets trivy configuration values for our scans and returns them as
func newTrivyContext(dir string) *trivyCtx { // a trivy Options structure.
tCtx := &trivyCtx{} func getNewScanOptions(dir string) *flag.Options {
scanOptions := flag.Options{
GlobalOptions: flag.GlobalOptions{
CacheDir: dir,
},
ScanOptions: flag.ScanOptions{
SecurityChecks: []string{types.SecurityCheckVulnerability},
OfflineScan: true,
},
VulnerabilityOptions: flag.VulnerabilityOptions{
VulnType: []string{types.VulnTypeOS, types.VulnTypeLibrary},
},
DBOptions: flag.DBOptions{
DBRepository: dbRepository,
SkipDBUpdate: true,
},
ReportOptions: flag.ReportOptions{
Format: "table",
Severities: []dbTypes.Severity{
dbTypes.SeverityUnknown,
dbTypes.SeverityLow,
dbTypes.SeverityMedium,
dbTypes.SeverityHigh,
dbTypes.SeverityCritical,
},
},
}
app := &cli.App{} return &scanOptions
flagSet := &flag.FlagSet{}
var cacheDir string
flagSet.StringVar(&cacheDir, "cache-dir", dir, "")
var vuln string
flagSet.StringVar(&vuln, "vuln-type", strings.Join([]string{types.VulnTypeOS, types.VulnTypeLibrary}, ","), "")
var severity string
flagSet.StringVar(&severity, "severity", strings.Join(dbTypes.SeverityNames, ","), "")
flagSet.StringVar(&tCtx.Input, "input", "", "")
var securityCheck string
flagSet.StringVar(&securityCheck, "security-checks", types.SecurityCheckVulnerability, "")
var reportFormat string
flagSet.StringVar(&reportFormat, "format", "table", "")
ctx := cli.NewContext(app, flagSet, nil)
tCtx.Ctx = ctx
return tCtx
} }
type cveTrivyController struct { type cveTrivyController struct {
DefaultCveConfig *trivyCtx DefaultCveConfig *flag.Options
SubCveConfig map[string]*trivyCtx SubCveConfig map[string]*flag.Options
} }
type Scanner struct { type Scanner struct {
@ -85,25 +77,27 @@ func NewScanner(storeController storage.StoreController,
) *Scanner { ) *Scanner {
cveController := cveTrivyController{} cveController := cveTrivyController{}
subCveConfig := make(map[string]*trivyCtx) subCveConfig := make(map[string]*flag.Options)
if storeController.DefaultStore != nil { if storeController.DefaultStore != nil {
imageStore := storeController.DefaultStore imageStore := storeController.DefaultStore
rootDir := imageStore.RootDir() rootDir := imageStore.RootDir()
ctx := newTrivyContext(rootDir) cacheDir := path.Join(rootDir, "_trivy")
opts := getNewScanOptions(cacheDir)
cveController.DefaultCveConfig = ctx cveController.DefaultCveConfig = opts
} }
if storeController.SubStore != nil { if storeController.SubStore != nil {
for route, storage := range storeController.SubStore { for route, storage := range storeController.SubStore {
rootDir := storage.RootDir() rootDir := storage.RootDir()
ctx := newTrivyContext(rootDir) cacheDir := path.Join(rootDir, "_trivy")
opts := getNewScanOptions(cacheDir)
subCveConfig[route] = ctx subCveConfig[route] = opts
} }
} }
@ -119,33 +113,58 @@ func NewScanner(storeController storage.StoreController,
} }
} }
func (scanner Scanner) getTrivyContext(image string) *trivyCtx { func (scanner Scanner) getTrivyOptions(image string) flag.Options {
// Split image to get route prefix // Split image to get route prefix
prefixName := common.GetRoutePrefix(image) prefixName := common.GetRoutePrefix(image)
var tCtx *trivyCtx var opts flag.Options
var ok bool var ok bool
var rootDir string var rootDir string
// Get corresponding CVE trivy config, if no sub cve config present that means its default // Get corresponding CVE trivy config, if no sub cve config present that means its default
tCtx, ok = scanner.cveController.SubCveConfig[prefixName] _, ok = scanner.cveController.SubCveConfig[prefixName]
if ok { if ok {
opts = *scanner.cveController.SubCveConfig[prefixName]
imgStore := scanner.storeController.SubStore[prefixName] imgStore := scanner.storeController.SubStore[prefixName]
rootDir = imgStore.RootDir() rootDir = imgStore.RootDir()
} else { } else {
tCtx = scanner.cveController.DefaultCveConfig opts = *scanner.cveController.DefaultCveConfig
imgStore := scanner.storeController.DefaultStore imgStore := scanner.storeController.DefaultStore
rootDir = imgStore.RootDir() rootDir = imgStore.RootDir()
} }
tCtx.Input = path.Join(rootDir, image) opts.ScanOptions.Target = path.Join(rootDir, image)
opts.ImageOptions.Input = path.Join(rootDir, image)
return tCtx return opts
}
func (scanner Scanner) runTrivy(opts flag.Options) (types.Report, error) {
ctx := context.Background()
runner, err := artifact.NewRunner(ctx, opts)
if err != nil {
return types.Report{}, err
}
defer runner.Close(ctx)
report, err := runner.ScanImage(ctx, opts)
if err != nil {
return types.Report{}, err
}
report, err = runner.Filter(ctx, opts, report)
if err != nil {
return types.Report{}, err
}
return report, nil
} }
func (scanner Scanner) IsImageFormatScannable(image string) (bool, error) { func (scanner Scanner) IsImageFormatScannable(image string) (bool, error) {
@ -208,10 +227,9 @@ func (scanner Scanner) ScanImage(image string) (map[string]cvemodel.CVE, error)
scanner.log.Debug().Str("image", image).Msg("scanning image") scanner.log.Debug().Str("image", image).Msg("scanning image")
tCtx := scanner.getTrivyContext(image)
scanner.dbLock.Lock() scanner.dbLock.Lock()
report, err := artifact.TrivyImageRun(tCtx.Ctx) opts := scanner.getTrivyOptions(image)
report, err := scanner.runTrivy(opts)
scanner.dbLock.Unlock() scanner.dbLock.Unlock()
if err != nil { //nolint: wsl if err != nil { //nolint: wsl
@ -288,7 +306,7 @@ func (scanner Scanner) UpdateDB() error {
defer scanner.dbLock.Unlock() defer scanner.dbLock.Unlock()
if scanner.storeController.DefaultStore != nil { if scanner.storeController.DefaultStore != nil {
dbDir := scanner.storeController.DefaultStore.RootDir() dbDir := path.Join(scanner.storeController.DefaultStore.RootDir(), "_trivy")
err := scanner.updateDB(dbDir) err := scanner.updateDB(dbDir)
if err != nil { if err != nil {
@ -298,7 +316,9 @@ func (scanner Scanner) UpdateDB() error {
if scanner.storeController.SubStore != nil { if scanner.storeController.SubStore != nil {
for _, storage := range scanner.storeController.SubStore { for _, storage := range scanner.storeController.SubStore {
err := scanner.updateDB(storage.RootDir()) dbDir := path.Join(storage.RootDir(), "_trivy")
err := scanner.updateDB(dbDir)
if err != nil { if err != nil {
return err return err
} }
@ -313,7 +333,7 @@ func (scanner Scanner) UpdateDB() error {
func (scanner Scanner) updateDB(dbDir string) error { func (scanner Scanner) updateDB(dbDir string) error {
scanner.log.Debug().Msgf("Download Trivy DB to destination dir: %s", dbDir) scanner.log.Debug().Msgf("Download Trivy DB to destination dir: %s", dbDir)
err := operation.DownloadDB("dev", dbDir, false, false, false) err := operation.DownloadDB("dev", dbDir, dbRepository, false, false, false)
if err != nil { if err != nil {
scanner.log.Error().Err(err).Msgf("Error downloading Trivy DB to destination dir: %s", dbDir) scanner.log.Error().Err(err).Msgf("Error downloading Trivy DB to destination dir: %s", dbDir)

View file

@ -102,19 +102,23 @@ func TestMultipleStoragePath(t *testing.T) {
img1 := "a/test/image1:tag1" img1 := "a/test/image1:tag1"
img2 := "b/test/image2:tag2" img2 := "b/test/image2:tag2"
ctx := scanner.getTrivyContext(img0) opts := scanner.getTrivyOptions(img0)
So(ctx.Input, ShouldEqual, path.Join(firstStore.RootDir(), img0)) So(opts.ScanOptions.Target, ShouldEqual, path.Join(firstStore.RootDir(), img0))
ctx = scanner.getTrivyContext(img1) opts = scanner.getTrivyOptions(img1)
So(ctx.Input, ShouldEqual, path.Join(secondStore.RootDir(), img1)) So(opts.ScanOptions.Target, ShouldEqual, path.Join(secondStore.RootDir(), img1))
ctx = scanner.getTrivyContext(img2) opts = scanner.getTrivyOptions(img2)
So(ctx.Input, ShouldEqual, path.Join(thirdStore.RootDir(), img2)) So(opts.ScanOptions.Target, ShouldEqual, path.Join(thirdStore.RootDir(), img2))
generateTestImage(storeController, img0) generateTestImage(storeController, img0)
generateTestImage(storeController, img1) generateTestImage(storeController, img1)
generateTestImage(storeController, img2) generateTestImage(storeController, img2)
// Download DB since DB download on scan is disabled
err = scanner.UpdateDB()
So(err, ShouldBeNil)
// Scanning image in default store // Scanning image in default store
cveMap, err := scanner.ScanImage(img0) cveMap, err := scanner.ScanImage(img0)
So(err, ShouldBeNil) So(err, ShouldBeNil)
@ -152,3 +156,65 @@ func TestMultipleStoragePath(t *testing.T) {
So(err, ShouldBeNil) So(err, ShouldBeNil)
}) })
} }
func TestTrivyLibraryErrors(t *testing.T) {
Convey("Test trivy API errors", t, func() {
// Create temporary directory
rootDir := t.TempDir()
err := test.CopyFiles("../../../../../test/data/zot-test", path.Join(rootDir, "zot-test"))
So(err, ShouldBeNil)
log := log.NewLogger("debug", "")
metrics := monitoring.NewMetricsServer(false, log)
conf := config.New()
conf.Extensions = &extconf.ExtensionConfig{}
conf.Extensions.Lint = &extconf.LintConfig{}
// Create ImageStore
store := local.NewImageStore(rootDir, false, storage.DefaultGCDelay, false, false, log, metrics, nil, nil)
storeController := storage.StoreController{}
storeController.DefaultStore = store
repoDB, err := bolt.NewBoltDBWrapper(bolt.DBParameters{
RootDir: rootDir,
})
So(err, ShouldBeNil)
err = repodb.SyncRepoDB(repoDB, storeController, log)
So(err, ShouldBeNil)
scanner := NewScanner(storeController, repoDB, log)
// Download DB since DB download on scan is disabled
err = scanner.UpdateDB()
So(err, ShouldBeNil)
img := "zot-test:0.0.1"
// Scanning image with correct options
opts := scanner.getTrivyOptions(img)
_, err = scanner.runTrivy(opts)
So(err, ShouldBeNil)
// Scanning image with incorrect cache options
// to trigger runner initialization errors
opts.CacheOptions.CacheBackend = "redis://asdf!$%&!*)("
_, err = scanner.runTrivy(opts)
So(err, ShouldNotBeNil)
// Scanning image with invalid input to trigger a scanner error
opts = scanner.getTrivyOptions("nonexisting_image:0.0.1")
_, err = scanner.runTrivy(opts)
So(err, ShouldNotBeNil)
// Scanning image with incorrect report options
// to trigger report filtering errors
opts = scanner.getTrivyOptions(img)
opts.ReportOptions.IgnorePolicy = "invalid file path"
_, err = scanner.runTrivy(opts)
So(err, ShouldNotBeNil)
})
}

View file

@ -1,4 +1,4 @@
package api package regexp
import "regexp" import "regexp"
@ -26,6 +26,10 @@ var (
NameRegexp = expression( NameRegexp = expression(
nameComponentRegexp, nameComponentRegexp,
optional(repeated(literal(`/`), nameComponentRegexp))) optional(repeated(literal(`/`), nameComponentRegexp)))
// FullNameRegexp is the format which matches the full string of the
// name component of reference.
FullNameRegexp = expression(match("^"), NameRegexp, match("$"))
) )
// match compiles the string to a regular expression. // match compiles the string to a regular expression.

View file

@ -31,6 +31,7 @@ import (
"zotregistry.io/zot/pkg/common" "zotregistry.io/zot/pkg/common"
"zotregistry.io/zot/pkg/extensions/monitoring" "zotregistry.io/zot/pkg/extensions/monitoring"
zlog "zotregistry.io/zot/pkg/log" zlog "zotregistry.io/zot/pkg/log"
zreg "zotregistry.io/zot/pkg/regexp"
"zotregistry.io/zot/pkg/scheduler" "zotregistry.io/zot/pkg/scheduler"
"zotregistry.io/zot/pkg/storage" "zotregistry.io/zot/pkg/storage"
"zotregistry.io/zot/pkg/storage/cache" "zotregistry.io/zot/pkg/storage/cache"
@ -154,6 +155,12 @@ func (is *ImageStoreLocal) initRepo(name string) error {
return zerr.ErrInvalidRepositoryName return zerr.ErrInvalidRepositoryName
} }
if !zreg.FullNameRegexp.MatchString(name) {
is.log.Error().Str("repo", name).Msg("invalid repository name")
return zerr.ErrInvalidRepositoryName
}
// create "blobs" subdir // create "blobs" subdir
err := ensureDir(path.Join(repoDir, "blobs"), is.log) err := ensureDir(path.Join(repoDir, "blobs"), is.log)
if err != nil { if err != nil {
@ -221,6 +228,10 @@ func (is *ImageStoreLocal) ValidateRepo(name string) (bool, error) {
// https://github.com/opencontainers/image-spec/blob/master/image-layout.md#content // https://github.com/opencontainers/image-spec/blob/master/image-layout.md#content
// at least, expect at least 3 entries - ["blobs", "oci-layout", "index.json"] // at least, expect at least 3 entries - ["blobs", "oci-layout", "index.json"]
// and an additional/optional BlobUploadDir in each image store // and an additional/optional BlobUploadDir in each image store
if !zreg.FullNameRegexp.MatchString(name) {
return false, zerr.ErrInvalidRepositoryName
}
dir := path.Join(is.rootDir, name) dir := path.Join(is.rootDir, name)
if !is.DirExists(dir) { if !is.DirExists(dir) {
return false, zerr.ErrRepoNotFound return false, zerr.ErrRepoNotFound

View file

@ -30,6 +30,7 @@ import (
"zotregistry.io/zot/pkg/log" "zotregistry.io/zot/pkg/log"
"zotregistry.io/zot/pkg/storage" "zotregistry.io/zot/pkg/storage"
"zotregistry.io/zot/pkg/storage/cache" "zotregistry.io/zot/pkg/storage/cache"
storageConstants "zotregistry.io/zot/pkg/storage/constants"
"zotregistry.io/zot/pkg/storage/local" "zotregistry.io/zot/pkg/storage/local"
"zotregistry.io/zot/pkg/test" "zotregistry.io/zot/pkg/test"
) )
@ -1326,6 +1327,11 @@ func TestNegativeCases(t *testing.T) {
// Init repo should fail if repo is invalid UTF-8 // Init repo should fail if repo is invalid UTF-8
err = imgStore.InitRepo("hi \255") err = imgStore.InitRepo("hi \255")
So(err, ShouldNotBeNil) So(err, ShouldNotBeNil)
// Init repo should fail if repo name does not match spec
err = imgStore.InitRepo("_trivy")
So(err, ShouldNotBeNil)
So(errors.Is(err, zerr.ErrInvalidRepositoryName), ShouldBeTrue)
}) })
Convey("Invalid validate repo", t, func(c C) { Convey("Invalid validate repo", t, func(c C) {
@ -1430,7 +1436,7 @@ func TestNegativeCases(t *testing.T) {
So(func() { _, _ = imgStore.ValidateRepo("test") }, ShouldPanic) So(func() { _, _ = imgStore.ValidateRepo("test") }, ShouldPanic)
} }
err = os.Chmod(dir, 0o755) // remove all perms err = os.Chmod(dir, 0o755) // add perms
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -2483,10 +2489,53 @@ func TestValidateRepo(t *testing.T) {
_, err = imgStore.ValidateRepo("test-dir") _, err = imgStore.ValidateRepo("test-dir")
So(err, ShouldNotBeNil) So(err, ShouldNotBeNil)
}) })
Convey("Get error when repo name is not compliant with repo spec", t, func() {
dir := t.TempDir()
log := log.Logger{Logger: zerolog.New(os.Stdout)}
metrics := monitoring.NewMetricsServer(false, log)
cacheDriver, _ := storage.Create("boltdb", cache.BoltDBDriverParameters{
RootDir: dir,
Name: "cache",
UseRelPaths: true,
}, log)
imgStore := local.NewImageStore(dir, true, storage.DefaultGCDelay,
true, true, log, metrics, nil, cacheDriver)
_, err := imgStore.ValidateRepo(".")
So(err, ShouldNotBeNil)
So(errors.Is(err, zerr.ErrInvalidRepositoryName), ShouldBeTrue)
_, err = imgStore.ValidateRepo("..")
So(err, ShouldNotBeNil)
So(errors.Is(err, zerr.ErrInvalidRepositoryName), ShouldBeTrue)
err = os.Mkdir(path.Join(dir, "_test-dir"), 0o755)
So(err, ShouldBeNil)
_, err = imgStore.ValidateRepo("_test-dir")
So(err, ShouldNotBeNil)
So(errors.Is(err, zerr.ErrInvalidRepositoryName), ShouldBeTrue)
err = os.Mkdir(path.Join(dir, ".test-dir"), 0o755)
So(err, ShouldBeNil)
_, err = imgStore.ValidateRepo(".test-dir")
So(err, ShouldNotBeNil)
So(errors.Is(err, zerr.ErrInvalidRepositoryName), ShouldBeTrue)
err = os.Mkdir(path.Join(dir, "-test-dir"), 0o755)
So(err, ShouldBeNil)
_, err = imgStore.ValidateRepo("-test-dir")
So(err, ShouldNotBeNil)
So(errors.Is(err, zerr.ErrInvalidRepositoryName), ShouldBeTrue)
})
} }
func TestGetRepositoriesError(t *testing.T) { func TestGetRepositories(t *testing.T) {
Convey("Get error when returning relative path", t, func() { Convey("Verify errors and repos returned by GetRepositories()", t, func() {
dir := t.TempDir() dir := t.TempDir()
log := log.Logger{Logger: zerolog.New(os.Stdout)} log := log.Logger{Logger: zerolog.New(os.Stdout)}
@ -2500,15 +2549,178 @@ func TestGetRepositoriesError(t *testing.T) {
true, true, log, metrics, nil, cacheDriver, true, true, log, metrics, nil, cacheDriver,
) )
// create valid directory with permissions // Create valid directory with permissions
err := os.Mkdir(path.Join(dir, "test-dir"), 0o755) err := os.Mkdir(path.Join(dir, "test-dir"), 0o755) //nolint: gosec
So(err, ShouldBeNil) So(err, ShouldBeNil)
err = os.WriteFile(path.Join(dir, "test-dir/test-file"), []byte("this is test file"), 0o000) err = os.WriteFile(path.Join(dir, "test-dir/test-file"), []byte("this is test file"), 0o755) //nolint: gosec
So(err, ShouldBeNil) So(err, ShouldBeNil)
_, err = imgStore.GetRepositories() // Folder is not a repo as it is missing the requires files/subfolder
repos, err := imgStore.GetRepositories()
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(len(repos), ShouldEqual, 0)
il := ispec.ImageLayout{Version: ispec.ImageLayoutVersion}
layoutFileContent, err := json.Marshal(il)
So(err, ShouldBeNil)
// Folder becomes a repo after the missing content is added
err = os.Mkdir(path.Join(dir, "test-dir", "blobs"), 0o755) //nolint: gosec
So(err, ShouldBeNil)
err = os.Mkdir(path.Join(dir, "test-dir", storageConstants.BlobUploadDir), 0o755) //nolint: gosec
So(err, ShouldBeNil)
err = os.WriteFile(path.Join(dir, "test-dir", "index.json"), []byte{}, 0o755) //nolint: gosec
So(err, ShouldBeNil)
err = os.WriteFile(path.Join(dir, "test-dir", ispec.ImageLayoutFile), layoutFileContent, 0o755) //nolint: gosec
So(err, ShouldBeNil)
// Verify the new repo is turned
repos, err = imgStore.GetRepositories()
So(err, ShouldBeNil)
So(len(repos), ShouldEqual, 1)
So(repos[0], ShouldEqual, "test-dir")
// create directory starting with underscore, which is not OCI a dist spec compliant repo name
// [a-z0-9]+([._-][a-z0-9]+)*(/[a-z0-9]+([._-][a-z0-9]+)*)*
err = os.MkdirAll(path.Join(dir, "_trivy", "db"), 0o755)
So(err, ShouldBeNil)
err = os.WriteFile(path.Join(dir, "_trivy", "db", "trivy.db"), []byte("this is test file"), 0o755) //nolint: gosec
So(err, ShouldBeNil)
// Folder with invalid name is not a repo as it is missing the requires files/subfolder
repos, err = imgStore.GetRepositories()
So(err, ShouldBeNil)
So(len(repos), ShouldEqual, 1)
So(repos[0], ShouldEqual, "test-dir")
// Add missing content to folder with invalid name
err = os.Mkdir(path.Join(dir, "_trivy", "blobs"), 0o755) //nolint: gosec
So(err, ShouldBeNil)
err = os.Mkdir(path.Join(dir, "_trivy", storageConstants.BlobUploadDir), 0o755) //nolint: gosec
So(err, ShouldBeNil)
err = os.WriteFile(path.Join(dir, "_trivy", "index.json"), []byte{}, 0o755) //nolint: gosec
So(err, ShouldBeNil)
err = os.WriteFile(path.Join(dir, "_trivy", ispec.ImageLayoutFile), layoutFileContent, 0o755) //nolint: gosec
So(err, ShouldBeNil)
// Folder with invalid name doesn't become a repo after the missing content is added
repos, err = imgStore.GetRepositories()
So(err, ShouldBeNil)
t.Logf("repos %v", repos)
So(len(repos), ShouldEqual, 1)
So(repos[0], ShouldEqual, "test-dir")
// Rename folder with invalid name to a valid one
err = os.Rename(path.Join(dir, "_trivy"), path.Join(dir, "test-dir-2"))
So(err, ShouldBeNil)
// Verify both repos are now visible
repos, err = imgStore.GetRepositories()
So(err, ShouldBeNil)
t.Logf("repos %v", repos)
So(len(repos), ShouldEqual, 2)
So(repos, ShouldContain, "test-dir")
So(repos, ShouldContain, "test-dir-2")
})
Convey("Verify GetRepositories() doesn't return '.' when having an oci layout as root directory ", t, func() {
dir := t.TempDir()
log := log.Logger{Logger: zerolog.New(os.Stdout)}
metrics := monitoring.NewMetricsServer(false, log)
cacheDriver, _ := storage.Create("boltdb", cache.BoltDBDriverParameters{
RootDir: dir,
Name: "cache",
UseRelPaths: true,
}, log)
imgStore := local.NewImageStore(dir, true, storage.DefaultGCDelay,
true, true, log, metrics, nil, cacheDriver,
)
// Root dir does not contain repos
repos, err := imgStore.GetRepositories()
So(err, ShouldBeNil)
So(len(repos), ShouldEqual, 0)
// Configure root directory as an oci layout
err = os.Mkdir(path.Join(dir, "blobs"), 0o755) //nolint: gosec
So(err, ShouldBeNil)
err = os.Mkdir(path.Join(dir, storageConstants.BlobUploadDir), 0o755) //nolint: gosec
So(err, ShouldBeNil)
err = os.WriteFile(path.Join(dir, "index.json"), []byte{}, 0o755) //nolint: gosec
So(err, ShouldBeNil)
il := ispec.ImageLayout{Version: ispec.ImageLayoutVersion}
layoutFileContent, err := json.Marshal(il)
So(err, ShouldBeNil)
err = os.WriteFile(path.Join(dir, ispec.ImageLayoutFile), layoutFileContent, 0o755) //nolint: gosec
So(err, ShouldBeNil)
// Verify root directory is not returned as a repo
repos, err = imgStore.GetRepositories()
So(err, ShouldBeNil)
t.Logf("repos %v", repos)
So(len(repos), ShouldEqual, 0)
})
Convey("Verify GetRepositories() doesn't return '..'", t, func() {
dir := t.TempDir()
rootDir := path.Join(dir, "rootDir")
err := os.Mkdir(rootDir, 0o755)
So(err, ShouldBeNil)
log := log.Logger{Logger: zerolog.New(os.Stdout)}
metrics := monitoring.NewMetricsServer(false, log)
cacheDriver, _ := storage.Create("boltdb", cache.BoltDBDriverParameters{
RootDir: rootDir,
Name: "cache",
UseRelPaths: true,
}, log)
imgStore := local.NewImageStore(rootDir, true, storage.DefaultGCDelay,
true, true, log, metrics, nil, cacheDriver,
)
// Root dir does not contain repos
repos, err := imgStore.GetRepositories()
So(err, ShouldBeNil)
So(len(repos), ShouldEqual, 0)
// Configure parent of root directory as an oci layout
err = os.Mkdir(path.Join(dir, "blobs"), 0o755) //nolint: gosec
So(err, ShouldBeNil)
err = os.Mkdir(path.Join(dir, storageConstants.BlobUploadDir), 0o755) //nolint: gosec
So(err, ShouldBeNil)
err = os.WriteFile(path.Join(dir, "index.json"), []byte{}, 0o755) //nolint: gosec
So(err, ShouldBeNil)
il := ispec.ImageLayout{Version: ispec.ImageLayoutVersion}
layoutFileContent, err := json.Marshal(il)
So(err, ShouldBeNil)
err = os.WriteFile(path.Join(dir, ispec.ImageLayoutFile), layoutFileContent, 0o755) //nolint: gosec
So(err, ShouldBeNil)
// Verify root directory is not returned as a repo
repos, err = imgStore.GetRepositories()
So(err, ShouldBeNil)
t.Logf("repos %v", repos)
So(len(repos), ShouldEqual, 0)
}) })
} }

View file

@ -26,6 +26,7 @@ import (
zerr "zotregistry.io/zot/errors" zerr "zotregistry.io/zot/errors"
"zotregistry.io/zot/pkg/extensions/monitoring" "zotregistry.io/zot/pkg/extensions/monitoring"
zlog "zotregistry.io/zot/pkg/log" zlog "zotregistry.io/zot/pkg/log"
zreg "zotregistry.io/zot/pkg/regexp"
"zotregistry.io/zot/pkg/scheduler" "zotregistry.io/zot/pkg/scheduler"
"zotregistry.io/zot/pkg/storage" "zotregistry.io/zot/pkg/storage"
"zotregistry.io/zot/pkg/storage/cache" "zotregistry.io/zot/pkg/storage/cache"
@ -122,6 +123,12 @@ func (is *ObjectStorage) Unlock(lockStart *time.Time) {
func (is *ObjectStorage) initRepo(name string) error { func (is *ObjectStorage) initRepo(name string) error {
repoDir := path.Join(is.rootDir, name) repoDir := path.Join(is.rootDir, name)
if !zreg.FullNameRegexp.MatchString(name) {
is.log.Error().Str("repo", name).Msg("invalid repository name")
return zerr.ErrInvalidRepositoryName
}
// "oci-layout" file - create if it doesn't exist // "oci-layout" file - create if it doesn't exist
ilPath := path.Join(repoDir, ispec.ImageLayoutFile) ilPath := path.Join(repoDir, ispec.ImageLayoutFile)
if _, err := is.store.Stat(context.Background(), ilPath); err != nil { if _, err := is.store.Stat(context.Background(), ilPath); err != nil {
@ -176,6 +183,10 @@ func (is *ObjectStorage) InitRepo(name string) error {
// ValidateRepo validates that the repository layout is complaint with the OCI repo layout. // ValidateRepo validates that the repository layout is complaint with the OCI repo layout.
func (is *ObjectStorage) ValidateRepo(name string) (bool, error) { func (is *ObjectStorage) ValidateRepo(name string) (bool, error) {
if !zreg.FullNameRegexp.MatchString(name) {
return false, zerr.ErrInvalidRepositoryName
}
// https://github.com/opencontainers/image-spec/blob/master/image-layout.md#content // https://github.com/opencontainers/image-spec/blob/master/image-layout.md#content
// at least, expect at least 3 entries - ["blobs", "oci-layout", "index.json"] // at least, expect at least 3 entries - ["blobs", "oci-layout", "index.json"]
// and an additional/optional BlobUploadDir in each image store // and an additional/optional BlobUploadDir in each image store

View file

@ -386,8 +386,8 @@ func TestStorageDriverStatFunction(t *testing.T) {
3) the returned storageDriver.FileInfo will report that isDir() is true. 3) the returned storageDriver.FileInfo will report that isDir() is true.
*/ */
Convey("Validate storageDriver.Stat() and isDir() functions with zot storage API", t, func(c C) { Convey("Validate storageDriver.Stat() and isDir() functions with zot storage API", t, func(c C) {
repo1 := "repo/testImageA" repo1 := "repo/testimagea"
repo2 := "repo/testImage" repo2 := "repo/testimage"
So(imgStore, ShouldNotBeNil) So(imgStore, ShouldNotBeNil)
@ -446,6 +446,8 @@ func TestStorageDriverStatFunction(t *testing.T) {
} }
func TestGetOrasAndOCIReferrers(t *testing.T) { func TestGetOrasAndOCIReferrers(t *testing.T) {
skipIt(t)
repo := "zot-test" repo := "zot-test"
uuid, err := guuid.NewV4() uuid, err := guuid.NewV4()
@ -655,6 +657,50 @@ func TestNegativeCasesObjectsStorage(t *testing.T) {
storeDriver, imgStore, _ := createObjectsStore(testDir, tdir, true) storeDriver, imgStore, _ := createObjectsStore(testDir, tdir, true)
defer cleanupStorage(storeDriver, testDir) defer cleanupStorage(storeDriver, testDir)
Convey("Invalid repo name", func(c C) {
// Validate repo should fail if repo name does not match spec
_, err := imgStore.ValidateRepo(".")
So(err, ShouldNotBeNil)
So(errors.Is(err, zerr.ErrInvalidRepositoryName), ShouldBeTrue)
_, err = imgStore.ValidateRepo("..")
So(err, ShouldNotBeNil)
So(errors.Is(err, zerr.ErrInvalidRepositoryName), ShouldBeTrue)
_, err = imgStore.ValidateRepo("_test-dir")
So(err, ShouldNotBeNil)
So(errors.Is(err, zerr.ErrInvalidRepositoryName), ShouldBeTrue)
_, err = imgStore.ValidateRepo(".test-dir")
So(err, ShouldNotBeNil)
So(errors.Is(err, zerr.ErrInvalidRepositoryName), ShouldBeTrue)
_, err = imgStore.ValidateRepo("-test-dir")
So(err, ShouldNotBeNil)
So(errors.Is(err, zerr.ErrInvalidRepositoryName), ShouldBeTrue)
// Init repo should fail if repo name does not match spec
err = imgStore.InitRepo(".")
So(err, ShouldNotBeNil)
So(errors.Is(err, zerr.ErrInvalidRepositoryName), ShouldBeTrue)
err = imgStore.InitRepo("..")
So(err, ShouldNotBeNil)
So(errors.Is(err, zerr.ErrInvalidRepositoryName), ShouldBeTrue)
err = imgStore.InitRepo("_test-dir")
So(err, ShouldNotBeNil)
So(errors.Is(err, zerr.ErrInvalidRepositoryName), ShouldBeTrue)
err = imgStore.InitRepo(".test-dir")
So(err, ShouldNotBeNil)
So(errors.Is(err, zerr.ErrInvalidRepositoryName), ShouldBeTrue)
err = imgStore.InitRepo("-test-dir")
So(err, ShouldNotBeNil)
So(errors.Is(err, zerr.ErrInvalidRepositoryName), ShouldBeTrue)
})
Convey("Invalid validate repo", func(c C) { Convey("Invalid validate repo", func(c C) {
So(imgStore.InitRepo(testImage), ShouldBeNil) So(imgStore.InitRepo(testImage), ShouldBeNil)
objects, err := storeDriver.List(context.Background(), path.Join(imgStore.RootDir(), testImage)) objects, err := storeDriver.List(context.Background(), path.Join(imgStore.RootDir(), testImage))

View file

@ -149,6 +149,11 @@ func CopyFiles(sourceDir, destDir string) error {
destFilePath := path.Join(destDir, file.Name()) destFilePath := path.Join(destDir, file.Name())
if file.IsDir() { if file.IsDir() {
if strings.HasPrefix(file.Name(), "_") {
// Some tests create the trivy related folders under test/_trivy
continue
}
if err = CopyFiles(sourceFilePath, destFilePath); err != nil { if err = CopyFiles(sourceFilePath, destFilePath); err != nil {
return err return err
} }
@ -283,7 +288,7 @@ func WaitTillServerReady(url string) {
func WaitTillTrivyDBDownloadStarted(rootDir string) { func WaitTillTrivyDBDownloadStarted(rootDir string) {
for { for {
if _, err := os.Stat(path.Join(rootDir, "trivy.db")); err == nil { if _, err := os.Stat(path.Join(rootDir, "_trivy", "db", "trivy.db")); err == nil {
break break
} }

View file

@ -72,6 +72,47 @@ func TestCopyFiles(t *testing.T) {
err = test.CopyFiles(dir, os.TempDir()) err = test.CopyFiles(dir, os.TempDir())
So(err, ShouldNotBeNil) So(err, ShouldNotBeNil)
}) })
Convey("sourceDir contains a folder starting with invalid characters", t, func() {
srcDir := t.TempDir()
dstDir := t.TempDir()
err := os.MkdirAll(path.Join(srcDir, "_trivy", "db"), 0o755)
if err != nil {
panic(err)
}
err = os.MkdirAll(path.Join(srcDir, "test-index"), 0o755)
if err != nil {
panic(err)
}
filePathTrivy := path.Join(srcDir, "_trivy", "db", "trivy.db")
err = os.WriteFile(filePathTrivy, []byte("some dummy file content"), 0o644) //nolint: gosec
if err != nil {
panic(err)
}
var index ispec.Index
content, err := json.Marshal(index)
if err != nil {
panic(err)
}
err = os.WriteFile(path.Join(srcDir, "test-index", "index.json"), content, 0o644) //nolint: gosec
if err != nil {
panic(err)
}
err = test.CopyFiles(srcDir, dstDir)
So(err, ShouldBeNil)
_, err = os.Stat(path.Join(dstDir, "_trivy", "db", "trivy.db"))
So(err, ShouldNotBeNil)
So(os.IsNotExist(err), ShouldBeTrue)
_, err = os.Stat(path.Join(dstDir, "test-index", "index.json"))
So(err, ShouldBeNil)
})
} }
func TestGetOciLayoutDigests(t *testing.T) { func TestGetOciLayoutDigests(t *testing.T) {

9
tools.go Normal file
View file

@ -0,0 +1,9 @@
//go:build tools
// +build tools
package tools
import (
_ "github.com/99designs/gqlgen"
_ "github.com/99designs/gqlgen/graphql/introspection"
)