The old implementation only counted full images when sharing content
between them. That is wrong, the store is layer based. We can have two
images with no parent image that shares layers.
As such get rid of the image tree that only is able to walk child/parent
images. Instead we actually walk all layers now and correctly notice
when they are shared.
To this this correctly, first convert all layers to map so we can look
them up by ID. And add missing size information if needed. Then we walk
all images layers and count how often each layers is used. Then walk
again but this time we know if the layer size must be shared or not so
we can actually acount things correctly.
Fixes: containers/podman#24452
Fixes: https://issues.redhat.com/browse/RHEL-29641
Signed-off-by: Paul Holzinger <pholzing@redhat.com>
To prevent the podman remote client from using libimage which causes a
lot of bloat due the c/image and c/storage dependencies add the
`!remote` tag.
This will cause a hard compile time failure if the remote client ends up
pulling in libimage.
Fixes#1702
Signed-off-by: Paul Holzinger <pholzing@redhat.com>
Computing the layer tree requires listing all images. Certain code
paths have all images at hand already, so let's optimize a bit to
avoid listing them redundantly.
Signed-off-by: Valentin Rothberg <vrothberg@redhat.com>
It turns out only counting the layers size is not sufficient for
`podman systemd df` as it excludes the size of the manifests, configs
and potentially attached meta data in the storage.
Instead, sum the image sizes but distract redundant layers. That indeed
gives the expected result and does not yield negative results for
reclaimable space.
Remove the unrelease LayersDiskUsage function again to avoid expensive
recalculation of the layer tree. We are still below 1.0, and I am
convinced the total image size belongs into DiskUsage.
NOTE: The DiskUsage function does not have test coverage in libimage.
This should be addressed at some point but in the interest of
time I leverage podman's system tests.
Signed-off-by: Valentin Rothberg <vrothberg@redhat.com>
Add an API to query the sum of the layer sizes. This data is needed to
fix containers/podman/issues/16135.
Signed-off-by: Valentin Rothberg <vrothberg@redhat.com>
Make sure to check an image for corruption before running disk usage on
it. Such checks are already applied on various execution paths but not
yet on disk usage.
Further update the corrupted-image error to include that the image
should be removed to resolve the error. This should ultimately guide
users to resolve the issue.
Fixes: containers/common#751
Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
The following changes were not split into smaller commits since the
entire package is still work in progress and I want to keep moving:
* Various small fixes.
* The internal image cache has been removed as it's a recipe for
inconsistencies for longer running processes. This should make
libimage easier to use for CRI-O and a Podman service.
* LookupImage now returns storage.ErrUnknownImage rather than nil.
This simplifies the callers and makes sure we have a consistent
error.
* LookupImage is now able to handle manifests lists. Unless the
platform is explicitly ignored via the options, the matching
image within the manifest list is now returned. This greatly
simplifies the spec generation in Podman; no callers should have
to worry about this kind of detail.
* LookupImage has been refactored into smaller-sized and easier to
read functions.
* RemoveImages has been changed to assemble the data of removed or
untagged images. This comes in handy for pruning images. I am
heavily against having a dedicated API for pruning since the it's
really just a combination of filtering and removing images which
RemoveImages already supports. Hence these changes to satisfy
the needs of `podman image prune`.
Furthermore, it now returns an []error slice rather than a single
error. Again to make Podman happy which needs to inspect *all*
errors for setting the appropriate exit code.
* A rather large refactoring of the removal code along with very
verbose comments. Those were largely absent in the Podman code base
but there many rules and contracts embedded that I partially could
only reconstruct by manually tests and comparing to Docker.
* Add a new `containers={true,false}` filter which allows filtering
images whether they are used by containers (=true) or if no container
is using them (=false). This filter is required for pruning images
in Podman.
* `libimage/types` has been merged into `libimage`. Podman has to do
_a lot of_ massaging for the remote client already and the types
are pretty much nailed down for the remote API. Hence, I prefer to
do some translation between `libimage` types and what Podman needs
rather than splitting `libimage` in half without an obvious reason.
This way the package is self-contained allowing for an easier
navigation and maintenance.
* `libimage.PullPolicy` has been merged into `pkg/config.PullPolicy`
to have _one_ central place to deal with pull policies. The type
system in `pkg/config` sets "always" as the default unfortunately
but I think consistency is more important at that point.
* Added `CopyOptions.DirForceCompress` to enforce layer compression
when copying to a `dir` destination.
* We now use `github.com/disiqueira/gotree` for pretty printing image
trees. That greatly simplifies the code and we don't have to worry
about the logic of printing a tree. Note that trees are now always
printed top down!
* Added a new `libimage.ManifestList` type along with an API for local
lookups and performing certain operations on it to wrap around
`libimage/manifests` as previously done in `libpod/image` and other
places in Podman.
* Correct caching of `(*Image).Inspect`.
* In addition to username, password and credentials, allow for
speciying an identity token for copying images. That's needed for
Podman's remote API.
* Make image removal more tolerant toward corrupted images.
* A new "until=timestamp" filter that can be used by all APIs
supporting filtering.
* An empty string now resolves to PullPolicyMissing.
* `(*Runtime) systemContextCopy()` returns a deep copy of the runtime's
system context. Golang's shallow copies are very dangerous for long
running processes such as Podman's system service. Hence, we need to
make sure that base data is not altered over time. That adds another
external dependency but I do not see a way around that. Long term,
I desire a `(*containers/image/types.SystemContext).Copy()` function.
Signed-off-by: Valentin Rothberg <rothberg@redhat.com>