Commit Graph

111 Commits

Author SHA1 Message Date
Miloslav Trmač 7466f0d0df Remove a redundant check
err must be nil at that point.

This also un-indents the success case, so that
it proceeds as a straight-line code.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-04-22 16:07:46 +02:00
Nalin Dahyabhai c10f77d7ef layerStore.Put(): update digest-based indexes when creating from templates
When we're creating a layer using another layer as a template, add the
new layer's uncompressed and compressed digest to the maps we use to
index layers using those digests.

When we forgot to do that, searching for a layer by either would still
turn up the original template, so this didn't really break anything.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2022-04-18 15:11:38 -04:00
Nalin Dahyabhai 9395518b1c layerStore.PutAdditionalLayer(): fix a copy/paste error
We mistakenly mixed up the uncompressed and compressed digests when
populating the by-uncompressed-digest map.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2022-04-18 15:10:56 -04:00
Nalin Dahyabhai fd507de875 Fully populate layer records for mapped image top layers
When we create a copy of an image's top layer that's intended to be
identical to the top layer, except for having some set of ID mappings
already applied to it, copy over the template layer's compressed and
uncompressed digest and size information, compression information,
tar-split data, and lists of used UIDs and GIDs, if we have them.

The lack of sizing information was forcing ImageSize() to regenerate the
diffs to determine the size of the mapped layers, which shouldn't have
been necessary.

Teach the overlay DiffGetter to look for files in the diff directories
of lower layers if we can't find them in the current layer, so that
tar-split can retrieve content that we didn't have to pull up.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2022-04-12 15:39:51 -04:00
Aditya R 5b58ed404e store: add independent AddNames and RemoveNames for images,layers,containers
Adds AddNames and RemoveNames so operations which are invoked in parallel
manner can use it without destroying names from storage.

For instance

We are deleting names which were already written in store.
This creates faulty behavior when builds are invoked in parallel manner, as
this removes names for other builds.

To fix this behavior we must append to already written names and
override if needed. But this should be optional and not break public API

Following patch will be used by parallel operations at podman or buildah end, directly or indirectly.

Signed-off-by: Aditya R <arajan@redhat.com>
2022-03-01 01:33:35 +05:30
Miloslav Trmač e50e11c88c Warn if we are deleting an incomplete layer
... to help diagnosing later possible broken references
to this layer; compare https://github.com/containers/storage/issues/1136 .

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-02-23 13:56:14 +01:00
Giuseppe Scrivano 6e8f3fa03f Merge pull request #1146 from mtrmac/remove-dead-id
Remove dead code
2022-02-22 14:46:25 +01:00
Miloslav Trmač 78814e6e93 Fix a pasto from #1138
Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-02-22 01:32:02 +01:00
Miloslav Trmač 372c810c91 Remove dead code
id is known to be non-empty because we generate
a random value earlier in the function, in that case.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-02-22 00:21:11 +01:00
Miloslav Trmač e25e8e8d00 Try to delete also the metadata of an incomplete layer
Account for the "diff != nil" path; try to remove even
the metadata of a layer on a failure saving.

Not that there's _much_ hope to be able to save
the version without the new layer when we weren't able
to save the version with the new layer.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-02-16 22:32:32 +01:00
Miloslav Trmač 6ede937d25 Log all kinds of failures to delete a layer
Currently, if the attempts to recover from a failure
themselves fail, we don't record that at all.

That makes diagnosing the situation, or hypothetically
detecting that the cleanup could never work, much
harder.

So, log the errors.

Alternatively, we could include those failures as extra
text in the returned error; that's less likely to be lost
(e.g. a Go caller would have the extra text available, without
setting up extra infrastructure to capture logs), but possibly
harder to follow.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-02-16 22:30:31 +01:00
Miloslav Trmač d41e1a3a9d Mark a layer to be deleted on cleanup before instructing the graph driver
Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-02-12 01:18:05 +01:00
Miloslav Trmač ff7070b5b0 Extract layerHasIncompleteFlag from layerStore.Load
Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-02-12 01:18:05 +01:00
Nalin Dahyabhai c09cc9a7fd layerStore.Diff(): don't use an unnecessary buffer
Don't ReadAll() from a Reader to create a buffer and then create another
Reader to read from that buffer.

Don't close a file and a decompressor that we're using to read the
file's contents when we we may still need to read from them after the
current function returns.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2021-12-13 13:14:11 -05:00
Daniel J Walsh ca4c0962c7 Standardize on capatalized logrus messages, and remove stutters
Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
2021-09-23 14:43:35 -04:00
Miloslav Trmač ecbde9d77c Add LayerOptions.OriginalDigest and LayerOptions.UncompressedDigest
This allows callers of Store.PutLayer to provide the values if
they have already computed them, so that ApplyDiff does not need
to compute them again.

