Commit Graph

78 Commits

Author SHA1 Message Date
Miloslav Trmač b941c6bf41 Add private.ImageDestination.NoteOriginalOCIConfig
For now, this only adds the API, nothing actually benefits from
it yet.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2024-11-28 19:34:59 +01:00
Miloslav Trmač 91d22b295c Introduce private.ImageDestination.CommitWithOptions
This only adds an API method, it does not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2024-11-04 17:22:49 +01:00
Miloslav Trmač 04deef6fe6 Call .Validate() before digest.Hex() / digest.Encoded()
... to prevent panics if the value does not contain a :, or other unexpected
values (e.g. a path traversal).

Don't bother on paths where we computed the digest ourselves, or it is already trusted
for other reasons.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2024-05-09 15:59:32 +02:00
Giuseppe Scrivano 21beb2820d
directory: use fileutils.(Le|E)xists
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
2024-04-11 09:54:09 +02:00
Miloslav Trmač ffd21be778 Rename *BlobMatchesRequiredCompression to *CandidateMatchesTryReusingBlobOptions
... because we will add more reasons to reject a match.

Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2024-02-02 23:19:37 +01:00
Aditya R 4f8c03922a
blob: TryReusingBlobWithOptions consider requiredCompression if set
TryReusingBlob now contains a new option `RequiredCompression` which
filters the blob by checking against a compression of the blob which is
considerd to be resued, in case `RequiredCompression` is set and `info`
of the blob being reused does not matches, no blob is returned.

Signed-off-by: Aditya R <arajan@redhat.com>
2023-07-12 23:58:41 +05:30
Miloslav Trmač d9a7aa0631 Return private.UploadedBlob from PutBlobWithOptions
This is a subset of types.BlobInfo the transports
actually should deal with, to be much more explicit
about what the transports are responsible for.

Should not change behavior, in practice.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2023-03-22 22:31:42 +01:00
Miloslav Trmač d12d1d1b59 Return private.ReusedBlob from TryReusingBlobWithOptions
This is a subset of types.BlobInfo the transports
actually should deal with. Also tighten the semantics a bit,
to be much more explicit about what the transports are responsible for.

This allows us to stop tracking MIME types in storage.addedLayerInfo,
so simplify that.

Then fix the generic code so that blob annotations are not discarded
on blob reuse.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2023-03-22 22:31:26 +01:00
Pedro Tôrres b8aad11d36
set directory transport destination as thread-safe
Signed-off-by: Pedro Tôrres <t0rr3sp3dr0@gmail.com>
2022-10-13 16:30:37 -03:00
Sascha Grunert 849dd70143 Switch to golang native error wrapping
`github.com/pkg/errors` is deprecated since quite some time so we now
use the native error wrapping for more idiomatic golang.

Signed-off-by: Sascha Grunert <sgrunert@redhat.com>
2022-07-13 16:50:50 +02:00
Miloslav Trmač a5ad6604a4 Introduce ImageDestination.PutSignaturesWithFormat
NOTE: This makes implementation choices:
- dir, docker LOOKASIDE, ostree and storage are going to store the
  generic-format blobs, and can represent any future formats
  of signatures.
- docker X-R-S-S and OpenShift only accept simple signatures,
  and fail when copying the other kind.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-07-07 13:44:22 +02:00
