-
Notifications
You must be signed in to change notification settings - Fork 395
Blob info caching + mount/reuse #536
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
0071274 to
090ac79
Compare
|
@vrothberg @runcom PTAL |
|
@nalind PTAL |
|
Tests are failing here due to the API change, updated Skopeo is running the tests in containers/skopeo#570 . |
This might not be the right thing to do - apparently rootless buildah runs in a user namespace, which causes it to see EUID==0, and try to write to |
037049e to
306c4e8
Compare
pkg/blobinfocache/boltdb.go
Outdated
| return err | ||
| } | ||
| return nil | ||
| }) // FIXME? Log error? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why don't you just logrus.Error when this happens?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, probably. That’s one of the WIP parts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(The a bit tricky aspect to this is that failures using the cache are never fatal (which might not be a good idea, to be fair), so a failure could result in dozens of identical or similar error messages per copy; we probably want to throttle them somehow, or maybe even mark the cache as broken after a few failures.)
pkg/blobinfocache/boltdb.go
Outdated
| return err | ||
| } | ||
| return nil | ||
| }) // FIXME? Log error? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not logrus.Error()
pkg/blobinfocache/boltdb.go
Outdated
| } | ||
| return nil | ||
| }); err != nil { // Including os.IsNotExist(err) | ||
| return []types.BICReplacementCandidate{} // FIXME? Log? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we log everything except IsNotExist?
| return types.BlobInfo{}, "", errors.Wrapf(err, "Error trying to reuse blob %s at destination", srcInfo.Digest) | ||
| } | ||
| if reused { | ||
| ic.c.Printf("Skipping fetch of repeat blob %s\n", srcInfo.Digest) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you reword this?
Skipping blob %s fetch, already exists?
Is this something we actually need to see, or would it be better to just see what is pulled?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(“fetch” in this message includes pushes.)
This can definitely be improved, at least s/blob/layer/, and maybe we don’t need the digests in the output at all. That’s all fairly independent from the functionality of this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(“fetch” in this message includes pushes.)
i.e. all of pull/push/copy go through this code path and may skip transferring a blob between transports here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this just become noise on the screen, would the user care? Seems to be more debugging information.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what about Blob transfer skip - more generic than fetch and more valid in the context of pushes
|
@mtrmac Is this still WIP? Can we get it vendored into skopeo so we can get tests to pass? |
Yes, at least for documentation.
Already exists in |
|
I'm willing to take it without Documentation, so we can move the testing along. Then open a separate PR for Docs Why is the tests failing? |
This will be used to record information about copied layers, and avoid the copies if possible. Does not add any users, so does not change behavior yet. Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This will be useful in the next commit. (If mocks are useful at all), let's start reusing them more widely. Signed-off-by: Miloslav Trmač <mitr@redhat.com>
The helpers have no users yet, they will be added momentarily along with the implementations to be tested. Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This will be called by at least two of the implementations. Has no users yet, but they will be added momentarily. Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This is the primary production implementation. Does not add any users yet, so should not change behavior. Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This exists for tests, as a fallback when we can't use the BoltDB locations, and possibly for non-copy.Image users. Has no users yet, so does not change behavior. Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This exists primarily for the benefit of Image.ConfigBlob and similar readers, which don't really benefit from the DiffID matching, blob mounting, and the like, or callers like ImageDestination.PutBlob, which actively wants to avoid using any extra cached data (because the cache lookup should have already happened and now it would just be redundant). Does not add any users yet, so should not change behavior. Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This returns a default BoltDB instance (which almost everyone should use to maximally benefit from the cache). The default location is chosen to exist near the containers/storage GraphRoot (i.e. typically on the same partition, with the same SELinux context), both for root and rootless modes of podman. This adds no users yet, so should not immediately change behavior. Signed-off-by: Miloslav Trmač <mitr@redhat.com>
The cache is not yet used, and initializing it can only create a few directories (without aborting the copy operation on failure), so this should not noticeably affect behavior right now. Signed-off-by: Miloslav Trmač <mitr@redhat.com>
Now that we are not using an in-memory cache, the query may be more expensive. OTOH we want to query the on-disk BlobInfoCache in any case, and the kernel is likely to cache short-term disk accesses, so an extra in-memory cache would likely only make things more expensive overall. Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This will, primarily, make it easier for the transport to use alternate locations without having to somehow carry state from HasBlob to ReapplyBlob. Also, all instances of ReapplyBlob have been either trivial or redundant, and there is a single primary caller of HasBlob/ReapplyBlob (+ a few in-transport users who are even a bit cleaner with the move to TryReusingBlob). Should not change behavior, apart from not doing the storageImageDestination.HasBlob check redundantly in storageImageDestination.ReapplyBlob. Signed-off-by: Miloslav Trmač <mitr@redhat.com>
For now, none of the transports actually use it, so should not change behavior. copy.Image uses its existing cache object; config parses in image/* usually use NoCache because they wouldn't appreciably benefit anyway. Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This will allow TryReusingBlob to substitute the required blob with an equivalent based on cache information if possible, or not doing so if it would break signatures. In addition, we set canSubstitute to false when signing an image, to make 100% sure the signed blob is safe (e.g. that we are not signing a third-party-compressed version which has been maliciously designed to attack some decompressor implementations). Nothing implements this, so does not change behavior yet. Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This will allow us to reliably detect that we have processed the full input (i.e. that PutBlob did not get the data from elsewhere and ignore it). The value is not uset yet, so does not change behavior. Signed-off-by: Miloslav Trmač <mitr@redhat.com>
…during a copy We have the data already available, so just use it. This primarily helps when pushing the same local layer twice to the same destination while compressing it. Signed-off-by: Miloslav Trmač <mitr@redhat.com>
…arerToken This is a trivial move, does not change behavior; but it will allow setupRequestAuth to be a bit more complex about the scopes and token caching in the future. Signed-off-by: Miloslav Trmač <mitr@redhat.com>
Now that the code has been moved, integrate it better into its uses. Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This will make it easier to cache several different tokens in a single client. Should not change behavior. Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This allows using cross-repository mounts, which require a token for both reading the source and reading and writing to the destination. Signed-off-by: Miloslav Trmač <mitr@redhat.com>
…ryReusingBlob We will add more calls to blobExists from TryReusingBlob soon. Should not change behavior. Signed-off-by: Miloslav Trmač <mitr@redhat.com>
Signed-off-by: Miloslav Trmač <mitr@redhat.com>
The implementation already computes both digests locally, so just record the data so that all transports benefit. Signed-off-by: Miloslav Trmač <mitr@redhat.com>
Because storage implements a flat layer namespace, and it already contains a layer<->DiffID mapping, we don't need to record everything redundantly in the cache and use cache.CandidateLocations; just use the cache for digest->DiffID lookups, and look up a layer by the DiffID using the existing data. Signed-off-by: Miloslav Trmač <mitr@redhat.com>
5c5e6b9 to
3a6fc86
Compare
|
Updated to avoid a no-op mount within a single repo, and added documentation to the interface/implementations; I can live with this being merged. Tests fail here due to the API change, should eventually pass in containers/skopeo#570 (and after merging this, a variant of containers/skopeo#570 that vendors from |
|
LGTM |
|
Reviewing this in a bit |
|
I had just a comment which we can live with for now/beginning of January. I'm gonna merge this, if you have anything against, please fill out issues/PRs |
|
Tests in skopeo pass as well containers/skopeo#570 |
This adds types.BlobInfoCache recording the encountered compressed/uncompressed digest relationships and
docker://blob locations, and using them to:docker://destinations instead of copying the data againcontainers-storage:destinations instead of pulling themThe blob info cache is stored in
/var/lib/containers/blob-info-cache-v1.boltdbfor EUID=0 users, and$XDG_DATA_HOME/containers/blob-info-cache-v1.boltdbfor unprivileged users.See individual commit messages for more details.
WIP items:
WhencanSubstitute,dockerImageDestinationmakes a mount request even within the same repo, which is unnecessary.Documentation of theBlobInfoCacheinterface and possibly other code