This could quite significantly reduce CPU usage.

The code is a bit clumsy in the use of compressedWriter; it
might make sense to implement a ReadCounter counterpart to the
existing WriteCounter.

(Note that it remains the case that during pulls, both c/image/storage
and ApplyDiff decompress the stream; c/image/storage stores the
compressed, not the decompressed, version in a temporary file.
Nothing changes about that here - it's not obvious that changing it
is worth it, and anyway it's a different concept for a different
PR/discussion.)

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2021-08-21 18:30:42 +02:00
Miloslav Trmač 67cee72236 Reorganize uncompressedCounter
Have it count the input to idLogger instead of uncompressedDigester;
they should get exactly the same data, but we are going to make
uncompressedDigester optional.

Also make the uncompressedDigester use a separate line so that we
can later change it more easily.

Should not change (observable) behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2021-08-21 18:30:42 +02:00
Miloslav Trmač e780df10c0 Only compute {un,}compressedDigester.Digest() once
It is a tiny bit expensive, but most importantly
this moves the uses of {un,}compressedDigester so that
we can later make them optional.

Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2021-08-21 18:30:42 +02:00
Miloslav Trmač 5258d1991c Reorganize the "defragmented" reader construction a bit.
Have one section deal with detecting compression and re-assembling
the original stream, and another with computing the length and digest
of the original stream.

Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2021-08-21 18:30:42 +02:00
Miloslav Trmač 86e101b543 Rename {un,}compressedDigest to {un,}compressedDigester
We will need ...Digest variables to hold the actual values.

Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2021-08-21 18:30:42 +02:00
Daniel J Walsh f01f77a489 Merge pull request #990 from rhatdan/main
Add codespell fixes
2021-08-12 06:40:40 -04:00
Daniel J Walsh b949772e2e Add codespell fixes
Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
2021-08-11 16:46:21 -04:00
Nalin Dahyabhai 058152e27a ApplyDiff: compress saved headers without concurrency
When we're applying a diff, we compress the headers and stash them
elsewhere so that we can use them to correctly reconstruct the layer if
we need to extract its contents later.

By default, the compression uses a 1MB block, and up to GOMAXPROCS
threads, which results in allocating GOMAXPROCS megabytes of memory up
front.  That can be much more than we need, especially if the system has
many, many cores.  Drop it down to 1 megabyte.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2021-08-11 16:10:46 -04:00
Sascha Grunert 6ce9c36c9c Reload layer storage if layers.json got externally modified
This helps long running processes like CRI-O to determine changes to the
local storage, while handling corrupted images automatically.

The corresponding fix in Podman [0] handles corrupt layers by reloading
the image. This does not work for CRI-O, because it will not reload the
storage on subsequent calls of pullImage if no storage modification has
been done.

[0]: b4bd886fcc

Signed-off-by: Sascha Grunert <sgrunert@redhat.com>
2021-06-17 13:16:48 +02:00
Daniel J Walsh 96afd93245 Merge pull request #926 from giuseppe/fix-race-reload-store
store: fix graphLock reload
2021-05-27 12:26:57 -04:00
Giuseppe Scrivano f2deb04325 store: ReloadIfChanged propagates errors from Modified()
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
2021-05-27 14:55:42 +02:00
Valentin Rothberg 4f7425fbb1 delete_internal: return error early
Return the error early instead of having big branch to improve
readability of the code.

Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
2021-05-27 10:39:02 +02:00
ktock f1b0a84f71 Enable to export layers from Additional Layer Store
Currently, layers aquired from additional layer store cannot be exported
(e.g. `podman save`, `podman push`).

This is because the current additional layer store exposes only *extracted view*
of layers. Tar is not reproducible so the runtime cannot reproduce the tar
archive that has the same diff ID as the original.

This commit solves this issue by introducing a new API "`blob`" to the
additional layer store. This file exposes the raw contents of that layer. When
*(c/storage).layerStore.Diff is called, it acquires the diff contents from this
`blob` file which the same digest as the original layer.