Miloslav Trmač 85db72593e Add Imagedestination.impl.Properties.AcceptsForeignLayerURLs
Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-07-02 01:34:26 +02:00
Miloslav Trmač c3e1251c58 Add imagedestination.impl.Properties.DesiredLayerCompression
Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-07-02 01:33:50 +02:00
Miloslav Trmač 52f1c33976 Add imagedestination.impl.Properties.SupportedManifestMIMETypes
Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-07-02 01:33:19 +02:00
Miloslav Trmač eed518d05d Add internal/imagedestination/impl.Properties, use it to reduce boilerplate
It's very annoying that Go allows silent zero-initilization,
and we have neither mandatory constructors nor parameter labels,
i.e. a forgotten field does not cause a compile-time error.  For _private_
transport implementations, relying on human review is just about acceptable.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-07-02 01:32:31 +02:00
Miloslav Trmač bebd5b6c59 Add stubs.NoSignatures and stubs.AlwaysSupportsSignatures, use them in transports
Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-07-02 01:32:02 +02:00
Miloslav Trmač 5e75f679a6 Implement private.ImageDestination in non-forwarding transports
This sets up the precedent that all transports should primarily implement
the private interface; that will allow us to make future changes to the
private interface easier, because we can just change the public interface
wrappers in a single place instead of modifying transports - especially
as more stubs are added soonish.

Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-07-02 01:29:14 +02:00
Miloslav Trmač 1799b98724 Only create dirImageDestination when all checks are done
This makes it clearer that dirImageDestination is only
used in a valid state.

Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-07-02 01:25:23 +02:00
Miloslav Trmač 1eb6aa9ba9 Replace uses of perrors.New with errors.New
This removes the stack trace, potentially visible
to callers.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-06-30 22:55:36 +02:00
Miloslav Trmač 72550dd582 Always refer to pkg/errors as perrors
This will allow imports of errors and pkg/errors to
coexist in a single package, avoid adding accidental
new uses via errors.New(), make any potential new
additions more visible in reviews.

Files that can import errors only (typically
because they only use errors.New) have been updated to
that import instead of renaming.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-06-30 22:04:10 +02:00
Miloslav Trmač 3852bb9a83 Fix typos
Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-06-30 21:47:41 +02:00
Miloslav Trmač 6accca5e04 Remove uses of errors.Errorf
This means we won't save the stack, which is cheaper
(and possibly might break callers' format strings that
want to print the stack, but we never promised the stack
to be available).

