Commit Graph

124 Commits

Author SHA1 Message Date
Giuseppe Scrivano 857a813795
docker: add workaround for CloudFront
CloudFront returns an unquoted ':' in the boundary, special handle it.
It is needed for partial pulls from quay.io.

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
2022-05-11 21:11:23 +02:00
Giuseppe Scrivano 6ef30ef088
docker: validate received parts
validate that the server returns the number of chunks we requested.

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
2022-05-11 15:19:46 +02:00
Miloslav Trmač 15e689d480 Don't require a Docker-Content-Digest header when deleting images
Per https://github.com/containers/image/issues/1010 , it seems
the header is not populated by AWS ECR.

We were actually computing the digest from the manifest bytes
already, so this is both more robust and simpler.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-04-22 17:46:34 +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č 5a4b8a4038 Use url.Redacted() in log output
... to be at least a bit protected against credentials in logs.

I did try to find all uses, but it's possible I have missed some.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-03-17 20:35:00 +01:00
Miloslav Trmač fa54b28a4d Modify makeRequestToResolvedURL and makeRequestToResolvedURLOnce to accept an *url.URL
This is, sadly, wasteful, because NewRequestWithContext() only accepts
a string and parses it again, but it gives us more type safety, and simplifies
at least some callers.

Most importantly, this will also allow us to call url.Redacted() for logging.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-03-17 20:35:00 +01:00
Miloslav Trmač f8c38d073e Add private.ImageSource and internal/imagesource.FromPublic
Following the now-established pattern, introduce private.ImageSource
(with a new SupportsGetBlobAt() method), implement it in
dockerImageSource, and use a wrapped version in c/image/copy.

This gives us private.ImageSource and private.ImageDestination,
to allow for future features.

Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-02-12 03:28:54 +01:00
Miloslav Trmač 1c2b3fa71d Rename private.ImageSourceSeekable to BlobChunkAccessor
The way we actually use this, injecting a progress-reporting
proxy, the PutBlobPartial method doesn't have access to the
full ImageSource; so, differentiate more clearly between
this small interface and an ImageSource.

Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-02-12 03:27:56 +01:00
Miloslav Trmač 98f24f0af0 Rename internal/types/types.go to internal/private/private.go
The goal is to establish a practical/convenient naming for
internal-only interfaces, now that we are going to start using them
much more frequently.

Design concerns:
- Don't duplicate any public package name (to avoid the
  publicTypes/internalTypes names in every single user).
  Rules out "types", "image" (as in "image.Destination").
- Don't just use "internal", to keep that around for
  very localized private utilities, like oci/internal

"private", as a more or less synonym to "internal", seems
to work acceptably well: we will have types.ImageDestination
and private.ImageDestination.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-02-11 10:17:34 +01:00
Kohei Tokunaga 3c00f20f21 Fix c/image fails to pull OCI image with non-`http(s)://` urls
Signed-off-by: Kohei Tokunaga <ktokunaga.mail@gmail.com>
2021-11-16 16:47:03 +09:00
Miloslav Trmač 550a81f757 Handle the GetBlobAt special cases of HTTP status code in there
No point in handling them in generic code, and callers that
aren't expecting StatusPartialContent could be confused.

Should not change behavior of GetBlobAt; might in change behavior of
other callers if they unexpectedly received the relevant HTTP status
codes.

This ~mechanically moves the code without much restructuring.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2021-08-26 03:33:10 +02:00
Miloslav Trmač 73139e45f8 Remove a res.Body != nil check
Body is guaranteed to be present in client's responses.

Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2021-08-26 03:33:10 +02:00
Giuseppe Scrivano ea19c43cf0
docker: convert fully body to partial requests
ghcr.io converts a multirange request to a 200 response when the
client request too much data.

