0
Fork 0
mirror of https://github.com/project-zot/zot.git synced 2025-03-18 02:22:53 -05:00

refactor(artifact): remove oci artifact support (#1359)

* refactor(artifact): remove oci artifact support
- add header to referrers call to indicated applied artifact type filters

Signed-off-by: Laurentiu Niculae <niculae.laurentiu1@gmail.com>

* feat(gc): simplify gc logic to increase coverage

Signed-off-by: Laurentiu Niculae <niculae.laurentiu1@gmail.com>

---------

Signed-off-by: Laurentiu Niculae <niculae.laurentiu1@gmail.com>
This commit is contained in:
LaurentiuNiculae 2023-05-10 20:15:33 +03:00 committed by GitHub
parent 3be690c2ac
commit ea79be64da
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
54 changed files with 604 additions and 1608 deletions

View file

@ -6,3 +6,4 @@ ignore:
- "./cmd/zb/*.go"
- "./pkg/test/mocks/*.go"
- "./swagger/*.go"
- "./pkg/test/test_http_server.go"

View file

@ -63,7 +63,6 @@ var (
ErrManifestConflict = errors.New("manifest: multiple manifests found")
ErrManifestMetaNotFound = errors.New("repodb: image metadata not found for given manifest reference")
ErrManifestDataNotFound = errors.New("repodb: image data not found for given manifest digest")
ErrArtifactDataNotFound = errors.New("repodb: artifact data not found for given digest")
ErrIndexDataNotFount = errors.New("repodb: index data not found for given digest")
ErrRepoMetaNotFound = errors.New("repodb: repo metadata not found for given repo name")
ErrTagMetaNotFound = errors.New("repodb: tag metadata not found for given repo and tag names")

View file

@ -20,7 +20,6 @@
"cacheTablename": "ZotBlobTable",
"repoMetaTablename": "ZotRepoMetadataTable",
"manifestDataTablename": "ZotManifestDataTable",
"artifactDataTablename": "ZotArtifactDataTable",
"userDataTablename": "ZotUserDataTable",
"versionTablename": "ZotVersion"
}

2
go.mod
View file

@ -462,7 +462,7 @@ require (
)
replace (
github.com/opencontainers/umoci => github.com/project-stacker/umoci v0.0.0-20230228184813-24efbd35e8ef
github.com/opencontainers/image-spec => github.com/project-zot/image-spec v0.0.0-20230428141304-a263befc67ea
// v0.3.1-0.20230104082527-d6f58551be3f is taken from github.com/moby/buildkit v0.11.0
// spdx logic write on v0.3.0 and incompatible with v0.3.1-0.20230104082527-d6f58551be3f
// see https://github.com/aquasecurity/trivy/commit/2033e05b6b563aa4bc46d6234b3657a54e71ee46

33
go.sum
View file

@ -244,7 +244,6 @@ github.com/Azure/go-ntlmssp v0.0.0-20220621081337-cb9428e4ac1e/go.mod h1:chxPXzS
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8=
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
@ -480,6 +479,7 @@ 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=
@ -512,6 +512,7 @@ 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/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E=
github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s=
github.com/cheggaaa/pb/v3 v3.1.2 h1:FIxT3ZjOj9XJl0U4o2XbEhjFfZl7jCVCDOGq1ZAB7wQ=
@ -521,6 +522,7 @@ 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/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA=
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=
@ -543,6 +545,7 @@ 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 v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw=
github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ=
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
github.com/containerd/containerd v1.7.0 h1:G/ZQr3gMZs6ZT0qPUZ15znx5QSdQdASW11nXTLTM2Pg=
github.com/containerd/containerd v1.7.0/go.mod h1:QfR7Efgb/6X2BDpTPJRvPTYDE9rsF0FsXX9J8sIs/sc=
@ -587,6 +590,7 @@ 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-20220623050100-57a0ce2678a7 h1:vU+EP9ZuFUCYE0NYLwTSob+3LNEJATzNfP/DC7SWGWI=
github.com/cyberphone/json-canonicalization v0.0.0-20220623050100-57a0ce2678a7/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 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI=
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -662,7 +666,7 @@ github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a h1:yDWHCSQ40h88yi
github.com/facebookgo/limitgroup v0.0.0-20150612190941-6abd8d71ec01 h1:IeaD1VDVBPlx3viJT9Md8if8IxxJnO+x0JCGb054heg=
github.com/facebookgo/muster v0.0.0-20150708232844-fd3d7953fd52 h1:a4DFiKFJiDRGFD1qIcqGLX/WlUMD9dyLSLDt+9QZgt8=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w=
github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg=
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
@ -1182,7 +1186,8 @@ github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlW
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.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
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.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
@ -1190,6 +1195,7 @@ github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx
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=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
@ -1250,6 +1256,7 @@ 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.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
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=
@ -1316,18 +1323,18 @@ 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.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/image-spec v1.1.0-rc2.0.20221020182949-4df8887994e8 h1:l9vfzobI7tZtG164u1Jf6NqDErHZoqAw8rlvBYQJpVI=
github.com/opencontainers/image-spec v1.1.0-rc2.0.20221020182949-4df8887994e8/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ=
github.com/opencontainers/runc v1.1.4/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg=
github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0=
github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/GDEs=
github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg=
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-rc.2 h1:ucBtEms2tamYYW/SvGpvq9yUN0NEVL6oyLEwDcTSrk8=
github.com/opencontainers/runtime-spec v1.1.0-rc.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8=
github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
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/oras-project/artifacts-spec v1.0.0-rc.2 h1:9SMCNSxkJEHqWGDiMCuy6TXHgvjgwXGdXZZGXLKQvVE=
@ -1368,8 +1375,8 @@ github.com/poy/onpar v0.0.0-20190519213022-ee068f8ea4d1 h1:oL4IBbcqwhhNWh31bjOX8
github.com/poy/onpar v0.0.0-20190519213022-ee068f8ea4d1/go.mod h1:nSbFQvMj97ZyhFRSJYtut+msi4sOY6zJDGCdSc+/rZU=
github.com/proglottis/gpgme v0.1.3 h1:Crxx0oz4LKB3QXc5Ea0J19K/3ICfy3ftr5exgUK1AU0=
github.com/proglottis/gpgme v0.1.3/go.mod h1:fPbW/EZ0LvwQtH8Hy7eixhp1eF3G39dtx7GUN+0Gmy0=
github.com/project-stacker/umoci v0.0.0-20230228184813-24efbd35e8ef h1:PMJXsXS3x5tiwsRrFgMSnjKmeH5c9ppFXrS5NKdIPEo=
github.com/project-stacker/umoci v0.0.0-20230228184813-24efbd35e8ef/go.mod h1:smZzWUkoRRHivXkcHQN7n+KGHVfR+HKJrtCaI8cMifg=
github.com/project-zot/image-spec v0.0.0-20230428141304-a263befc67ea h1:emnKit1I3avTxHcrDfGWXb9U+dG866wv2y8WcgAj3ys=
github.com/project-zot/image-spec v0.0.0-20230428141304-a263befc67ea/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
@ -1432,6 +1439,7 @@ github.com/saracen/walker v0.1.3/go.mod h1:FU+7qU8DeQQgSZDmmThMJi93kPkLFgy0oVAcL
github.com/sassoftware/relic v7.2.1+incompatible h1:Pwyh1F3I0r4clFJXkSI8bOyJINGqpgjJU3DYAZeI05A=
github.com/sassoftware/relic v7.2.1+incompatible/go.mod h1:CWfAxv73/iLZ17rbyhIEq3K9hs5w6FpNMdUT//qR+zk=
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/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg=
github.com/secure-systems-lab/go-securesystemslib v0.5.0 h1:oTiNu0QnulMQgN/hLK124wJD/r2f9ZhIUuKIeBsCBT8=
github.com/secure-systems-lab/go-securesystemslib v0.5.0/go.mod h1:uoCqUC0Ap7jrBSEanxT+SdACYJTVplRXWLkGMuDjXqk=
@ -1457,6 +1465,7 @@ github.com/sigstore/sigstore v1.6.3/go.mod h1:BpLOp7N2IECbatk4sXE2toY2krw615NmwA
github.com/sigstore/timestamp-authority v1.0.0 h1:UisIGA9anE6xyWctJaiEmsk1M+txQ6kAPQDCyu+ieQw=
github.com/sigstore/timestamp-authority v1.0.0/go.mod h1:DvyJt4w4by/hsutEi+th0MsK2tB3IwCPVr9ACrJAgIA=
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=
@ -1583,9 +1592,9 @@ github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtX
github.com/urfave/cli v1.22.12 h1:igJgVw1JdKH+trcLWLeLwZjU9fEfPesQ+9/e4MQ44S8=
github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8=
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
github.com/urfave/cli/v2 v2.10.3/go.mod h1:f8iq5LtQ/bLxafbdBSLPPNsgaW0l/2fYYEHhAyPlwvo=
github.com/urfave/cli/v2 v2.25.0 h1:ykdZKuQey2zq0yin/l7JOm9Mh+pg72ngYMeB0ABn6q8=
github.com/urfave/cli/v2 v2.25.0/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.3 h1:hLFqsOLQ1SsppQNTMpkpPXClLDfC2A3Zgy9OUU+RVck=
@ -1718,6 +1727,7 @@ 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=
@ -1939,6 +1949,7 @@ golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/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=
@ -1957,6 +1968,7 @@ 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=
@ -1987,7 +1999,6 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

View file

@ -52,8 +52,8 @@ linters-settings:
gomoddirectives:
replace-allow-list:
- helm.sh/helm/v3
- github.com/opencontainers/umoci
- github.com/spdx/tools-golang
- github.com/opencontainers/image-spec
issues:
exclude-rules:
- path: pkg/extensions/search/schema.resolvers.go

View file

@ -51,7 +51,6 @@ import (
"zotregistry.io/zot/pkg/log"
"zotregistry.io/zot/pkg/meta/repodb/repodbfactory"
"zotregistry.io/zot/pkg/storage"
storageConstants "zotregistry.io/zot/pkg/storage/constants"
"zotregistry.io/zot/pkg/storage/local"
"zotregistry.io/zot/pkg/test"
)
@ -157,7 +156,6 @@ func TestCreateCacheDatabaseDriver(t *testing.T) {
"cacheTablename": "BlobTable",
"repoMetaTablename": "RepoMetadataTable",
"manifestDataTablename": "ManifestDataTable",
"artifactDataTablename": "ArtifactDataTable",
"userDataTablename": "ZotUserDataTable",
"versionTablename": "Version",
}
@ -173,7 +171,6 @@ func TestCreateCacheDatabaseDriver(t *testing.T) {
"cacheTablename": "BlobTable",
"repoMetaTablename": "RepoMetadataTable",
"manifestDataTablename": "ManifestDataTable",
"artifactDataTablename": "ArtifactDataTable",
"userDataTablename": "ZotUserDataTable",
"versionTablename": "Version",
}
@ -188,7 +185,6 @@ func TestCreateCacheDatabaseDriver(t *testing.T) {
"cacheTablename": "BlobTable",
"repoMetaTablename": "RepoMetadataTable",
"manifestDataTablename": "ManifestDataTable",
"artifactDataTablename": "ArtifactDataTable",
"userDataTablename": "ZotUserDataTable",
"versionTablename": "Version",
}
@ -222,7 +218,6 @@ func TestCreateRepoDBDriver(t *testing.T) {
"cachetablename": "BlobTable",
"repometatablename": "RepoMetadataTable",
"manifestdatatablename": "ManifestDataTable",
"artifactDataTablename": "ArtifactDataTable",
"userdatatablename": "UserDatatable",
}
@ -236,7 +231,6 @@ func TestCreateRepoDBDriver(t *testing.T) {
"cachetablename": "",
"repometatablename": "RepoMetadataTable",
"manifestdatatablename": "ManifestDataTable",
"artifactDataTablename": "ArtifactDataTable",
"userDataTablename": "ZotUserDataTable",
"versiontablename": 1,
}
@ -252,7 +246,6 @@ func TestCreateRepoDBDriver(t *testing.T) {
"repometatablename": "RepoMetadataTable",
"manifestdatatablename": "ManifestDataTable",
"indexdatatablename": "IndexDataTable",
"artifactdatatablename": "ArtifactDataTable",
"userdatatablename": "ZotUserDataTable",
"versiontablename": "1",
}
@ -4395,138 +4388,15 @@ func TestArtifactReferences(t *testing.T) {
So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusOK)
So(resp.Header().Get("Content-Type"), ShouldEqual, ispec.MediaTypeImageIndex)
})
})
So(resp.Header().Get("OCI-Filters-Applied"), ShouldEqual, artifactType)
Convey("Validate Artifact Manifest Reference", func() {
resp, err := resty.R().Get(baseURL + fmt.Sprintf("/v2/%s/referrers/%s", repoName, digest.String()))
So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusOK)
var referrers ispec.Index
err = json.Unmarshal(resp.Body(), &referrers)
So(err, ShouldBeNil)
So(referrers.Manifests, ShouldBeEmpty)
// now upload a reference
// upload image config blob
resp, err = resty.R().Post(baseURL + fmt.Sprintf("/v2/%s/blobs/uploads/", repoName))
So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusAccepted)
loc := test.Location(baseURL, resp)
cblob, cdigest := test.GetEmptyImageConfig()
resp, err = resty.R().
SetContentLength(true).
SetHeader("Content-Length", fmt.Sprintf("%d", len(cblob))).
SetHeader("Content-Type", "application/octet-stream").
SetQueryParam("digest", cdigest.String()).
SetBody(cblob).
Put(loc)
So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusCreated)
// create a artifact
manifest := ispec.Artifact{
MediaType: ispec.MediaTypeArtifactManifest,
ArtifactType: artifactType,
Blobs: []ispec.Descriptor{
{
MediaType: "application/vnd.oci.image.layer.v1.tar",
Digest: digest,
Size: int64(len(content)),
},
},
Subject: &ispec.Descriptor{
MediaType: ispec.MediaTypeImageManifest,
Digest: digest,
Size: int64(len(content)),
},
Annotations: map[string]string{
"key": "val",
},
}
Convey("Using invalid content", func() {
content := []byte("invalid data")
So(err, ShouldBeNil)
mdigest := godigest.FromBytes(content)
So(mdigest, ShouldNotBeNil)
resp, err = resty.R().SetHeader("Content-Type", ispec.MediaTypeArtifactManifest).
SetBody(content).Put(baseURL + fmt.Sprintf("/v2/%s/manifests/%s", repoName, mdigest.String()))
So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusBadRequest)
// unknown repo will return status not found
resp, err = resty.R().Get(baseURL + fmt.Sprintf("/v2/%s/referrers/%s", "unknown", digest.String()))
So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusNotFound)
resp, err = resty.R().Get(baseURL + fmt.Sprintf("/v2/%s/referrers/%s", repoName, digest.String()))
So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusOK)
resp, err = resty.R().SetQueryParams(map[string]string{"artifactType": artifactType}).
Get(baseURL + fmt.Sprintf("/v2/%s/referrers/%s", repoName, digest.String()))
So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusOK)
})
Convey("Using valid content", func() {
content, err = json.Marshal(manifest)
So(err, ShouldBeNil)
mdigest := godigest.FromBytes(content)
So(mdigest, ShouldNotBeNil)
resp, err = resty.R().SetHeader("Content-Type", ispec.MediaTypeArtifactManifest).
SetBody(content).Put(baseURL + fmt.Sprintf("/v2/%s/manifests/%s", repoName, mdigest.String()))
So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusCreated)
resp, err = resty.R().Get(baseURL + fmt.Sprintf("/v2/%s/referrers/%s", repoName, digest.String()))
So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusOK)
resp, err = resty.R().SetQueryParams(map[string]string{"artifact": "invalid"}).
Get(baseURL + fmt.Sprintf("/v2/%s/referrers/%s", repoName, digest.String()))
So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusOK)
resp, err = resty.R().SetQueryParams(map[string]string{"artifactType": "invalid"}).
Get(baseURL + fmt.Sprintf("/v2/%s/referrers/%s", repoName, digest.String()))
So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusOK)
resp, err = resty.R().SetQueryParams(map[string]string{"artifactType": artifactType}).
Get(baseURL + fmt.Sprintf("/v2/%s/referrers/%s", repoName, digest.String()))
resp, err = resty.R().SetQueryParams(map[string]string{"artifactType": artifactType +
",otherArtType"}).Get(baseURL + fmt.Sprintf("/v2/%s/referrers/%s", repoName,
digest.String()))
So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusOK)
So(resp.Header().Get("Content-Type"), ShouldEqual, ispec.MediaTypeImageIndex)
var index ispec.Index
err = json.Unmarshal(resp.Body(), &index)
So(err, ShouldBeNil)
So(index.Manifests, ShouldNotBeEmpty)
So(index.Annotations[storageConstants.ReferrerFilterAnnotation], ShouldNotBeEmpty)
// filter by multiple artifactTypes
req, err := http.NewRequestWithContext(context.TODO(), http.MethodGet,
baseURL+fmt.Sprintf("/v2/%s/referrers/%s", repoName, digest.String()), nil)
So(err, ShouldBeNil)
values := url.Values{}
values.Add("artifactType", artifactType)
values.Add("artifactType", "foobar")
req.URL.RawQuery = values.Encode()
rsp, err := http.DefaultClient.Do(req)
So(err, ShouldBeNil)
defer rsp.Body.Close()
So(rsp.StatusCode, ShouldEqual, http.StatusOK)
So(rsp.Header.Get("Content-Type"), ShouldEqual, ispec.MediaTypeImageIndex)
body, err := io.ReadAll(rsp.Body)
So(err, ShouldBeNil)
err = json.Unmarshal(body, &index)
So(err, ShouldBeNil)
So(index.Manifests, ShouldNotBeEmpty)
So(index.Annotations[storageConstants.ReferrerFilterAnnotation], ShouldNotBeEmpty)
So(len(strings.Split(index.Annotations[storageConstants.ReferrerFilterAnnotation], ",")), ShouldEqual, 2)
So(resp.Header().Get("OCI-Filters-Applied"), ShouldEqual, artifactType+",otherArtType")
})
})
})

View file

