UI can now make use of OCI artifacts and references using `Referrers` gQL query.
It returns a list of descriptors that refer on their `subject` field to another
digest.
Signed-off-by: Alex Stan <alexandrustan96@yahoo.ro>
Suppose we push two identical manifests (sharing same digest) but with
different tags, then deleting by digest should throw an error otherwise
we end up deleting all image tags (with gc) or dangling references
(without gc)
This behaviour is controlled via Authorization, added a new policy
action named detectManifestsCollision which enables this behaviour
Signed-off-by: Ramkumar Chinchani <rchincha@cisco.com>
Signed-off-by: Petu Eusebiu <peusebiu@cisco.com>
Co-authored-by: Ramkumar Chinchani <rchincha@cisco.com>
Thanks @jdolitsky et al for kicking off these changes at:
https://github.com/oci-playground/zot/commits/main
Thanks @sudo-bmitch for reviewing the patch
Signed-off-by: Ramkumar Chinchani <rchincha@cisco.com>
Moved boltdb to a driver implementation for such interface
Added CreateCacheDatabaseDriver in controller
Fixed default directory creation (boltDB will only create the file, not the dir
Added coverage tests
Added example config for boltdb
Re-added caching on subpaths, rewrote CreateCacheDatabaseDriver
Fix tests
Made cacheDriver argument mandatory for NewImageStore, added more validation, added defaults
Moved cache interface to own file, removed useRelPaths from config
Got rid of cache config, refactored
Moved cache to own package and folder
Renamed + removed cache factory to backend, replaced CloudCache to RemoteCache
Moved storage constants back to storage package
moved cache interface and factory to storage package, changed remoteCache defaulting
Signed-off-by: Catalin Hofnar <catalin.hofnar@gmail.com>
Values returned now by GetCVESummaryForImage
// not scannable / error during scan - max severity "" - cve count 0 - Errors
// scannable no issues found - max severity "NONE" - cve count 0 - no Errors
// scannable issues found - max severity from Scanner - cve count >0 - no Errors
Before this change the max severity in case #1 and #2 was "UNKNOWN" which is also possible value
for case #3. To better distinguish them return different max severities.
This feature would be consumed by the UI.
Signed-off-by: Andrei Aaron <andaaron@cisco.com>
Issues fixed:
- the cli calls reaching out to the catalog endpoint used to request signature manifests
- resty was used instead of the cli http client to check if the discovery api was available
but it did not take into account TLS verification configuration
(testing locally withself-signed certificates did not work)
(cherry picked from commit ca42031ae9b1ceb459f5cd4f86cb82b3c9f78157)
Signed-off-by: Andrei Aaron <andaaron@cisco.com>
- Digests were represented by different ways
- We needed a uniform way to represent the digests and enforce a format
- also replace usage of github.com/google/go-containerregistry/pkg/v1
with github.com/opencontainers/image-spec/specs-go/v1
Signed-off-by: Laurentiu Niculae <niculae.laurentiu1@gmail.com>
(cherry picked from commit 96b2f29d6d57070a913ce419149cd481c0723815)
(cherry picked from commit 3d41b583daea654c98378ce3dcb78937d71538e8)
Co-authored-by: Laurentiu Niculae <niculae.laurentiu1@gmail.com>
* build: add commit hash to Config at build for proper discovery readme link
* fix: use tag instead of commit hash, add to release build
Signed-off-by: Catalin Hofnar <catalin.hofnar@gmail.com>
The lastUpdated field was picked from the first entry in image history
Now it is the created time of the image, or the last entry in
image history, if created time is unavailable
Signed-off-by: Andrei Aaron <andaaron@cisco.com>
Should help with test flakiness
(the order in which the policies are read from the map impacted tested codepath)
Signed-off-by: Andrei Aaron <andaaron@cisco.com>
Signed-off-by: Andrei Aaron <andaaron@cisco.com>
Return this data as part of GlobalSearch and RepoListWithNewestImage
query results.
This commit also includes refactoring of the CVE scanning logic in
order to better encapsulate trivy specific logic, remove CVE scanning
logic from the graphql resolver.
Signed-off-by: Andrei Aaron <andaaron@cisco.com>
* list all images that are base images for the given image + zli command
Signed-off-by: Lisca Ana-Roberta <ana.kagome@yahoo.com>
* Fix a failing test
The test expected the image size to be the size of the layer, not the manifest+config+layer
Signed-off-by: Andrei Aaron <andaaron@cisco.com>
Signed-off-by: Lisca Ana-Roberta <ana.kagome@yahoo.com>
Signed-off-by: Andrei Aaron <andaaron@cisco.com>
Co-authored-by: Lisca Ana-Roberta <ana.kagome@yahoo.com>
Under digest bucket create 2 buckets, one for storing origin blob
and one for storing deduped blobs.
PutBlob() - puts an origin blob in both buckets
- puts a deduped blob in deduped bucket
GetBlob() - returns blobs only from origin bucket
DeleteBlob() - deletes an origin blob from both buckets
and moves one deduped blob into origin bucket
- deletes a deduped blob from deduped bucket
[storage] When deleting an origin blob, next time we GetBlob() we get a
deduped blob with no content and we will move the content from
the deleted origin blob to it (inside s3.go).
Signed-off-by: Petu Eusebiu <peusebiu@cisco.com>
in order to know which blob is 'real' (has content)
we need to know which was the first blob inserted in cache,
because that is always the real one.
because we can not modify the keys order in boltdb we'll do this
by marking the first blob inserted with a value
when GetBlob() return the blob which is marked
when PutBlob() if is the first one, mark it
when DeleteBlob() in case deleted is marked then mark the next blob
Signed-off-by: Petu Eusebiu <peusebiu@cisco.com>
currently different subpaths can only point to same root directory only
when one or both of the storage config does not enable dedupe
different subpath should be able to point to same root directory and in
that case their storage config should be same i.e GC,Dedupe, GC delay
and GC interval
Signed-off-by: Shivam Mishra <shimish2@cisco.com>
- AccessControlContext now resides in a separate package from where it can be imported,
along with the contextKey that will be used to set and retrieve this context value.
- AccessControlContext has a new field called Username, that will be of use for future
implementations in graphQL resolvers.
- GlobalSearch resolver now uses this context to filter repos available to the logged user.
- moved logic for uploading images in tests so that it can be used in every package
- tests were added for multiple request scenarios, when zot-server requires authz
on specific repos
- added tests with injected errors for extended coverage
- added tests for status code error injection utilities
Closes https://github.com/project-zot/zot/issues/615
Signed-off-by: Alex Stan <alexandrustan96@yahoo.ro>
- replace dependency of tagsInfo and repoInfo with a list of manifests, since it provides
all the needed data
- Mock tests added
Signed-off-by: Alex Stan <alexandrustan96@yahoo.ro>
ExpandedRepoInfo currently returns RepoInfo that is a list of Manifests.
To comply with the newest UI requirements, a new field called Summary,
referring to RepoSummary structure, was added.
Signed-off-by: Alex Stan <alexandrustan96@yahoo.ro>
Conformance spec requires responding to PATCH requests with
response header 'Content-Range' and value <range>
Signed-off-by: Bogdan BIVOLARU <104334+bogdanbiv@users.noreply.github.com>
This commit uses native go fuzzing to fuzz test implementations
of storage in storage_fs.
moved fuzzing testdata for storage_fs in separate repo
added make target and script for importing fuzz data and running all fuzz tests
Signed-off-by: Alex Stan <alexandrustan96@yahoo.ro>
ImageListWithLatestTag currently returns a list of ImageInfo objects.
It needs to return consistent results with the API used for Global search as the same information will be used by the UI in the same type or cards.
So we need to update RepoSummary to include the data which right now is present in ImageInfo, but missing from RepoSummary (information on the latest tag in that specific repo).
Will update return type of ImageListWithLatestTag in a later PR (issue tracked in a separate GH issue)
Closes#666
Signed-off-by: Andrei Aaron <andaaron@cisco.com>
- Decrease RLIMIT_NOFILE and the number of goroutines used to reach this limit (from 512 to 100)
- Reset RLIMIT_NOFILE to the initial value before the test finishes
- Remove panic
- Use temporary dir managed by test framework
- Swith to using test logging in pkg/cli/stress_test.go
- Execute commands without `bash -c` in pkg/cli/stress_test.go
First item is needed as the GH runner seems to stop the test if stressed too much.
The lower number is still good enough to reproduce the test conditions
Signed-off-by: Andrei Aaron <andaaron@cisco.com>
We encountered some problems with using the existing folder structure,
but it looks like running the tooling with the latest versions works after
we regenerated the project using 'gql init' and refactoring to separate
the login previously in resolvers.go.
- the autogenerated code is now under the gql_generated folder
- the file resolvers.go now contains only the code which is not
rewritten by the gqlgen framework
- the file schema.resolvers.go is rewritten when gqlgen runs,
and we'll only keep there the actual resolvers matching query names
Changes we observed to schema.resolvers.go when gqlgen runs include
reordering methods, and renaming function parameters to match the
names used in schema.graphql
- we now have a gqlgen.yaml config file which governs the behavior of
gqlgen (can be tweaked to restructure the folder structure of the
generated code in the future)
Looks like the new graphql server has better validation
1 Returns 422 instead of 200 for missing query string - had to update tests
2 Correctly uncovered an error in a test for a bad `%` in query string.
As as result of 2, a `masked` bug was found in the way we check if images are
signed with Notary, the signatures were reasched for with the media type
of the image manifest itself instead of the media type for notation.
Fixed this bug, and improved error messages.
This bug would have also been reproducible with main branch if the bad `%`
in the test would have fixed.
Updated the linter to ignore some issues with the code which is
always rewritten when running:
`go run github.com/99designs/gqlgen@v0.17.13 generate`
Add a workflow to test gqlgen works and has no uncommitted changes
Signed-off-by: Andrei Aaron <andaaron@cisco.com>
Multiple go routines downloading trivy db
triggers data race on trivy internal db.Path().
In each go routine wait for db download to start.
closes#636
Signed-off-by: Petu Eusebiu <peusebiu@cisco.com>
config file may get removed before fsnotify starts watching it
make sure the config file gets removed when test ends, closes#608
Signed-off-by: Petu Eusebiu <peusebiu@cisco.com>
Files were added to be built whether an extension is on or off.
New build tags were added for each extension, while minimal and extended disappeared.
added custom binary naming depending on extensions used and changed references from binary to binary-extended
added automated blackbox tests for sync, search, scrub, metrics
added contributor guidelines
Signed-off-by: Alex Stan <alexandrustan96@yahoo.ro>
reuqest url also contains query parameter due to this in some scenarios
location header is setting up incorrectly, strip query parameter from
request url to correctly setup location header.
Closes#573#575
Signed-off-by: Shivam Mishra <shimish2@cisco.com>
expanded repo info also provides information if manifests of repo is signed or not
previously it was looking for only cosign signature.
Signed-off-by: Shivam Mishra <shimish2@cisco.com>
Because s3 doesn't support hard links we store duplicated blobs
as empty files. When the original blob is deleted its content is
moved to the the next duplicated blob and so on.
Signed-off-by: Petu Eusebiu <peusebiu@cisco.com>
Changed imagesToCopyFromUpstream to return a map[string][]types.ImageReference from just an array of refs
Rewrote some logic in sync.go to use the new signature of imagesToCopyFromUpstream
Split getLocalImageRef by adding function getLocalCachePath
Adapted tests for new changes, added some tests
Merged #481
Signed-off-by: Catalin Hofnar <catalin.hofnar@gmail.com>
PR (linter: upgrade linter version #405) triggered lint job which failed
with many errors generated by various linters. Configurations were added to
golangcilint.yaml and several refactorings were made in order to improve the
results of the linter.
maintidx linter disabled
Signed-off-by: Alex Stan <alexandrustan96@yahoo.ro>
Signed-off-by: laurentiuNiculae <themelopeus@gmail.com>
Separated updateDistSpec functionality
Removed rewriting of config when distSpecVersion was wrong
whenever we make a request that contains header apart from CORS allowed header, browser sends a preflight request
and in response accept *Access-Control-Allow-Headers*.
preflight request is in form of OPTIONS method, added new http handler func to set headers
and returns HTTP status ok in case of OPTIONS method.
in case of authorization, request contains authorization header
added authorization header in Access-Control-Allow-Headers list
added AllowOrigin field in HTTPConfig this field value is set to Access-Control-Allow-Origin header and will give zot adminstrator to limit incoming request.
Signed-off-by: Shivam Mishra <shimish2@cisco.com>
The directory created by `T.TempDir` is automatically removed when the
test and all its subtests complete.
Reference: https://pkg.go.dev/testing#T.TempDir
Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>
DetailedRepoInfo graphql api returns detailed repo info given repo name
repo contains its manifests info
Each manifest entry contains digest,signed, tag and layers info
Each layer info containes digest, size
Signed-off-by: Shivam Mishra <shimish2@cisco.com>
Behavior controlled by configuration (default=off)
It is a trade-off between performance and consistency.
References:
[1] https://github.com/golang/go/issues/20599
Signed-off-by: Ramkumar Chinchani <rchincha@cisco.com>
sync: don't return error on sync signatures, just skip them, closes#375
sync: sync signatures on demand
sync on demand: in case of parallel requests pull image just once, closes#344
Signed-off-by: Petu Eusebiu <peusebiu@cisco.com>
zot: registry server
zli: zot cli to interact with the zot registry
zui: zot ui (proposed)
zb: zot benchmark (proposed)
Signed-off-by: Ramkumar Chinchani <rchincha@cisco.com>
now it copies to a local cache and then it copies over storage APIs
- accept all images with or without signatures
- disable sync writing to stdout
- added more logs
- fixed switch statement in routes
- fixed enabling sync multiple times for storage subpaths
closes#266
Signed-off-by: Petu Eusebiu <peusebiu@cisco.com>
Periodically poll registries and pull images according to sync's config
Added sync on demand, syncing when clients asks for an image which
zot doesn't have.
Signed-off-by: Petu Eusebiu <peusebiu@cisco.com>
Some LDAP servers are not MT-safe in that when searches happen with binds
in flight leads to errors such as:
"comment: No other operations may be performed on the connection while a
bind is outstanding"
Add goroutine-id in logs to help debug MT bugs.
Signed-off-by: Ramkumar Chinchani <rchincha@cisco.com>
With recent docker client-side changes, on 'docker pull' we see:
"Error response from daemon: missing or empty Content-Type header"
Hence, set Content-Type header.
Signed-off-by: Ramkumar Chinchani <rchincha@cisco.com>
previously mount blob will look for blob that is provided in http request and try to hard link that path
but ideally we should look for path from our cache and do the hard link of that particular path.
this commit does the same.
- Show individual layers with size and digest under each image
- Include config digest for each image
See example below
```
IMAGE NAME TAG DIGEST CONFIG LAYERS SIZE
test/godev 0.4.7 7d38d8ca 05b9f86e 519MB
f824a027 65MB
a98af0f5 52MB
ba5b2bc4 163MB
58b1ca8d 228MB
67d798ee 12MB
test/cdev test 2292b4ae cf6f6c77 280MB
f824a027 65MB
a98af0f5 52MB
ba5b2bc4 163MB
test/cdev 0.4.7 2292b4ae cf6f6c77 280MB
f824a027 65MB
a98af0f5 52MB
ba5b2bc4 163MB
Note the new layers and config fields will be visible in the json/yaml format regardless of the value of the verbose flag
```
added support to point multiple storage locations in zot by running multiple instance of zot in background.
see examples/config-multiple.json for more info about config.
Closes#181
In use cases, when there are large images with shared layers across
repositories, clients may benefit from not re-uploading the same blobs
over and over again.
We ensure this by hard linking when check-blob api is called.
Signed-off-by: Ramkumar Chinchani <rchincha@cisco.com>
The idea initially was to use bazel to do our builds, however golang
build system is now good enough and our code base is entirely go.
It is also slowing down our travis ci/cd pipeline.
The storage layer is protected with read-write locks.
However, we may be holding the locks over unnecessarily large critical
sections.
The typical workflow is that a blob is first uploaded via a per-client
private session-id meaning the blob is not publicly visible yet. When
the blob being uploaded is very large, the transfer takes a long time
while holding the lock.
Private session-id based uploads don't really need locks, and hold locks
only when blobs are published after the upload is complete.
If image vulnerability scan does not support any media type, considering those images as an infected image and now this images will not be shown in fixed images list.
Fixes issue #130
Uses GraphQL API of zot to fetch CVE info
- Get all images affected by a CVE (input: CVEID)
- Get all CVEs of a layer (input: image:tag)
- Get all layers of an image which have resolved a CVE (input: image,
CVEID)
- Get all layers of an image affected by a CVE (input: image, CVEID)
dstRecord :- blob path stored in cache.
dst :- blob path that is trying to be uploaded.
Currently, if the actual blob on disk may have been removed by GC/delete, during syncing the cache dst is being passed to DeleteBlob function and retry section is being continuously called because DeleteBlob function never deletes dst path (doesn't exist in db), dstRecord should be passed into DeleteBlob function because dstRecord is actual blob path stored in db.
If dst and dstRecord path value is same then this issue will not be produced and DeleteBlob method will delete the blob info from cache but if both are different then DeleteBlob method will try to delete dst path which is not in cache.
Note:- boltdb delete method return nil even when value doesn't exist (https://godoc.org/github.com/boltdb/bolt#Bucket.Delete)
This is useful if we want to roll out experimental versions of zot
pointing to some storage shared with another zot instance.
Also, when under storage full conditions, will be useful to turn on this
flag to prevent further writes.
We perform inline garbage collection of orphan blobs. However, the
dist-spec poses a problem because blobs begin their life as orphan blobs
and then a manifest is add which refers to these blobs.
We use umoci's GC() to perform garbage collection and policy support
has been added recently which can control whether a blob can be skipped
for GC.
In this patch, we use a time-based policy to skip blobs.
Extends the existing zot CLI to add commands for listing all images and
their details on a zot server.
Listing all images introduces the need for configurations.
Each configuration has a name and URL at the least. Check 'zot config
-h' for more details.
The user can specify the URL of zot server explicitly while running the
command or configure a URL and pass it directly.
Adding a configuration:
zot config add aci-zot <zot-url>
Run 'zot config --help' for more.
Listing all images:
zot images --url <zot-url>
Pass a config instead of the url:
zot images <config-name>
Filter the list of images by image name:
zot images <config-name> --name <image-name>
Run 'zot images --help' for all details
- Stores configurations in '$HOME/.zot' file
Add CLI README