If the server replies with a 200 status to a partial request then
split the body ignoring any additional content that wasn't requested
by the caller.

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
2021-08-25 21:38:03 +02:00
Giuseppe Scrivano 9548c6c7d1
types: document GetBlobAt chunks assumption
add inline documentation to clarify the expectation for the chunks
specified to the GetBlobAt() function.

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
2021-08-25 21:38:02 +02:00
Miloslav Trmač 2d0e1422ad Use http.Method* constants instead of hard-coded strings
... just for the general principle of avoiding hard-coded
copy&pasted data.

Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2021-07-27 20:51:42 +02:00
Miloslav Trmač 0feff83304 Use http.NewRequestWithContext() instead of http.NewRequest().WithContext()
It is marginally more efficient, and more importantly, simpler.

Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2021-07-27 20:51:42 +02:00
Giuseppe Scrivano 93477e61a3
docker: support partial blob retrieval
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
2021-07-02 14:36:51 +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
Valentin Rothberg f35f0bc85c docker: remove duplicate debug log
Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
2021-06-29 11:16:18 +02:00
xiaoqing 05fa7577cb fix docker.GetDigest docker.makeRequestToResolvedURL docker.getExternalBlob socket leak 2021-03-19 10:03:33 +01:00
xiaoqing 71dd988005 fix GetBlob socket leak
Closes #1177
2021-03-15 12:59:33 +01:00
Qi Wang 6e02506a89 Add check sys != nil
Add check sys != nil

Signed-off-by: Qi Wang <qiwan@redhat.com>
2021-01-27 17:04:24 -05:00
Qi Wang a3a6d008f4 Add DockerLogMirrirChoice to ctx for log
Add DockerLogMirrorChoice to types.SystemContext for keeping log level of the physical pull source of images.
Crio could set it log the image source if it's from a mirror.

Signed-off-by: Qi Wang <qiwan@redhat.com>
2021-01-08 21:53:55 -05:00
Valentin Rothberg bee33d3549 add comment on CVE-2020-15157
While container/image is not affected by CVE-2020-15157 future
generations may wonder why authentication is turned off on additional
URLs provided by certain blobs.

Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
2020-10-21 09:32:40 +02:00
Qi Wang 701023dd1a Set default rootless sigstore
Set default rootless sigstore to ~/.local/share/containers/sigstore if the caller is non-root.
Export the func ConfiguredSignatureStorageBase() for Podman image sign implementation.
Signed-off-by: Qi Wang <qiwan@redhat.com>
2020-09-18 15:44:24 -04: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
Qi Wang 13e91ac645 Return error body if UnexpectedHTTPResponseError
Format the error message use the response body if the original error is returned as client.UnexpectedHTTPResponseError type

Signed-off-by: Qi Wang <qiwan@redhat.com>
2020-08-31 20:31:10 -04:00
Daniel J Walsh 7810876ebe Coverity found potential nil dereference
Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
2020-08-05 09:54:45 +02:00
Robb Manes fb987b1d36 Add debug line to get Content-Type from manifests
Often, manifests fail to pull because of a MIME type mismatch and have
to be debugged manually to figure out what the server/proxy is sending
the client.  This is much easier to see when it's just printed for you.

Signed-off-by: Robb Manes <rmanes@redhat.com>
2020-05-13 20:38:48 -04:00
Miloslav Trmač d52a99c532 Don't change dockerImageSource.Reference() if a mirror is used
... because that value is used for signature verification.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2020-05-04 16:37:06 +02:00
knqyf263 6b4551b1c6 feat(docker): support docker registry token
Signed-off-by: Teppei Fukuda <knqyf263@gmail.com>
2020-03-12 09:55:28 +02:00
Valentin Rothberg 61096ab725 restrict sizes of inmem processed blobs
Restrict the sizes of blobs which are copied into memory such as the
manifest, the config, signatures, etc.  This will protect consumers of
c/image from rogue or hijacked registries that return too big blobs in
hope to cause an OOM DOS attack.

Note that error message should be improved in a future change to make
sure that it's clear in which code path we hit a limit.

Fixes: CVE-2020-1702
BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1792796
Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
2020-02-03 13:38:42 +01:00
Miloslav Trmač fdf9c68aae Add a log entry after each pullSource access failure
... so that the debug log has timely information about
in-progress pulls, instead of only summarizing it at the end.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2020-01-09 18:02:45 +01:00
Miloslav Trmač 7dc2de0126 Use "Trying to access", not "Trying to pull" in the debug log
We don't say "pull" elsewhere, and it is a bad match (consider
(skopeo inspect) or a cross-registry copy).

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2020-01-09 18:02:45 +01:00
Miloslav Trmač 57586f9a39 Report all errors encountered when trying to use mirrors
Don't change the error format when no mirrors are involved, but record
all errors when they are.

