mirror of
https://github.com/project-zot/zot.git
synced 2024-12-16 21:56:37 -05:00
refactor(scrub): replace umoci logic in scrub implementation (#1845)
- implement scrub also for S3 storage by replacing umoci - change scrub implementation for ImageIndex - take the `Subject` into consideration when running scrub - remove test code relying on the umoci library. Since we started relying on images in test/data, and we create our own images using go code we can obtain digests by other means. (cherry picked from commit 489d4e2d23c1b4e48799283f8281024bbef6123f) Signed-off-by: Andrei Aaron <aaaron@luxoft.com> Signed-off-by: Andreea-Lupu <andreealupu1470@yahoo.com>
This commit is contained in:
parent
510b7a2e16
commit
92e382ce39
12 changed files with 469 additions and 411 deletions
|
@ -50,6 +50,7 @@ var (
|
|||
ErrCliBadConfig = errors.New("cli: bad config")
|
||||
ErrRepoNotFound = errors.New("repository: not found")
|
||||
ErrRepoBadVersion = errors.New("repository: unsupported layout version")
|
||||
ErrRepoBadLayout = errors.New("repository: invalid layout")
|
||||
ErrManifestNotFound = errors.New("manifest: not found")
|
||||
ErrBadManifest = errors.New("manifest: invalid contents")
|
||||
ErrUploadNotFound = errors.New("uploads: not found")
|
||||
|
|
5
go.mod
5
go.mod
|
@ -5,7 +5,6 @@ go 1.20
|
|||
require (
|
||||
github.com/99designs/gqlgen v0.17.38
|
||||
github.com/Masterminds/semver v1.5.0
|
||||
github.com/apex/log v1.9.0 // indirect
|
||||
github.com/aquasecurity/trivy-db v0.0.0-20230831170347-f732860d4917
|
||||
github.com/bmatcuk/doublestar/v4 v4.6.0
|
||||
github.com/briandowns/spinner v1.23.0
|
||||
|
@ -27,7 +26,6 @@ require (
|
|||
github.com/olekukonko/tablewriter v0.0.5
|
||||
github.com/opencontainers/go-digest v1.0.0
|
||||
github.com/opencontainers/image-spec v1.1.0-rc5
|
||||
github.com/opencontainers/umoci v0.4.8-0.20210922062158-e60a0cc726e6
|
||||
github.com/oras-project/artifacts-spec v1.0.0-rc.2
|
||||
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5
|
||||
github.com/prometheus/client_golang v1.16.0
|
||||
|
@ -439,7 +437,6 @@ require (
|
|||
github.com/protocolbuffers/txtpbfmt v0.0.0-20230328191034-3462fbc510c0 // indirect
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
|
||||
github.com/rivo/uniseg v0.4.4 // indirect
|
||||
github.com/rootless-containers/proto/go-proto v0.0.0-20210921234734-69430b6543fb // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/saracen/walker v0.1.3 // indirect
|
||||
github.com/sassoftware/relic v7.2.1+incompatible // indirect
|
||||
|
@ -471,8 +468,6 @@ require (
|
|||
github.com/transparency-dev/merkle v0.0.2 // indirect
|
||||
github.com/twitchtv/twirp v8.1.2+incompatible // indirect
|
||||
github.com/ulikunitz/xz v0.5.11 // indirect
|
||||
github.com/urfave/cli v1.22.14 // indirect
|
||||
github.com/vbatts/go-mtree v0.5.2 // indirect
|
||||
github.com/vbatts/tar-split v0.11.5 // indirect
|
||||
github.com/xanzy/go-gitlab v0.90.0 // indirect
|
||||
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
||||
|
|
68
go.sum
68
go.sum
|
@ -197,7 +197,6 @@ filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek=
|
|||
filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns=
|
||||
github.com/99designs/gqlgen v0.17.38 h1:3r7G7i8UAdY0iYreNiBAA55auVsrowO0+ZhMl5g4GYU=
|
||||
github.com/99designs/gqlgen v0.17.38/go.mod h1:2v+dKtpI8mIzYeW9dYN8mO69tMmjszW2xKLNcWR/5wQ=
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20210401092550-0a8691dafd0d/go.mod h1:CzsSbkDixRphAF5hS6wbMKq0eI6ccJRb7/A0M6JBnwg=
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU=
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
|
||||
github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0 h1:59MxjQVfjXsBpLy+dbd2/ELV5ofnUkUZBvWSC85sheA=
|
||||
|
@ -374,11 +373,6 @@ github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092/go.mod
|
|||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/apex/log v1.9.0 h1:FHtw/xuaM8AgmvDDTI9fiwoAL25Sq2cxojnZICUU8l0=
|
||||
github.com/apex/log v1.9.0/go.mod h1:m82fZlWIuiWzWP04XCTXmnX0xRkYYbCdYn8jbJeLBEA=
|
||||
github.com/apex/logs v1.0.0/go.mod h1:XzxuLZ5myVHDy9SAmYpamKKRNApGj54PfYLcFrXqDwo=
|
||||
github.com/aphistic/golf v0.0.0-20180712155816-02c07f170c5a/go.mod h1:3NqKYiepwy8kCu4PNA+aP7WUV72eXWJeP9/r3/K9aLE=
|
||||
github.com/aphistic/sweet v0.2.0/go.mod h1:fWDlIh/isSE9n6EPsRmC0det+whmX6dJid3stzu0Xys=
|
||||
github.com/apparentlymart/go-cidr v1.1.0 h1:2mAhrMoF+nhXqxTzSZMUzDHkLjmIHC+Zzn4tdgBZjnU=
|
||||
github.com/apparentlymart/go-cidr v1.1.0/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/YjEn/vI25Lg7Gwc=
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw=
|
||||
|
@ -419,7 +413,6 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPd
|
|||
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||
github.com/aws/aws-sdk-go v1.20.6/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
|
||||
github.com/aws/aws-sdk-go v1.44.287/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
|
||||
github.com/aws/aws-sdk-go v1.45.15 h1:gYBTVSYuhXdatrLbsPaRgVcc637zzdgThWmsDRwXLOo=
|
||||
|
@ -501,7 +494,6 @@ github.com/aws/smithy-go v1.14.2 h1:MJU9hqBGbvWZdApzpvoF2WAIJDbtjK2NDJSiJP7HblQ=
|
|||
github.com/aws/smithy-go v1.14.2/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
|
||||
github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20220228164355-396b2034c795 h1:IWeCJzU+IYaO2rVEBlGPTBfe90cmGXFTLdhUFlzDGsY=
|
||||
github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20220228164355-396b2034c795/go.mod h1:8vJsEZ4iRqG+Vx6pKhWK6U00qcj0KC37IsfszMkY6UE=
|
||||
github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I=
|
||||
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
|
@ -510,7 +502,6 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r
|
|||
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas=
|
||||
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
|
||||
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
|
||||
github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=
|
||||
github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
|
||||
|
@ -546,7 +537,6 @@ github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNS
|
|||
github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA=
|
||||
github.com/chartmuseum/auth v0.5.0 h1:ENNmoxvjxcR/JR0HrghAEtGQe7hToMNj16+UoS5CK9Y=
|
||||
github.com/chartmuseum/auth v0.5.0/go.mod h1:BvoSXHyvbsq+/bbhNgVTDQsModM+HERBTNY5o9Vyrig=
|
||||
github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M=
|
||||
github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s=
|
||||
github.com/cheggaaa/pb/v3 v3.1.4 h1:DN8j4TVVdKu3WxVwcRKu0sG00IIU6FewoABZzXbRQeo=
|
||||
github.com/cheggaaa/pb/v3 v3.1.4/go.mod h1:6wVjILNBaXMs8c21qRiaUM8BR82erfgau1DQ4iUXmSA=
|
||||
|
@ -555,7 +545,6 @@ github.com/chrismellard/docker-credential-acr-env v0.0.0-20220119192733-fe33c00c
|
|||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
|
||||
github.com/clbanning/mxj/v2 v2.5.6 h1:Jm4VaCI/+Ug5Q57IzEoZbwx4iQFA6wkXv72juUSeK+g=
|
||||
github.com/clbanning/mxj/v2 v2.5.6/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
|
@ -579,7 +568,6 @@ github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be h1:J5BL
|
|||
github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be/go.mod h1:mk5IQ+Y0ZeO87b858TlA645sVcEcbiX6YqP98kt+7+w=
|
||||
github.com/containerd/cgroups/v3 v3.0.2 h1:f5WFqIVSgo5IZmtTT3qVBo6TzI1ON6sycSBKkymb9L0=
|
||||
github.com/containerd/cgroups/v3 v3.0.2/go.mod h1:JUgITrzdFqp42uI2ryGA+ge0ap/nxzYgkGmIcetmErE=
|
||||
github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ=
|
||||
github.com/containerd/containerd v1.7.6 h1:oNAVsnhPoy4BTPQivLgTzI9Oleml9l/+eYIDYXRCYo8=
|
||||
github.com/containerd/containerd v1.7.6/go.mod h1:SY6lrkkuJT40BVNO37tlYTSnKJnP5AXBc0fhx0q+TJ4=
|
||||
github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM=
|
||||
|
@ -623,8 +611,6 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
|
|||
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
|
||||
github.com/cyberphone/json-canonicalization v0.0.0-20230710064741-aa7fe85c7dbd h1:0av0vtcjA8Hqv5gyWj79CLCFVwOOyBNWPjrfUWceMNg=
|
||||
github.com/cyberphone/json-canonicalization v0.0.0-20230710064741-aa7fe85c7dbd/go.mod h1:uzvlm1mxhHkdfqitSA92i7Se+S9ksOn3a3qmv/kyOCw=
|
||||
github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
|
||||
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
||||
github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
|
||||
github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
||||
github.com/danieljoos/wincred v1.2.0 h1:ozqKHaLK0W/ii4KVbbvluM91W2H3Sh0BncbUNPS7jLE=
|
||||
|
@ -675,7 +661,6 @@ github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ
|
|||
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
|
||||
github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8=
|
||||
github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw=
|
||||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 h1:UhxFibDNY/bfvqU5CAUmr9zpesgbU6SWc8/B4mflAE4=
|
||||
|
@ -720,7 +705,6 @@ github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSw
|
|||
github.com/flynn/go-docopt v0.0.0-20140912013429-f6dd2ebbb31e/go.mod h1:HyVoz1Mz5Co8TFO8EupIdlcpwShBmY98dkT2xeHkvEI=
|
||||
github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
|
||||
github.com/foxcpp/go-mockdns v1.0.0 h1:7jBqxd3WDWwi/6WhDvacvH1XsN3rOLXyHM1uhvIx6FI=
|
||||
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
|
||||
github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps=
|
||||
github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
|
@ -1124,7 +1108,6 @@ github.com/jedisct1/go-minisign v0.0.0-20211028175153-1c139d1cc84b h1:ZGiXF8sz7P
|
|||
github.com/jedisct1/go-minisign v0.0.0-20211028175153-1c139d1cc84b/go.mod h1:hQmNrgofl+IY/8L+n20H6E6PWBBTokdsv+q49j0QhsU=
|
||||
github.com/jellydator/ttlcache/v3 v3.0.1 h1:cHgCSMS7TdQcoprXnWUptJZzyFsqs18Lt8VVhRuZYVU=
|
||||
github.com/jeremija/gosubmit v0.2.7 h1:At0OhGCFGPXyjPYAsCchoBUhE099pcBXmsb4iZqROIc=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
|
||||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
|
||||
|
@ -1136,7 +1119,6 @@ github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqx
|
|||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7/go.mod h1:2iMrUgbbvHEiQClaW2NsSzMyGHqN+rDFqY705q49KG0=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
|
@ -1159,12 +1141,10 @@ github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF
|
|||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM=
|
||||
github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
|
||||
github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||
github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
|
||||
github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||
github.com/knqyf263/go-apk-version v0.0.0-20200609155635-041fdbb8563f h1:GvCU5GXhHq+7LeOzx/haG7HSIZokl3/0GkoUFzsRJjg=
|
||||
|
@ -1183,7 +1163,6 @@ github.com/kortschak/utter v1.0.1/go.mod h1:vSmSjbyrlKjjsL71193LmzBOKgwePk9DH6uF
|
|||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
|
@ -1262,16 +1241,12 @@ github.com/masahiro331/go-xfs-filesystem v0.0.0-20230608043311-a335f4599b70/go.m
|
|||
github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A=
|
||||
github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
|
@ -1292,7 +1267,6 @@ github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S
|
|||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||
github.com/microsoft/go-rustaudit v0.0.0-20220808201409-204dfee52032 h1:TLygBUBxikNJJfLwgm+Qwdgq1FtfV8Uh7bcxRyTzK8s=
|
||||
github.com/microsoft/go-rustaudit v0.0.0-20220808201409-204dfee52032/go.mod h1:vYT9HE7WCvL64iVeZylKmCsWKfE+JZ8105iuh2Trk8g=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
|
@ -1334,7 +1308,6 @@ github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
|
|||
github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
|
||||
github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8=
|
||||
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
|
||||
github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
|
||||
github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78=
|
||||
github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI=
|
||||
github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc=
|
||||
|
@ -1350,8 +1323,6 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
|
|||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
||||
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0=
|
||||
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
||||
|
@ -1361,7 +1332,6 @@ github.com/mozillazg/docker-credential-acr-helper v0.3.0 h1:DVWFZ3/O8BP6Ue3iS/Ol
|
|||
github.com/mozillazg/docker-credential-acr-helper v0.3.0/go.mod h1:cZlu3tof523ujmLuiNUb6JsjtHcNA70u1jitrrdnuyA=
|
||||
github.com/mpvl/unique v0.0.0-20150818121801-cbe035fff7de h1:D5x39vF5KCwKQaw+OC9ZPiLVHXz3UFw2+psEX+gYcto=
|
||||
github.com/mpvl/unique v0.0.0-20150818121801-cbe035fff7de/go.mod h1:kJun4WP5gFuHZgRjZUWWuH1DTxCtxbHDOIJsudS8jzY=
|
||||
github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
|
@ -1396,7 +1366,6 @@ github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042
|
|||
github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
|
||||
github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
|
||||
github.com/onsi/ginkgo/v2 v2.12.0 h1:UIVDowFPwpg6yMUpPjGkYvf06K3RAiJXUhCxEwQVHRI=
|
||||
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||
|
@ -1409,20 +1378,14 @@ github.com/opencontainers/distribution-spec/specs-go v0.0.0-20230117141039-067a0
|
|||
github.com/opencontainers/distribution-spec/specs-go v0.0.0-20230117141039-067a0f5b0e25/go.mod h1:uLvbyisMXc6uWXBmKrPegq9igec91coS/kGM2sHL660=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI=
|
||||
github.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8=
|
||||
github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0=
|
||||
github.com/opencontainers/runc v1.1.9 h1:XR0VIHTGce5eWPkaPesqTBrhW2yAcaraWfsEalNwQLM=
|
||||
github.com/opencontainers/runc v1.1.9/go.mod h1:CbUumNnWCuTGFukNXahoo/RFBZvDAgRh/smNYNOhA50=
|
||||
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg=
|
||||
github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8=
|
||||
github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU=
|
||||
github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec=
|
||||
github.com/opencontainers/umoci v0.4.8-0.20210922062158-e60a0cc726e6 h1:yRmw/21YcR/78dRoFyWNJ6c3VxOXqe97PhNZI0Ib7bM=
|
||||
github.com/opencontainers/umoci v0.4.8-0.20210922062158-e60a0cc726e6/go.mod h1:kO0Bh4G4BZUh2QSlqsCR/OCtdqLjmt3mvD6okZhMBlU=
|
||||
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
|
||||
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
|
||||
github.com/openvex/go-vex v0.2.5 h1:41utdp2rHgAGCsG+UbjmfMG5CWQxs15nGqir1eRgSrQ=
|
||||
|
@ -1514,7 +1477,6 @@ github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ
|
|||
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
|
||||
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/fastuuid v1.1.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
|
@ -1523,8 +1485,6 @@ github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE
|
|||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||
github.com/rootless-containers/proto/go-proto v0.0.0-20210921234734-69430b6543fb h1:nkbcM8VoyGDolfdJKoIZc9QSlJrm3IrCg/0/v7VhK/0=
|
||||
github.com/rootless-containers/proto/go-proto v0.0.0-20210921234734-69430b6543fb/go.mod h1:LLjEAc6zmycfeN7/1fxIphWQPjHpTt7ElqT7eVf8e4A=
|
||||
github.com/rs/cors v1.9.0 h1:l9HGsTsHJcvW14Nk7J9KFz8bzeAWXn3CG6bgt7LsrAE=
|
||||
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A=
|
||||
|
@ -1545,7 +1505,6 @@ github.com/sassoftware/relic v7.2.1+incompatible h1:Pwyh1F3I0r4clFJXkSI8bOyJINGq
|
|||
github.com/sassoftware/relic v7.2.1+incompatible/go.mod h1:CWfAxv73/iLZ17rbyhIEq3K9hs5w6FpNMdUT//qR+zk=
|
||||
github.com/sassoftware/relic/v7 v7.5.5 h1:2ZUM6ovo3STCAp0hZnO9nQY9lOB8OyfneeYIi4YUxMU=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo=
|
||||
github.com/secure-systems-lab/go-securesystemslib v0.3.1/go.mod h1:o8hhjkbNl2gOamKUA/eNW3xUrntHT9L4W89W1nfj43U=
|
||||
github.com/secure-systems-lab/go-securesystemslib v0.7.0 h1:OwvJ5jQf9LnIAS83waAjPbcMsODrTQUpJ02eNLUoxBg=
|
||||
github.com/secure-systems-lab/go-securesystemslib v0.7.0/go.mod h1:/2gYnlnHVQ6xeGtfIqFy7Do03K4cdCY0A/GlJLDKLHI=
|
||||
|
@ -1553,7 +1512,6 @@ github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys=
|
|||
github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
|
||||
github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c=
|
||||
github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
|
||||
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
|
||||
|
@ -1578,7 +1536,6 @@ github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.7.2 h1:GquAXZRIVJ8e
|
|||
github.com/sigstore/timestamp-authority v1.1.2 h1:xgBs9Ct27sEgFb35GL1trKD2XOgYbtk0q2G0HLZHDDY=
|
||||
github.com/sigstore/timestamp-authority v1.1.2/go.mod h1:7rGe/e6ZJNMqPiwFiv7w+qNXT8GID9gL7nMcRwZ007I=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
|
@ -1594,13 +1551,10 @@ github.com/smallstep/assert v0.0.0-20200723003110-82e2b9b3b262 h1:unQFBIznI+VYD1
|
|||
github.com/smarty/assertions v1.15.0 h1:cR//PqUBUiQRakZWqBiFFQ9wb8emQGDb0HeGdqGByCY=
|
||||
github.com/smarty/assertions v1.15.0/go.mod h1:yABtdzeQs6l1brC900WlRNwj6ZR55d7B+E8C6HtKdec=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM=
|
||||
github.com/smartystreets/assertions v1.1.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
|
||||
github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY=
|
||||
github.com/smartystreets/goconvey v1.8.1/go.mod h1:+/u4qLyY6x1jReYOp7GOM2FSt8aP9CzCZL03bI28W60=
|
||||
github.com/smartystreets/gunit v1.0.0/go.mod h1:qwPWnhz6pn0NnRBP++URONOVyNkPyr4SauJk4cUOwJs=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/sosedoff/gitkit v0.4.0 h1:opyQJ/h9xMRLsz2ca/2CRXtstePcpldiZN8DpLLF8Os=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
|
@ -1688,13 +1642,6 @@ github.com/tinylib/msgp v1.1.8 h1:FCXC1xanKO4I8plpHGH2P7koL/RzZs12l/+r7vakfm0=
|
|||
github.com/tinylib/msgp v1.1.8/go.mod h1:qkpG+2ldGg4xRFmx+jfTvZPxfGFhi64BcnL9vkCm/Tw=
|
||||
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 h1:e/5i7d4oYZ+C1wj2THlRK+oAhjeS/TRQwMfkIuet3w0=
|
||||
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399/go.mod h1:LdwHTNJT99C5fTAzDz0ud328OgXz+gierycbcIx2fRs=
|
||||
github.com/tj/assert v0.0.0-20171129193455-018094318fb0/go.mod h1:mZ9/Rh9oLWpLLDRpvE+3b7gP/C2YyLFYxNmcLnPTMe0=
|
||||
github.com/tj/assert v0.0.3 h1:Df/BlaZ20mq6kuai7f5z2TvPFiwC3xaWJSDQNiIS3Rk=
|
||||
github.com/tj/assert v0.0.3/go.mod h1:Ne6X72Q+TB1AteidzQncjw9PabbMp4PBMZ1k+vd1Pvk=
|
||||
github.com/tj/go-buffer v1.1.0/go.mod h1:iyiJpfFcR2B9sXu7KvjbT9fpM4mOelRSDTbntVj52Uc=
|
||||
github.com/tj/go-elastic v0.0.0-20171221160941-36157cbbebc2/go.mod h1:WjeM0Oo1eNAjXGDx2yma7uG2XoyRZTq1uv3M/o7imD0=
|
||||
github.com/tj/go-kinesis v0.0.0-20171128231115-08b17f58cb1b/go.mod h1:/yhzCV0xPfx6jb1bBgRFjl5lytqVqZXEaeqWP8lTEao=
|
||||
github.com/tj/go-spin v1.1.0/go.mod h1:Mg1mzmePZm4dva8Qz60H2lHwmJ2loum4VIrLgVnKwh4=
|
||||
github.com/tjfoc/gmsm v1.3.2 h1:7JVkAn5bvUJ7HtU08iW6UiD+UTmJTIToHCfeFzkcCxM=
|
||||
github.com/tjfoc/gmsm v1.3.2/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
|
@ -1706,16 +1653,9 @@ github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGr
|
|||
github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8=
|
||||
github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/urfave/cli v1.22.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk=
|
||||
github.com/urfave/cli v1.22.14/go.mod h1:X0eDS6pD6Exaclxm99NJ3FiCDRED7vIHpx2mDOHLvkA=
|
||||
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
||||
github.com/urfave/cli/v2 v2.25.5 h1:d0NIAyhh5shGscroL7ek/Ya9QYQE0KNabJgiUinIQkc=
|
||||
github.com/urfave/cli/v2 v2.25.5/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc=
|
||||
github.com/vbatts/go-mtree v0.5.0/go.mod h1:7JbaNHyBMng+RP8C3Q4E+4Ca8JnGQA2R/MB+jb4tSOk=
|
||||
github.com/vbatts/go-mtree v0.5.2 h1:d8SAbLJiR1cR3pe1J+FBaalRkCQw95gP12/P+a9PUcA=
|
||||
github.com/vbatts/go-mtree v0.5.2/go.mod h1:e0NDJ+bT3jG7ZINeB9HR5AxTvjskCsOR54+9KoaXyDc=
|
||||
github.com/vbatts/tar-split v0.11.5 h1:3bHCTIheBm1qFTcgh9oPu+nNBtX+XJIupG/vacinCts=
|
||||
github.com/vbatts/tar-split v0.11.5/go.mod h1:yZbwRsSeGjusneWgA781EKej9HF8vme8okylkAeNKLk=
|
||||
github.com/vbauerster/mpb/v8 v8.6.1 h1:XbBpIbJxJOO9yMcKPpI4oEFPW6tLAptefNQJNcGWri8=
|
||||
|
@ -1723,8 +1663,6 @@ github.com/vbauerster/mpb/v8 v8.6.1/go.mod h1:S0tuIjikxlLxCeNijNhwAuD/BB3UE/d2ny
|
|||
github.com/vektah/gqlparser/v2 v2.5.10 h1:6zSM4azXC9u4Nxy5YmdmGu4uKamfwsdKTwp5zsEealU=
|
||||
github.com/vektah/gqlparser/v2 v2.5.10/go.mod h1:1rCcfwB2ekJofmluGWXMSEnPMZgbxzwj6FaZ/4OT8Cc=
|
||||
github.com/veraison/go-cose v1.1.0 h1:AalPS4VGiKavpAzIlBjrn7bhqXiXi4jbMYY/2+UC+4o=
|
||||
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
|
||||
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
|
||||
github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4=
|
||||
github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU=
|
||||
github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
|
||||
|
@ -1849,7 +1787,6 @@ golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnf
|
|||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
|
@ -1859,7 +1796,6 @@ golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPh
|
|||
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
|
@ -2056,7 +1992,6 @@ golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
@ -2064,7 +1999,6 @@ golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
@ -2086,7 +2020,6 @@ golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201005172224-997123666555/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
@ -2105,7 +2038,6 @@ golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
|
|
|
@ -4350,7 +4350,7 @@ func TestInvalidCases(t *testing.T) {
|
|||
panic(err)
|
||||
}
|
||||
|
||||
digest := test.GetTestBlobDigest("zot-cve-test", "config").String()
|
||||
digest := godigest.FromString("dummy").String()
|
||||
name := "zot-c-test"
|
||||
|
||||
client := resty.New()
|
||||
|
@ -4449,7 +4449,8 @@ func TestCrossRepoMount(t *testing.T) {
|
|||
ctlr.Config.Storage.RemoteCache = false
|
||||
ctlr.Config.Storage.Dedupe = false
|
||||
|
||||
err := test.WriteImageToFileSystem(CreateDefaultImage(), "zot-cve-test", "test", storage.StoreController{
|
||||
image := CreateDefaultImage()
|
||||
err := test.WriteImageToFileSystem(image, "zot-cve-test", "test", storage.StoreController{
|
||||
DefaultStore: test.GetDefaultImageStore(dir, ctlr.Log),
|
||||
})
|
||||
So(err, ShouldBeNil)
|
||||
|
@ -4459,8 +4460,7 @@ func TestCrossRepoMount(t *testing.T) {
|
|||
|
||||
params := make(map[string]string)
|
||||
|
||||
var manifestDigest godigest.Digest
|
||||
manifestDigest, _, _ = test.GetOciLayoutDigests(path.Join(dir, "zot-cve-test"))
|
||||
manifestDigest := image.ManifestDescriptor.Digest
|
||||
|
||||
dgst := manifestDigest
|
||||
name := "zot-cve-test"
|
||||
|
@ -4487,7 +4487,7 @@ func TestCrossRepoMount(t *testing.T) {
|
|||
baseURL, constants.RoutePrefix, constants.Blobs, constants.Uploads))
|
||||
|
||||
incorrectParams := make(map[string]string)
|
||||
incorrectParams["mount"] = test.GetTestBlobDigest("zot-cve-test", "manifest").String()
|
||||
incorrectParams["mount"] = godigest.FromString("dummy").String()
|
||||
incorrectParams["from"] = "zot-x-test"
|
||||
|
||||
postResponse, err = client.R().
|
||||
|
|
|
@ -28,25 +28,19 @@ func EnableScrubExtension(config *config.Config, log log.Logger, storeController
|
|||
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
|
||||
}
|
||||
|
||||
// is local imagestore (because of umoci dependency which works only locally)
|
||||
if config.Storage.StorageDriver == nil {
|
||||
generator := &taskGenerator{
|
||||
imgStore: storeController.DefaultStore,
|
||||
log: log,
|
||||
}
|
||||
sch.SubmitGenerator(generator, config.Extensions.Scrub.Interval, scheduler.LowPriority)
|
||||
generator := &taskGenerator{
|
||||
imgStore: storeController.DefaultStore,
|
||||
log: log,
|
||||
}
|
||||
sch.SubmitGenerator(generator, config.Extensions.Scrub.Interval, scheduler.LowPriority)
|
||||
|
||||
if config.Storage.SubPaths != nil {
|
||||
for route := range config.Storage.SubPaths {
|
||||
// is local imagestore (because of umoci dependency which works only locally)
|
||||
if config.Storage.SubPaths[route].StorageDriver == nil {
|
||||
generator := &taskGenerator{
|
||||
imgStore: storeController.SubStore[route],
|
||||
log: log,
|
||||
}
|
||||
sch.SubmitGenerator(generator, config.Extensions.Scrub.Interval, scheduler.LowPriority)
|
||||
generator := &taskGenerator{
|
||||
imgStore: storeController.SubStore[route],
|
||||
log: log,
|
||||
}
|
||||
sch.SubmitGenerator(generator, config.Extensions.Scrub.Interval, scheduler.LowPriority)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -39,6 +39,7 @@ func RunScrubRepo(ctx context.Context, imgStore storageTypes.ImageStore, repo st
|
|||
Str("image", result.ImageName).
|
||||
Str("tag", result.Tag).
|
||||
Str("status", result.Status).
|
||||
Str("affected blob", result.AffectedBlob).
|
||||
Str("error", result.Error).
|
||||
Msg("scrub: blobs/manifest affected")
|
||||
}
|
||||
|
|
|
@ -381,19 +381,21 @@ func TestRepoListWithNewestImage(t *testing.T) {
|
|||
ctlrManager.StartAndWait(port)
|
||||
defer ctlrManager.StopServer()
|
||||
|
||||
config, layers, manifest, err := GetImageComponents(100)
|
||||
config, layers, _, err := GetImageComponents(100)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = UploadImage(Image{Manifest: manifest, Config: config, Layers: layers}, baseURL, "zot-cve-test", "0.0.1")
|
||||
uploadedImage := CreateImageWith().LayerBlobs(layers).ImageConfig(config).Build()
|
||||
|
||||
err = UploadImage(uploadedImage, baseURL, "zot-cve-test", "0.0.1")
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = UploadImage(Image{Manifest: manifest, Config: config, Layers: layers}, baseURL, "a/zot-cve-test", "0.0.1")
|
||||
err = UploadImage(uploadedImage, baseURL, "a/zot-cve-test", "0.0.1")
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = UploadImage(Image{Manifest: manifest, Config: config, Layers: layers}, baseURL, "zot-test", "0.0.1")
|
||||
err = UploadImage(uploadedImage, baseURL, "zot-test", "0.0.1")
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = UploadImage(Image{Manifest: manifest, Config: config, Layers: layers}, baseURL, "a/zot-test", "0.0.1")
|
||||
err = UploadImage(uploadedImage, baseURL, "a/zot-test", "0.0.1")
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
resp, err := resty.R().Get(baseURL + "/v2/")
|
||||
|
@ -590,9 +592,8 @@ func TestRepoListWithNewestImage(t *testing.T) {
|
|||
panic(err)
|
||||
}
|
||||
|
||||
var manifestDigest godigest.Digest
|
||||
var configDigest godigest.Digest
|
||||
manifestDigest, configDigest, _ = GetOciLayoutDigests(path.Join(subRootDir, "a/zot-test"))
|
||||
manifestDigest := uploadedImage.ManifestDescriptor.Digest
|
||||
configDigest := uploadedImage.ConfigDescriptor.Digest
|
||||
|
||||
// Delete config blob and try.
|
||||
err = os.Remove(path.Join(subRootDir, "a/zot-test/blobs/sha256", configDigest.Encoded()))
|
||||
|
@ -1269,22 +1270,25 @@ func TestExpandedRepoInfo(t *testing.T) {
|
|||
ctlrManager.StartAndWait(port)
|
||||
defer ctlrManager.StopServer()
|
||||
|
||||
config, layers, manifest, err := GetImageComponents(100)
|
||||
config, layers, _, err := GetImageComponents(100)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
manifest.Annotations = make(map[string]string)
|
||||
manifest.Annotations["org.opencontainers.image.vendor"] = "zot"
|
||||
annotations := make(map[string]string)
|
||||
annotations["org.opencontainers.image.vendor"] = "zot"
|
||||
|
||||
err = UploadImage(Image{Manifest: manifest, Config: config, Layers: layers}, baseURL, "zot-cve-test", "0.0.1")
|
||||
uploadedImage := CreateImageWith().LayerBlobs(layers).ImageConfig(config).
|
||||
Annotations(annotations).Build()
|
||||
|
||||
err = UploadImage(uploadedImage, baseURL, "zot-cve-test", "0.0.1")
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = UploadImage(Image{Manifest: manifest, Config: config, Layers: layers}, baseURL, "a/zot-cve-test", "0.0.1")
|
||||
err = UploadImage(uploadedImage, baseURL, "a/zot-cve-test", "0.0.1")
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = UploadImage(Image{Manifest: manifest, Config: config, Layers: layers}, baseURL, "zot-test", "0.0.1")
|
||||
err = UploadImage(uploadedImage, baseURL, "zot-test", "0.0.1")
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = UploadImage(Image{Manifest: manifest, Config: config, Layers: layers}, baseURL, "a/zot-test", "0.0.1")
|
||||
err = UploadImage(uploadedImage, baseURL, "a/zot-test", "0.0.1")
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
log := log.NewLogger("debug", "")
|
||||
|
@ -1455,8 +1459,7 @@ func TestExpandedRepoInfo(t *testing.T) {
|
|||
}
|
||||
So(found, ShouldEqual, true)
|
||||
|
||||
var manifestDigest godigest.Digest
|
||||
manifestDigest, _, _ = GetOciLayoutDigests(path.Join(rootDir, "zot-test"))
|
||||
manifestDigest := uploadedImage.ManifestDescriptor.Digest
|
||||
|
||||
err = os.Remove(path.Join(rootDir, "zot-test/blobs/sha256", manifestDigest.Encoded()))
|
||||
So(err, ShouldBeNil)
|
||||
|
|
|
@ -5,16 +5,12 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/olekukonko/tablewriter"
|
||||
godigest "github.com/opencontainers/go-digest"
|
||||
ispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/opencontainers/umoci"
|
||||
"github.com/opencontainers/umoci/oci/casext"
|
||||
|
||||
"zotregistry.io/zot/errors"
|
||||
storageTypes "zotregistry.io/zot/pkg/storage/types"
|
||||
|
@ -24,19 +20,22 @@ const (
|
|||
colImageNameIndex = iota
|
||||
colTagIndex
|
||||
colStatusIndex
|
||||
colAffectedBlobIndex
|
||||
colErrorIndex
|
||||
|
||||
imageNameWidth = 32
|
||||
tagWidth = 24
|
||||
statusWidth = 8
|
||||
errorWidth = 8
|
||||
imageNameWidth = 32
|
||||
tagWidth = 24
|
||||
statusWidth = 8
|
||||
affectedBlobWidth = 24
|
||||
errorWidth = 8
|
||||
)
|
||||
|
||||
type ScrubImageResult struct {
|
||||
ImageName string `json:"imageName"`
|
||||
Tag string `json:"tag"`
|
||||
Status string `json:"status"`
|
||||
Error string `json:"error"`
|
||||
ImageName string `json:"imageName"`
|
||||
Tag string `json:"tag"`
|
||||
Status string `json:"status"`
|
||||
AffectedBlob string `json:"affectedBlob"`
|
||||
Error string `json:"error"`
|
||||
}
|
||||
|
||||
type ScrubResults struct {
|
||||
|
@ -92,153 +91,228 @@ func CheckRepo(ctx context.Context, imageName string, imgStore storageTypes.Imag
|
|||
return results, ctx.Err()
|
||||
}
|
||||
|
||||
dir := path.Join(imgStore.RootDir(), imageName)
|
||||
if !imgStore.DirExists(dir) {
|
||||
return results, errors.ErrRepoNotFound
|
||||
}
|
||||
|
||||
oci, err := umoci.OpenLayout(dir)
|
||||
if err != nil {
|
||||
return results, err
|
||||
}
|
||||
|
||||
defer oci.Close()
|
||||
|
||||
var lockLatency time.Time
|
||||
|
||||
imgStore.RLock(&lockLatency)
|
||||
defer imgStore.RUnlock(&lockLatency)
|
||||
|
||||
buf, err := os.ReadFile(path.Join(dir, "index.json"))
|
||||
// check image structure / layout
|
||||
ok, err := imgStore.ValidateRepo(imageName)
|
||||
if err != nil {
|
||||
return results, err
|
||||
}
|
||||
|
||||
if !ok {
|
||||
return results, errors.ErrRepoBadLayout
|
||||
}
|
||||
|
||||
// check "index.json" content
|
||||
indexContent, err := imgStore.GetIndexContent(imageName)
|
||||
if err != nil {
|
||||
return results, err
|
||||
}
|
||||
|
||||
var index ispec.Index
|
||||
if err := json.Unmarshal(buf, &index); err != nil {
|
||||
if err := json.Unmarshal(indexContent, &index); err != nil {
|
||||
return results, errors.ErrRepoNotFound
|
||||
}
|
||||
|
||||
listOfManifests := []ispec.Descriptor{}
|
||||
scrubbedManifests := make(map[godigest.Digest]ScrubImageResult)
|
||||
|
||||
for _, manifest := range index.Manifests {
|
||||
if manifest.MediaType == ispec.MediaTypeImageIndex {
|
||||
buf, err := os.ReadFile(path.Join(dir, "blobs", manifest.Digest.Algorithm().String(), manifest.Digest.Encoded()))
|
||||
if err != nil {
|
||||
tagName := manifest.Annotations[ispec.AnnotationRefName]
|
||||
imgRes := getResult(imageName, tagName, errors.ErrBadBlobDigest)
|
||||
results = append(results, imgRes)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
var idx ispec.Index
|
||||
if err := json.Unmarshal(buf, &idx); err != nil {
|
||||
tagName := manifest.Annotations[ispec.AnnotationRefName]
|
||||
imgRes := getResult(imageName, tagName, errors.ErrBadBlobDigest)
|
||||
results = append(results, imgRes)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
listOfManifests = append(listOfManifests, idx.Manifests...)
|
||||
} else if manifest.MediaType == ispec.MediaTypeImageManifest {
|
||||
listOfManifests = append(listOfManifests, manifest)
|
||||
}
|
||||
}
|
||||
|
||||
for _, m := range listOfManifests {
|
||||
tag := m.Annotations[ispec.AnnotationRefName]
|
||||
imageResult := CheckIntegrity(ctx, imageName, tag, oci, m, dir)
|
||||
results = append(results, imageResult)
|
||||
tag := manifest.Annotations[ispec.AnnotationRefName]
|
||||
scrubManifest(ctx, manifest, imgStore, imageName, tag, scrubbedManifests)
|
||||
results = append(results, scrubbedManifests[manifest.Digest])
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
func CheckIntegrity(ctx context.Context, imageName, tagName string, oci casext.Engine, manifest ispec.Descriptor, dir string) ScrubImageResult { //nolint: lll
|
||||
func scrubManifest(
|
||||
ctx context.Context, manifest ispec.Descriptor, imgStore storageTypes.ImageStore, imageName, tag string,
|
||||
scrubbedManifests map[godigest.Digest]ScrubImageResult,
|
||||
) {
|
||||
res, ok := scrubbedManifests[manifest.Digest]
|
||||
if ok {
|
||||
scrubbedManifests[manifest.Digest] = newScrubImageResult(imageName, tag, res.Status,
|
||||
res.AffectedBlob, res.Error)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
switch manifest.MediaType {
|
||||
case ispec.MediaTypeImageIndex:
|
||||
buf, err := imgStore.GetBlobContent(imageName, manifest.Digest)
|
||||
if err != nil {
|
||||
imgRes := getResult(imageName, tag, manifest.Digest, errors.ErrBadBlobDigest)
|
||||
scrubbedManifests[manifest.Digest] = imgRes
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
var idx ispec.Index
|
||||
if err := json.Unmarshal(buf, &idx); err != nil {
|
||||
imgRes := getResult(imageName, tag, manifest.Digest, errors.ErrBadBlobDigest)
|
||||
scrubbedManifests[manifest.Digest] = imgRes
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// check all manifests
|
||||
for _, m := range idx.Manifests {
|
||||
scrubManifest(ctx, m, imgStore, imageName, tag, scrubbedManifests)
|
||||
|
||||
// if the manifest is affected then this index is also affected
|
||||
if scrubbedManifests[m.Digest].Error != "" {
|
||||
mRes := scrubbedManifests[m.Digest]
|
||||
|
||||
scrubbedManifests[manifest.Digest] = newScrubImageResult(imageName, tag, mRes.Status,
|
||||
mRes.AffectedBlob, mRes.Error)
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// at this point, before starting to check de subject we can consider the index is ok
|
||||
scrubbedManifests[manifest.Digest] = getResult(imageName, tag, "", nil)
|
||||
|
||||
// check subject if exists
|
||||
if idx.Subject != nil {
|
||||
scrubManifest(ctx, *idx.Subject, imgStore, imageName, tag, scrubbedManifests)
|
||||
|
||||
subjectRes := scrubbedManifests[idx.Subject.Digest]
|
||||
|
||||
scrubbedManifests[manifest.Digest] = newScrubImageResult(imageName, tag, subjectRes.Status,
|
||||
subjectRes.AffectedBlob, subjectRes.Error)
|
||||
}
|
||||
case ispec.MediaTypeImageManifest:
|
||||
imgRes := CheckIntegrity(ctx, imageName, tag, manifest, imgStore)
|
||||
scrubbedManifests[manifest.Digest] = imgRes
|
||||
|
||||
// if integrity ok then check subject if exists
|
||||
if imgRes.Error == "" {
|
||||
manifestContent, _ := imgStore.GetBlobContent(imageName, manifest.Digest)
|
||||
|
||||
var man ispec.Manifest
|
||||
|
||||
_ = json.Unmarshal(manifestContent, &man)
|
||||
|
||||
if man.Subject != nil {
|
||||
scrubManifest(ctx, *man.Subject, imgStore, imageName, tag, scrubbedManifests)
|
||||
|
||||
subjectRes := scrubbedManifests[man.Subject.Digest]
|
||||
|
||||
scrubbedManifests[manifest.Digest] = newScrubImageResult(imageName, tag, subjectRes.Status,
|
||||
subjectRes.AffectedBlob, subjectRes.Error)
|
||||
}
|
||||
}
|
||||
default:
|
||||
scrubbedManifests[manifest.Digest] = getResult(imageName, tag, manifest.Digest, errors.ErrBadManifest)
|
||||
}
|
||||
}
|
||||
|
||||
func CheckIntegrity(
|
||||
ctx context.Context, imageName, tagName string, manifest ispec.Descriptor, imgStore storageTypes.ImageStore,
|
||||
) ScrubImageResult {
|
||||
// check manifest and config
|
||||
if _, err := umoci.Stat(ctx, oci, manifest); err != nil {
|
||||
return getResult(imageName, tagName, err)
|
||||
if affectedBlob, err := CheckManifestAndConfig(imageName, manifest, imgStore); err != nil {
|
||||
return getResult(imageName, tagName, affectedBlob, err)
|
||||
}
|
||||
|
||||
// check layers
|
||||
return CheckLayers(ctx, imageName, tagName, dir, manifest)
|
||||
return CheckLayers(ctx, imageName, tagName, manifest, imgStore)
|
||||
}
|
||||
|
||||
func CheckLayers(ctx context.Context, imageName, tagName, dir string, manifest ispec.Descriptor) ScrubImageResult {
|
||||
func CheckManifestAndConfig(
|
||||
imageName string, manifestDesc ispec.Descriptor, imgStore storageTypes.ImageStore,
|
||||
) (godigest.Digest, error) {
|
||||
if manifestDesc.MediaType != ispec.MediaTypeImageManifest {
|
||||
return manifestDesc.Digest, errors.ErrBadManifest
|
||||
}
|
||||
|
||||
manifestContent, err := imgStore.GetBlobContent(imageName, manifestDesc.Digest)
|
||||
if err != nil {
|
||||
return manifestDesc.Digest, err
|
||||
}
|
||||
|
||||
var manifest ispec.Manifest
|
||||
|
||||
err = json.Unmarshal(manifestContent, &manifest)
|
||||
if err != nil {
|
||||
return manifestDesc.Digest, errors.ErrBadManifest
|
||||
}
|
||||
|
||||
configContent, err := imgStore.GetBlobContent(imageName, manifest.Config.Digest)
|
||||
if err != nil {
|
||||
return manifest.Config.Digest, err
|
||||
}
|
||||
|
||||
var config ispec.Image
|
||||
|
||||
err = json.Unmarshal(configContent, &config)
|
||||
if err != nil {
|
||||
return manifest.Config.Digest, errors.ErrBadConfig
|
||||
}
|
||||
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func CheckLayers(
|
||||
ctx context.Context, imageName, tagName string, manifest ispec.Descriptor, imgStore storageTypes.ImageStore,
|
||||
) ScrubImageResult {
|
||||
imageRes := ScrubImageResult{}
|
||||
|
||||
buf, err := os.ReadFile(path.Join(dir, "blobs", manifest.Digest.Algorithm().String(), manifest.Digest.Encoded()))
|
||||
buf, err := imgStore.GetBlobContent(imageName, manifest.Digest)
|
||||
if err != nil {
|
||||
imageRes = getResult(imageName, tagName, err)
|
||||
imageRes = getResult(imageName, tagName, manifest.Digest, err)
|
||||
|
||||
return imageRes
|
||||
}
|
||||
|
||||
var man ispec.Manifest
|
||||
if err := json.Unmarshal(buf, &man); err != nil {
|
||||
imageRes = getResult(imageName, tagName, err)
|
||||
imageRes = getResult(imageName, tagName, manifest.Digest, errors.ErrBadManifest)
|
||||
|
||||
return imageRes
|
||||
}
|
||||
|
||||
for _, layer := range man.Layers {
|
||||
layerPath := path.Join(dir, "blobs", layer.Digest.Algorithm().String(), layer.Digest.Encoded())
|
||||
|
||||
_, err = os.Stat(layerPath)
|
||||
layerContent, err := imgStore.GetBlobContent(imageName, layer.Digest)
|
||||
if err != nil {
|
||||
imageRes = getResult(imageName, tagName, errors.ErrBlobNotFound)
|
||||
imageRes = getResult(imageName, tagName, layer.Digest, err)
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
layerFh, err := os.Open(layerPath)
|
||||
if err != nil {
|
||||
imageRes = getResult(imageName, tagName, errors.ErrBlobNotFound)
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
computedDigest, err := godigest.FromReader(layerFh)
|
||||
layerFh.Close()
|
||||
|
||||
if err != nil {
|
||||
imageRes = getResult(imageName, tagName, errors.ErrBadBlobDigest)
|
||||
|
||||
break
|
||||
}
|
||||
computedDigest := godigest.FromBytes(layerContent)
|
||||
|
||||
if computedDigest != layer.Digest {
|
||||
imageRes = getResult(imageName, tagName, errors.ErrBadBlobDigest)
|
||||
imageRes = getResult(imageName, tagName, layer.Digest, errors.ErrBadBlobDigest)
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
imageRes = getResult(imageName, tagName, nil)
|
||||
imageRes = getResult(imageName, tagName, "", nil)
|
||||
}
|
||||
|
||||
return imageRes
|
||||
}
|
||||
|
||||
func getResult(imageName, tag string, err error) ScrubImageResult {
|
||||
var status string
|
||||
|
||||
var errField string
|
||||
|
||||
func getResult(imageName, tag string, affectedBlobDigest godigest.Digest, err error) ScrubImageResult {
|
||||
if err != nil {
|
||||
status = "affected"
|
||||
errField = err.Error()
|
||||
} else {
|
||||
status = "ok"
|
||||
errField = ""
|
||||
return newScrubImageResult(imageName, tag, "affected", affectedBlobDigest.Encoded(), err.Error())
|
||||
}
|
||||
|
||||
return newScrubImageResult(imageName, tag, "ok", "", "")
|
||||
}
|
||||
|
||||
func newScrubImageResult(imageName, tag, status, affectedBlob, err string) ScrubImageResult {
|
||||
return ScrubImageResult{
|
||||
ImageName: imageName,
|
||||
Tag: tag,
|
||||
Status: status,
|
||||
Error: errField,
|
||||
ImageName: imageName,
|
||||
Tag: tag,
|
||||
Status: status,
|
||||
AffectedBlob: affectedBlob,
|
||||
Error: err,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -259,12 +333,13 @@ func getScrubTableWriter(writer io.Writer) *tablewriter.Table {
|
|||
table.SetColMinWidth(colImageNameIndex, imageNameWidth)
|
||||
table.SetColMinWidth(colTagIndex, tagWidth)
|
||||
table.SetColMinWidth(colStatusIndex, statusWidth)
|
||||
table.SetColMinWidth(colErrorIndex, affectedBlobWidth)
|
||||
table.SetColMinWidth(colErrorIndex, errorWidth)
|
||||
|
||||
return table
|
||||
}
|
||||
|
||||
const tableCols = 4
|
||||
const tableCols = 5
|
||||
|
||||
func printScrubTableHeader(writer io.Writer) {
|
||||
table := getScrubTableWriter(writer)
|
||||
|
@ -274,6 +349,7 @@ func printScrubTableHeader(writer io.Writer) {
|
|||
row[colImageNameIndex] = "REPOSITORY"
|
||||
row[colTagIndex] = "TAG"
|
||||
row[colStatusIndex] = "STATUS"
|
||||
row[colAffectedBlobIndex] = "AFFECTED BLOB"
|
||||
row[colErrorIndex] = "ERROR"
|
||||
|
||||
table.Append(row)
|
||||
|
@ -287,6 +363,7 @@ func printImageResult(imageResult ScrubImageResult) string {
|
|||
table.SetColMinWidth(colImageNameIndex, imageNameWidth)
|
||||
table.SetColMinWidth(colTagIndex, tagWidth)
|
||||
table.SetColMinWidth(colStatusIndex, statusWidth)
|
||||
table.SetColMinWidth(colAffectedBlobIndex, affectedBlobWidth)
|
||||
table.SetColMinWidth(colErrorIndex, errorWidth)
|
||||
|
||||
row := make([]string, tableCols)
|
||||
|
@ -294,6 +371,7 @@ func printImageResult(imageResult ScrubImageResult) string {
|
|||
row[colImageNameIndex] = imageResult.ImageName
|
||||
row[colTagIndex] = imageResult.Tag
|
||||
row[colStatusIndex] = imageResult.Status
|
||||
row[colAffectedBlobIndex] = imageResult.AffectedBlob
|
||||
row[colErrorIndex] = imageResult.Error
|
||||
|
||||
table.Append(row)
|
||||
|
|
|
@ -4,23 +4,31 @@ import (
|
|||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"os"
|
||||
"errors"
|
||||
"fmt"
|
||||
"path"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/distribution/registry/storage/driver"
|
||||
guuid "github.com/gofrs/uuid"
|
||||
godigest "github.com/opencontainers/go-digest"
|
||||
ispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
|
||||
zerr "zotregistry.io/zot/errors"
|
||||
"zotregistry.io/zot/pkg/extensions/monitoring"
|
||||
"zotregistry.io/zot/pkg/log"
|
||||
"zotregistry.io/zot/pkg/storage"
|
||||
"zotregistry.io/zot/pkg/storage/cache"
|
||||
common "zotregistry.io/zot/pkg/storage/common"
|
||||
"zotregistry.io/zot/pkg/storage/local"
|
||||
"zotregistry.io/zot/pkg/storage/s3"
|
||||
storageTypes "zotregistry.io/zot/pkg/storage/types"
|
||||
"zotregistry.io/zot/pkg/test"
|
||||
. "zotregistry.io/zot/pkg/test/image-utils"
|
||||
"zotregistry.io/zot/pkg/test/mocks"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -28,31 +36,60 @@ const (
|
|||
tag = "1.0"
|
||||
)
|
||||
|
||||
func TestCheckAllBlobsIntegrity(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
var errUnexpectedError = errors.New("unexpected err")
|
||||
|
||||
log := log.NewLogger("debug", "")
|
||||
func TestLocalCheckAllBlobsIntegrity(t *testing.T) {
|
||||
Convey("test with local storage", t, func() {
|
||||
tdir := t.TempDir()
|
||||
log := log.NewLogger("debug", "")
|
||||
metrics := monitoring.NewMetricsServer(false, log)
|
||||
cacheDriver, _ := storage.Create("boltdb", cache.BoltDBDriverParameters{
|
||||
RootDir: tdir,
|
||||
Name: "cache",
|
||||
UseRelPaths: true,
|
||||
}, log)
|
||||
driver := local.New(true)
|
||||
imgStore := local.NewImageStore(tdir, true, true, log, metrics, nil, cacheDriver)
|
||||
|
||||
metrics := monitoring.NewMetricsServer(false, log)
|
||||
cacheDriver, _ := storage.Create("boltdb", cache.BoltDBDriverParameters{
|
||||
RootDir: dir,
|
||||
Name: "cache",
|
||||
UseRelPaths: true,
|
||||
}, log)
|
||||
imgStore := local.NewImageStore(dir, true, true, log, metrics, nil, cacheDriver)
|
||||
RunCheckAllBlobsIntegrityTests(t, imgStore, driver, log)
|
||||
})
|
||||
}
|
||||
|
||||
Convey("Scrub only one repo", t, func(c C) {
|
||||
func TestS3CheckAllBlobsIntegrity(t *testing.T) {
|
||||
skipIt(t)
|
||||
|
||||
Convey("test with S3 storage", t, func() {
|
||||
uuid, err := guuid.NewV4()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
testDir := path.Join("/oci-repo-test", uuid.String())
|
||||
tdir := t.TempDir()
|
||||
log := log.NewLogger("debug", "")
|
||||
|
||||
var store driver.StorageDriver
|
||||
store, imgStore, _ := createObjectsStore(testDir, tdir)
|
||||
defer cleanupStorage(store, testDir)
|
||||
|
||||
driver := s3.New(store)
|
||||
|
||||
RunCheckAllBlobsIntegrityTests(t, imgStore, driver, log)
|
||||
})
|
||||
}
|
||||
|
||||
func RunCheckAllBlobsIntegrityTests( //nolint: thelper
|
||||
t *testing.T, imgStore storageTypes.ImageStore, driver storageTypes.Driver, log log.Logger,
|
||||
) {
|
||||
Convey("Scrub only one repo", func() {
|
||||
// initialize repo
|
||||
err := imgStore.InitRepo(repoName)
|
||||
So(err, ShouldBeNil)
|
||||
ok := imgStore.DirExists(path.Join(imgStore.RootDir(), repoName))
|
||||
So(ok, ShouldBeTrue)
|
||||
storeController := storage.StoreController{}
|
||||
storeController.DefaultStore = imgStore
|
||||
So(storeController.GetImageStore(repoName), ShouldResemble, imgStore)
|
||||
|
||||
storeCtlr := storage.StoreController{}
|
||||
storeCtlr.DefaultStore = imgStore
|
||||
So(storeCtlr.GetImageStore(repoName), ShouldResemble, imgStore)
|
||||
|
||||
config, layers, manifest, err := test.GetImageComponents(1000) //nolint:staticcheck
|
||||
So(err, ShouldBeNil)
|
||||
|
@ -84,7 +121,7 @@ func TestCheckAllBlobsIntegrity(t *testing.T) {
|
|||
space := regexp.MustCompile(`\s+`)
|
||||
str := space.ReplaceAllString(buff.String(), " ")
|
||||
actual := strings.TrimSpace(str)
|
||||
So(actual, ShouldContainSubstring, "REPOSITORY TAG STATUS ERROR")
|
||||
So(actual, ShouldContainSubstring, "REPOSITORY TAG STATUS AFFECTED BLOB ERROR")
|
||||
So(actual, ShouldContainSubstring, "test 1.0 ok")
|
||||
})
|
||||
|
||||
|
@ -96,9 +133,15 @@ func TestCheckAllBlobsIntegrity(t *testing.T) {
|
|||
// delete content of manifest file
|
||||
manifestDig := manifestDigest.Encoded()
|
||||
manifestFile := path.Join(imgStore.RootDir(), repoName, "/blobs/sha256", manifestDig)
|
||||
err = os.Truncate(manifestFile, 0)
|
||||
err = driver.Delete(manifestFile)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
defer func() {
|
||||
// put manifest content back to file
|
||||
_, err = driver.WriteFile(manifestFile, content)
|
||||
So(err, ShouldBeNil)
|
||||
}()
|
||||
|
||||
buff := bytes.NewBufferString("")
|
||||
|
||||
res, err := storeCtlr.CheckAllBlobsIntegrity(context.Background())
|
||||
|
@ -108,9 +151,9 @@ func TestCheckAllBlobsIntegrity(t *testing.T) {
|
|||
space := regexp.MustCompile(`\s+`)
|
||||
str := space.ReplaceAllString(buff.String(), " ")
|
||||
actual := strings.TrimSpace(str)
|
||||
So(actual, ShouldContainSubstring, "REPOSITORY TAG STATUS ERROR")
|
||||
So(actual, ShouldContainSubstring, "REPOSITORY TAG STATUS AFFECTED BLOB ERROR")
|
||||
// verify error message
|
||||
So(actual, ShouldContainSubstring, "test 1.0 affected parse application/vnd.oci.image.manifest.v1+json")
|
||||
So(actual, ShouldContainSubstring, fmt.Sprintf("test 1.0 affected %s blob: not found", manifestDig))
|
||||
|
||||
index, err := common.GetIndex(imgStore, repoName, log)
|
||||
So(err, ShouldBeNil)
|
||||
|
@ -118,14 +161,34 @@ func TestCheckAllBlobsIntegrity(t *testing.T) {
|
|||
So(len(index.Manifests), ShouldEqual, 1)
|
||||
manifestDescriptor := index.Manifests[0]
|
||||
|
||||
repoDir := path.Join(dir, repoName)
|
||||
imageRes := storage.CheckLayers(context.Background(), repoName, tag, repoDir, manifestDescriptor)
|
||||
imageRes := storage.CheckLayers(context.Background(), repoName, tag, manifestDescriptor, imgStore)
|
||||
So(imageRes.Status, ShouldEqual, "affected")
|
||||
So(imageRes.Error, ShouldEqual, "unexpected end of JSON input")
|
||||
So(imageRes.Error, ShouldEqual, "blob: not found")
|
||||
|
||||
// put manifest content back to file
|
||||
err = os.WriteFile(manifestFile, content, 0o600)
|
||||
_, err = driver.WriteFile(manifestFile, []byte("invalid content"))
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
buff = bytes.NewBufferString("")
|
||||
|
||||
res, err = storeCtlr.CheckAllBlobsIntegrity(context.Background())
|
||||
res.PrintScrubResults(buff)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
str = space.ReplaceAllString(buff.String(), " ")
|
||||
actual = strings.TrimSpace(str)
|
||||
So(actual, ShouldContainSubstring, "REPOSITORY TAG STATUS AFFECTED BLOB ERROR")
|
||||
// verify error message
|
||||
So(actual, ShouldContainSubstring, fmt.Sprintf("test 1.0 affected %s manifest: invalid contents", manifestDig))
|
||||
|
||||
index, err = common.GetIndex(imgStore, repoName, log)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(len(index.Manifests), ShouldEqual, 1)
|
||||
manifestDescriptor = index.Manifests[0]
|
||||
|
||||
imageRes = storage.CheckLayers(context.Background(), repoName, tag, manifestDescriptor, imgStore)
|
||||
So(imageRes.Status, ShouldEqual, "affected")
|
||||
So(imageRes.Error, ShouldEqual, "manifest: invalid contents")
|
||||
})
|
||||
|
||||
Convey("Config integrity affected", func() {
|
||||
|
@ -136,9 +199,15 @@ func TestCheckAllBlobsIntegrity(t *testing.T) {
|
|||
// delete content of config file
|
||||
configDig := configDigest.Encoded()
|
||||
configFile := path.Join(imgStore.RootDir(), repoName, "/blobs/sha256", configDig)
|
||||
err = os.Truncate(configFile, 0)
|
||||
err = driver.Delete(configFile)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
defer func() {
|
||||
// put config content back to file
|
||||
_, err = driver.WriteFile(configFile, content)
|
||||
So(err, ShouldBeNil)
|
||||
}()
|
||||
|
||||
buff := bytes.NewBufferString("")
|
||||
|
||||
res, err := storeCtlr.CheckAllBlobsIntegrity(context.Background())
|
||||
|
@ -148,12 +217,22 @@ func TestCheckAllBlobsIntegrity(t *testing.T) {
|
|||
space := regexp.MustCompile(`\s+`)
|
||||
str := space.ReplaceAllString(buff.String(), " ")
|
||||
actual := strings.TrimSpace(str)
|
||||
So(actual, ShouldContainSubstring, "REPOSITORY TAG STATUS ERROR")
|
||||
So(actual, ShouldContainSubstring, "test 1.0 affected stat: parse application/vnd.oci.image.config.v1+json")
|
||||
So(actual, ShouldContainSubstring, "REPOSITORY TAG STATUS AFFECTED BLOB ERROR")
|
||||
So(actual, ShouldContainSubstring, fmt.Sprintf("test 1.0 affected %s blob: not found", configDig))
|
||||
|
||||
// put config content back to file
|
||||
err = os.WriteFile(configFile, content, 0o600)
|
||||
_, err = driver.WriteFile(configFile, []byte("invalid content"))
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
buff = bytes.NewBufferString("")
|
||||
|
||||
res, err = storeCtlr.CheckAllBlobsIntegrity(context.Background())
|
||||
res.PrintScrubResults(buff)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
str = space.ReplaceAllString(buff.String(), " ")
|
||||
actual = strings.TrimSpace(str)
|
||||
So(actual, ShouldContainSubstring, "REPOSITORY TAG STATUS AFFECTED BLOB ERROR")
|
||||
So(actual, ShouldContainSubstring, fmt.Sprintf("test 1.0 affected %s config: invalid config", configDig))
|
||||
})
|
||||
|
||||
Convey("Layers integrity affected", func() {
|
||||
|
@ -164,9 +243,15 @@ func TestCheckAllBlobsIntegrity(t *testing.T) {
|
|||
// delete content of layer file
|
||||
layerDig := layerDigest.Encoded()
|
||||
layerFile := path.Join(imgStore.RootDir(), repoName, "/blobs/sha256", layerDig)
|
||||
err = os.Truncate(layerFile, 0)
|
||||
_, err = driver.WriteFile(layerFile, []byte(" "))
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
defer func() {
|
||||
// put layer content back to file
|
||||
_, err = driver.WriteFile(layerFile, content)
|
||||
So(err, ShouldBeNil)
|
||||
}()
|
||||
|
||||
buff := bytes.NewBufferString("")
|
||||
|
||||
res, err := storeCtlr.CheckAllBlobsIntegrity(context.Background())
|
||||
|
@ -176,37 +261,36 @@ func TestCheckAllBlobsIntegrity(t *testing.T) {
|
|||
space := regexp.MustCompile(`\s+`)
|
||||
str := space.ReplaceAllString(buff.String(), " ")
|
||||
actual := strings.TrimSpace(str)
|
||||
So(actual, ShouldContainSubstring, "REPOSITORY TAG STATUS ERROR")
|
||||
So(actual, ShouldContainSubstring, "test 1.0 affected blob: bad blob digest")
|
||||
|
||||
// put layer content back to file
|
||||
err = os.WriteFile(layerFile, content, 0o600)
|
||||
So(err, ShouldBeNil)
|
||||
So(actual, ShouldContainSubstring, "REPOSITORY TAG STATUS AFFECTED BLOB ERROR")
|
||||
So(actual, ShouldContainSubstring, fmt.Sprintf("test 1.0 affected %s blob: bad blob digest", layerDig))
|
||||
})
|
||||
|
||||
Convey("Layer not found", func() {
|
||||
// get content of layer
|
||||
content, err := imgStore.GetBlobContent(repoName, layerDigest)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
// change layer file permissions
|
||||
layerDig := layerDigest.Encoded()
|
||||
repoDir := path.Join(dir, repoName)
|
||||
repoDir := path.Join(imgStore.RootDir(), repoName)
|
||||
layerFile := path.Join(repoDir, "/blobs/sha256", layerDig)
|
||||
err = os.Chmod(layerFile, 0x0200)
|
||||
err = driver.Delete(layerFile)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
defer func() {
|
||||
_, err := driver.WriteFile(layerFile, content)
|
||||
So(err, ShouldBeNil)
|
||||
}()
|
||||
|
||||
index, err := common.GetIndex(imgStore, repoName, log)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(len(index.Manifests), ShouldEqual, 1)
|
||||
manifestDescriptor := index.Manifests[0]
|
||||
|
||||
imageRes := storage.CheckLayers(context.Background(), repoName, tag, repoDir, manifestDescriptor)
|
||||
imageRes := storage.CheckLayers(context.Background(), repoName, tag, manifestDescriptor, imgStore)
|
||||
So(imageRes.Status, ShouldEqual, "affected")
|
||||
So(imageRes.Error, ShouldEqual, "blob: not found")
|
||||
err = os.Chmod(layerFile, 0x0600)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
// delete layer file
|
||||
err = os.Remove(layerFile)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
buff := bytes.NewBufferString("")
|
||||
|
||||
|
@ -217,8 +301,8 @@ func TestCheckAllBlobsIntegrity(t *testing.T) {
|
|||
space := regexp.MustCompile(`\s+`)
|
||||
str := space.ReplaceAllString(buff.String(), " ")
|
||||
actual := strings.TrimSpace(str)
|
||||
So(actual, ShouldContainSubstring, "REPOSITORY TAG STATUS ERROR")
|
||||
So(actual, ShouldContainSubstring, "test 1.0 affected blob: not found")
|
||||
So(actual, ShouldContainSubstring, "REPOSITORY TAG STATUS AFFECTED BLOB ERROR")
|
||||
So(actual, ShouldContainSubstring, fmt.Sprintf("test 1.0 affected %s blob: not found", layerDig))
|
||||
})
|
||||
|
||||
Convey("Scrub index", func() {
|
||||
|
@ -244,8 +328,15 @@ func TestCheckAllBlobsIntegrity(t *testing.T) {
|
|||
_, _, err = imgStore.FullBlobUpload(repoName, newManifestReader, newManifestDigest)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
idx, err := common.GetIndex(imgStore, repoName, log)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
manifestDescriptor, ok := common.GetManifestDescByReference(idx, manifestDigest.String())
|
||||
So(ok, ShouldBeTrue)
|
||||
|
||||
var index ispec.Index
|
||||
index.SchemaVersion = 2
|
||||
index.Subject = &manifestDescriptor
|
||||
index.Manifests = []ispec.Descriptor{
|
||||
{
|
||||
MediaType: ispec.MediaTypeImageManifest,
|
||||
|
@ -268,13 +359,14 @@ func TestCheckAllBlobsIntegrity(t *testing.T) {
|
|||
space := regexp.MustCompile(`\s+`)
|
||||
str := space.ReplaceAllString(buff.String(), " ")
|
||||
actual := strings.TrimSpace(str)
|
||||
So(actual, ShouldContainSubstring, "REPOSITORY TAG STATUS ERROR")
|
||||
So(actual, ShouldContainSubstring, "REPOSITORY TAG STATUS AFFECTED BLOB ERROR")
|
||||
So(actual, ShouldContainSubstring, "test 1.0 ok")
|
||||
So(actual, ShouldContainSubstring, "test ok")
|
||||
|
||||
// test scrub index - errors
|
||||
indexFile := path.Join(imgStore.RootDir(), repoName, "/blobs/sha256", indexDigest.Encoded())
|
||||
err = os.Chmod(indexFile, 0o000)
|
||||
// delete content of manifest file
|
||||
manifestFile := path.Join(imgStore.RootDir(), repoName, "/blobs/sha256", newManifestDigest.Encoded())
|
||||
err = driver.Delete(manifestFile)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
buff = bytes.NewBufferString("")
|
||||
|
@ -285,13 +377,11 @@ func TestCheckAllBlobsIntegrity(t *testing.T) {
|
|||
|
||||
str = space.ReplaceAllString(buff.String(), " ")
|
||||
actual = strings.TrimSpace(str)
|
||||
So(actual, ShouldContainSubstring, "REPOSITORY TAG STATUS ERROR")
|
||||
So(actual, ShouldContainSubstring, "REPOSITORY TAG STATUS AFFECTED BLOB ERROR")
|
||||
So(actual, ShouldContainSubstring, "test affected")
|
||||
|
||||
err = os.Chmod(indexFile, 0o600)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = os.Truncate(indexFile, 0)
|
||||
indexFile := path.Join(imgStore.RootDir(), repoName, "/blobs/sha256", indexDigest.Encoded())
|
||||
err = driver.Delete(indexFile)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
buff = bytes.NewBufferString("")
|
||||
|
@ -302,7 +392,48 @@ func TestCheckAllBlobsIntegrity(t *testing.T) {
|
|||
|
||||
str = space.ReplaceAllString(buff.String(), " ")
|
||||
actual = strings.TrimSpace(str)
|
||||
So(actual, ShouldContainSubstring, "REPOSITORY TAG STATUS ERROR")
|
||||
So(actual, ShouldContainSubstring, "REPOSITORY TAG STATUS AFFECTED BLOB ERROR")
|
||||
So(actual, ShouldContainSubstring, "test affected")
|
||||
|
||||
index.Manifests[0].MediaType = "invalid"
|
||||
indexBlob, err = json.Marshal(index)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
_, err = driver.WriteFile(indexFile, indexBlob)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
buff = bytes.NewBufferString("")
|
||||
|
||||
res, err = storeCtlr.CheckAllBlobsIntegrity(context.Background())
|
||||
res.PrintScrubResults(buff)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
_, err = storage.CheckManifestAndConfig(repoName, index.Manifests[0], imgStore)
|
||||
So(err, ShouldNotBeNil)
|
||||
So(err, ShouldEqual, zerr.ErrBadManifest)
|
||||
|
||||
str = space.ReplaceAllString(buff.String(), " ")
|
||||
actual = strings.TrimSpace(str)
|
||||
So(actual, ShouldContainSubstring, "REPOSITORY TAG STATUS AFFECTED BLOB ERROR")
|
||||
So(actual, ShouldContainSubstring, "test affected")
|
||||
|
||||
_, err = driver.WriteFile(indexFile, []byte("invalid cotent"))
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
defer func() {
|
||||
err := driver.Delete(indexFile)
|
||||
So(err, ShouldBeNil)
|
||||
}()
|
||||
|
||||
buff = bytes.NewBufferString("")
|
||||
|
||||
res, err = storeCtlr.CheckAllBlobsIntegrity(context.Background())
|
||||
res.PrintScrubResults(buff)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
str = space.ReplaceAllString(buff.String(), " ")
|
||||
actual = strings.TrimSpace(str)
|
||||
So(actual, ShouldContainSubstring, "REPOSITORY TAG STATUS AFFECTED BLOB ERROR")
|
||||
So(actual, ShouldContainSubstring, "test affected")
|
||||
})
|
||||
|
||||
|
@ -310,7 +441,7 @@ func TestCheckAllBlobsIntegrity(t *testing.T) {
|
|||
// delete manifest file
|
||||
manifestDig := manifestDigest.Encoded()
|
||||
manifestFile := path.Join(imgStore.RootDir(), repoName, "/blobs/sha256", manifestDig)
|
||||
err = os.Remove(manifestFile)
|
||||
err = driver.Delete(manifestFile)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
buff := bytes.NewBufferString("")
|
||||
|
@ -322,20 +453,76 @@ func TestCheckAllBlobsIntegrity(t *testing.T) {
|
|||
space := regexp.MustCompile(`\s+`)
|
||||
str := space.ReplaceAllString(buff.String(), " ")
|
||||
actual := strings.TrimSpace(str)
|
||||
So(actual, ShouldContainSubstring, "REPOSITORY TAG STATUS ERROR")
|
||||
So(actual, ShouldContainSubstring, "test 1.0 affected")
|
||||
So(actual, ShouldContainSubstring, "no such file or directory")
|
||||
So(actual, ShouldContainSubstring, "REPOSITORY TAG STATUS AFFECTED BLOB ERROR")
|
||||
So(actual, ShouldContainSubstring, fmt.Sprintf("test 1.0 affected %s blob: not found", manifestDig))
|
||||
|
||||
index, err := common.GetIndex(imgStore, repoName, log)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(len(index.Manifests), ShouldEqual, 2)
|
||||
So(len(index.Manifests), ShouldEqual, 1)
|
||||
manifestDescriptor := index.Manifests[0]
|
||||
|
||||
repoDir := path.Join(dir, repoName)
|
||||
imageRes := storage.CheckLayers(context.Background(), repoName, tag, repoDir, manifestDescriptor)
|
||||
imageRes := storage.CheckLayers(context.Background(), repoName, tag, manifestDescriptor, imgStore)
|
||||
So(imageRes.Status, ShouldEqual, "affected")
|
||||
So(imageRes.Error, ShouldContainSubstring, "no such file or directory")
|
||||
So(imageRes.Error, ShouldContainSubstring, "blob: not found")
|
||||
})
|
||||
|
||||
Convey("use the result of an already scrubed manifest which is the subject of the current manifest", func() {
|
||||
index, err := common.GetIndex(imgStore, repoName, log)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
manifestDescriptor, ok := common.GetManifestDescByReference(index, manifestDigest.String())
|
||||
So(ok, ShouldBeTrue)
|
||||
|
||||
err = test.WriteImageToFileSystem(CreateDefaultImageWith().Subject(&manifestDescriptor).Build(),
|
||||
repoName, "0.0.1", storeCtlr)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
buff := bytes.NewBufferString("")
|
||||
|
||||
res, err := storeCtlr.CheckAllBlobsIntegrity(context.Background())
|
||||
res.PrintScrubResults(buff)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
space := regexp.MustCompile(`\s+`)
|
||||
str := space.ReplaceAllString(buff.String(), " ")
|
||||
actual := strings.TrimSpace(str)
|
||||
So(actual, ShouldContainSubstring, "REPOSITORY TAG STATUS AFFECTED BLOB ERROR")
|
||||
So(actual, ShouldContainSubstring, "test 1.0 ok")
|
||||
So(actual, ShouldContainSubstring, "test 0.0.1 ok")
|
||||
})
|
||||
})
|
||||
|
||||
Convey("test errors", func() {
|
||||
mockedImgStore := mocks.MockedImageStore{
|
||||
GetRepositoriesFn: func() ([]string, error) {
|
||||
return []string{repoName}, nil
|
||||
},
|
||||
ValidateRepoFn: func(name string) (bool, error) {
|
||||
return false, nil
|
||||
},
|
||||
}
|
||||
|
||||
storeController := storage.StoreController{}
|
||||
storeController.DefaultStore = mockedImgStore
|
||||
|
||||
_, err := storeController.CheckAllBlobsIntegrity(context.Background())
|
||||
So(err, ShouldNotBeNil)
|
||||
So(err, ShouldEqual, zerr.ErrRepoBadLayout)
|
||||
|
||||
mockedImgStore = mocks.MockedImageStore{
|
||||
GetRepositoriesFn: func() ([]string, error) {
|
||||
return []string{repoName}, nil
|
||||
},
|
||||
GetIndexContentFn: func(repo string) ([]byte, error) {
|
||||
return []byte{}, errUnexpectedError
|
||||
},
|
||||
}
|
||||
|
||||
storeController.DefaultStore = mockedImgStore
|
||||
|
||||
_, err = storeController.CheckAllBlobsIntegrity(context.Background())
|
||||
So(err, ShouldNotBeNil)
|
||||
So(err, ShouldEqual, errUnexpectedError)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -35,7 +35,6 @@ import (
|
|||
godigest "github.com/opencontainers/go-digest"
|
||||
"github.com/opencontainers/image-spec/specs-go"
|
||||
ispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/opencontainers/umoci"
|
||||
"github.com/phayes/freeport"
|
||||
"github.com/project-zot/mockoidc"
|
||||
"github.com/sigstore/cosign/v2/cmd/cosign/cli/generate"
|
||||
|
@ -72,29 +71,6 @@ var (
|
|||
|
||||
var NotationPathLock = new(sync.Mutex) //nolint: gochecknoglobals
|
||||
|
||||
// which: manifest, config, layer
|
||||
func GetTestBlobDigest(image, which string) godigest.Digest {
|
||||
prePath := "../test/data"
|
||||
|
||||
for _, err := os.Stat(prePath); err != nil; _, err = os.Stat(prePath) {
|
||||
prePath = "../" + prePath
|
||||
}
|
||||
|
||||
imgPath := path.Join(prePath, image)
|
||||
manifest, config, layer := GetOciLayoutDigests(imgPath)
|
||||
|
||||
switch which {
|
||||
case "manifest":
|
||||
return manifest
|
||||
case "config":
|
||||
return config
|
||||
case "layer":
|
||||
return layer
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func GetFreePort() string {
|
||||
port, err := freeport.GetFreePort()
|
||||
if err != nil {
|
||||
|
@ -434,57 +410,6 @@ func GetRandomImageConfig() ([]byte, godigest.Digest) {
|
|||
return configBlobContent, configBlobDigestRaw
|
||||
}
|
||||
|
||||
func GetOciLayoutDigests(imagePath string) (godigest.Digest, godigest.Digest, godigest.Digest) {
|
||||
var (
|
||||
manifestDigest godigest.Digest
|
||||
configDigest godigest.Digest
|
||||
layerDigest godigest.Digest
|
||||
)
|
||||
|
||||
oci, err := umoci.OpenLayout(imagePath)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("error opening layout at '%s' : %w", imagePath, err))
|
||||
}
|
||||
|
||||
defer oci.Close()
|
||||
|
||||
ctxUmoci := context.Background()
|
||||
|
||||
index, err := oci.GetIndex(ctxUmoci)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for _, manifest := range index.Manifests {
|
||||
manifestDigest = manifest.Digest
|
||||
|
||||
manifestBlob, err := oci.GetBlob(ctxUmoci, manifest.Digest)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
manifestBuf, err := io.ReadAll(manifestBlob)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var manifest ispec.Manifest
|
||||
|
||||
err = json.Unmarshal(manifestBuf, &manifest)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
configDigest = manifest.Config.Digest
|
||||
|
||||
for _, layer := range manifest.Layers {
|
||||
layerDigest = layer.Digest
|
||||
}
|
||||
}
|
||||
|
||||
return manifestDigest, configDigest, layerDigest
|
||||
}
|
||||
|
||||
// Deprecated: Should use the new functions starting with "Create".
|
||||
func GetImageComponents(layerSize int) (ispec.Image, [][]byte, ispec.Manifest, error) {
|
||||
config := ispec.Image{
|
||||
|
|
|
@ -22,7 +22,6 @@ import (
|
|||
|
||||
"zotregistry.io/zot/pkg/api"
|
||||
"zotregistry.io/zot/pkg/api/config"
|
||||
"zotregistry.io/zot/pkg/log"
|
||||
"zotregistry.io/zot/pkg/storage"
|
||||
"zotregistry.io/zot/pkg/test"
|
||||
. "zotregistry.io/zot/pkg/test/image-utils"
|
||||
|
@ -125,64 +124,6 @@ func TestCopyFiles(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestGetOciLayoutDigests(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
|
||||
Convey("image path is wrong", t, func() {
|
||||
So(func() { _, _, _ = test.GetOciLayoutDigests("inexistent-image") }, ShouldPanic)
|
||||
})
|
||||
|
||||
Convey("no permissions when getting index", t, func() {
|
||||
storageCtlr := test.GetDefaultStoreController(dir, log.NewLogger("debug", ""))
|
||||
image := CreateDefaultImage()
|
||||
|
||||
err := test.WriteImageToFileSystem(image, "test-index", "0.0.1", storageCtlr)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = os.Chmod(path.Join(dir, "test-index", "index.json"), 0o000)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
So(func() { _, _, _ = test.GetOciLayoutDigests(path.Join(dir, "test-index")) }, ShouldPanic)
|
||||
|
||||
err = os.Chmod(path.Join(dir, "test-index", "index.json"), 0o755)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
})
|
||||
|
||||
Convey("can't access manifest digest", t, func() {
|
||||
storageCtlr := test.GetDefaultStoreController(dir, log.NewLogger("debug", ""))
|
||||
image := CreateDefaultImage()
|
||||
|
||||
err := test.WriteImageToFileSystem(image, "test-manifest", "0.0.1", storageCtlr)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
buf, err := os.ReadFile(path.Join(dir, "test-manifest", "index.json"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var index ispec.Index
|
||||
if err := json.Unmarshal(buf, &index); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = os.Chmod(path.Join(dir, "test-manifest", "blobs/sha256", index.Manifests[0].Digest.Encoded()), 0o000)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
So(func() { _, _, _ = test.GetOciLayoutDigests(path.Join(dir, "test-manifest")) }, ShouldPanic)
|
||||
|
||||
err = os.Chmod(path.Join(dir, "test-manifest", "blobs/sha256", index.Manifests[0].Digest.Encoded()), 0o755)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetImageComponents(t *testing.T) {
|
||||
Convey("Inject failures for unreachable lines", t, func() {
|
||||
injected := inject.InjectFailure(0)
|
||||
|
|
|
@ -33,8 +33,6 @@ import (
|
|||
var ErrTestError = fmt.Errorf("testError")
|
||||
|
||||
func TestBaseOciLayoutUtils(t *testing.T) {
|
||||
manifestDigest := GetTestBlobDigest("zot-test", "config").String()
|
||||
|
||||
Convey("GetImageManifestSize fail", t, func() {
|
||||
mockStoreController := mocks.MockedImageStore{
|
||||
GetBlobContentFn: func(repo string, digest godigest.Digest) ([]byte, error) {
|
||||
|
@ -64,6 +62,9 @@ func TestBaseOciLayoutUtils(t *testing.T) {
|
|||
})
|
||||
|
||||
Convey("GetImageConfigSize: config GetBlobContent fail", t, func() {
|
||||
image := CreateRandomImage()
|
||||
manifestDigest := image.ConfigDescriptor.Digest.String()
|
||||
|
||||
mockStoreController := mocks.MockedImageStore{
|
||||
GetBlobContentFn: func(repo string, digest godigest.Digest) ([]byte, error) {
|
||||
if digest.String() == manifestDigest {
|
||||
|
@ -83,7 +84,7 @@ func TestBaseOciLayoutUtils(t *testing.T) {
|
|||
"layers": [
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
|
||||
"digest": "` + GetTestBlobDigest("zot-test", "layer").String() + `",
|
||||
"digest": "` + image.Manifest.Layers[0].Digest.String() + `",
|
||||
"size": 76097157
|
||||
}
|
||||
]
|
||||
|
|
Loading…
Reference in a new issue