@ -433,7 +433,7 @@ func (rh *RouteHandler) GetManifest(response http.ResponseWriter, request *http.
}
if rh.c.RepoDB != nil {
err := meta.OnGetManifest(name, reference, digest, content, rh.c.StoreController, rh.c.RepoDB, rh.c.Log)
err := meta.OnGetManifest(name, reference, content, rh.c.StoreController, rh.c.RepoDB, rh.c.Log)
if errors.Is(err, zerr.ErrOrphanSignature) {
rh.c.Log.Error().Err(err).Msg("image is an orphan signature")
@ -546,6 +546,10 @@ func (rh *RouteHandler) GetReferrers(response http.ResponseWriter, request *http
return
}
if len(artifactTypes) > 0 {
response.Header().Set("OCI-Filters-Applied", strings.Join(artifactTypes, ","))
}
WriteData(response, http.StatusOK, ispec.MediaTypeImageIndex, out)
}

View file

@ -490,10 +490,8 @@ func isNotationSigned(ctx context.Context, repo, digestStr string, searchConf se
return false
}
for _, reference := range referrers.Manifests {
if reference.ArtifactType == notreg.ArtifactTypeNotation {
return true
}
if len(referrers.Manifests) > 0 {
return true
}
return false

View file

@ -5,7 +5,6 @@ package cli //nolint:testpackage
import (
"context"
"errors"
"fmt"
"io"
"net/http"
@ -20,48 +19,6 @@ import (
"zotregistry.io/zot/pkg/test"
)
type RouteHandler struct {
Route string
// HandlerFunc is the HTTP handler function that receives a writer for output and an HTTP request as input.
HandlerFunc http.HandlerFunc
// AllowedMethods specifies the HTTP methods allowed for the current route.
AllowedMethods []string
}
// Routes is a map that associates HTTP paths to their corresponding HTTP handlers.
type HTTPRoutes []RouteHandler
func StartTestHTTPServer(routes HTTPRoutes, port string) *http.Server {
baseURL := test.GetBaseURL(port)
mux := mux.NewRouter()
mux.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
_, err := w.Write([]byte("{}"))
if err != nil {
return
}
}).Methods(http.MethodGet)
for _, routeHandler := range routes {
mux.HandleFunc(routeHandler.Route, routeHandler.HandlerFunc).Methods(routeHandler.AllowedMethods...)
}
server := &http.Server{ //nolint:gosec
Addr: fmt.Sprintf(":%s", port),
Handler: mux,
}
go func() {
if err := server.ListenAndServe(); !errors.Is(err, http.ErrServerClosed) {
return
}
}()
test.WaitTillServerReady(baseURL + "/test")
return server
}
func getDefaultSearchConf(baseURL string) searchConfig {
verifyTLS := false
debug := false
@ -81,7 +38,7 @@ func getDefaultSearchConf(baseURL string) searchConfig {
func TestDoHTTPRequest(t *testing.T) {
Convey("doHTTPRequest nil result pointer", t, func() {
port := test.GetFreePort()
server := StartTestHTTPServer(nil, port)
server := test.StartTestHTTPServer(nil, port)
defer server.Close()
url := fmt.Sprintf("http://127.0.0.1:%s/asd", port)
@ -93,7 +50,7 @@ func TestDoHTTPRequest(t *testing.T) {
Convey("doHTTPRequest bad return json", t, func() {
port := test.GetFreePort()
server := StartTestHTTPServer(HTTPRoutes{
server := test.StartTestHTTPServer(test.HTTPRoutes{
{
Route: "/test",
HandlerFunc: func(w http.ResponseWriter, r *http.Request) {
@ -135,7 +92,7 @@ func TestDoHTTPRequest(t *testing.T) {
searchConf := getDefaultSearchConf(baseURL)
// 404 erorr will appear
server := StartTestHTTPServer(HTTPRoutes{}, port)
server := test.StartTestHTTPServer(test.HTTPRoutes{}, port)
defer server.Close()
URL := baseURL + "/v2/repo/manifests/tag"
@ -158,7 +115,7 @@ func TestDoHTTPRequest(t *testing.T) {
searchConf := getDefaultSearchConf(baseURL)
Convey("makeGETRequest manifest error, context is done", func() {
server := StartTestHTTPServer(HTTPRoutes{}, port)
server := test.StartTestHTTPServer(test.HTTPRoutes{}, port)
defer server.Close()
ctx, cancel := context.WithCancel(context.Background())
@ -172,7 +129,7 @@ func TestDoHTTPRequest(t *testing.T) {
})
Convey("makeGETRequest manifest error, context is not done", func() {
server := StartTestHTTPServer(HTTPRoutes{}, port)
server := test.StartTestHTTPServer(test.HTTPRoutes{}, port)
defer server.Close()
_, err := fetchManifestStruct(context.Background(), "repo", "tag", searchConf,
@ -182,7 +139,7 @@ func TestDoHTTPRequest(t *testing.T) {
})
Convey("makeGETRequest config error, context is not done", func() {
server := StartTestHTTPServer(HTTPRoutes{
server := test.StartTestHTTPServer(test.HTTPRoutes{
{
Route: "/v2/{name}/manifests/{reference}",
HandlerFunc: func(w http.ResponseWriter, r *http.Request) {
@ -203,7 +160,7 @@ func TestDoHTTPRequest(t *testing.T) {
})
Convey("Platforms on config", func() {
server := StartTestHTTPServer(HTTPRoutes{
server := test.StartTestHTTPServer(test.HTTPRoutes{
{
Route: "/v2/{name}/manifests/{reference}",
HandlerFunc: func(w http.ResponseWriter, r *http.Request) {
@ -258,7 +215,7 @@ func TestDoHTTPRequest(t *testing.T) {
})
Convey("fetchImageIndexStruct no errors", func() {
server := StartTestHTTPServer(HTTPRoutes{
server := test.StartTestHTTPServer(test.HTTPRoutes{
{
Route: "/v2/{name}/manifests/{reference}",
HandlerFunc: func(writer http.ResponseWriter, req *http.Request) {
@ -327,7 +284,7 @@ func TestDoHTTPRequest(t *testing.T) {
})
Convey("fetchImageIndexStruct makeGETRequest errors context done", func() {
server := StartTestHTTPServer(HTTPRoutes{}, port)
server := test.StartTestHTTPServer(test.HTTPRoutes{}, port)
defer server.Close()
ctx, cancel := context.WithCancel(context.Background())
@ -349,7 +306,7 @@ func TestDoHTTPRequest(t *testing.T) {
})
Convey("fetchImageIndexStruct makeGETRequest errors context not done", func() {
server := StartTestHTTPServer(HTTPRoutes{}, port)
server := test.StartTestHTTPServer(test.HTTPRoutes{}, port)
defer server.Close()
URL := baseURL + "/v2/repo/manifests/indexRef"
@ -384,7 +341,7 @@ func TestDoJobErrors(t *testing.T) {
reqPool.wtgrp.Add(1)
Convey("Do Job makeHEADRequest error context done", func() {
server := StartTestHTTPServer(HTTPRoutes{}, port)
server := test.StartTestHTTPServer(test.HTTPRoutes{}, port)
defer server.Close()
URL := baseURL + "/v2/repo/manifests/manifestRef"
@ -404,7 +361,7 @@ func TestDoJobErrors(t *testing.T) {
})
Convey("Do Job makeHEADRequest error context not done", func() {
server := StartTestHTTPServer(HTTPRoutes{}, port)
server := test.StartTestHTTPServer(test.HTTPRoutes{}, port)
defer server.Close()
URL := baseURL + "/v2/repo/manifests/manifestRef"
@ -426,7 +383,7 @@ func TestDoJobErrors(t *testing.T) {
})
Convey("Do Job fetchManifestStruct errors context canceled", func() {
server := StartTestHTTPServer(HTTPRoutes{
server := test.StartTestHTTPServer(test.HTTPRoutes{
{
Route: "/v2/{name}/manifests/{reference}",
HandlerFunc: func(w http.ResponseWriter, r *http.Request) {
@ -459,7 +416,7 @@ func TestDoJobErrors(t *testing.T) {
})
Convey("Do Job fetchManifestStruct errors context not canceled", func() {
server := StartTestHTTPServer(HTTPRoutes{
server := test.StartTestHTTPServer(test.HTTPRoutes{
{
Route: "/v2/{name}/manifests/{reference}",
HandlerFunc: func(w http.ResponseWriter, r *http.Request) {
@ -493,7 +450,7 @@ func TestDoJobErrors(t *testing.T) {
})
Convey("Do Job fetchIndexStruct errors context canceled", func() {
server := StartTestHTTPServer(HTTPRoutes{
server := test.StartTestHTTPServer(test.HTTPRoutes{
{
Route: "/v2/{name}/manifests/{reference}",
HandlerFunc: func(w http.ResponseWriter, r *http.Request) {
@ -526,7 +483,7 @@ func TestDoJobErrors(t *testing.T) {
})
Convey("Do Job fetchIndexStruct errors context not canceled", func() {
server := StartTestHTTPServer(HTTPRoutes{
server := test.StartTestHTTPServer(test.HTTPRoutes{
{
Route: "/v2/{name}/manifests/{reference}",
HandlerFunc: func(w http.ResponseWriter, r *http.Request) {
@ -559,7 +516,7 @@ func TestDoJobErrors(t *testing.T) {
So(result.StrValue, ShouldResemble, "")
})
Convey("Do Job fetchIndexStruct not supported content type", func() {
server := StartTestHTTPServer(HTTPRoutes{
server := test.StartTestHTTPServer(test.HTTPRoutes{
{
Route: "/v2/{name}/manifests/{reference}",
HandlerFunc: func(w http.ResponseWriter, r *http.Request) {
@ -589,7 +546,7 @@ func TestDoJobErrors(t *testing.T) {
})
Convey("Media type is MediaTypeImageIndex image.string erorrs", func() {
server := StartTestHTTPServer(HTTPRoutes{
server := test.StartTestHTTPServer(test.HTTPRoutes{
{
Route: "/v2/{name}/manifests/{reference}",
HandlerFunc: func(w http.ResponseWriter, r *http.Request) {

View file

@ -713,7 +713,7 @@ func TestServerCVEResponse(t *testing.T) {
str := space.ReplaceAllString(buff.String(), " ")
str = strings.TrimSpace(str)
So(err, ShouldBeNil)
So(str, ShouldEqual, "IMAGE NAME TAG OS/ARCH DIGEST SIGNED SIZE zot-cve-test 0.0.1 82836dd7 false 548B")
So(str, ShouldEqual, "IMAGE NAME TAG OS/ARCH DIGEST SIGNED SIZE zot-cve-test 0.0.1 40d1f749 false 605B")
})
Convey("Test images by CVE ID - GQL - invalid CVE ID", t, func() {
@ -829,7 +829,7 @@ func TestServerCVEResponse(t *testing.T) {
str := space.ReplaceAllString(buff.String(), " ")
So(err, ShouldBeNil)
So(strings.TrimSpace(str), ShouldEqual,
"IMAGE NAME TAG OS/ARCH DIGEST SIGNED SIZE zot-cve-test 0.0.1 82836dd7 false 548B")
"IMAGE NAME TAG OS/ARCH DIGEST SIGNED SIZE zot-cve-test 0.0.1 40d1f749 false 605B")
})
Convey("Test CVE by name and CVE ID - GQL - invalid name and CVE ID", t, func() {
@ -907,7 +907,7 @@ func TestServerCVEResponse(t *testing.T) {
str := space.ReplaceAllString(buff.String(), " ")
str = strings.TrimSpace(str)
So(err, ShouldBeNil)
So(str, ShouldEqual, "IMAGE NAME TAG OS/ARCH DIGEST SIGNED SIZE zot-cve-test 0.0.1 linux/amd64 82836dd7 false 548B")
So(str, ShouldEqual, "IMAGE NAME TAG OS/ARCH DIGEST SIGNED SIZE zot-cve-test 0.0.1 linux/amd64 40d1f749 false 605B")
})
Convey("Test images by CVE ID - invalid CVE ID", t, func() {
@ -992,7 +992,7 @@ func TestServerCVEResponse(t *testing.T) {
str := space.ReplaceAllString(buff.String(), " ")
So(err, ShouldBeNil)
So(strings.TrimSpace(str), ShouldEqual,
"IMAGE NAME TAG OS/ARCH DIGEST SIGNED SIZE zot-cve-test 0.0.1 linux/amd64 82836dd7 false 548B")
"IMAGE NAME TAG OS/ARCH DIGEST SIGNED SIZE zot-cve-test 0.0.1 linux/amd64 40d1f749 false 605B")
})
Convey("Test CVE by name and CVE ID - invalid name and CVE ID", t, func() {

View file

@ -333,7 +333,7 @@ func TestSignature(t *testing.T) {
str := space.ReplaceAllString(buff.String(), " ")
actual := strings.TrimSpace(str)
So(actual, ShouldContainSubstring, "IMAGE NAME TAG OS/ARCH DIGEST SIGNED SIZE")
So(actual, ShouldContainSubstring, "repo7 test:1.0 linux/amd64 6742241d true 447B")
So(actual, ShouldContainSubstring, "repo7 test:1.0 linux/amd64 8e59ed3b true 504B")
t.Log("Test getting all images using rest calls to get catalog and individual manifests")
cmd = MockNewImageCommand(new(searchService))
@ -346,7 +346,7 @@ func TestSignature(t *testing.T) {
str = space.ReplaceAllString(buff.String(), " ")
actual = strings.TrimSpace(str)
So(actual, ShouldContainSubstring, "IMAGE NAME TAG OS/ARCH DIGEST SIGNED SIZE")
So(actual, ShouldContainSubstring, "repo7 test:1.0 linux/amd64 6742241d true 447B")
So(actual, ShouldContainSubstring, "repo7 test:1.0 linux/amd64 8e59ed3b true 504B")
err = os.Chdir(currentWorkingDir)
So(err, ShouldBeNil)
@ -410,7 +410,7 @@ func TestSignature(t *testing.T) {
str := space.ReplaceAllString(buff.String(), " ")
actual := strings.TrimSpace(str)
So(actual, ShouldContainSubstring, "IMAGE NAME TAG OS/ARCH DIGEST SIGNED SIZE")
So(actual, ShouldContainSubstring, "repo7 0.0.1 linux/amd64 6742241d true 447B")
So(actual, ShouldContainSubstring, "repo7 0.0.1 linux/amd64 8e59ed3b true 504B")
t.Log("Test getting all images using rest calls to get catalog and individual manifests")
cmd = MockNewImageCommand(new(searchService))
@ -423,7 +423,7 @@ func TestSignature(t *testing.T) {
str = space.ReplaceAllString(buff.String(), " ")
actual = strings.TrimSpace(str)
So(actual, ShouldContainSubstring, "IMAGE NAME TAG OS/ARCH DIGEST SIGNED SIZE")
So(actual, ShouldContainSubstring, "repo7 0.0.1 linux/amd64 6742241d true 447B")
So(actual, ShouldContainSubstring, "repo7 0.0.1 linux/amd64 8e59ed3b true 504B")
err = os.Chdir(currentWorkingDir)
So(err, ShouldBeNil)
@ -1333,13 +1333,13 @@ func runDisplayIndexTests(baseURL string) {
actual := strings.TrimSpace(str)
// Actual cli output should be something similar to (order of images may differ):
// IMAGE NAME TAG OS/ARCH DIGEST SIGNED SIZE
// repo multi-arch * 46b78b06 false 1.4kB
// linux/amd64 97b0d65c false 577B
// repo multi-arch * 59b25ae4 false 1.5kB
// linux/amd64 97b0d65c false 634B
// windows/arm64/v6 dcfa3a9c false 444B
So(actual, ShouldContainSubstring, "IMAGE NAME TAG OS/ARCH DIGEST SIGNED SIZE")
So(actual, ShouldContainSubstring, "repo multi-arch * 46b78b06 false 1.4kB ")
So(actual, ShouldContainSubstring, "linux/amd64 97b0d65c false 577B ")
So(actual, ShouldContainSubstring, "windows/arm64/v6 dcfa3a9c false 444B")
So(actual, ShouldContainSubstring, "repo multi-arch * 59b25ae4 false 1.5kB ")
So(actual, ShouldContainSubstring, "linux/amd64 2ab1a275 false 634B ")
So(actual, ShouldContainSubstring, "windows/arm64/v6 55fdd23a false 501B")
})
Convey("Test Image Index Verbose", func() {
@ -1361,18 +1361,18 @@ func runDisplayIndexTests(baseURL string) {
actual := strings.TrimSpace(str)
// Actual cli output should be something similar to (order of images may differ):
// IMAGE NAME TAG OS/ARCH DIGEST CONFIG SIGNED LAYERS SIZE
// repo multi-arch * 46b78b06 false 1.4kB
// linux/amd64 97b0d65c 58cc9abe false 577B
// repo multi-arch * 59b25ae4 false 1.5kB
// linux/amd64 2ab1a275 58cc9abe false 634B
// cbb5b121 4B
// a00291e8 4B
// windows/arm64/v6 dcfa3a9c 5132a1cd false 444B
// windows/arm64/v6 55fdd23a 5132a1cd false 501B
// 7d08ce29 4B
So(actual, ShouldContainSubstring, "IMAGE NAME TAG OS/ARCH DIGEST CONFIG SIGNED LAYERS SIZE")
So(actual, ShouldContainSubstring, "repo multi-arch * 46b78b06 false 1.4kB")
So(actual, ShouldContainSubstring, "linux/amd64 97b0d65c 58cc9abe false 577B")
So(actual, ShouldContainSubstring, "repo multi-arch * 59b25ae4 false 1.5kB")
So(actual, ShouldContainSubstring, "linux/amd64 2ab1a275 58cc9abe false 634B")
So(actual, ShouldContainSubstring, "cbb5b121 4B")
So(actual, ShouldContainSubstring, "a00291e8 4B")
So(actual, ShouldContainSubstring, "windows/arm64/v6 dcfa3a9c 5132a1cd false 444B")
So(actual, ShouldContainSubstring, "windows/arm64/v6 55fdd23a 5132a1cd false 501B")
So(actual, ShouldContainSubstring, "7d08ce29 4B")
})
}

View file

@ -17,6 +17,7 @@ import (
"unicode/utf8"
"github.com/opencontainers/go-digest"
ispec "github.com/opencontainers/image-spec/specs-go/v1"
"zotregistry.io/zot/pkg/log"
)
@ -274,3 +275,11 @@ func DContains(slice []digest.Digest, item digest.Digest) bool {
return false
}
func GetManifestArtifactType(manifestContent ispec.Manifest) string {
if manifestContent.ArtifactType != "" {
return manifestContent.ArtifactType
}
return manifestContent.Config.MediaType
}

View file

@ -78,7 +78,8 @@ func (linter *Linter) CheckMandatoryAnnotations(repo string, manifestDigest godi
content, err = imgStore.GetBlobContent(repo, configDigest)
if err != nil {
linter.log.Error().Err(err).Msg("linter: couldn't get config JSON " + configDigest.String())
linter.log.Error().Err(err).Msg("linter: couldn't get config JSON " +
configDigest.String())
return false, err
}

View file

@ -183,7 +183,7 @@ func TestConvertErrors(t *testing.T) {
Referrers: map[string][]repodb.ReferrerInfo{},
},
repodb.ManifestMetadata{
ManifestBlob: []byte("{}"),
ManifestBlob: []byte(`{}`),
ConfigBlob: []byte("bad json"),
},
nil,

View file

@ -923,7 +923,7 @@ func TestCVEStruct(t *testing.T) {
},
Layers: []ispec.Descriptor{
{
MediaType: ispec.MediaTypeImageLayerNonDistributableGzip,
MediaType: ispec.MediaTypeImageLayerNonDistributableGzip, //nolint:staticcheck
Size: 0,
Digest: godigest.NewDigestFromEncoded(godigest.SHA256, "digest"),
},

View file

@ -1449,7 +1449,7 @@ func TestGetReferrers(t *testing.T) {
Convey("GetReferrers return index of descriptors", func() {
testLogger := log.NewLogger("debug", "")
referrerDescriptor := ispec.Descriptor{
MediaType: ispec.MediaTypeArtifactManifest,
MediaType: ispec.MediaTypeImageManifest,
ArtifactType: "com.artifact.test",
Size: 403,
Digest: godigest.FromString("test"),

View file

@ -21,6 +21,7 @@ import (
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
"github.com/gobwas/glob"
regTypes "github.com/google/go-containerregistry/pkg/v1/types"
notreg "github.com/notaryproject/notation-go/registry"
godigest "github.com/opencontainers/go-digest"
"github.com/opencontainers/image-spec/specs-go"
ispec "github.com/opencontainers/image-spec/specs-go/v1"
@ -31,7 +32,7 @@ import (
"zotregistry.io/zot/pkg/api"
"zotregistry.io/zot/pkg/api/config"
"zotregistry.io/zot/pkg/api/constants"
"zotregistry.io/zot/pkg/common"
zcommon "zotregistry.io/zot/pkg/common"
extconf "zotregistry.io/zot/pkg/extensions/config"
"zotregistry.io/zot/pkg/extensions/monitoring"
cveinfo "zotregistry.io/zot/pkg/extensions/search/cve"
@ -97,7 +98,7 @@ type ReferrersResp struct {
}
type ReferrersResult struct {
Referrers []common.Referrer `json:"referrers"`
Referrers []zcommon.Referrer `json:"referrers"`
}
type GlobalSearchResultResp struct {
GlobalSearchResult GlobalSearchResult `json:"data"`
@ -109,24 +110,24 @@ type GlobalSearchResult struct {
}
type GlobalSearch struct {
Images []common.ImageSummary `json:"images"`
Repos []common.RepoSummary `json:"repos"`
Layers []common.LayerSummary `json:"layers"`
Page repodb.PageInfo `json:"page"`
Images []zcommon.ImageSummary `json:"images"`
Repos []zcommon.RepoSummary `json:"repos"`
Layers []zcommon.LayerSummary `json:"layers"`
Page repodb.PageInfo `json:"page"`
}
type ExpandedRepoInfo struct {
RepoInfo common.RepoInfo `json:"expandedRepoInfo"`
RepoInfo zcommon.RepoInfo `json:"expandedRepoInfo"`
}
type PaginatedReposResult struct {
Results []common.RepoSummary `json:"results"`
Page repodb.PageInfo `json:"page"`
Results []zcommon.RepoSummary `json:"results"`
Page repodb.PageInfo `json:"page"`
}
type PaginatedImagesResult struct {
Results []common.ImageSummary `json:"results"`
Page repodb.PageInfo `json:"page"`
Results []zcommon.ImageSummary `json:"results"`
Page repodb.PageInfo `json:"page"`
}
//nolint:tagliatelle // graphQL schema
@ -140,7 +141,7 @@ type ErrorGQL struct {
}
type SingleImageSummary struct {
ImageSummary common.ImageSummary `json:"Image"` //nolint:tagliatelle
ImageSummary zcommon.ImageSummary `json:"Image"` //nolint:tagliatelle
}
type ImageSummaryResult struct {
SingleImageSummary SingleImageSummary `json:"data"`
@ -189,7 +190,7 @@ func readFileAndSearchString(filePath string, stringToMatch string, timeout time
}
func verifyRepoSummaryFields(t *testing.T,
actualRepoSummary, expectedRepoSummary *common.RepoSummary,
actualRepoSummary, expectedRepoSummary *zcommon.RepoSummary,
) {
t.Helper()
@ -218,7 +219,7 @@ func verifyRepoSummaryFields(t *testing.T,
}
func verifyImageSummaryFields(t *testing.T,
actualImageSummary, expectedImageSummary *common.ImageSummary,
actualImageSummary, expectedImageSummary *zcommon.ImageSummary,
) {
t.Helper()
@ -972,30 +973,37 @@ func TestGetReferrersGQL(t *testing.T) {
artifactContentBlobDigest := godigest.FromBytes(artifactContentBlob)
artifactType := "com.artifact.test"
err = UploadBlob(baseURL, repo, artifactContentBlob, artifactContentType)
So(err, ShouldBeNil)
artifact := &ispec.Artifact{
Blobs: []ispec.Descriptor{
{
MediaType: artifactContentType,
Digest: artifactContentBlobDigest,
Size: artifactContentBlobSize,
artifactImg := Image{
Manifest: ispec.Manifest{
Layers: []ispec.Descriptor{
{
MediaType: artifactContentType,
Digest: artifactContentBlobDigest,
Size: artifactContentBlobSize,
},
},
Subject: subjectDescriptor,
ArtifactType: artifactType,
Config: ispec.Descriptor{
MediaType: ispec.MediaTypeScratch,
Digest: ispec.ScratchDescriptor.Digest,
Data: ispec.ScratchDescriptor.Data,
},
MediaType: ispec.MediaTypeImageManifest,
Annotations: map[string]string{
"com.artifact.format": "test",
},
},
Subject: subjectDescriptor,
ArtifactType: artifactType,
MediaType: ispec.MediaTypeArtifactManifest,
Annotations: map[string]string{
"com.artifact.format": "test",
},
Config: ispec.Image{},
Layers: [][]byte{artifactContentBlob},
}
artifactManifestBlob, err := json.Marshal(artifact)
artifactManifestBlob, err := json.Marshal(artifactImg.Manifest)
So(err, ShouldBeNil)
artifactManifestDigest := godigest.FromBytes(artifactManifestBlob)
artifactImg.Reference = artifactManifestDigest.String()
err = UploadArtifactManifest(artifact, nil, baseURL, repo)
err = UploadImage(artifactImg, baseURL, repo)
So(err, ShouldBeNil)
gqlQuery := `
@ -1029,7 +1037,7 @@ func TestGetReferrersGQL(t *testing.T) {
So(err, ShouldBeNil)
So(referrersResp.Errors, ShouldBeNil)
So(referrersResp.ReferrersResult.Referrers[0].ArtifactType, ShouldEqual, artifactType)
So(referrersResp.ReferrersResult.Referrers[0].MediaType, ShouldEqual, ispec.MediaTypeArtifactManifest)
So(referrersResp.ReferrersResult.Referrers[0].MediaType, ShouldEqual, ispec.MediaTypeImageManifest)
So(referrersResp.ReferrersResult.Referrers[0].Annotations[0].Key, ShouldEqual, "com.artifact.format")
So(referrersResp.ReferrersResult.Referrers[0].Annotations[0].Value, ShouldEqual, "test")
@ -1505,6 +1513,7 @@ func TestExpandedRepoInfo(t *testing.T) {
})
Convey("Test expanded repo info with tagged referrers", t, func() {
const test = "test"
rootDir := t.TempDir()
port := GetFreePort()
baseURL := GetBaseURL(port)
@ -1524,7 +1533,7 @@ func TestExpandedRepoInfo(t *testing.T) {
ctlrManager.StartAndWait(port)
defer ctlrManager.StopServer()
image, err := GetRandomImage("test")
image, err := GetRandomImage(test)
So(err, ShouldBeNil)
manifestDigest, err := image.Digest()
So(err, ShouldBeNil)
@ -1532,17 +1541,15 @@ func TestExpandedRepoInfo(t *testing.T) {
err = UploadImage(image, baseURL, "repo")
So(err, ShouldBeNil)
referrer, err := GetRandomArtifact(&ispec.Descriptor{
Digest: manifestDigest,
MediaType: ispec.MediaTypeImageManifest,
})
referrer, err := GetImageWithSubject(manifestDigest, ispec.MediaTypeImageManifest)
So(err, ShouldBeNil)
tag := "test-ref-tag"
err = UploadArtifactManifest(&referrer.Manifest, &tag, baseURL, "repo")
referrer.Reference = tag
err = UploadImage(referrer, baseURL, "repo")
So(err, ShouldBeNil)
// ------- Make the call to GQL and see that it doesn't crash and that the referrer isn't in the list of tags
// ------- Make the call to GQL and see that it doesn't crash
responseStruct := &ExpandedRepoInfoResp{}
query := `
{
@ -1564,10 +1571,23 @@ func TestExpandedRepoInfo(t *testing.T) {
err = json.Unmarshal(resp.Body(), responseStruct)
So(err, ShouldBeNil)
So(len(responseStruct.ExpandedRepoInfo.RepoInfo.ImageSummaries), ShouldEqual, 1)
So(len(responseStruct.ExpandedRepoInfo.RepoInfo.ImageSummaries), ShouldEqual, 2)
repoInfo := responseStruct.ExpandedRepoInfo.RepoInfo
So(repoInfo.ImageSummaries[0].Tag, ShouldEqual, "test")
foundTagTest := false
foundTagRefTag := false
for _, imgSum := range repoInfo.ImageSummaries {
switch imgSum.Tag {
case test:
foundTagTest = true
case "test-ref-tag":
foundTagRefTag = true
}
}
So(foundTagTest || foundTagRefTag, ShouldEqual, true)
})
Convey("Test image tags order", t, func() {
@ -3241,8 +3261,8 @@ func TestGlobalSearch(t *testing.T) {
repos, err := olu.GetRepositories()
So(err, ShouldBeNil)
allExpectedRepoInfoMap := make(map[string]common.RepoInfo)
allExpectedImageSummaryMap := make(map[string]common.ImageSummary)
allExpectedRepoInfoMap := make(map[string]zcommon.RepoInfo)
allExpectedImageSummaryMap := make(map[string]zcommon.ImageSummary)
for _, repo := range repos {
repoInfo, err := olu.GetExpandedRepoInfo(repo)
So(err, ShouldBeNil)
@ -3310,8 +3330,8 @@ func TestGlobalSearch(t *testing.T) {
t.Logf("returned layers: %v", responseStruct.GlobalSearchResult.GlobalSearch.Layers)
So(responseStruct.GlobalSearchResult.GlobalSearch.Layers, ShouldBeEmpty)
newestImageMap := make(map[string]common.ImageSummary)
actualRepoMap := make(map[string]common.RepoSummary)
newestImageMap := make(map[string]zcommon.ImageSummary)
actualRepoMap := make(map[string]zcommon.RepoSummary)
for _, repo := range responseStruct.GlobalSearchResult.GlobalSearch.Repos {
newestImageMap[repo.Name] = repo.NewestImage
actualRepoMap[repo.Name] = repo
@ -3570,8 +3590,8 @@ func TestGlobalSearch(t *testing.T) {
repos, err := olu.GetRepositories()
So(err, ShouldBeNil)
allExpectedRepoInfoMap := make(map[string]common.RepoInfo)
allExpectedImageSummaryMap := make(map[string]common.ImageSummary)
allExpectedRepoInfoMap := make(map[string]zcommon.RepoInfo)
allExpectedImageSummaryMap := make(map[string]zcommon.ImageSummary)
for _, repo := range repos {
repoInfo, err := olu.GetExpandedRepoInfo(repo)
So(err, ShouldBeNil)
@ -3637,8 +3657,8 @@ func TestGlobalSearch(t *testing.T) {
t.Logf("returned layers: %v", responseStruct.GlobalSearchResult.GlobalSearch.Layers)
So(responseStruct.GlobalSearchResult.GlobalSearch.Layers, ShouldBeEmpty)
newestImageMap := make(map[string]common.ImageSummary)
actualRepoMap := make(map[string]common.RepoSummary)
newestImageMap := make(map[string]zcommon.ImageSummary)
actualRepoMap := make(map[string]zcommon.RepoSummary)
for _, repo := range responseStruct.GlobalSearchResult.GlobalSearch.Repos {
newestImageMap[repo.Name] = repo.NewestImage
actualRepoMap[repo.Name] = repo
@ -5626,10 +5646,17 @@ func TestRepoDBWhenDeletingImages(t *testing.T) {
signatureReference := ""
var sigManifestContent ispec.Artifact
var sigManifestContent ispec.Manifest
for _, manifest := range indexContent.Manifests {
if manifest.MediaType == ispec.MediaTypeArtifactManifest {
manifestBlob, _, _, err := storage.GetImageManifest(repo, manifest.Digest.String())
So(err, ShouldBeNil)
var manifestContent ispec.Manifest
err = json.Unmarshal(manifestBlob, &manifestContent)
So(err, ShouldBeNil)
if zcommon.GetManifestArtifactType(manifestContent) == notreg.ArtifactTypeNotation {
signatureReference = manifest.Digest.String()
manifestBlob, _, _, err := storage.GetImageManifest(repo, signatureReference)
So(err, ShouldBeNil)
@ -6233,11 +6260,11 @@ func TestImageSummary(t *testing.T) {
So(imgSummary.Vulnerabilities.Count, ShouldEqual, 0)
So(imgSummary.Vulnerabilities.MaxSeverity, ShouldEqual, "")
So(len(imgSummary.Referrers), ShouldEqual, 1)
So(imgSummary.Referrers[0], ShouldResemble, common.Referrer{
So(imgSummary.Referrers[0], ShouldResemble, zcommon.Referrer{
MediaType: ispec.MediaTypeImageManifest,
ArtifactType: "test.artifact.type",
Digest: referrerManifestDigest.String(),
Annotations: []common.Annotation{{Key: "testAnnotationKey", Value: "testAnnotationValue"}},
Annotations: []zcommon.Annotation{{Key: "testAnnotationKey", Value: "testAnnotationValue"}},
})
t.Log("starting Test retrieve duplicated image same layers based on image identifier")

View file

@ -355,23 +355,8 @@ func (sig *signaturesCopier) syncOCIRefs(localRepo, remoteRepo, digestStr string
if err := syncBlob(sig, imageStore, localRepo, remoteRepo, manifest.Config.Digest); err != nil {
return err
}
} else if ref.MediaType == ispec.MediaTypeArtifactManifest {
// read manifest
var manifest ispec.Artifact
err = json.Unmarshal(OCIRefBody, &manifest)
if err != nil {
sig.log.Error().Str("errorType", common.TypeOf(err)).Err(err).
Str("manifest", getRefManifestURL.String()).Msg("couldn't unmarshal oci reference manifest")
return err
}
for _, layer := range manifest.Blobs {
if err := syncBlob(sig, imageStore, localRepo, remoteRepo, layer.Digest); err != nil {
return err
}
}
} else {
continue
}
digest, err := imageStore.PutImageManifest(localRepo, ref.Digest.String(),
@ -404,78 +389,6 @@ func (sig *signaturesCopier) syncOCIRefs(localRepo, remoteRepo, digestStr string
return nil
}
func (sig *signaturesCopier) syncOCIArtifact(localRepo, remoteRepo, reference string,
ociArtifactBuf []byte,
) error {
var ociArtifact ispec.Artifact
err := json.Unmarshal(ociArtifactBuf, &ociArtifact)
if err != nil {
sig.log.Error().Err(err).Str("repository", remoteRepo).Str("reference", reference).
Msg("couldn't unmarshal OCI artifact")
return err
}
canSkipOCIArtifact, err := sig.canSkipOCIArtifact(localRepo, reference, ociArtifact)
if err != nil {
sig.log.Error().Err(err).Str("repository", remoteRepo).Str("reference", reference).
Msg("couldn't check if OCI artifact can be skipped")
}
if canSkipOCIArtifact {
return nil
}
imageStore := sig.storeController.GetImageStore(localRepo)
sig.log.Info().Msg("syncing OCI artifacts")
for _, blob := range ociArtifact.Blobs {
if err := syncBlob(sig, imageStore, localRepo, remoteRepo, blob.Digest); err != nil {
return err
}
}
artifactManifestBuf, err := json.Marshal(ociArtifact)
if err != nil {
sig.log.Error().Str("errorType", common.TypeOf(err)).
Err(err).Msg("couldn't marshal OCI artifact")
return err
}
// push manifest
digest, err := imageStore.PutImageManifest(localRepo, reference,
ispec.MediaTypeArtifactManifest, artifactManifestBuf)
if err != nil {
sig.log.Error().Str("errorType", common.TypeOf(err)).
Err(err).Msg("couldn't upload OCI artifact manifest")
return err
}
if sig.repoDB != nil {
sig.log.Debug().Str("repository", localRepo).Str("digest", digest.String()).
Msg("trying to OCI refs for repo digest")
err = repodb.SetMetadataFromInput(localRepo, reference, ispec.MediaTypeArtifactManifest,
digest, artifactManifestBuf, sig.storeController.GetImageStore(localRepo),
sig.repoDB, sig.log)
if err != nil {
return fmt.Errorf("failed to set metadata for OCI Artifact '%s@%s': %w", localRepo, digest.String(), err)
}
sig.log.Info().Str("repository", localRepo).Str("digest", digest.String()).
Msg("successfully added oci artifacts to RepoDB for repo digest")
}
sig.log.Info().Str("repository", localRepo).Str("tag", reference).
Msg("successfully synced OCI artifact for repo tag")
return nil
}
func (sig *signaturesCopier) canSkipORASRefs(localRepo, digestStr string, refs ReferenceList,
) (bool, error) {
imageStore := sig.storeController.GetImageStore(localRepo)
@ -509,47 +422,6 @@ func (sig *signaturesCopier) canSkipORASRefs(localRepo, digestStr string, refs R
return true, nil
}
func (sig *signaturesCopier) canSkipOCIArtifact(localRepo, reference string, artifact ispec.Artifact,
) (bool, error) {
imageStore := sig.storeController.GetImageStore(localRepo)
var localArtifactManifest ispec.Artifact
localArtifactBuf, _, _, err := imageStore.GetImageManifest(localRepo, reference)
if err != nil {
if errors.Is(err, zerr.ErrManifestNotFound) || errors.Is(err, zerr.ErrRepoNotFound) {
return false, nil
}
sig.log.Error().Str("errorType", common.TypeOf(err)).Err(err).
Str("repository", localRepo).Str("reference", reference).
Msg("couldn't get local OCI artifact manifest")
return false, err
}
err = json.Unmarshal(localArtifactBuf, &localArtifactManifest)
if err != nil {
sig.log.Error().Str("errorType", common.TypeOf(err)).Err(err).
Str("repository", localRepo).Str("reference", reference).
Msg("couldn't unmarshal local OCI artifact manifest")
return false, err
}
if !artifactsEqual(localArtifactManifest, artifact) {
sig.log.Info().Str("repository", localRepo).Str("reference", reference).
Msg("upstream OCI artifact changed, syncing again")
return false, nil
}
sig.log.Info().Str("repository", localRepo).Str("reference", reference).
Msg("skipping OCI artifact, already synced")
return true, nil
}
func (sig *signaturesCopier) canSkipCosignSignature(localRepo, digestStr string, cosignManifest *ispec.Manifest,
) (bool, error) {
imageStore := sig.storeController.GetImageStore(localRepo)

View file

@ -361,7 +361,7 @@ func TestSyncInternal(t *testing.T) {
So(regURL, ShouldNotBeNil)
ref := ispec.Descriptor{
MediaType: ispec.MediaTypeArtifactManifest,
MediaType: ispec.MediaTypeImageManifest,
Digest: "fakeDigest",
ArtifactType: "application/vnd.cncf.notary.signature",
}
@ -406,7 +406,7 @@ func TestSyncInternal(t *testing.T) {
refs := ispec.Index{Manifests: []ispec.Descriptor{
{
MediaType: ispec.MediaTypeArtifactManifest,
MediaType: ispec.MediaTypeImageManifest,
Digest: "fakeDigest",
ArtifactType: "application/vnd.cncf.notary.signature",
},
@ -446,7 +446,7 @@ func TestSyncInternal(t *testing.T) {
err = json.Unmarshal(buf, &index)
So(err, ShouldBeNil)
index.Manifests = append(index.Manifests, ispec.Descriptor{
MediaType: ispec.MediaTypeArtifactManifest,
MediaType: ispec.MediaTypeImageManifest,
Digest: godigest.FromString(""),
ArtifactType: "application/vnd.cncf.notary.signature",
})
@ -548,6 +548,59 @@ func TestSyncInternal(t *testing.T) {
So(canBeSkipped, ShouldBeFalse)
})
Convey("Test syncOCIRefs with bad mediaType", t, func() {
downPort, upPort := test.GetFreePort(), test.GetFreePort()
downStream := test.StartTestHTTPServer(
[]test.RouteHandler{
{
Route: "",
HandlerFunc: func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
},
AllowedMethods: []string{},
},
},
downPort,
)
defer downStream.Close()
upStream := test.StartTestHTTPServer(
[]test.RouteHandler{
{
Route: "/v2/{name}/manifests/{digest}",
HandlerFunc: func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
_, err := w.Write([]byte("{}"))
if err != nil {
t.FailNow()
}
},
AllowedMethods: []string{"GET"},
},
},
upPort,
)
defer upStream.Close()
upStreamURL, err := url.Parse(fmt.Sprintf("http://127.0.0.1:%s", upPort))
So(err, ShouldBeNil)
client := &http.Client{}
mockRepoDB := mocks.RepoDBMock{}
mockImageStore := mocks.MockedImageStore{}
sig := newSignaturesCopier(client, syncconf.Credentials{},
*upStreamURL, mockRepoDB, storage.StoreController{DefaultStore: mockImageStore},
log.NewLogger("debug", ""),
)
digest := godigest.FromString("1")
err = sig.syncOCIRefs("repo", "repo", digest.String(),
ispec.Index{Manifests: []ispec.Descriptor{{MediaType: "bad media type", Digest: digest}}})
So(err, ShouldBeNil)
})
Convey("Test filterRepos()", t, func() {
repos := []string{"repo", "repo1", "repo2", "repo/repo2", "repo/repo2/repo3/repo4"}
contents := []syncconf.Content{
@ -1265,61 +1318,3 @@ func TestCompareArtifactRefs(t *testing.T) {
}
})
}
func TestCompareArtifactManifests(t *testing.T) {
testCases := []struct {
refs1 ispec.Artifact
refs2 ispec.Artifact
expected bool
}{
{
refs1: ispec.Artifact{
MediaType: "mediatype",
ArtifactType: "signature",
Blobs: []ispec.Descriptor{
{
Digest: "digest1",
},
},
},
refs2: ispec.Artifact{
MediaType: "mediatype",
ArtifactType: "signature",
Blobs: []ispec.Descriptor{
{
Digest: "digest1",
},
},
},
expected: true,
},
{
refs1: ispec.Artifact{
MediaType: "mediatype",
ArtifactType: "signature",
Blobs: []ispec.Descriptor{
{
Digest: "digest1",
},
},
},
refs2: ispec.Artifact{
MediaType: "mediatype",
ArtifactType: "signature",
Blobs: []ispec.Descriptor{
{
Digest: "digest2",
},
},
},
expected: false,
},
}
Convey("Test artifactsEqual()", t, func() {
for _, test := range testCases {
actualResult := artifactsEqual(test.refs1, test.refs2)
So(actualResult, ShouldEqual, test.expected)
}
})
}

View file

@ -400,19 +400,24 @@ func TestORAS(t *testing.T) {
digest = godigest.FromBytes(resp.Body())
content := []byte("blob content")
adigest := pushBlob(srcBaseURL, repoName, content)
// layer
layer := []byte("blob content")
blobDigest := pushBlob(srcBaseURL, repoName, layer)
artifactManifest := ispec.Artifact{
// config
_ = pushBlob(srcBaseURL, repoName, ispec.ScratchDescriptor.Data)
artifactManifest := ispec.Manifest{
MediaType: artifactspec.MediaTypeArtifactManifest,
ArtifactType: "application/vnd.oras.artifact",
Blobs: []ispec.Descriptor{
Layers: []ispec.Descriptor{
{
MediaType: "application/octet-stream",
Digest: adigest,
Size: int64(len(content)),
Digest: blobDigest,
Size: int64(len(layer)),
},
},
Config: ispec.ScratchDescriptor,
Subject: &ispec.Descriptor{
MediaType: "application/vnd.oci.image.manifest.v1+json",
Digest: digest,
@ -420,19 +425,15 @@ func TestORAS(t *testing.T) {
},
}
content, err = json.Marshal(artifactManifest)
if err != nil {
panic(err)
}
artManifestBlob, err := json.Marshal(artifactManifest)
So(err, ShouldBeNil)
adigest = godigest.FromBytes(content)
artifactDigest := godigest.FromBytes(artManifestBlob)
// put OCI reference artifact mediaType artifact
_, err = resty.R().SetHeader("Content-Type", artifactspec.MediaTypeArtifactManifest).
SetBody(content).Put(srcBaseURL + fmt.Sprintf("/v2/%s/manifests/%s", repoName, adigest.String()))
if err != nil {
panic(err)
}
SetBody(artManifestBlob).Put(srcBaseURL + fmt.Sprintf("/v2/%s/manifests/%s", repoName, artifactDigest.String()))
So(err, ShouldBeNil)
err = os.Chmod(path.Join(destDir, testImage, "index.json"), 0o000)
So(err, ShouldBeNil)
@ -447,7 +448,7 @@ func TestORAS(t *testing.T) {
So(err, ShouldBeNil)
// trigger getORASRefs err
err = os.Chmod(path.Join(srcDir, testImage, "blobs/sha256", adigest.Encoded()), 0o000)
err = os.Chmod(path.Join(srcDir, testImage, "blobs/sha256", artifactDigest.Encoded()), 0o000)
So(err, ShouldBeNil)
resp, err = resty.R().Get(destBaseURL + "/v2/" + testImage + "/manifests/" + digest.String())
@ -455,7 +456,7 @@ func TestORAS(t *testing.T) {
So(resp, ShouldNotBeEmpty)
So(resp.StatusCode(), ShouldEqual, http.StatusOK)
err = os.Chmod(path.Join(srcDir, testImage, "blobs/sha256", adigest.Encoded()), 0o755)
err = os.Chmod(path.Join(srcDir, testImage, "blobs/sha256", artifactDigest.Encoded()), 0o755)
So(err, ShouldBeNil)
resp, err = resty.R().Get(getORASReferrersURL)
@ -473,11 +474,12 @@ func TestORAS(t *testing.T) {
err = os.RemoveAll(path.Join(destDir, repoName))
So(err, ShouldBeNil)
err = os.WriteFile(path.Join(srcDir, repoName, "blobs", "sha256", adigest.Encoded()), []byte("wrong content"), 0o600)
err = os.WriteFile(path.Join(srcDir, repoName, "blobs", "sha256", artifactDigest.Encoded()),
[]byte("wrong content"), 0o600)
So(err, ShouldBeNil)
_, err = resty.R().SetHeader("Content-Type", artifactspec.MediaTypeArtifactManifest).
SetBody(content).Put(srcBaseURL + fmt.Sprintf("/v2/%s/manifests/%s", repoName, adigest.String()))
SetBody(artManifestBlob).Put(srcBaseURL + fmt.Sprintf("/v2/%s/manifests/%s", repoName, artifactDigest.String()))
if err != nil {
panic(err)
}
@ -665,20 +667,33 @@ func TestOnDemand(t *testing.T) {
So(err, ShouldBeNil)
// add OCI Ref
OCIRefManifest := ispec.Artifact{
_ = pushBlob(srcBaseURL, "remote-repo", ispec.ScratchDescriptor.Data)
OCIRefManifest := ispec.Manifest{
Subject: &ispec.Descriptor{
MediaType: ispec.MediaTypeImageManifest,
Digest: manifestDigest,
},
Blobs: []ispec.Descriptor{},
MediaType: ispec.MediaTypeArtifactManifest,
Config: ispec.Descriptor{
MediaType: ispec.MediaTypeScratch,
Digest: ispec.ScratchDescriptor.Digest,
Size: 2,
},
Layers: []ispec.Descriptor{
{
MediaType: ispec.MediaTypeScratch,
Digest: ispec.ScratchDescriptor.Digest,
Size: 2,
},
},
MediaType: ispec.MediaTypeImageManifest,
}
OCIRefManifestBlob, err := json.Marshal(OCIRefManifest)
So(err, ShouldBeNil)
resp, err := resty.R().
SetHeader("Content-type", ispec.MediaTypeArtifactManifest).
SetHeader("Content-type", ispec.MediaTypeImageManifest).
SetBody(OCIRefManifestBlob).
Put(srcBaseURL + "/v2/remote-repo/manifests/oci.ref")
@ -763,7 +778,7 @@ func TestOnDemand(t *testing.T) {
dctlr.RepoDB = mocks.RepoDBMock{
SetRepoReferenceFn: func(repo, Reference string, manifestDigest godigest.Digest, mediaType string) error {
if mediaType == ispec.MediaTypeArtifactManifest {
if mediaType == ispec.MediaTypeImageManifest {
return sync.ErrTestError
}
@ -854,7 +869,7 @@ func TestSyncWithNonDistributableBlob(t *testing.T) {
nonDistributableLayer := make([]byte, 10)
nonDistributableDigest := godigest.FromBytes(nonDistributableLayer)
nonDistributableLayerDesc := ispec.Descriptor{
MediaType: ispec.MediaTypeImageLayerNonDistributableGzip,
MediaType: ispec.MediaTypeImageLayerNonDistributableGzip, //nolint:staticcheck
Digest: nonDistributableDigest,
Size: int64(len(nonDistributableLayer)),
URLs: []string{
@ -3018,7 +3033,7 @@ func TestPeriodicallySignaturesErr(t *testing.T) {
So(err, ShouldBeNil)
// read manifest
var artifactManifest ispec.Artifact
var artifactManifest ispec.Manifest
for _, ref := range referrers.Manifests {
refPath := path.Join(srcDir, repoName, "blobs", string(ref.Digest.Algorithm()), ref.Digest.Encoded())
body, err := os.ReadFile(refPath)
@ -3028,7 +3043,7 @@ func TestPeriodicallySignaturesErr(t *testing.T) {
So(err, ShouldBeNil)
// triggers perm denied on sig blobs
for _, blob := range artifactManifest.Blobs {
for _, blob := range artifactManifest.Layers {
blobPath := path.Join(srcDir, repoName, "blobs", string(blob.Digest.Algorithm()), blob.Digest.Encoded())
err := os.Chmod(blobPath, 0o000)
So(err, ShouldBeNil)
@ -3145,7 +3160,7 @@ func TestPeriodicallySignaturesErr(t *testing.T) {
Convey("of type OCI artifact", func() { //nolint: dupl
// read manifest
var artifactManifest ispec.Artifact
var artifactManifest ispec.Manifest
for _, ref := range referrers.Manifests {
refPath := path.Join(srcDir, repoName, "blobs", string(ref.Digest.Algorithm()), ref.Digest.Encoded())
body, err := os.ReadFile(refPath)
@ -3155,7 +3170,7 @@ func TestPeriodicallySignaturesErr(t *testing.T) {
So(err, ShouldBeNil)
// triggers perm denied on artifact blobs
for _, blob := range artifactManifest.Blobs {
for _, blob := range artifactManifest.Layers {
blobPath := path.Join(srcDir, repoName, "blobs", string(blob.Digest.Algorithm()), blob.Digest.Encoded())
err := os.Chmod(blobPath, 0o000)
So(err, ShouldBeNil)
@ -3349,7 +3364,7 @@ func TestSignatures(t *testing.T) {
err = os.RemoveAll(path.Join(destDir, repoName))
So(err, ShouldBeNil)
var artifactManifest ispec.Artifact
var artifactManifest ispec.Manifest
for _, ref := range referrers.Manifests {
refPath := path.Join(srcDir, repoName, "blobs", string(ref.Digest.Algorithm()), ref.Digest.Encoded())
body, err := os.ReadFile(refPath)
@ -3359,7 +3374,7 @@ func TestSignatures(t *testing.T) {
So(err, ShouldBeNil)
// triggers perm denied on notary sig blobs on downstream
for _, blob := range artifactManifest.Blobs {
for _, blob := range artifactManifest.Layers {
blobPath := path.Join(destDir, repoName, "blobs", string(blob.Digest.Algorithm()), blob.Digest.Encoded())
err := os.MkdirAll(blobPath, 0o755)
So(err, ShouldBeNil)
@ -3392,7 +3407,7 @@ func TestSignatures(t *testing.T) {
So(resp.StatusCode(), ShouldEqual, http.StatusOK)
// triggers perm denied on sig blobs
for _, blob := range artifactManifest.Blobs {
for _, blob := range artifactManifest.Layers {
blobPath := path.Join(srcDir, repoName, "blobs", string(blob.Digest.Algorithm()), blob.Digest.Encoded())
err := os.Chmod(blobPath, 0o000)
So(err, ShouldBeNil)
@ -5390,331 +5405,6 @@ func TestSyncImageIndex(t *testing.T) {
})
}
func TestSyncOCIArtifactsWithTag(t *testing.T) {
Convey("Verify syncing tagged OCI artifacts", t, func() {
updateDuration, _ := time.ParseDuration("10s")
sctlr, srcBaseURL, _, _, _ := makeUpstreamServer(t, false, false)
scm := test.NewControllerManager(sctlr)
scm.StartAndWait(sctlr.Config.HTTP.Port)
defer scm.StopServer()
regex := ".*"
var semver bool
tlsVerify := false
repoName := "artifact"
syncRegistryConfig := syncconf.RegistryConfig{
Content: []syncconf.Content{
{
Prefix: repoName,
Tags: &syncconf.Tags{
Regex: &regex,
Semver: &semver,
},
},
},
URLs: []string{srcBaseURL},
OnDemand: false,
PollInterval: updateDuration,
TLSVerify: &tlsVerify,
}
defaultVal := true
syncConfig := &syncconf.Config{
Enable: &defaultVal,
Registries: []syncconf.RegistryConfig{syncRegistryConfig},
}
// create artifact blob
buf := []byte("this is an artifact")
digest := pushBlob(srcBaseURL, repoName, buf)
// create artifact config blob
cbuf := []byte("{}")
cdigest := pushBlob(srcBaseURL, repoName, cbuf)
// push a referrer artifact
manifest := ispec.Manifest{
MediaType: ispec.MediaTypeImageManifest,
Config: ispec.Descriptor{
MediaType: "application/vnd.cncf.icecream",
Digest: cdigest,
Size: int64(len(cbuf)),
},
Layers: []ispec.Descriptor{
{
MediaType: "application/octet-stream",
Digest: digest,
Size: int64(len(buf)),
},
},
}
artifactManifest := ispec.Artifact{
MediaType: ispec.MediaTypeArtifactManifest,
ArtifactType: "application/vnd.cncf.icecream",
Blobs: []ispec.Descriptor{
{
MediaType: "application/octet-stream",
Digest: digest,
Size: int64(len(buf)),
},
},
}
manifest.SchemaVersion = 2
content, err := json.Marshal(manifest)
So(err, ShouldBeNil)
// put OCI artifact mediatype oci image
_, err = resty.R().SetHeader("Content-Type", ispec.MediaTypeImageManifest).
SetBody(content).Put(srcBaseURL + fmt.Sprintf("/v2/%s/manifests/%s", repoName, "1.0"))
So(err, ShouldBeNil)
content, err = json.Marshal(artifactManifest)
So(err, ShouldBeNil)
artifactDigest := godigest.FromBytes(content)
// put OCI artifact mediatype artifact
_, err = resty.R().SetHeader("Content-Type", ispec.MediaTypeArtifactManifest).
SetBody(content).Put(srcBaseURL + fmt.Sprintf("/v2/%s/manifests/%s", repoName, "2.0"))
So(err, ShouldBeNil)
Convey("sync periodically", func() {
// start downstream server
dctlr, destBaseURL, _, _ := makeDownstreamServer(t, false, syncConfig)
dcm := test.NewControllerManager(dctlr)
dcm.StartAndWait(dctlr.Config.HTTP.Port)
defer dcm.StopServer()
// give it time to set up sync
t.Logf("waitsync(%s, %s)", dctlr.Config.Storage.RootDirectory, repoName)
waitSync(dctlr.Config.Storage.RootDirectory, repoName)
resp, err := resty.R().SetHeader("Content-Type", ispec.MediaTypeImageManifest).
Get(destBaseURL + fmt.Sprintf("/v2/%s/manifests/%s", repoName, "1.0"))
So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusOK)
So(resp.Body(), ShouldNotBeEmpty)
So(resp.Header().Get("Content-Type"), ShouldNotBeEmpty)
var syncedManifest ispec.Manifest
err = json.Unmarshal(resp.Body(), &syncedManifest)
So(err, ShouldBeNil)
So(reflect.DeepEqual(syncedManifest, manifest), ShouldEqual, true)
resp, err = resty.R().SetHeader("Content-Type", ispec.MediaTypeArtifactManifest).
Get(destBaseURL + fmt.Sprintf("/v2/%s/manifests/%s", repoName, "2.0"))
So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusOK)
So(resp.Body(), ShouldNotBeEmpty)
So(resp.Header().Get("Content-Type"), ShouldNotBeEmpty)
var syncedArtifact ispec.Artifact
err = json.Unmarshal(resp.Body(), &syncedArtifact)
So(err, ShouldBeNil)
So(reflect.DeepEqual(syncedArtifact, artifactManifest), ShouldEqual, true)
// for coverage
found, err := test.ReadLogFileAndSearchString(dctlr.Config.Log.Output,
"skipping OCI artifact", 15*time.Second)
if err != nil {
panic(err)
}
if !found {
data, err := os.ReadFile(dctlr.Config.Log.Output)
So(err, ShouldBeNil)
t.Logf("downstream log: %s", string(data))
}
So(found, ShouldBeTrue)
waitSyncFinish(dctlr.Config.Log.Output)
})
Convey("sync on demand", func() {
// start downstream server
syncConfig.Registries[0].OnDemand = true
syncConfig.Registries[0].PollInterval = 0
dctlr, destBaseURL, _, _ := makeDownstreamServer(t, false, syncConfig)
dcm := test.NewControllerManager(dctlr)
dcm.StartAndWait(dctlr.Config.HTTP.Port)
defer dcm.StopServer()
resp, err := resty.R().SetHeader("Content-Type", ispec.MediaTypeArtifactManifest).
Get(destBaseURL + fmt.Sprintf("/v2/%s/manifests/%s", repoName, "2.0"))
So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusOK)
So(resp.Body(), ShouldNotBeEmpty)
So(resp.Header().Get("Content-Type"), ShouldNotBeEmpty)
var syncedArtifact ispec.Artifact
err = json.Unmarshal(resp.Body(), &syncedArtifact)
So(err, ShouldBeNil)
So(reflect.DeepEqual(syncedArtifact, artifactManifest), ShouldEqual, true)
resp, err = resty.R().SetHeader("Content-Type", ispec.MediaTypeImageManifest).
Get(destBaseURL + fmt.Sprintf("/v2/%s/manifests/%s", repoName, "1.0"))
So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusOK)
So(resp.Body(), ShouldNotBeEmpty)
So(resp.Header().Get("Content-Type"), ShouldNotBeEmpty)
var syncedManifest ispec.Manifest
err = json.Unmarshal(resp.Body(), &syncedManifest)
So(err, ShouldBeNil)
So(reflect.DeepEqual(syncedManifest, manifest), ShouldEqual, true)
})
Convey("sync periodically error on mediatype", func() {
manifestPath := path.Join(sctlr.Config.Storage.RootDirectory, repoName, "blobs", "sha256", artifactDigest.Encoded())
So(os.Chmod(manifestPath, 0o000), ShouldBeNil)
// start downstream server
dctlr, destBaseURL, _, _ := makeDownstreamServer(t, false, syncConfig)
dcm := test.NewControllerManager(dctlr)
dcm.StartAndWait(dctlr.Config.HTTP.Port)
defer dcm.StopServer()
defer func() {
err := os.Chmod(manifestPath, 0o755)
So(err, ShouldBeNil)
}()
found, err := test.ReadLogFileAndSearchString(dctlr.Config.Log.Output,
"finished syncing", 15*time.Second)
if err != nil {
panic(err)
}
if !found {
data, err := os.ReadFile(dctlr.Config.Log.Output)
So(err, ShouldBeNil)
t.Logf("downstream log: %s", string(data))
}
So(found, ShouldBeTrue)
resp, err := resty.R().SetHeader("Content-Type", ispec.MediaTypeArtifactManifest).
Get(destBaseURL + fmt.Sprintf("/v2/%s/manifests/%s", repoName, artifactDigest.String()))
So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusNotFound)
found, err = test.ReadLogFileAndSearchString(dctlr.Config.Log.Output,
"couldn't get upstream image", 5*time.Second)
if err != nil {
panic(err)
}
if !found {
data, err := os.ReadFile(dctlr.Config.Log.Output)
So(err, ShouldBeNil)
t.Logf("downstream log: %s", string(data))
}
So(found, ShouldBeTrue)
})
Convey("sync on demand error on mediatype", func() {
// start downstream server
syncConfig.Registries[0].OnDemand = true
syncConfig.Registries[0].PollInterval = 0
dctlr, destBaseURL, _, _ := makeDownstreamServer(t, false, syncConfig)
dcm := test.NewControllerManager(dctlr)
dcm.StartAndWait(dctlr.Config.HTTP.Port)
defer dcm.StopServer()
manifestPath := path.Join(sctlr.Config.Storage.RootDirectory, repoName, "blobs", "sha256", artifactDigest.Encoded())
So(os.Chmod(manifestPath, 0o000), ShouldBeNil)
defer func() {
err := os.Chmod(manifestPath, 0o755)
So(err, ShouldBeNil)
}()
resp, err := resty.R().SetHeader("Content-Type", ispec.MediaTypeArtifactManifest).
Get(destBaseURL + fmt.Sprintf("/v2/%s/manifests/%s", repoName, artifactDigest.String()))
So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusNotFound)
})
Convey("sync on demand and periodically error on PutImageManifest", func() {
// start downstream server
syncConfig.Registries[0].OnDemand = true
destDir := t.TempDir()
destConfig := config.New()
destConfig.HTTP.Port = test.GetFreePort()
destBaseURL := test.GetBaseURL(destConfig.HTTP.Port)
destConfig.Storage.RootDirectory = destDir
destConfig.Extensions = &extconf.ExtensionConfig{}
destConfig.Extensions.Search = nil
destConfig.Extensions.Sync = syncConfig
destConfig.Log.Output = path.Join(destDir, "sync.log")
dctlr := api.NewController(destConfig)
dcm := test.NewControllerManager(dctlr)
manifestPath := path.Join(destDir, repoName, "blobs", "sha256", artifactDigest.Encoded())
So(os.MkdirAll(manifestPath, 0o755), ShouldBeNil)
So(os.Chmod(manifestPath, 0o000), ShouldBeNil)
dcm.StartAndWait(destConfig.HTTP.Port)
defer dcm.StopServer()
defer func() {
err := os.Chmod(manifestPath, 0o755)
So(err, ShouldBeNil)
}()
found, err := test.ReadLogFileAndSearchString(dctlr.Config.Log.Output,
"couldn't upload OCI artifact manifest", 15*time.Second)
if err != nil {
panic(err)
}
if !found {
data, err := os.ReadFile(dctlr.Config.Log.Output)
So(err, ShouldBeNil)
t.Logf("downstream log: %s", string(data))
}
So(found, ShouldBeTrue)
resp, err := resty.R().SetHeader("Content-Type", ispec.MediaTypeArtifactManifest).
Get(destBaseURL + fmt.Sprintf("/v2/%s/manifests/%s", repoName, artifactDigest.String()))
So(err, ShouldBeNil)
So(resp.StatusCode(), ShouldEqual, http.StatusNotFound)
waitSyncFinish(dctlr.Config.Log.Output)
})
})
}
func generateKeyPairs(tdir string) {
// generate a keypair
os.Setenv("COSIGN_PASSWORD", "")
@ -5817,6 +5507,35 @@ func pushRepo(url, repoName string) godigest.Digest {
panic(err)
}
// upload scratch image config
resp, err = resty.R().
Post(fmt.Sprintf("%s/v2/%s/blobs/uploads/", url, repoName))
if err != nil {
panic(err)
}
if resp.StatusCode() != http.StatusAccepted {
panic(fmt.Errorf("invalid status code: %d %w", resp.StatusCode(), errBadStatus))
}
loc = test.Location(url, resp)
cblob, cdigest := ispec.ScratchDescriptor.Data, ispec.ScratchDescriptor.Digest
resp, err = resty.R().
SetContentLength(true).
SetHeader("Content-Length", fmt.Sprintf("%d", len(cblob))).
SetHeader("Content-Type", "application/octet-stream").
SetQueryParam("digest", cdigest.String()).
SetBody(cblob).
Put(loc)
if err != nil {
panic(err)
}
if resp.StatusCode() != http.StatusCreated {
panic(fmt.Errorf("invalid status code: %d %w", resp.StatusCode(), errBadStatus))
}
// upload image config blob
resp, err = resty.R().
Post(fmt.Sprintf("%s/v2/%s/blobs/uploads/", url, repoName))
@ -5829,7 +5548,7 @@ func pushRepo(url, repoName string) godigest.Digest {
}
loc = test.Location(url, resp)
cblob, cdigest := test.GetRandomImageConfig()
cblob, cdigest = test.GetRandomImageConfig()
resp, err = resty.R().
SetContentLength(true).
@ -5907,10 +5626,15 @@ func pushRepo(url, repoName string) godigest.Digest {
},
}
artifactManifest := ispec.Artifact{
MediaType: ispec.MediaTypeArtifactManifest,
artifactManifest := ispec.Manifest{
MediaType: ispec.MediaTypeImageManifest,
ArtifactType: "application/vnd.cncf.icecream",
Blobs: []ispec.Descriptor{
Config: ispec.Descriptor{
MediaType: ispec.MediaTypeScratch,
Digest: ispec.ScratchDescriptor.Digest,
Size: 2,
},
Layers: []ispec.Descriptor{
{
MediaType: "application/octet-stream",
Digest: adigest,
@ -5948,7 +5672,7 @@ func pushRepo(url, repoName string) godigest.Digest {
adigest = godigest.FromBytes(content)
// put OCI reference artifact mediaType artifact
_, err = resty.R().SetHeader("Content-Type", ispec.MediaTypeArtifactManifest).
_, err = resty.R().SetHeader("Content-Type", ispec.MediaTypeImageManifest).
SetBody(content).Put(url + fmt.Sprintf("/v2/%s/manifests/%s", repoName, adigest.String()))
if err != nil {
panic(err)

View file

@ -590,17 +590,6 @@ func manifestsEqual(manifest1, manifest2 ispec.Manifest) bool {
return false
}
func artifactsEqual(manifest1, manifest2 ispec.Artifact) bool {
if manifest1.ArtifactType == manifest2.ArtifactType &&
manifest1.MediaType == manifest2.MediaType {
if descriptorsEqual(manifest1.Blobs, manifest2.Blobs) {
return true
}
}
return false
}
func artifactDescriptorsEqual(desc1, desc2 []artifactspec.Descriptor) bool {
if len(desc1) != len(desc2) {
return false
@ -690,16 +679,6 @@ func syncImageWithRefs(ctx context.Context, localRepo, upstreamRepo, reference s
upstreamImageDigest := godigest.FromBytes(manifestBuf)
if !isSupportedMediaType(mediaType) {
if mediaType == ispec.MediaTypeArtifactManifest {
err = sig.syncOCIArtifact(localRepo, upstreamRepo, reference, manifestBuf) //nolint
if err != nil {
log.Error().Err(err).Str("image", upstreamImageRef.DockerReference().String()).
Msg("couldn't sync oci artifact with artifact mediaType")
return skipped, err
}
}
return skipped, nil
}

View file

@ -92,7 +92,7 @@ func GoroutineID() int {
type goroutineHook struct{}
func (h goroutineHook) Run(e *zerolog.Event, level zerolog.Level, msg string) {
func (h goroutineHook) Run(e *zerolog.Event, level zerolog.Level, _ string) {
if level != zerolog.NoLevel {
e.Int("goroutine", GoroutineID())
}

View file

@ -4,7 +4,6 @@ package bolt
const (
ManifestDataBucket = "ManifestData"
IndexDataBucket = "IndexData"
ArtifactDataBucket = "ArtifactData"
RepoMetadataBucket = "RepoMetadata"
UserDataBucket = "UserData"
VersionBucket = "Version"

View file

@ -10,7 +10,7 @@ import (
type DBDriverParameters struct {
Endpoint, Region, RepoMetaTablename, ManifestDataTablename, IndexDataTablename,
ArtifactDataTablename, VersionTablename, UserDataTablename string
VersionTablename, UserDataTablename string
}
func GetDynamoClient(params DBDriverParameters) (*dynamodb.Client, error) {

View file

@ -49,11 +49,6 @@ func NewBoltDBWrapper(boltDB *bbolt.DB, log log.Logger) (*DBWrapper, error) {
return err
}
_, err = transaction.CreateBucketIfNotExists([]byte(bolt.ArtifactDataBucket))
if err != nil {
return err
}
_, err = transaction.CreateBucketIfNotExists([]byte(bolt.RepoMetadataBucket))
if err != nil {
return err
@ -258,49 +253,6 @@ func (bdw *DBWrapper) GetIndexData(indexDigest godigest.Digest) (repodb.IndexDat
return indexMetadata, err
}
func (bdw DBWrapper) SetArtifactData(artifactDigest godigest.Digest, artifactData repodb.ArtifactData) error {
err := bdw.DB.Update(func(tx *bbolt.Tx) error {
buck := tx.Bucket([]byte(bolt.ArtifactDataBucket))
imBlob, err := json.Marshal(artifactData)
if err != nil {
return fmt.Errorf("repodb: error while calculating blob for artifact with digest %s %w", artifactDigest, err)
}
err = buck.Put([]byte(artifactDigest), imBlob)
if err != nil {
return fmt.Errorf("repodb: error while setting artifact blob for digest %s %w", artifactDigest, err)
}
return nil
})
return err
}
func (bdw DBWrapper) GetArtifactData(artifactDigest godigest.Digest) (repodb.ArtifactData, error) {
var artifactData repodb.ArtifactData
err := bdw.DB.View(func(tx *bbolt.Tx) error {
buck := tx.Bucket([]byte(bolt.ArtifactDataBucket))
blob := buck.Get([]byte(artifactDigest))
if len(blob) == 0 {
return zerr.ErrArtifactDataNotFound
}
err := json.Unmarshal(blob, &artifactData)
if err != nil {
return fmt.Errorf("repodb: error while unmashaling artifact data for digest %s %w", artifactDigest, err)
}
return nil
})
return artifactData, err
}
func (bdw DBWrapper) SetReferrer(repo string, referredDigest godigest.Digest, referrer repodb.ReferrerInfo) error {
err := bdw.DB.Update(func(tx *bbolt.Tx) error {
buck := tx.Bucket([]byte(bolt.RepoMetadataBucket))

View file

@ -91,18 +91,6 @@ func TestWrapperErrors(t *testing.T) {
So(err, ShouldNotBeNil)
})
Convey("GetArtifactData", func() {
err := boltdbWrapper.DB.Update(func(tx *bbolt.Tx) error {
artifactBuck := tx.Bucket([]byte(bolt.ArtifactDataBucket))
return artifactBuck.Put([]byte("artifactDigest"), []byte("wrong json"))
})
So(err, ShouldBeNil)
_, err = boltdbWrapper.GetArtifactData("artifactDigest")
So(err, ShouldNotBeNil)
})
Convey("SetReferrer", func() {
err := boltdbWrapper.DB.Update(func(tx *bbolt.Tx) error {
repoBuck := tx.Bucket([]byte(bolt.RepoMetadataBucket))

View file

@ -30,7 +30,6 @@ func TestWrapperErrors(t *testing.T) {
repoMetaTablename := "RepoMetadataTable" + uuid.String()
manifestDataTablename := "ManifestDataTable" + uuid.String()
indexDataTablename := "IndexDataTable" + uuid.String()
artifactDataTablename := "ArtifactDataTable" + uuid.String()
userDataTablename := "UserDataTable" + uuid.String()
versionTablename := "Version" + uuid.String()
@ -57,7 +56,6 @@ func TestWrapperErrors(t *testing.T) {
RepoMetaTablename: repoMetaTablename,
ManifestDataTablename: manifestDataTablename,
IndexDataTablename: indexDataTablename,
ArtifactDataTablename: artifactDataTablename,
VersionTablename: versionTablename,
UserDataTablename: userDataTablename,
Patches: version.GetDynamoDBPatches(),
@ -99,7 +97,6 @@ func TestWrapperErrors(t *testing.T) {
ManifestDataTablename: manifestDataTablename,
VersionTablename: versionTablename,
IndexDataTablename: indexDataTablename,
ArtifactDataTablename: artifactDataTablename,
UserDataTablename: userDataTablename,
Patches: version.GetDynamoDBPatches(),
Log: log.Logger{Logger: zerolog.New(os.Stdout)},

View file

@ -42,7 +42,6 @@ func TestIterator(t *testing.T) {
manifestDataTablename := "ManifestDataTable" + uuid.String()
versionTablename := "Version" + uuid.String()
indexDataTablename := "IndexDataTable" + uuid.String()
artifactDataTablename := "ArtifactDataTable" + uuid.String()
userDataTablename := "UserDataTable" + uuid.String()
log := log.NewLogger("debug", "")
@ -54,7 +53,6 @@ func TestIterator(t *testing.T) {
RepoMetaTablename: repoMetaTablename,
ManifestDataTablename: manifestDataTablename,
IndexDataTablename: indexDataTablename,
ArtifactDataTablename: artifactDataTablename,
VersionTablename: versionTablename,
UserDataTablename: userDataTablename,
}
@ -145,7 +143,6 @@ func TestWrapperErrors(t *testing.T) {
manifestDataTablename := "ManifestDataTable" + uuid.String()
versionTablename := "Version" + uuid.String()
indexDataTablename := "IndexDataTable" + uuid.String()
artifactDataTablename := "ArtifactData" + uuid.String()
userDataTablename := "UserDataTable" + uuid.String()
ctx := context.Background()
@ -159,7 +156,6 @@ func TestWrapperErrors(t *testing.T) {
RepoMetaTablename: repoMetaTablename,
ManifestDataTablename: manifestDataTablename,
IndexDataTablename: indexDataTablename,
ArtifactDataTablename: artifactDataTablename,
UserDataTablename: userDataTablename,
VersionTablename: versionTablename,
}
@ -417,20 +413,6 @@ func TestWrapperErrors(t *testing.T) {
So(err, ShouldNotBeNil)
})
Convey("GetArtifactData", func() {
dynamoWrapper.ArtifactDataTablename = badTablename
_, err = dynamoWrapper.GetArtifactData("dig")
So(err, ShouldNotBeNil)
})
Convey("GetArtifactData unmarhsal error", func() {
err = setBadArtifactData(dynamoWrapper.Client, artifactDataTablename, "dig")
So(err, ShouldBeNil)
_, err = dynamoWrapper.GetArtifactData("dig")
So(err, ShouldNotBeNil)
})
Convey("SetRepoReference client error", func() {
dynamoWrapper.RepoMetaTablename = badTablename
digest := digest.FromString("str")
@ -488,7 +470,6 @@ func TestWrapperErrors(t *testing.T) {
Convey("GetReferrersInfo getData fails", func() {
dynamoWrapper.ManifestDataTablename = badTablename
dynamoWrapper.ArtifactDataTablename = badTablename
err = dynamoWrapper.SetReferrer("repo", "rf", repodb.ReferrerInfo{
Digest: "dig1",
MediaType: ispec.MediaTypeImageManifest,
@ -497,7 +478,7 @@ func TestWrapperErrors(t *testing.T) {
err = dynamoWrapper.SetReferrer("repo", "rf", repodb.ReferrerInfo{
Digest: "dig2",
MediaType: ispec.MediaTypeArtifactManifest,
MediaType: ispec.MediaTypeImageManifest,
})
So(err, ShouldBeNil)
@ -506,11 +487,6 @@ func TestWrapperErrors(t *testing.T) {
})
Convey("GetReferrersInfo bad descriptor blob", func() {
err = dynamoWrapper.SetArtifactData("dig2", repodb.ArtifactData{
ManifestBlob: []byte("bad json"),
})
So(err, ShouldBeNil)
err = dynamoWrapper.SetManifestData("dig3", repodb.ManifestData{
ManifestBlob: []byte("bad json"),
})
@ -518,7 +494,7 @@ func TestWrapperErrors(t *testing.T) {
err = dynamoWrapper.SetReferrer("repo", "rf", repodb.ReferrerInfo{
Digest: "dig2",
MediaType: ispec.MediaTypeArtifactManifest,
MediaType: ispec.MediaTypeImageManifest,
})
So(err, ShouldBeNil)
@ -1095,7 +1071,6 @@ func TestWrapperErrors(t *testing.T) {
RepoMetaTablename: "",
ManifestDataTablename: manifestDataTablename,
IndexDataTablename: indexDataTablename,
ArtifactDataTablename: artifactDataTablename,
UserDataTablename: userDataTablename,
VersionTablename: versionTablename,
}
@ -1111,7 +1086,6 @@ func TestWrapperErrors(t *testing.T) {
RepoMetaTablename: repoMetaTablename,
ManifestDataTablename: "",
IndexDataTablename: indexDataTablename,
ArtifactDataTablename: artifactDataTablename,
UserDataTablename: userDataTablename,
VersionTablename: versionTablename,
}
@ -1127,7 +1101,6 @@ func TestWrapperErrors(t *testing.T) {
RepoMetaTablename: repoMetaTablename,
ManifestDataTablename: manifestDataTablename,
IndexDataTablename: "",
ArtifactDataTablename: artifactDataTablename,
UserDataTablename: userDataTablename,
VersionTablename: versionTablename,
}
@ -1143,7 +1116,6 @@ func TestWrapperErrors(t *testing.T) {
RepoMetaTablename: repoMetaTablename,
ManifestDataTablename: manifestDataTablename,
IndexDataTablename: indexDataTablename,
ArtifactDataTablename: artifactDataTablename,
UserDataTablename: userDataTablename,
VersionTablename: "",
}
@ -1159,41 +1131,8 @@ func TestWrapperErrors(t *testing.T) {
RepoMetaTablename: repoMetaTablename,
ManifestDataTablename: manifestDataTablename,
IndexDataTablename: indexDataTablename,
ArtifactDataTablename: "",
UserDataTablename: userDataTablename,
VersionTablename: versionTablename,
}
client, err = dynamo.GetDynamoClient(params)
So(err, ShouldBeNil)
_, err = dynamoWrapper.NewDynamoDBWrapper(client, params, log)
So(err, ShouldNotBeNil)
params = dynamo.DBDriverParameters{ //nolint:contextcheck
Endpoint: endpoint,
Region: region,
RepoMetaTablename: repoMetaTablename,
ManifestDataTablename: manifestDataTablename,
IndexDataTablename: indexDataTablename,
VersionTablename: versionTablename,
UserDataTablename: userDataTablename,
ArtifactDataTablename: artifactDataTablename,
}
client, err = dynamo.GetDynamoClient(params)
So(err, ShouldBeNil)
_, err = dynamoWrapper.NewDynamoDBWrapper(client, params, log)
So(err, ShouldBeNil)
params = dynamo.DBDriverParameters{ //nolint:contextcheck
Endpoint: endpoint,
Region: region,
RepoMetaTablename: repoMetaTablename,
ManifestDataTablename: manifestDataTablename,
IndexDataTablename: indexDataTablename,
VersionTablename: versionTablename,
UserDataTablename: "",
ArtifactDataTablename: artifactDataTablename,
VersionTablename: versionTablename,
}
client, err = dynamo.GetDynamoClient(params)
So(err, ShouldBeNil)
@ -1228,26 +1167,26 @@ func setBadManifestData(client *dynamodb.Client, manifestDataTableName, digest s
return err
}
func setBadArtifactData(client *dynamodb.Client, artifactDataTablename, digest string) error {
mdAttributeValue, err := attributevalue.Marshal("string")
func setBadRepoMeta(client *dynamodb.Client, repoMetadataTableName, repoName string) error {
repoAttributeValue, err := attributevalue.Marshal("string")
if err != nil {
return err
}
_, err = client.UpdateItem(context.TODO(), &dynamodb.UpdateItemInput{
ExpressionAttributeNames: map[string]string{
"#AD": "ArtifactData",
"#RM": "RepoMetadata",
},
ExpressionAttributeValues: map[string]types.AttributeValue{
":ArtifactData": mdAttributeValue,
":RepoMetadata": repoAttributeValue,
},
Key: map[string]types.AttributeValue{
"ArtifactDigest": &types.AttributeValueMemberS{
Value: digest,
"RepoName": &types.AttributeValueMemberS{
Value: repoName,
},
},
TableName: aws.String(artifactDataTablename),
UpdateExpression: aws.String("SET #AD = :ArtifactData"),
TableName: aws.String(repoMetadataTableName),
UpdateExpression: aws.String("SET #RM = :RepoMetadata"),
})
return err
@ -1278,31 +1217,6 @@ func setBadIndexData(client *dynamodb.Client, indexDataTableName, digest string)
return err
}
func setBadRepoMeta(client *dynamodb.Client, repoMetadataTableName, repoName string) error {
repoAttributeValue, err := attributevalue.Marshal("string")
if err != nil {
return err
}
_, err = client.UpdateItem(context.TODO(), &dynamodb.UpdateItemInput{
ExpressionAttributeNames: map[string]string{
"#RM": "RepoMetadata",
},
ExpressionAttributeValues: map[string]types.AttributeValue{
":RepoMetadata": repoAttributeValue,
},
Key: map[string]types.AttributeValue{
"RepoName": &types.AttributeValueMemberS{
Value: repoName,
},
},
TableName: aws.String(repoMetadataTableName),
UpdateExpression: aws.String("SET #RM = :RepoMetadata"),
})
return err
}
func setBadUserData(client *dynamodb.Client, userDataTablename, userID string) error {
userAttributeValue, err := attributevalue.Marshal("string")
if err != nil {

View file

@ -32,7 +32,6 @@ type DBWrapper struct {
RepoMetaTablename string
IndexDataTablename string
ManifestDataTablename string
ArtifactDataTablename string
UserDataTablename string
VersionTablename string
Patches []func(client *dynamodb.Client, tableNames map[string]string) error
@ -45,7 +44,6 @@ func NewDynamoDBWrapper(client *dynamodb.Client, params dynamo.DBDriverParameter
RepoMetaTablename: params.RepoMetaTablename,
ManifestDataTablename: params.ManifestDataTablename,
IndexDataTablename: params.IndexDataTablename,
ArtifactDataTablename: params.ArtifactDataTablename,
VersionTablename: params.VersionTablename,
UserDataTablename: params.UserDataTablename,
Patches: version.GetDynamoDBPatches(),
@ -67,11 +65,6 @@ func NewDynamoDBWrapper(client *dynamodb.Client, params dynamo.DBDriverParameter
return nil, err
}
err = dynamoWrapper.createArtifactDataTable()
if err != nil {
return nil, err
}
err = dynamoWrapper.createIndexDataTable()
if err != nil {
return nil, err
@ -301,58 +294,6 @@ func (dwr *DBWrapper) GetIndexData(indexDigest godigest.Digest) (repodb.IndexDat
return indexData, nil
}
func (dwr DBWrapper) SetArtifactData(artifactDigest godigest.Digest, artifactData repodb.ArtifactData) error {
artifactAttributeValue, err := attributevalue.Marshal(artifactData)
if err != nil {
return err
}
_, err = dwr.Client.UpdateItem(context.TODO(), &dynamodb.UpdateItemInput{
ExpressionAttributeNames: map[string]string{
"#AD": "ArtifactData",
},
ExpressionAttributeValues: map[string]types.AttributeValue{
":ArtifactData": artifactAttributeValue,
},
Key: map[string]types.AttributeValue{
"ArtifactDigest": &types.AttributeValueMemberS{
Value: artifactDigest.String(),
},
},
TableName: aws.String(dwr.ArtifactDataTablename),
UpdateExpression: aws.String("SET #AD = :ArtifactData"),
})
return err
}
func (dwr DBWrapper) GetArtifactData(artifactDigest godigest.Digest) (repodb.ArtifactData, error) {
resp, err := dwr.Client.GetItem(context.TODO(), &dynamodb.GetItemInput{
TableName: aws.String(dwr.ArtifactDataTablename),
Key: map[string]types.AttributeValue{
"ArtifactDigest": &types.AttributeValueMemberS{
Value: artifactDigest.String(),
},
},
})
if err != nil {
return repodb.ArtifactData{}, err
}
if resp.Item == nil {
return repodb.ArtifactData{}, zerr.ErrRepoMetaNotFound
}
var artifactData repodb.ArtifactData
err = attributevalue.Unmarshal(resp.Item["ArtifactData"], &artifactData)
if err != nil {
return repodb.ArtifactData{}, err
}
return artifactData, nil
}
func (dwr DBWrapper) SetReferrer(repo string, referredDigest godigest.Digest, referrer repodb.ReferrerInfo) error {
resp, err := dwr.Client.GetItem(context.TODO(), &dynamodb.GetItemInput{
TableName: aws.String(dwr.RepoMetaTablename),
@ -1664,31 +1605,6 @@ func (dwr *DBWrapper) createIndexDataTable() error {
return dwr.waitTableToBeCreated(dwr.IndexDataTablename)
}
func (dwr DBWrapper) createArtifactDataTable() error {
_, err := dwr.Client.CreateTable(context.Background(), &dynamodb.CreateTableInput{
TableName: aws.String(dwr.ArtifactDataTablename),
AttributeDefinitions: []types.AttributeDefinition{
{
AttributeName: aws.String("ArtifactDigest"),
AttributeType: types.ScalarAttributeTypeS,
},
},
KeySchema: []types.KeySchemaElement{
{
AttributeName: aws.String("ArtifactDigest"),
KeyType: types.KeyTypeHash,
},
},
BillingMode: types.BillingModePayPerRequest,
})
if err != nil && !strings.Contains(err.Error(), "Table already exists") {
return err
}
return dwr.waitTableToBeCreated(dwr.ManifestDataTablename)
}
func (dwr *DBWrapper) createVersionTable() error {
_, err := dwr.Client.CreateTable(context.Background(), &dynamodb.CreateTableInput{
TableName: aws.String(dwr.VersionTablename),

View file

@ -77,12 +77,6 @@ type RepoDB interface { //nolint:interfacebloat
// GetIndexData returns indexData for a given Index from the database
GetIndexData(indexDigest godigest.Digest) (IndexData, error)
// SetArtifactData sets artifactData for a given artifact in the database
SetArtifactData(artifactDigest godigest.Digest, artifactData ArtifactData) error
// GetArtifactData returns artifactData for a given artifact from the database
GetArtifactData(artifactDigest godigest.Digest) (ArtifactData, error)
// SetReferrer adds a referrer to the referrers list of a manifest inside a repo
SetReferrer(repo string, referredDigest godigest.Digest, referrer ReferrerInfo) error
@ -150,10 +144,6 @@ type ManifestData struct {
ConfigBlob []byte
}
type ArtifactData struct {
ManifestBlob []byte
}
type ReferrerInfo struct {
Digest string
MediaType string

View file

@ -87,7 +87,6 @@ func TestDynamoDBWrapper(t *testing.T) {
manifestDataTablename := "ManifestDataTable" + uuid.String()
versionTablename := "Version" + uuid.String()
indexDataTablename := "IndexDataTable" + uuid.String()
artifactDataTablename := "ArtifactDataTable" + uuid.String()
userDataTablename := "UserDataTable" + uuid.String()
Convey("DynamoDB Wrapper", t, func() {
@ -96,7 +95,6 @@ func TestDynamoDBWrapper(t *testing.T) {
RepoMetaTablename: repoMetaTablename,
ManifestDataTablename: manifestDataTablename,
IndexDataTablename: indexDataTablename,
ArtifactDataTablename: artifactDataTablename,
VersionTablename: versionTablename,
UserDataTablename: userDataTablename,
Region: "us-east-2",
@ -2174,27 +2172,6 @@ func RunRepoDBTests(repoDB repodb.RepoDB, preparationFuncs ...func() error) {
So(err, ShouldNotBeNil)
})
Convey("Test artifact logic", func() {
artifact, err := test.GetRandomArtifact(nil)
So(err, ShouldBeNil)
artifactDigest, err := artifact.Digest()
So(err, ShouldBeNil)
artifactData, err := artifact.ArtifactData()
So(err, ShouldBeNil)
err = repoDB.SetArtifactData(artifactDigest, artifactData)
So(err, ShouldBeNil)
result, err := repoDB.GetArtifactData(artifactDigest)
So(err, ShouldBeNil)
So(result, ShouldResemble, artifactData)
_, err = repoDB.GetArtifactData(godigest.FromString("inexistent"))
So(err, ShouldNotBeNil)
})
Convey("Test Referrers", func() {
image, err := test.GetRandomImage("tag")
So(err, ShouldBeNil)
@ -2221,10 +2198,10 @@ func RunRepoDBTests(repoDB repodb.RepoDB, preparationFuncs ...func() error) {
// ------- Add Artifact 1
artifact1, err := test.GetRandomArtifact(&ispec.Descriptor{
Digest: referredDigest,
MediaType: ispec.MediaTypeImageManifest,
})
artifact1, err := test.GetImageWithSubject(
referredDigest,
ispec.MediaTypeImageManifest,
)
So(err, ShouldBeNil)
artifactDigest1, err := artifact1.Digest()
@ -2238,10 +2215,10 @@ func RunRepoDBTests(repoDB repodb.RepoDB, preparationFuncs ...func() error) {
// ------- Add Artifact 2
artifact2, err := test.GetRandomArtifact(&ispec.Descriptor{
Digest: referredDigest,
MediaType: ispec.MediaTypeImageManifest,
})
artifact2, err := test.GetImageWithSubject(
referredDigest,
ispec.MediaTypeImageManifest,
)
So(err, ShouldBeNil)
artifactDigest2, err := artifact2.Digest()
@ -2249,7 +2226,7 @@ func RunRepoDBTests(repoDB repodb.RepoDB, preparationFuncs ...func() error) {
err = repoDB.SetReferrer("repo", referredDigest, repodb.ReferrerInfo{
Digest: artifactDigest2.String(),
MediaType: ispec.MediaTypeArtifactManifest,
MediaType: ispec.MediaTypeImageManifest,
})
So(err, ShouldBeNil)
@ -2263,7 +2240,7 @@ func RunRepoDBTests(repoDB repodb.RepoDB, preparationFuncs ...func() error) {
})
So(referrers, ShouldContain, repodb.ReferrerInfo{
Digest: artifactDigest2.String(),
MediaType: ispec.MediaTypeArtifactManifest,
MediaType: ispec.MediaTypeImageManifest,
})
So(err, ShouldBeNil)
@ -2333,12 +2310,6 @@ func RunRepoDBTests(repoDB repodb.RepoDB, preparationFuncs ...func() error) {
})
So(err, ShouldBeNil)
err = repoDB.SetReferrer("repo", referredDigest, repodb.ReferrerInfo{
Digest: "inexistendArtifactManifestDigest",
MediaType: ispec.MediaTypeArtifactManifest,
})
So(err, ShouldBeNil)
// ------- Set existent manifest and artifact manifest
err = repoDB.SetManifestData("goodManifest", repodb.ManifestData{
ManifestBlob: []byte(`{"artifactType": "unwantedType"}`),
@ -2347,20 +2318,15 @@ func RunRepoDBTests(repoDB repodb.RepoDB, preparationFuncs ...func() error) {
So(err, ShouldBeNil)
err = repoDB.SetReferrer("repo", referredDigest, repodb.ReferrerInfo{
Digest: "goodManifest",
Digest: "goodManifestUnwanted",
MediaType: ispec.MediaTypeImageManifest,
ArtifactType: "unwantedType",
})
So(err, ShouldBeNil)
err = repoDB.SetArtifactData("goodArtifact", repodb.ArtifactData{
ManifestBlob: []byte(`{"artifactType": "wantedType"}`),
})
So(err, ShouldBeNil)
err = repoDB.SetReferrer("repo", referredDigest, repodb.ReferrerInfo{
Digest: "goodArtifact",
MediaType: ispec.MediaTypeArtifactManifest,
Digest: "goodManifest",
MediaType: ispec.MediaTypeImageManifest,
ArtifactType: "wantedType",
})
So(err, ShouldBeNil)
@ -2369,7 +2335,7 @@ func RunRepoDBTests(repoDB repodb.RepoDB, preparationFuncs ...func() error) {
So(err, ShouldBeNil)
So(len(referrerInfo), ShouldEqual, 1)
So(referrerInfo[0].ArtifactType, ShouldResemble, "wantedType")
So(referrerInfo[0].Digest, ShouldResemble, "goodArtifact")
So(referrerInfo[0].Digest, ShouldResemble, "goodManifest")
})
Convey("FilterRepos", func() {

View file

@ -89,9 +89,6 @@ func getDynamoParams(cacheDriverConfig map[string]interface{}, log log.Logger) d
indexDataTablename, ok := toStringIfOk(cacheDriverConfig, "indexdatatablename", log)
allParametersOk = allParametersOk && ok
artifactDataTablename, ok := toStringIfOk(cacheDriverConfig, "artifactdatatablename", log)
allParametersOk = allParametersOk && ok
versionTablename, ok := toStringIfOk(cacheDriverConfig, "versiontablename", log)
allParametersOk = allParametersOk && ok
@ -108,7 +105,6 @@ func getDynamoParams(cacheDriverConfig map[string]interface{}, log log.Logger) d
RepoMetaTablename: repoMetaTablename,
ManifestDataTablename: manifestDataTablename,
IndexDataTablename: indexDataTablename,
ArtifactDataTablename: artifactDataTablename,
UserDataTablename: userDataTablename,
VersionTablename: versionTablename,
}

View file

@ -22,7 +22,6 @@ func TestCreateDynamo(t *testing.T) {
RepoMetaTablename: "RepoMetadataTable",
ManifestDataTablename: "ManifestDataTable",
IndexDataTablename: "IndexDataTable",
ArtifactDataTablename: "ArtifactDataTable",
UserDataTablename: "UserDataTable",
VersionTablename: "Version",
Region: "us-east-2",

View file

@ -9,6 +9,7 @@ import (
ispec "github.com/opencontainers/image-spec/specs-go/v1"
zerr "zotregistry.io/zot/errors"
zcommon "zotregistry.io/zot/pkg/common"
"zotregistry.io/zot/pkg/log"
"zotregistry.io/zot/pkg/storage"
)
@ -263,13 +264,6 @@ func NewIndexData(repoName string, indexBlob []byte, imageStore storage.ImageSto
return indexData
}
func NewArtifactData(repo string, descriptorBlob []byte, imageStore storage.ImageStore,
) ArtifactData {
return ArtifactData{
ManifestBlob: descriptorBlob,
}
}
// SetMetadataFromInput tries to set manifest metadata and update repo metadata by adding the current tag
// (in case the reference is a tag). The function expects image manifests and indexes (multi arch images).
func SetMetadataFromInput(repo, reference, mediaType string, digest godigest.Digest, descriptorBlob []byte,
@ -295,15 +289,6 @@ func SetMetadataFromInput(repo, reference, mediaType string, digest godigest.Dig
if err != nil {
log.Error().Err(err).Msg("repodb: error while putting index data")
return err
}
case ispec.MediaTypeArtifactManifest:
artifactData := NewArtifactData(repo, descriptorBlob, imageStore)
err := repoDB.SetArtifactData(digest, artifactData)
if err != nil {
log.Error().Err(err).Msg("repodb: error while putting artifact data")
return err
}
}
@ -335,43 +320,22 @@ func GetReferredSubject(descriptorBlob []byte, referrerDigest, mediaType string,
referrerSubject *ispec.Descriptor
)
switch mediaType {
case ispec.MediaTypeImageManifest:
var manifestContent ispec.Manifest
var manifestContent ispec.Manifest
err := json.Unmarshal(descriptorBlob, &manifestContent)
if err != nil {
return "", referrerInfo, false,
fmt.Errorf("repodb: can't unmarhsal manifest for digest %s: %w", referrerDigest, err)
}
err := json.Unmarshal(descriptorBlob, &manifestContent)
if err != nil {
return "", referrerInfo, false,
fmt.Errorf("repodb: can't unmarshal manifest for digest %s: %w", referrerDigest, err)
}
referrerSubject = manifestContent.Subject
referrerSubject = manifestContent.Subject
referrerInfo = ReferrerInfo{
Digest: referrerDigest,
MediaType: mediaType,
ArtifactType: manifestContent.Config.MediaType,
Size: len(descriptorBlob),
Annotations: manifestContent.Annotations,
}
case ispec.MediaTypeArtifactManifest:
manifestContent := ispec.Artifact{}
err := json.Unmarshal(descriptorBlob, &manifestContent)
if err != nil {
return "", referrerInfo, false,
fmt.Errorf("repodb: can't unmarhsal artifact manifest for digest %s: %w", referrerDigest, err)
}
referrerSubject = manifestContent.Subject
referrerInfo = ReferrerInfo{
Digest: referrerDigest,
MediaType: manifestContent.MediaType,
ArtifactType: manifestContent.ArtifactType,
Size: len(descriptorBlob),
Annotations: manifestContent.Annotations,
}
referrerInfo = ReferrerInfo{
Digest: referrerDigest,
MediaType: mediaType,
ArtifactType: zcommon.GetManifestArtifactType(manifestContent),
Size: len(descriptorBlob),
Annotations: manifestContent.Annotations,
}
if referrerSubject == nil || referrerSubject.Digest.String() == "" {

View file

@ -237,7 +237,7 @@ func TestParseStorageErrors(t *testing.T) {
})
Convey("CheckIsImageSignature -> is signature", func() {
manifestContent := ispec.Artifact{
manifestContent := ispec.Manifest{
Subject: &ispec.Descriptor{
Digest: "123",
},
@ -292,7 +292,6 @@ func TestParseStorageDynamoWrapper(t *testing.T) {
RepoMetaTablename: "RepoMetadataTable",
ManifestDataTablename: "ManifestDataTable",
IndexDataTablename: "IndexDataTable",
ArtifactDataTablename: "ArtifactDataTable",
UserDataTablename: "UserDataTable",
VersionTablename: "Version",
}
@ -515,10 +514,7 @@ func RunParseStorageTests(rootDir string, repoDB repodb.RepoDB) {
func TestGetReferredSubject(t *testing.T) {
Convey("GetReferredSubject error", t, func() {
_, _, _, err := repodb.GetReferredSubject([]byte("bad json"), "digest", ispec.MediaTypeArtifactManifest)
So(err, ShouldNotBeNil)
_, _, _, err = repodb.GetReferredSubject([]byte("bad json"), "digest", ispec.MediaTypeImageManifest)
_, _, _, err := repodb.GetReferredSubject([]byte("bad json"), "digest", ispec.MediaTypeImageManifest)
So(err, ShouldNotBeNil)
})
}

View file

@ -144,7 +144,7 @@ func OnDeleteManifest(repo, reference, mediaType string, digest godigest.Digest,
}
// OnDeleteManifest is called when a manifest is downloaded. It increments the download couter on that manifest.
func OnGetManifest(name, reference string, digest godigest.Digest, body []byte,
func OnGetManifest(name, reference string, body []byte,
storeController storage.StoreController, repoDB repodb.RepoDB, log log.Logger,
) error {
// check if image is a signature

View file

@ -100,7 +100,7 @@ func TestUpdateErrors(t *testing.T) {
log := log.NewLogger("debug", "")
Convey("zerr.ErrOrphanSignature", func() {
manifestContent := ispec.Artifact{
manifestContent := ispec.Manifest{
Subject: &ispec.Descriptor{
Digest: "123",
},
@ -126,7 +126,7 @@ func TestUpdateErrors(t *testing.T) {
log := log.NewLogger("debug", "")
Convey("CheckIsImageSignature errors", func() {
manifestContent := ispec.Artifact{
manifestContent := ispec.Manifest{
Subject: &ispec.Descriptor{
Digest: "123",
},
@ -179,7 +179,7 @@ func TestUpdateErrors(t *testing.T) {
log := log.NewLogger("debug", "")
Convey("CheckIsImageSignature errors", func() {
manifestContent := ispec.Artifact{
manifestContent := ispec.Manifest{
Subject: &ispec.Descriptor{
Digest: "123",
},
@ -192,7 +192,7 @@ func TestUpdateErrors(t *testing.T) {
return []byte{}, "", "", zerr.ErrManifestNotFound
}
err = meta.OnGetManifest("repo", "tag1", "digest", manifestBlob,
err = meta.OnGetManifest("repo", "tag1", manifestBlob,
storeController, repoDB, log)
So(err, ShouldNotBeNil)
@ -200,7 +200,7 @@ func TestUpdateErrors(t *testing.T) {
return []byte{}, "", "", ErrTestError
}
err = meta.OnGetManifest("repo", "tag1", "media", manifestBlob,
err = meta.OnGetManifest("repo", "tag1", manifestBlob,
storeController, repoDB, log)
So(err, ShouldNotBeNil)
})
@ -245,22 +245,18 @@ func TestUpdateErrors(t *testing.T) {
err := repodb.SetMetadataFromInput("repo", "ref", ispec.MediaTypeImageManifest, "digest",
[]byte("{}"), imageStore, repoDB, log)
So(err, ShouldNotBeNil)
})
repoDB = mocks.RepoDBMock{
Convey("SetMetadataFromInput SetIndexData errors", func() {
imageStore := mocks.MockedImageStore{}
log := log.NewLogger("debug", "")
repoDB := mocks.RepoDBMock{
SetIndexDataFn: func(digest godigest.Digest, indexData repodb.IndexData) error {
return ErrTestError
},
}
err = repodb.SetMetadataFromInput("repo", "ref", ispec.MediaTypeImageIndex, "digest",
[]byte("{}"), imageStore, repoDB, log)
So(err, ShouldNotBeNil)
repoDB = mocks.RepoDBMock{
SetArtifactDataFn: func(digest godigest.Digest, artifactData repodb.ArtifactData) error {
return ErrTestError
},
}
err = repodb.SetMetadataFromInput("repo", "ref", ispec.MediaTypeArtifactManifest, "digest",
err := repodb.SetMetadataFromInput("repo", "ref", ispec.MediaTypeImageIndex, "digest",
[]byte("{}"), imageStore, repoDB, log)
So(err, ShouldNotBeNil)
})

View file

@ -125,7 +125,6 @@ func TestVersioningDynamoDB(t *testing.T) {
Region: region,
RepoMetaTablename: "RepoMetadataTable",
ManifestDataTablename: "ManifestDataTable",
ArtifactDataTablename: "ArtifactDataTable",
IndexDataTablename: "IndexDataTable",
UserDataTablename: "UserDataTable",
VersionTablename: "Version",

View file

@ -16,10 +16,16 @@ import (
"github.com/sigstore/cosign/v2/pkg/oci/remote"
zerr "zotregistry.io/zot/errors"
zcommon "zotregistry.io/zot/pkg/common"
"zotregistry.io/zot/pkg/scheduler"
storageConstants "zotregistry.io/zot/pkg/storage/constants"
)
const (
CosignType = "cosign"
NotationType = "notation"
)
func SignatureMediaTypes() map[string]bool {
return map[string]bool{
notreg.ArtifactTypeNotation: true,
@ -106,22 +112,6 @@ func ValidateManifest(imgStore ImageStore, repo, reference, mediaType string, bo
return "", zerr.ErrBadManifest
}
case ispec.MediaTypeArtifactManifest:
var artifact ispec.Artifact
if err := json.Unmarshal(body, &artifact); err != nil {
log.Error().Err(err).Msg("unable to unmarshal JSON")
return "", zerr.ErrBadManifest
}
if artifact.Subject != nil {
var m ispec.Descriptor
if err := json.Unmarshal(body, &m); err != nil {
log.Error().Err(err).Msg("unable to unmarshal JSON")
return "", zerr.ErrBadManifest
}
}
}
return "", nil
@ -303,6 +293,27 @@ func GetImageIndex(imgStore ImageStore, repo string, digest godigest.Digest, log
return imageIndex, nil
}
func GetImageManifest(imgStore ImageStore, repo string, digest godigest.Digest, log zerolog.Logger,
) (ispec.Manifest, error) {
var manifestContent ispec.Manifest
manifestBlob, err := imgStore.GetBlobContent(repo, digest)
if err != nil {
return manifestContent, err
}
manifestPath := path.Join(imgStore.RootDir(), repo, "blobs",
digest.Algorithm().String(), digest.Encoded())
if err := json.Unmarshal(manifestBlob, &manifestContent); err != nil {
log.Error().Err(err).Str("path", manifestPath).Msg("invalid JSON")
return manifestContent, err
}
return manifestContent, nil
}
func RemoveManifestDescByReference(index *ispec.Index, reference string, detectCollisions bool,
) (ispec.Descriptor, error) {
var removedManifest ispec.Descriptor
@ -456,31 +467,50 @@ func PruneImageManifestsFromIndex(imgStore ImageStore, repo string, digest godig
return prunedManifests, nil
}
func ApplyLinter(imgStore ImageStore, linter Lint, repo string, manifestDesc ispec.Descriptor) (bool, error) {
func ApplyLinter(imgStore ImageStore, linter Lint, repo string, descriptor ispec.Descriptor) (bool, error) {
pass := true
if linter != nil {
tag := manifestDesc.Annotations[ispec.AnnotationRefName]
// apply linter only on images, not signatures
if manifestDesc.MediaType == ispec.MediaTypeImageManifest &&
// check that image manifest is not cosign signature
!strings.HasPrefix(tag, "sha256-") &&
!strings.HasSuffix(tag, remote.SignatureTagSuffix) {
// lint new index with new manifest before writing to disk
pass, err := linter.Lint(repo, manifestDesc.Digest, imgStore)
if err != nil {
return false, err
}
// we'll skip anything that's not a image manifest
if descriptor.MediaType != ispec.MediaTypeImageManifest {
return pass, nil
}
if !pass {
return false, zerr.ErrImageLintAnnotations
}
if linter != nil && !IsSignature(descriptor) {
// lint new index with new manifest before writing to disk
pass, err := linter.Lint(repo, descriptor.Digest, imgStore)
if err != nil {
return false, err
}
if !pass {
return false, zerr.ErrImageLintAnnotations
}
}
return pass, nil
}
func IsSignature(descriptor ispec.Descriptor) bool {
tag := descriptor.Annotations[ispec.AnnotationRefName]
switch descriptor.MediaType {
case ispec.MediaTypeImageManifest:
// is cosgin signature
if strings.HasPrefix(tag, "sha256-") && strings.HasSuffix(tag, remote.SignatureTagSuffix) {
return true
}
// is notation signature
if descriptor.ArtifactType == notreg.ArtifactTypeNotation {
return true
}
default:
return false
}
return false
}
func GetOrasReferrers(imgStore ImageStore, repo string, gdigest godigest.Digest, artifactType string,
log zerolog.Logger,
) ([]oras.Descriptor, error) {
@ -609,67 +639,18 @@ func GetReferrers(imgStore ImageStore, repo string, gdigest godigest.Digest, art
}
// filter by artifact type
if len(artifactTypes) > 0 {
found := false
manifestArtifactType := zcommon.GetManifestArtifactType(mfst)
for _, artifactType := range artifactTypes {
if artifactType != "" && mfst.Config.MediaType != artifactType {
continue
}
found = true
break
}
if !found {
continue
}
}
result = append(result, ispec.Descriptor{
MediaType: manifest.MediaType,
ArtifactType: mfst.Config.MediaType,
Size: manifest.Size,
Digest: manifest.Digest,
Annotations: mfst.Annotations,
})
} else if manifest.MediaType == ispec.MediaTypeArtifactManifest {
var art ispec.Artifact
if err := json.Unmarshal(buf, &art); err != nil {
log.Error().Err(err).Str("manifest digest", manifest.Digest.String()).Msg("invalid JSON")
return nilIndex, err
}
if art.Subject == nil || art.Subject.Digest != gdigest {
if len(artifactTypes) > 0 && !zcommon.Contains(artifactTypes, manifestArtifactType) {
continue
}
// filter by artifact type
if len(artifactTypes) > 0 {
found := false
for _, artifactType := range artifactTypes {
if artifactType != "" && art.ArtifactType != artifactType {
continue
}
found = true
break
}
if !found {
continue
}
}
result = append(result, ispec.Descriptor{
MediaType: manifest.MediaType,
ArtifactType: art.ArtifactType,
ArtifactType: manifestArtifactType,
Size: manifest.Size,
Digest: manifest.Digest,
Annotations: art.Annotations,
Annotations: mfst.Annotations,
})
}
}
@ -719,14 +700,13 @@ func GetOrasManifestByDigest(imgStore ImageStore, repo string, digest godigest.D
func IsSupportedMediaType(mediaType string) bool {
return mediaType == ispec.MediaTypeImageIndex ||
mediaType == ispec.MediaTypeImageManifest ||
mediaType == ispec.MediaTypeArtifactManifest ||
mediaType == oras.MediaTypeArtifactManifest
}
func IsNonDistributable(mediaType string) bool {
return mediaType == ispec.MediaTypeImageLayerNonDistributable ||
mediaType == ispec.MediaTypeImageLayerNonDistributableGzip ||
mediaType == ispec.MediaTypeImageLayerNonDistributableZstd
return mediaType == ispec.MediaTypeImageLayerNonDistributable || //nolint:staticcheck
mediaType == ispec.MediaTypeImageLayerNonDistributableGzip || //nolint:staticcheck
mediaType == ispec.MediaTypeImageLayerNonDistributableZstd //nolint:staticcheck
}
// CheckIsImageSignature checks if the given image (repo:tag) represents a signature. The function
@ -742,30 +722,30 @@ func IsNonDistributable(mediaType string) bool {
func CheckIsImageSignature(repoName string, manifestBlob []byte, reference string,
storeController StoreController,
) (bool, string, godigest.Digest, error) {
const cosign = "cosign"
var manifestContent ispec.Artifact
var manifestContent ispec.Manifest
err := json.Unmarshal(manifestBlob, &manifestContent)
if err != nil {
return false, "", "", err
}
manifestArtifactType := zcommon.GetManifestArtifactType(manifestContent)
// check notation signature
if _, ok := SignatureMediaTypes()[manifestContent.ArtifactType]; ok && manifestContent.Subject != nil {
if _, ok := SignatureMediaTypes()[manifestArtifactType]; ok && manifestContent.Subject != nil {
imgStore := storeController.GetImageStore(repoName)
_, signedImageManifestDigest, _, err := imgStore.GetImageManifest(repoName,
manifestContent.Subject.Digest.String())
if err != nil {
if errors.Is(err, zerr.ErrManifestNotFound) {
return true, "notation", signedImageManifestDigest, zerr.ErrOrphanSignature
return true, NotationType, signedImageManifestDigest, zerr.ErrOrphanSignature
}
return false, "", "", err
}
return true, "notation", signedImageManifestDigest, nil
return true, NotationType, signedImageManifestDigest, nil
}
// check cosign
@ -785,17 +765,17 @@ func CheckIsImageSignature(repoName string, manifestBlob []byte, reference strin
signedImageManifestDigest.String())
if err != nil {
if errors.Is(err, zerr.ErrManifestNotFound) {
return true, cosign, signedImageManifestDigest, zerr.ErrOrphanSignature
return true, CosignType, signedImageManifestDigest, zerr.ErrOrphanSignature
}
return false, "", "", err
}
if signedImageManifestDigest.String() == "" {
return true, cosign, signedImageManifestDigest, zerr.ErrOrphanSignature
return true, CosignType, signedImageManifestDigest, zerr.ErrOrphanSignature
}
return true, cosign, signedImageManifestDigest, nil
return true, CosignType, signedImageManifestDigest, nil
}
return false, "", "", nil

View file

@ -118,7 +118,7 @@ func TestValidateManifest(t *testing.T) {
},
Layers: []ispec.Descriptor{
{
MediaType: ispec.MediaTypeImageLayerNonDistributable,
MediaType: ispec.MediaTypeImageLayerNonDistributable, //nolint:staticcheck
Digest: digest,
Size: int64(len(content)),
},
@ -299,38 +299,11 @@ func TestGetReferrersErrors(t *testing.T) {
So(err, ShouldNotBeNil)
})
Convey("Trigger unmarshal error on artifact mediaType", func(c C) {
index = ispec.Index{
Manifests: []ispec.Descriptor{
{
MediaType: ispec.MediaTypeArtifactManifest,
Digest: digest,
},
},
}
indexBuf, err = json.Marshal(index)
So(err, ShouldBeNil)
imgStore = &mocks.MockedImageStore{
GetIndexContentFn: func(repo string) ([]byte, error) {
return indexBuf, nil
},
GetBlobContentFn: func(repo string, digest godigest.Digest) ([]byte, error) {
return []byte{}, nil
},
}
_, err = storage.GetReferrers(imgStore, "zot-test", validDigest,
[]string{artifactType}, log.With().Caller().Logger())
So(err, ShouldNotBeNil)
})
Convey("Trigger nil subject", func(c C) {
index = ispec.Index{
Manifests: []ispec.Descriptor{
{
MediaType: ispec.MediaTypeArtifactManifest,
MediaType: ispec.MediaTypeImageManifest,
Digest: digest,
},
},
@ -398,3 +371,12 @@ func TestGetImageIndexErrors(t *testing.T) {
So(err, ShouldNotBeNil)
})
}
func TestIsSignature(t *testing.T) {
Convey("Unknown media type", t, func(c C) {
isSingature := storage.IsSignature(ispec.Descriptor{
MediaType: "unknown media type",
})
So(isSingature, ShouldBeFalse)
})
}

View file

@ -29,7 +29,7 @@ import (
"github.com/sigstore/cosign/v2/pkg/oci/remote"
zerr "zotregistry.io/zot/errors"
"zotregistry.io/zot/pkg/common"
zcommon "zotregistry.io/zot/pkg/common"
"zotregistry.io/zot/pkg/extensions/monitoring"
zlog "zotregistry.io/zot/pkg/log"
zreg "zotregistry.io/zot/pkg/regexp"
@ -66,7 +66,7 @@ func (is *ImageStoreLocal) RootDir() string {
}
func (is *ImageStoreLocal) DirExists(d string) bool {
return common.DirExists(d)
return zcommon.DirExists(d)
}
// NewImageStore returns a new image store backed by a file storage.
@ -535,7 +535,18 @@ func (is *ImageStoreLocal) PutImageManifest(repo, reference, mediaType string, /
return "", err
}
// apply linter only on images, not signatures
if mediaType == ispec.MediaTypeImageManifest {
var manifest ispec.Manifest
err := json.Unmarshal(body, &manifest)
if err != nil {
return "", err
}
desc.ArtifactType = zcommon.GetManifestArtifactType(manifest)
}
// apply linter only on images, not signatures or indexes
pass, err := storage.ApplyLinter(is, is.linter, repo, desc)
if !pass {
is.log.Error().Err(err).Str("repository", repo).Str("reference", reference).Msg("linter didn't pass")
@ -1440,6 +1451,12 @@ func ensureDir(dir string, log zerolog.Logger) error {
return nil
}
type extendedManifest struct {
ispec.Manifest
Digest godigest.Digest
}
func (is *ImageStoreLocal) garbageCollect(dir string, repo string) error {
oci, err := umoci.OpenLayout(dir)
if err := test.Error(err); err != nil {
@ -1455,7 +1472,7 @@ func (is *ImageStoreLocal) garbageCollect(dir string, repo string) error {
referencedByImageIndex := []string{}
cosignDescriptors := []ispec.Descriptor{}
notationDescriptors := []ispec.Descriptor{}
notationManifests := []extendedManifest{}
/* gather manifests references by multiarch images (to skip gc)
gather cosign and notation signatures descriptors */
@ -1479,10 +1496,27 @@ func (is *ImageStoreLocal) garbageCollect(dir string, repo string) error {
// gather cosign signatures
if strings.HasPrefix(tag, "sha256-") && strings.HasSuffix(tag, remote.SignatureTagSuffix) {
cosignDescriptors = append(cosignDescriptors, desc)
continue
}
}
case ispec.MediaTypeArtifactManifest:
notationDescriptors = append(notationDescriptors, desc)
manifestContent, err := storage.GetImageManifest(is, repo, desc.Digest, is.log)
if err != nil {
is.log.Error().Err(err).Str("repo", repo).Str("digest", desc.Digest.String()).
Msg("gc: failed to read manifest image")
return err
}
if zcommon.GetManifestArtifactType(manifestContent) == notreg.ArtifactTypeNotation {
notationManifests = append(notationManifests, extendedManifest{
Digest: desc.Digest,
Manifest: manifestContent,
})
continue
}
}
}
@ -1500,7 +1534,7 @@ func (is *ImageStoreLocal) garbageCollect(dir string, repo string) error {
is.log.Info().Msg("gc: notation signatures")
if err := gcNotationSignatures(is, oci, &index, repo, notationDescriptors); err != nil {
if err := gcNotationSignatures(is, oci, &index, repo, notationManifests); err != nil {
return err
}
@ -1519,7 +1553,7 @@ func gcUntaggedManifests(imgStore *ImageStoreLocal, oci casext.Engine, index *is
) error {
for _, desc := range index.Manifests {
// skip manifests referenced in image indexex
if common.Contains(referencedByImageIndex, desc.Digest.String()) {
if zcommon.Contains(referencedByImageIndex, desc.Digest.String()) {
continue
}
@ -1616,46 +1650,24 @@ func gcCosignSignatures(imgStore *ImageStoreLocal, oci casext.Engine, index *isp
}
func gcNotationSignatures(imgStore *ImageStoreLocal, oci casext.Engine, index *ispec.Index, repo string,
notationDescriptors []ispec.Descriptor,
notationManifests []extendedManifest,
) error {
for _, notationDesc := range notationDescriptors {
for _, notationManifest := range notationManifests {
foundSubject := false
// check if we can find the manifest which the signature points to
var artManifest ispec.Artifact
buf, err := imgStore.GetBlobContent(repo, notationDesc.Digest)
if err != nil {
imgStore.log.Error().Err(err).Str("repository", repo).Str("digest", notationDesc.Digest.String()).
Msg("gc: failed to get oras artifact manifest")
return err
}
if err := json.Unmarshal(buf, &artManifest); err != nil {
imgStore.log.Error().Err(err).Str("repository", repo).Str("digest", notationDesc.Digest.String()).
Msg("gc: failed to get oras artifact manifest")
return err
}
// skip oci artifacts which are not signatures
if artManifest.ArtifactType != notreg.ArtifactTypeNotation {
continue
}
for _, desc := range index.Manifests {
if desc.Digest == artManifest.Subject.Digest {
if desc.Digest == notationManifest.Subject.Digest {
foundSubject = true
}
}
if !foundSubject {
// remove manifest
imgStore.log.Info().Str("repository", repo).Str("digest", notationDesc.Digest.String()).
imgStore.log.Info().Str("repository", repo).Str("digest", notationManifest.Digest.String()).
Msg("gc: removing notation signature without subject")
// no need to check for manifest conflict, if one doesn't have a subject, then none with same digest will have
_, _ = storage.RemoveManifestDescByReference(index, notationDesc.Digest.String(), false)
_, _ = storage.RemoveManifestDescByReference(index, notationManifest.Digest.String(), false)
err := oci.PutIndex(context.Background(), *index)
if err != nil {
@ -1808,7 +1820,7 @@ func (is *ImageStoreLocal) GetNextDigestWithBlobPaths(lastDigests []godigest.Dig
return nil //nolint:nilerr // ignore files which are not blobs
}
if digest == "" && !common.DContains(lastDigests, blobDigest) {
if digest == "" && !zcommon.DContains(lastDigests, blobDigest) {
digest = blobDigest
}

View file

@ -24,7 +24,7 @@ import (
"github.com/rs/zerolog"
zerr "zotregistry.io/zot/errors"
"zotregistry.io/zot/pkg/common"
zcommon "zotregistry.io/zot/pkg/common"
"zotregistry.io/zot/pkg/extensions/monitoring"
zlog "zotregistry.io/zot/pkg/log"
zreg "zotregistry.io/zot/pkg/regexp"
@ -438,6 +438,17 @@ func (is *ObjectStorage) PutImageManifest(repo, reference, mediaType string, //n
return "", err
}
if mediaType == ispec.MediaTypeImageManifest {
var manifest ispec.Manifest
err := json.Unmarshal(body, &manifest)
if err != nil {
return "", err
}
desc.ArtifactType = zcommon.GetManifestArtifactType(manifest)
}
// apply linter only on images, not signatures
pass, err := storage.ApplyLinter(is, is.linter, repo, desc)
if !pass {
@ -1419,7 +1430,7 @@ func (is *ObjectStorage) GetNextDigestWithBlobPaths(lastDigests []godigest.Diges
return nil //nolint:nilerr // ignore files which are not blobs
}
if digest == "" && !common.DContains(lastDigests, blobDigest) {
if digest == "" && !zcommon.DContains(lastDigests, blobDigest) {
digest = blobDigest
}

View file

@ -584,44 +584,6 @@ func TestGetOrasAndOCIReferrers(t *testing.T) {
So(index.Manifests[0].Digest, ShouldEqual, manDigest)
})
Convey("Get oci referrers - application/vnd.oci.artifact.manifest.v1+json", func(c C) {
artifactType := "application/vnd.example.icecream.v1"
artifactManifest := ispec.Artifact{
MediaType: ispec.MediaTypeArtifactManifest,
ArtifactType: artifactType,
Blobs: []ispec.Descriptor{
{
MediaType: "application/octet-stream",
Size: int64(buflen),
Digest: digest,
},
},
Subject: &ispec.Descriptor{
MediaType: ispec.MediaTypeImageManifest,
Size: int64(mbuflen),
Digest: mdigest,
},
}
manBuf, err := json.Marshal(artifactManifest)
So(err, ShouldBeNil)
manBufLen := len(manBuf)
manDigest := godigest.FromBytes(manBuf)
_, err = imgStore.PutImageManifest(repo, manDigest.Encoded(), ispec.MediaTypeArtifactManifest, manBuf)
So(err, ShouldBeNil)
index, err := imgStore.GetReferrers(repo, mdigest, []string{artifactType})
So(err, ShouldBeNil)
So(index, ShouldNotBeEmpty)
So(index.Manifests[1].ArtifactType, ShouldEqual, artifactType)
So(index.Manifests[1].MediaType, ShouldEqual, ispec.MediaTypeArtifactManifest)
So(index.Manifests[1].Size, ShouldEqual, manBufLen)
So(index.Manifests[1].Digest, ShouldEqual, manDigest)
})
Convey("Get oras referrers", func(c C) {
artifactManifest := artifactspec.Manifest{}
artifactManifest.ArtifactType = "signature-example"

View file

@ -105,32 +105,6 @@ func (img Image) Digest() (godigest.Digest, error) {
return godigest.FromBytes(blob), nil
}
type Artifact struct {
Manifest ispec.Artifact
Blobs []ArtifactBlobs
Reference string
}
func (a Artifact) Digest() (godigest.Digest, error) {
blob, err := json.Marshal(a.Manifest)
if err != nil {
return "", err
}
return godigest.FromBytes(blob), nil
}
func (a Artifact) ArtifactData() (repodb.ArtifactData, error) {
blob, err := json.Marshal(a.Manifest)
if err != nil {
return repodb.ArtifactData{}, err
}
return repodb.ArtifactData{
ManifestBlob: blob,
}, nil
}
type ArtifactBlobs struct {
Blob []byte
MediaType string
@ -588,6 +562,7 @@ func GetImageComponents(layerSize int) (ispec.Image, [][]byte, ispec.Manifest, e
schemaVersion := 2
manifest := ispec.Manifest{
MediaType: ispec.MediaTypeImageManifest,
Versioned: specs.Versioned{
SchemaVersion: schemaVersion,
},
@ -642,6 +617,7 @@ func GetRandomImageComponents(layerSize int) (ispec.Image, [][]byte, ispec.Manif
schemaVersion := 2
manifest := ispec.Manifest{
MediaType: ispec.MediaTypeImageManifest,
Versioned: specs.Versioned{
SchemaVersion: schemaVersion,
},
@ -657,7 +633,6 @@ func GetRandomImageComponents(layerSize int) (ispec.Image, [][]byte, ispec.Manif
Size: int64(len(layers[0])),
},
},
MediaType: ispec.MediaTypeImageManifest,
}
return config, layers, manifest, nil
@ -702,6 +677,7 @@ func GetImageComponentsWithConfig(conf ispec.Image) (ispec.Image, [][]byte, ispe
schemaVersion := 2
manifest := ispec.Manifest{
MediaType: ispec.MediaTypeImageManifest,
Versioned: specs.Versioned{
SchemaVersion: schemaVersion,
},
@ -760,6 +736,7 @@ func GetImageWithComponents(config ispec.Image, layers [][]byte) (Image, error)
const schemaVersion = 2
manifest := ispec.Manifest{
MediaType: ispec.MediaTypeImageManifest,
Versioned: specs.Versioned{
SchemaVersion: schemaVersion,
},
@ -784,49 +761,6 @@ func GetImageWithComponents(config ispec.Image, layers [][]byte) (Image, error)
}, nil
}
func GetRandomArtifact(subject *ispec.Descriptor) (Artifact, error) {
var randBlob [10]byte
_, err := rand.Read(randBlob[:])
if err != nil {
return Artifact{}, err
}
artifactBlobs := []ArtifactBlobs{
{
Blob: randBlob[:],
MediaType: "application/octet-stream",
},
}
blobsDescriptors := make([]ispec.Descriptor, 0, len(artifactBlobs))
for _, artifactBlob := range artifactBlobs {
blobsDescriptors = append(blobsDescriptors, ispec.Descriptor{
Digest: godigest.FromBytes(artifactBlob.Blob),
MediaType: artifactBlob.MediaType,
Size: int64(len(artifactBlob.Blob)),
})
}
artifactManifest := ispec.Artifact{
MediaType: ispec.MediaTypeArtifactManifest,
Blobs: blobsDescriptors,
Subject: subject,
}
artifactManifestBlob, err := json.Marshal(artifactManifest)
if err != nil {
return Artifact{}, err
}
return Artifact{
Manifest: artifactManifest,
Blobs: artifactBlobs,
Reference: godigest.FromBytes(artifactManifestBlob).String(),
}, nil
}
func GetCosignSignatureTagForManifest(manifest ispec.Manifest) (string, error) {
manifestBlob, err := json.Marshal(manifest)
if err != nil {
@ -906,6 +840,11 @@ func UploadImage(img Image, baseURL, repo string) error {
cdigest := godigest.FromBytes(cblob)
if img.Manifest.Config.MediaType == ispec.MediaTypeScratch {
cblob = ispec.ScratchDescriptor.Data
cdigest = ispec.ScratchDescriptor.Digest
}
resp, err := resty.R().
Post(baseURL + "/v2/" + repo + "/blobs/uploads/")
if err = Error(err); err != nil {
@ -940,7 +879,7 @@ func UploadImage(img Image, baseURL, repo string) error {
}
resp, err = resty.R().
SetHeader("Content-type", "application/vnd.oci.image.manifest.v1+json").
SetHeader("Content-type", ispec.MediaTypeImageManifest).
SetBody(manifestBlob).
Put(baseURL + "/v2/" + repo + "/manifests/" + img.Reference)
@ -966,27 +905,6 @@ func DeleteImage(repo, reference, baseURL string) (int, error) {
return resp.StatusCode(), err
}
// UploadArtifactManifest is used in tests where we don't need to upload the blobs of the artifact.
func UploadArtifactManifest(artifactManifest *ispec.Artifact, ref *string, baseURL, repo string) error {
// put manifest
artifactManifestBlob, err := json.Marshal(artifactManifest)
if err != nil {
return err
}
reference := godigest.FromBytes(artifactManifestBlob).String()
if ref != nil {
reference = *ref
}
_, err = resty.R().
SetHeader("Content-type", ispec.MediaTypeArtifactManifest).
SetBody(artifactManifestBlob).
Put(baseURL + "/v2/" + repo + "/manifests/" + reference)
return err
}
func UploadBlob(baseURL, repo string, blob []byte, artifactBlobMediaType string) error {
resp, err := resty.R().Post(baseURL + "/v2/" + repo + "/blobs/uploads/")
if err != nil {
@ -1252,7 +1170,11 @@ func SignWithNotation(keyName string, reference string, tdir string) error {
PlainHTTP: plainHTTP,
}
sigRepo := notreg.NewRepository(remoteRepo)
repositoryOpts := notreg.RepositoryOptions{
OCIImageManifest: true,
}
sigRepo := notreg.NewRepositoryWithOptions(remoteRepo, repositoryOpts)
sigOpts := notation.RemoteSignOptions{
SignOptions: notation.SignOptions{
@ -1334,7 +1256,11 @@ func VerifyWithNotation(reference string, tdir string) error {
PlainHTTP: plainHTTP,
}
repo := notreg.NewRepository(remoteRepo)
repositoryOpts := notreg.RepositoryOptions{
OCIImageManifest: true,
}
repo := notreg.NewRepositoryWithOptions(remoteRepo, repositoryOpts)
manifestDesc, err := repo.Resolve(ctx, ref.Reference)
if err != nil {
@ -1357,7 +1283,7 @@ func VerifyWithNotation(reference string, tdir string) error {
PlainHTTP: plainHTTP,
}
repo = notreg.NewRepository(remoteRepo)
repo = notreg.NewRepositoryWithOptions(remoteRepo, repositoryOpts)
configs := map[string]string{}
@ -1587,6 +1513,11 @@ func UploadImageWithBasicAuth(img Image, baseURL, repo, user, password string) e
cdigest := godigest.FromBytes(cblob)
if img.Manifest.Config.MediaType == ispec.MediaTypeScratch {
cblob = ispec.ScratchDescriptor.Data
cdigest = ispec.ScratchDescriptor.Digest
}
resp, err := resty.R().
SetBasicAuth(user, password).
Post(baseURL + "/v2/" + repo + "/blobs/uploads/")

View file

@ -234,18 +234,6 @@ func TestControllerManager(t *testing.T) {
})
}
func TestUploadArtifact(t *testing.T) {
Convey("Put request results in an error", t, func() {
port := test.GetFreePort()
baseURL := test.GetBaseURL(port)
artifact := ispec.Artifact{}
err := test.UploadArtifactManifest(&artifact, nil, baseURL, "test")
So(err, ShouldNotBeNil)
})
}
func TestUploadBlob(t *testing.T) {
Convey("Post request results in an error", t, func() {
port := test.GetFreePort()

View file

@ -44,10 +44,6 @@ type RepoDBMock struct {
GetIndexDataFn func(indexDigest godigest.Digest) (repodb.IndexData, error)
SetArtifactDataFn func(digest godigest.Digest, artifactData repodb.ArtifactData) error
GetArtifactDataFn func(artifactDigest godigest.Digest) (repodb.ArtifactData, error)
SetReferrerFn func(repo string, referredDigest godigest.Digest, referrer repodb.ReferrerInfo) error
DeleteReferrerFn func(repo string, referredDigest godigest.Digest, referrerDigest godigest.Digest) error
@ -348,22 +344,6 @@ func (sdm RepoDBMock) PatchDB() error {
return nil
}
func (sdm RepoDBMock) SetArtifactData(digest godigest.Digest, artifactData repodb.ArtifactData) error {
if sdm.SetArtifactDataFn != nil {
return sdm.SetArtifactDataFn(digest, artifactData)
}
return nil
}
func (sdm RepoDBMock) GetArtifactData(artifactDigest godigest.Digest) (repodb.ArtifactData, error) {
if sdm.GetArtifactDataFn != nil {
return sdm.GetArtifactDataFn(artifactDigest)
}
return repodb.ArtifactData{}, nil
}
func (sdm RepoDBMock) SetReferrer(repo string, referredDigest godigest.Digest, referrer repodb.ReferrerInfo) error {
if sdm.SetReferrerFn != nil {
return sdm.SetReferrerFn(repo, referredDigest, referrer)

View file

@ -376,7 +376,7 @@ func TestExtractImageDetails(t *testing.T) {
olu := ocilayout.NewBaseOciLayoutUtils(storeController, testLogger)
resDigest, resManifest, resIspecImage, resErr := olu.ExtractImageDetails("zot-test", "latest", testLogger)
So(string(resDigest), ShouldContainSubstring, "sha256:c52f15d2d4")
So(string(resDigest), ShouldContainSubstring, "sha256:8492645f16")
So(resManifest.Config.Digest.String(), ShouldContainSubstring, configDigest.Encoded())
So(resIspecImage.Architecture, ShouldContainSubstring, "amd64")

View file

@ -0,0 +1,51 @@
package test
import (
"errors"
"fmt"
"net/http"
"github.com/gorilla/mux"
)
type RouteHandler struct {
Route string
// HandlerFunc is the HTTP handler function that receives a writer for output and an HTTP request as input.
HandlerFunc http.HandlerFunc
// AllowedMethods specifies the HTTP methods allowed for the current route.
AllowedMethods []string
}
// Routes is a map that associates HTTP paths to their corresponding HTTP handlers.
type HTTPRoutes []RouteHandler
func StartTestHTTPServer(routes HTTPRoutes, port string) *http.Server {
baseURL := GetBaseURL(port)
mux := mux.NewRouter()
mux.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
_, err := w.Write([]byte("{}"))
if err != nil {
return
}
}).Methods(http.MethodGet)
for _, routeHandler := range routes {
mux.HandleFunc(routeHandler.Route, routeHandler.HandlerFunc).Methods(routeHandler.AllowedMethods...)
}
server := &http.Server{ //nolint:gosec
Addr: fmt.Sprintf(":%s", port),
Handler: mux,
}
go func() {
if err := server.ListenAndServe(); !errors.Is(err, http.ErrServerClosed) {
return
}
}()
WaitTillServerReady(baseURL + "/test")
return server
}

View file

@ -145,7 +145,7 @@ function teardown_file() {
}
EOF
run notation sign --key "notation-sign-test" --plain-http localhost:8080/annotations:latest
run notation sign --signature-manifest image --key "notation-sign-test" --plain-http localhost:8080/annotations:latest
[ "$status" -eq 0 ]
run notation verify --plain-http localhost:8080/annotations:latest
[ "$status" -eq 0 ]

View file

@ -37,7 +37,6 @@ function setup() {
"cacheTablename": "BlobTable",
"repoMetaTablename": "RepoMetadataTable",
"manifestDataTablename": "ManifestDataTable",
"artifactDataTablename": "ArtifactDataTable",
"indexDataTablename": "IndexDataTable",
"userDataTablename": "UserDataTable",
"versionTablename": "Version"

View file

@ -120,11 +120,11 @@ function teardown_file() {
@test "attach oras artifacts" {
# attach signature
echo "{\"artifact\": \"\", \"signature\": \"pat hancock\"}" > signature.json
run oras attach --plain-http 127.0.0.1:8080/golang:1.20 --artifact-type 'signature/example' ./signature.json:application/json
run oras attach --plain-http 127.0.0.1:8080/golang:1.20 --image-spec v1.1-image --artifact-type 'signature/example' ./signature.json:application/json
[ "$status" -eq 0 ]
# attach sbom
echo "{\"version\": \"0.0.0.0\", \"artifact\": \"'127.0.0.1:8080/golang:1.20'\", \"contents\": \"good\"}" > sbom.json
run oras attach --plain-http 127.0.0.1:8080/golang:1.20 --artifact-type 'sbom/example' ./sbom.json:application/json
run oras attach --plain-http 127.0.0.1:8080/golang:1.20 --image-spec v1.1-image --artifact-type 'sbom/example' ./sbom.json:application/json
[ "$status" -eq 0 ]
}
@ -248,7 +248,7 @@ EOF
run regctl artifact list localhost:8080/artifact-ref:demo --format raw-body
[ "$status" -eq 0 ]
[ $(echo "${lines[-1]}" | jq '.manifests | length') -eq 0 ]
run regctl artifact put --media-type "application/vnd.oci.artifact.manifest.v1+json" --annotation demo=true --annotation format=oci --artifact-type "application/vnd.example.icecream.v1" --subject localhost:8080/artifact-ref:demo << EOF
run regctl artifact put --annotation demo=true --annotation format=oci --artifact-type "application/vnd.example.icecream.v1" --subject localhost:8080/artifact-ref:demo << EOF
test reference
EOF
[ "$status" -eq 0 ]

View file

@ -49,12 +49,6 @@ EOF
This artifact is represented as an ispec image manifest, this is the layer inside the manifest.
EOF
ARTIFACT_MANIFEST_REFERRER=${ARTIFACT_BLOBS_DIR}/artifact-manifest-ref-blob
touch ${ARTIFACT_MANIFEST_REFERRER}
cat >${ARTIFACT_MANIFEST_REFERRER} <<EOF
This artifact is represented as an ispec artifact manifest, this is the blob inside the manifest.
EOF
setup_zot_file_level ${ZOT_CONFIG_FILE}
wait_zot_reachable "http://127.0.0.1:8080/v2/_catalog"
@ -69,9 +63,6 @@ EOF
run oras attach --plain-http --image-spec v1.1-image --artifact-type image.type 127.0.0.1:8080/golang:1.20 ${IMAGE_MANIFEST_REFERRER}
[ "$status" -eq 0 ]
run oras attach --plain-http --image-spec v1.1-artifact --artifact-type artifact.type 127.0.0.1:8080/golang:1.20 ${ARTIFACT_MANIFEST_REFERRER}
[ "$status" -eq 0 ]
MANIFEST_DIGEST=$(skopeo inspect --tls-verify=false docker://localhost:8080/golang:1.20 | jq -r '.Digest')
echo ${MANIFEST_DIGEST}
@ -91,18 +82,9 @@ function teardown() {
[ "$status" -eq 0 ]
[ $(echo "${lines[-1]}" | jq '.manifests[].artifactType') = '"image.type"' ]
run curl -X GET http://127.0.0.1:8080/v2/golang/referrers/${MANIFEST_DIGEST}?artifactType=artifact.type
[ "$status" -eq 0 ]
[ $(echo "${lines[-1]}" | jq '.manifests[].artifactType') = '"artifact.type"' ]
# Check referrers API using the GQL endpoint
REFERRER_QUERY_DATA="{ \"query\": \"{ Referrers(repo:\\\"golang\\\", digest:\\\"${MANIFEST_DIGEST}\\\", type:[\\\"image.type\\\"]) { MediaType ArtifactType Digest Size} }\"}"
run curl -X POST -H "Content-Type: application/json" --data "${REFERRER_QUERY_DATA}" http://localhost:8080/v2/_zot/ext/search
[ "$status" -eq 0 ]
[ $(echo "${lines[-1]}" | jq '.data.Referrers[].ArtifactType') = '"image.type"' ]
REFERRER_QUERY_DATA="{ \"query\": \"{ Referrers(repo:\\\"golang\\\", digest:\\\"${MANIFEST_DIGEST}\\\", type:[\\\"artifact.type\\\"]) { MediaType ArtifactType Digest Size} }\"}"
run curl -X POST -H "Content-Type: application/json" --data "${REFERRER_QUERY_DATA}" http://localhost:8080/v2/_zot/ext/search
[ "$status" -eq 0 ]
[ $(echo "${lines[-1]}" | jq '.data.Referrers[].ArtifactType') = '"artifact.type"' ]
}

View file

@ -272,9 +272,9 @@ function teardown_file() {
}
EOF
run notation sign --key "notation-sign-sync-test" --plain-http localhost:9000/golang:1.20
run notation sign --signature-manifest image --key "notation-sign-sync-test" --plain-http localhost:9000/golang:1.20
[ "$status" -eq 0 ]
run notation verify --plain-http localhost:9000/golang:1.20
run notation verify --plain-http localhost:9000/golang:1.20
[ "$status" -eq 0 ]
run notation list --plain-http localhost:9000/golang:1.20
[ "$status" -eq 0 ]
@ -381,7 +381,7 @@ EOF
}
@test "push OCI artifact (oci artifact mediatype) with regclient" {
run regctl artifact put --media-type "application/vnd.oci.artifact.manifest.v1+json" --artifact-type "application/vnd.example.icecream.v1" localhost:9000/newartifact:demo <<EOF
run regctl artifact put --artifact-type "application/vnd.example.icecream.v1" localhost:9000/newartifact:demo <<EOF
this is an oci artifact
EOF
[ "$status" -eq 0 ]
@ -425,7 +425,7 @@ EOF
run regctl artifact list localhost:9000/artifact-ref:demo --format raw-body
[ "$status" -eq 0 ]
[ $(echo "${lines[-1]}" | jq '.manifests | length') -eq 0 ]
run regctl artifact put --media-type "application/vnd.oci.artifact.manifest.v1+json" --annotation demo=true --annotation format=oci --artifact-type "application/vnd.example.icecream.v1" --subject localhost:9000/artifact-ref:demo << EOF
run regctl artifact put --annotation demo=true --annotation format=oci --artifact-type "application/vnd.example.icecream.v1" --subject localhost:9000/artifact-ref:demo << EOF
test reference
EOF
[ "$status" -eq 0 ]