An example error:
(First tried mirrors: [docker.io/library/busybox:thisdoesnotexist: Error reading manifest thisdoesnotexist in docker.io/library/busybox: manifest unknown: manifest unknown]): does-not-exist-primary.example.com/library/busybox:thisdoesnotexist: error pinging docker registry does-not-exist-primary.example.com: Get https://does-not-exist-primary.example.com/v2/: dial tcp: lookup does-not-exist-primary.example.com on 192.168.64.1:53: no such host

This could obviously be improved with various user-focused heuristics
(e.g. prefer mirror TLS/authentication errors to primary DNS not found),
or by dropping unnecessary context in common cases of the individual errors,
but we can tinker with that later.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2020-01-09 18:02:45 +01:00
Miloslav Trmač 62a1caaeee Simplify variable names in newImageSource*
... now that their scope is smaller and we don't need to disambiguate
so much or to be so explicit about their respective purposes.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2020-01-09 16:53:52 +01:00
Miloslav Trmač b1bafa85ee Behavior change: Make all errors in newImageSourceAttempt non-fatal
i.e. try the following mirrors.

The currently fatal cases are:
- newReference fails, i.e. input was completely invalid or :tag@digest.
  That should never happen, but if it did, it could well be pullSource-specific.
- newDockerClientFromEnv fails, which can be several cases,
  but notably the registry being blocked; in that case we should definitely
  try another endpoint.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2020-01-09 16:53:51 +01:00
Miloslav Trmač db99047f67 Split newImageSourceAttempt from newImageSource
... to improve error reporting in the future.

This only moves code, should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2020-01-09 16:51:33 +01:00
Miloslav Trmač 75cb5d58cd Re-add some context to unexpected HTTP status errors
... to indicate the operation that failed

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2020-01-06 17:23:57 +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
Valentin Rothberg d51a7cabae docker: handle http 429 status codes
Consolidate checking the http-status codes to allow for a more uniform
error handling.  Also treat code 429 (too many requests) as a known
error instead of an invalid status code.

When hitting 429, perform an exponential back off starting a 2 seconds
for at most 5 iterations.  If the http.Response set the `Retry-Header`
then use the provided value or date to compute the delay until the
next attempt.  Note that the maximum delay is 60 seconds.

Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
2019-10-18 11:47:57 +02: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
Miloslav Trmač 77bd7e015d Use map literals for headers intead of explicit updates
This is trivially more readable, and hopefully easier to optimize.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2019-06-19 23:12:09 +02:00
Miloslav Trmač b47f2ebc4e Remove a no longer accurate comment
Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2019-06-19 22:49:50 +02:00
Valentin Rothberg 0ed266902e docker: delete: support all MIME types
Accept the types listed in `manifest.DefaultRequestedManifestMIMETypes`.

Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
2019-06-18 10:56:31 +02:00
Valentin Rothberg 026dc96aad docker: allow deleting OCI images
Fixes: containers/skopeo/issues/667
Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
2019-06-17 11:28:05 +02:00
Miloslav Trmač 84a0069b42 RFC: Drastically simplify the documentation of newImageSource
Revert the public docstring to only say what the caller needs to know.
Drop most of the contents entirely, as this should be clear from the
code or from containers-registries.conf.5.md; move a bit inside
the function.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2019-06-08 21:43:13 +02:00
Valentin Rothberg 9713e6dc23 sysregistriesv2: add mirror-by-digest-only attribute
Add a new mirror-by-digest-only attribute to the registries configuration.
If set true, mirrors will only be consulted when the passed reference
includes a digest.

To facilitate using the API, add a new method
`PullSourcesFromReference(reference.Named) ([]PullSource, Error)`.
The new `PullSource` type contains an `Endpoint` and a written
reference.  `Endpoint.RewriteReference(...)...` is now private.

Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
2019-05-27 16:23:27 +02:00
Miloslav Trmač f71a964cdd Make very sure that newImageSource can never fail with a nil error.
This can never happen with the current code, but making sure that will
continue to be the case in the future does not cost any extra lines.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2019-05-13 22:32:43 +02:00