Use either fmt.Errorf, or errors.New (usually as a local
edit, not carring about errors.new vs. pkg/errors.New;
that's going to be cleaned up later).

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-06-30 21:45:07 +02:00
Miloslav Trmač 7152f888b9 Update users of deprecated io/ioutil
Mostly just name changes that should not change behavior,
apart from ioutil.ReadDir -> os.ReadDir avoiding per-item
lstat(2) in some cases.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-04-13 20:46:48 +02:00
Miloslav Trmač bc2f150462 Don't unnecessarily compute the blob digest in PutBlob
Introduce internal/putblobdigest.Digester to encapsulate
the two alternatives, so that the PutBlob implementations only
need to plug it in.

Then use it throughout: let PutBlob use caller-provided digest
values, if any (and they use the right algorithm).

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2021-08-23 14:58:56 +02:00
Miloslav Trmač a2c13e95f7 Reorganize PutBlob implementations a bit
Mostly remove some extra variables, instead modify stream
by wrapping it in io.TeeReader()s.

In dockerImageDestination, move more of the pipeline
construction outside of the uploadReader closure, and
use consecutiveio.TeeReader()s instead of io.MultiWriter.

Should not change (observable) behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2021-08-23 14:58:56 +02:00
Miloslav Trmač 91075c973b Rename computedDigest to blobDigest
It will not always be computed in PutBlob in the future.

Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2021-08-23 14:58:55 +02:00
Miloslav Trmač 9b911933cf Document that PutBlob callers must only provide validated digests
This was always sort of implied, and we now rely on that explicitly
to avoid computing the digests; it turns out the digest computation
can consume a very noticeable amount of CPU time.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2021-08-23 14:58:55 +02:00
Silvio Moioli e3f0cac14a
Prevent simultaneous compression and decompression
Signed-off-by: Silvio Moioli <moio@suse.com>
2021-07-27 14:20:45 +02:00
Silvio Moioli 401b391cc1
refactoring per PR comments
Signed-off-by: Silvio Moioli <moio@suse.com>
2021-07-27 14:04:18 +02:00
Silvio Moioli 3556c3159a
Add support for decompressing while copying to dir://
Signed-off-by: Silvio Moioli <moio@suse.com>
2021-07-27 13:51:14 +02:00
Daniel J Walsh 1f79791095
Do not prepend Error on each wrapped error message.
Podman and other tools already add Error: to the front of returned error
message, and this ends up as a stutter.

podman pull fedora.io/fred
Trying to pull fedora.io/fred:latest...
Error: Error initializing image from source docker://fedora.io/fred:latest: invalid character '<' looking for beginning of value

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
2021-07-01 05:01:27 -04:00
Miloslav Trmač e3aa82e5c9 Document the unparsedToplevel parameter to Commit
... and acknowledge that various tests are strictly speaking
invalid, to reinforce that real callers must not pass nil.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2021-06-22 21:45:50 +02:00
Daniel J Walsh 1fc5bea27b
Fix up errors linter is complaining about
Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
2021-01-19 17:03:52 -05:00
Nalin Dahyabhai 5364600209 blobinfocache: track compression types for locations
Extend the blob info cache to also cache the name of the type of
compression used on a blob that we've seen, or specific values that
indicate that we know the blob was not compressed, or that we don't
know whether or not it was compressed.

New methods for adding known blob-compression pairs and reading
candidate locations including compression information are part of a new
internal BlobInfoCache2 interface which the library's BlobInfoCache
implementors also implement.

When we copy a blob, try to record the state of compression for the
source blob, and if we applied any changes, the blob we produced.

Make sure that when TryReusingBlob successfully uses a blob from the
blob info cache, that it provides compression information in the
BlobInfo that it returns, so that manifests can be updated to describe
layers using the correct MIME types.

When attempting to write a manifest, if a manifest can't be written
because layers were compressed using an algorithm which can't be
expressed using that manifest type, continue on to trying other manifest
formats.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2021-01-16 13:58:15 -05:00
Daniel J Walsh 33bcba75bb
Fix problems found by codespell
Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
2020-09-15 10:17:41 -04:00
Boris Kuschel fd5888f999 Add comment about chmod
Signed-off-by: Boris Kuschel <boris.kuschel@qlik.com>
2020-01-28 08:49:07 -05:00
Boris Kuschel d034e89be5 Windows fixes for dir: destination
Signed-off-by: Boris Kuschel <boris.kuschel@qlik.com>
2020-01-28 08:21:33 -05:00
Miloslav Trmač 0d948696b4 Redefine ImageDestination.MustMatchRuntimeOS to also include architecture
This has arguably been implied (OTOH, also arguably, it's a breaking change),
make it explicit.

This does not yet implement the semantics.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2019-11-22 15:46:14 +01:00
Miloslav Trmač 7d9cde7252 Update to major version v5
> gomove github.com/containers/image/v4 github.com/containers/image/v5
+ a manual edit of go.mod

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2019-10-25 22:27:45 +02:00
Nalin Dahyabhai ca5fe04cb3 Add manifest list support
Add the manifest.List interface, and implementations for OCIv1 Index and
Docker Schema2List documents.

Add an instanceDigest parameter to PutManifest(), PutSignatures(), and
LayerInfosForCopy, for symmetry with GetManifest() and GetSignatures().
Return an error if the instanceDigest is supplied to destinations which
don't support them, and add stubs that do so even to the transports
which would support it, so that we don't break compilation here.

Add a MultipleImages flag to copy.Options, and if the source for a copy
operation contains multiple images, copy all of the images if we can.
If we can't copy them all, but we were told to, return an error.

Use the generic manifest list API to select a single image to copy from
a list, so that we aren't just limited to the Docker manifest list
format for those cases.

When guessing at the type of a manifest, if the manifest contains a list
of manifests, use its declared MIME type if it included one, else assume
it's an OCI index, because an OCI index doesn't include its MIME type.

When copying, switch from using an encode-then-compare of the original
and updated versions of the list to checking if the instance list was
changed (one of the things we might have changed) or if its type has
changed due to conversion (the other change we might have made).  If
neither has changed, then we don't need to change the encoded value of
the manifest.

When copying, when checking for a digest mismatch in a target image
reference, ignore a mismatch between the digest in the reference and the
digest of the main manifest if we're copying one element from a list,
and the digest in the reference matches the digest of the manifest list.

When copying, if conversion of manifests for single images is being
forced, convert manifest lists to the corresponding list types.

When copying, supply the unparsed top level to Commit() by attaching the
value to the context.Context.

Support manifest lists in the directory transport by using the instance
digest as a prefix of the filename used to store a manifest or a piece
of signature data.

Support manifest lists in the oci-layout transport by accepting indexes
as we do images, and stop guessing about Platform values to add to the
top-level index.

Support storing manifest lists to registries in the docker: transport by
using the manifest digest when we're writing one image as part of
pushing a list of them, and by using the instance digest when reading or
writing signature data, when one is specified, or the cached digest of
the non-instanced digest when one is not specified.

Add partial support for manifest lists to the storage transport: when
committing one image from a list into storage, also add a copy of the
manifest list by extracting it from the context.Context.  The logic is
already in place to enable locating an image using any of multiple
manifest digests.

When writing an image that has an instanceDigest value (meaning it's a
secondary image), don't try to generate a canonical reference to add to
the image's list of names if the reference for the primary image doesn't
contain a name.  That should only happen if we're writing using just an
image ID, which is unlikely, but we still need to handle it.

Avoid computing the digest of the manifest, or retrieving the
either-a-tag-or-a-digest value from the target reference, if we're given
an instanceDigest, which would override them anyway.

Move the check for non-nil instanceDigest values up into the main
PutSignatures() method instead of duplicating it in the per-strategy
helpers.

Add mention of the instanceDigest parameter and its use to various
PutManifest, PutSignatures, and LayerInfosForCopy implementations and
their declarations in interfaces.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2019-10-18 15:15:13 -04:00
Miloslav Trmač e568c94ef3 Correctly use a c/image/v4 module namespace
... so that major-version-aware Go module import
(as opposed to vX.Y.Z+incompatible, which does not allow different
packages to use different versions) works right.

Also requires adding some more GO111MODULE=on options to Makefile.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2019-10-03 22:54:27 +02:00
Valentin Rothberg 9a5bfe3c78 ImageDestination: add HasThreadSafePutBlob() method
Add a HasThreadSafePutBlob() method to the ImageDestination interface
and all its implementations to indicate whether the corresponding
PutBlob() method can be executed concurrently.  This is a first step to
enable parallel image copying.  By default, all transports are not
thread-safe and must be carefully migrated in later changes.

Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
2018-12-18 17:15:02 +01:00
Miloslav Trmač d8d866bdc9 Add a "canSubstitute" parameter to TryReusingBlob
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>
2018-12-06 18:59:24 +01:00
Miloslav Trmač 7ad78ecdfd Add a BlobInfoCache parameter to GetBlob, PutBlob and TryReusingBlob.
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>
2018-12-06 18:59:24 +01:00
Miloslav Trmač 223c722a2a Combine HasBlob and ReapplyBlob into TryReusingBlob
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>
2018-12-06 18:59:24 +01:00
Miloslav Trmač 9b4590b549 Add types.ImageDestination.IgnoresEmbeddedDockerReference
This allows a destination to opt out of updating the embedded name:tag in schema1
manifests without violating the ImageDestination.Reference / ImageReference API
expectations.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2018-06-04 16:50:17 +02:00
Miloslav Trmač 2f122a2760 Add TODO notes for places which do a lot of work on the local filesystem
It would be nice if those could be canceled, although so far we seem not
to have any users which would benefit.

Many would be easily handled with a cancelable variant of io.Copy,
but a few might be much more involved.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2018-04-10 19:12:04 +02:00
Mike Lundy 369c44212b Put context.Context arguments on almost everything
- Network IO paths should react to cancels now.
- File IO paths generally still won't.
- `SystemContext` objects have been renamed to `sys` to leave `ctx`
  available for the stdlib context objects.

Signed-off-by: Mike Lundy <mike@fluffypenguin.org>
2018-04-07 04:34:51 -07:00
Antoine Eiche 69b3fccb5c docker-archive generates docker legacy compatible images
docker save generates image compatible with the legacy format, ie,
layers are tar, they have a configuration file and a repositories file
is created.

There are some external tools that still relie on this old format such
as mesos [1] and nixos [2].

[1] 7ca46e24b3/src/slave/containerizer/mesos/provisioner/docker/local_puller.cpp (L168)
[2] 5c6dc717a6/pkgs/build-support/docker/default.nix (L143)

Signed-off-by: Antoine Eiche <lewo@abesis.fr>
2018-03-27 17:34:45 +02:00
umohnani8 2f131cc136 Remove .tar extension from blob and config file names
The config file was being saved as digest.tar for the directory transport.
This is misleading as the config file is not a tar archive.
Dropped the .tar extension from all files now, including blobs.
The user can use a tool like file to determine the format of the files in the directory.

Signed-off-by: umohnani8 <umohnani@redhat.com>
2018-02-20 13:54:30 -05:00