Signed-off-by: Kohei Tokunaga <ktokunaga.mail@gmail.com>
2021-05-15 10:38:39 +09:00
Daniel J Walsh 05af705288 Merge pull request #775 from giuseppe/zstd-chunked
Enable zstd:chunked support in containers/image
2021-05-14 16:11:58 -04:00
Giuseppe Scrivano 8e3278d821 store: new method ROFileBasedStore.ReloadIfChanged()
add a new method to reload the store information from the hard disk if
has changed.

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
2021-05-13 09:05:42 +02:00
Giuseppe Scrivano fceff1de20 drivers: add interface to directly write diff
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
2021-05-07 11:29:25 +02:00
Nalin Dahyabhai 019495cec4 Use json-iterator instead of encoding/json
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2021-05-06 12:24:24 -04:00
ktock cd3603c1ee Support additional layer store
Signed-off-by: Kohei Tokunaga <ktokunaga.mail@gmail.com>
2021-04-07 17:53:36 +09:00
Giuseppe Scrivano 658fe46698 layers: support BigData
similarly to containers and images, add support for storing big data
also for layers, so that it is possible to store arbitrary data when
it is not feasible to embed it in the layers JSON metadata file.

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
2021-02-02 11:39:03 +01:00
yangfeiyu ca7595ae93 archive: defer close after DecompressStream to fix resource leak
Signed-off-by: yangfeiyu <yangfeiyu20102011@163.com>
2020-10-28 15:56:28 +08:00
Daniel J Walsh 7a78e3b875 Update layers.go
Co-authored-by: Sascha Grunert <sgrunert@suse.com>
2020-10-15 07:27:40 -04:00
Daniel J Walsh f911c269e2 Stop excessive wrapping
Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
2020-10-15 06:08:37 -04:00
Jeff Zvier 9352421cee fix goroutine leak with close tatLogger in a defer clause
Signed-off-by: Jeff Zvier <zvier20@gmail.com>
2020-08-31 19:31:33 +08:00
Daniel J Walsh 15fd16c6df Merge pull request #665 from zvier/master
clean residual resources in layerStore when remove an image
2020-07-13 14:33:28 -04:00
Valentin Rothberg d4fe07e7d8 layer mount: fix RO logic
Fix the logic in an anon-func looking for the `ro` option to allow for
mounting images that are set as read-only.

Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
2020-07-13 11:13:01 +02:00
zvier e1cfe75686 layerStore: clean residual resources in layerStore when remove an image
# - type: feat, fix, docs, style, refactor, test, chore
 # - scope: can be empty (eg. if the change is a global or difficult to assign to a single component)
 # - subject: start with verb (such as 'change'), 50-character line

 body: 72-character wrapped. This should answer:
 # * Why was this change necessary?
 # * How does it address the problem?
 # * Are there any side effects?

 footer:
 # - Include a link to the ticket, if any.
 # - BREAKING CHANGE

Signed-off-by: zvier <zvier20@gmail.com>
2020-07-12 09:02:30 +08:00
Daniel J Walsh 3a39e3355b Allow mounting of Non Read Write images read/only
We want to block the mounting of additional stores, for
read/write, since they will not have any containers associated
with them.  But if a user is mounting an image for read/only
access then their is no reason to block the mount.

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
2020-07-10 10:14:29 -04:00
Ryan Phillips c472f573e6 internalDelete needs the r.byname name deletion 2020-04-14 19:14:53 -05:00
Giuseppe Scrivano 83876673e0 layers: copy UIDs and GIDs
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
2020-03-25 13:58:14 +01:00
Sascha Grunert 1d0785fa5d Remove locking from layer store creation
The `layerstore.Load()` on `new[RO]LayerStore` required a held lock on
store initialization. Since the consumers of the layer storage already
call `Load()`, it should not be necessary to lock on initialization of
the layer store.

Signed-off-by: Sascha Grunert <sgrunert@suse.com>
2020-01-30 10:39:58 +01:00
Sascha Grunert c4785cf391 Revert API break due to lint fixes
Signed-off-by: Sascha Grunert <sgrunert@suse.com>
2020-01-29 11:46:52 +01:00
Sascha Grunert 9f54ec7535 Enable golint linter and fix lints
Signed-off-by: Sascha Grunert <sgrunert@suse.com>
2020-01-28 15:59:15 +01:00
Daniel J Walsh 386fba4147 Check if the layer is actually mounted.
There are cases where the storage database gets out of whack with
whether or not the storage is actually mounted.  We need to check
before returning the mount point.

1 A user could go in and umount the storage.
2 If the storage was mounted in a different mount namespace and then
the mount namespace goes away the counter will never get decremented
even though the mount point was removed.
3. If storage runtime is on non tmpfs storage a system reboot could be
done that will not clear the mount count.

This patch will fix the problem with the layer not being mounted, but
we still have a problem in that we can't figure out when to umount the
image. Not sure that is a solveable problem.

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
2019-12-18 12:26:10 -05:00
Sascha Grunert 1d2afa5536 Lazy initialize the layer store
The layer store gets memoized in any case so we can skip the initial
setup on store load.

Signed-off-by: Sascha Grunert <sgrunert@suse.com>
2019-12-09 15:01:14 +01:00
Nalin Dahyabhai 13bf992e5e layerStore.Load(): don't try to lock the mounts list on cleanup
When cleaning up an incomplete layer, don't call regular Delete() to
handle it, since that calls Save(), which tries to lock the mountpoints
list, which we've already obtained a lock over.  Add a variation on
Delete() that skips the Save() step, which we're about to do anyway, and
call that instead.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2019-09-12 11:17:54 -04:00