Commit Graph

187 Commits

Author SHA1 Message Date
Paul Holzinger 093536c0d6
docker: expand use of UnexpectedHTTPStatusError
So that callers can actually check the status code of all requests if
needed. This changes error text slightly but I think it still carries
the same meaning.

Signed-off-by: Paul Holzinger <pholzing@redhat.com>
2025-03-24 11:47:48 +01:00
Miloslav Trmač 01036eb5bd Avoid an allocation when iterating over WWW-Authenticate headers
Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2025-03-12 20:16:50 +01:00
warjiang 4d39b3e2c6 feat: add proxy for http client in dockerClient
Signed-off-by: warjiang <1096409085@qq.com>
2025-03-12 08:12:07 +08:00
Miloslav Trmač 4dd6f6eeb7 Don't silently ignore errors determining size in TryReuseBlob
When looking for inexact matches, this will cause the matches to be skipped.
When checking for an exact match, this will cause an upload failure;
we don't have any other way to handle pre-existing blobs on the destination.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2025-03-11 20:10:11 +01:00
dingwenjiang 56e64f4ee5 fix: typo err and grammar err
Signed-off-by: warjiang <1096409085@qq.com>
2025-03-06 07:36:12 +08:00
Miloslav Trmač ccd291ec72 Validate digests of data downloaded while fetching sigstore attachments
This is not a security vulnerability because the registry can just as well
send a manifest modified to match, but doing this correctly protects us
in case this function were used for other purposes in the future.

Fixes #2687.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2025-01-21 22:53:05 +01:00
Carlos Rodriguez-Fernandez 2e5c4f43b9 registry: remove ping v1
The ping v1 happens when the ping v2 fails, however, it causes the ping
v2 error to be skipped and not output to the user. As result, when a
registry has v1 and v2 enabled, and there are, for example, intermittent
connectivity issues making the ping v2 fail, the user is presented with
a misleading error saying "can't talk to V1 registry."

Since the only use of v1 is for the search API as a workaround for
docker.io, and new container registries setups are very unlikely to be
v1-only, there is little utility in keeping this v1 detection in the
attempt to help the user realize their setup is v1-only, hence not
compatible. On the contratry, it just presents the user with a
misleading error in certain circumstances.

Signed-off-by: Carlos Rodriguez-Fernandez <carlosrodrifernandez@gmail.com>
2024-10-02 15:13:10 +02:00
Miloslav Trmač d6f4f35c13 Move newBearerTokenFromHTTPResponseBody closer to its callers
Only moves unchanged code, should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2024-07-09 22:32:31 +02:00
Miloslav Trmač 9b43674741 Remove unnecessary fields from bearerToken
These fields need to exist when parsing JSON; but we can just
record the outcome of processing them.

Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2024-07-09 22:32:31 +02:00
Miloslav Trmač dc3703be47 Make bearerToken.Token private
No need to make it a public field now.

Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2024-07-09 22:32:31 +02:00
Miloslav Trmač 57d7e83476 Split the token storage type from the JSON representation
We will want to add locks and more to the in-memory type;
sharing that with JSON gets awkward, and an explicit separation
between the externally-imposed structure and internal records
is cleaner anyway.

For now, just introduces a separate type with the same structure,
should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2024-07-09 22:32:31 +02:00
Miloslav Trmač 2044bb9412 Include more data when we fail to fetch a token
Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2024-06-20 18:13:57 +02:00
Miloslav Trmač b9806105bb Turn newBearerTokenFromJSON into newBearerTokenFromHTTPResponseBody
... so that we have more context for error reporting.

Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2024-06-20 18:13:57 +02:00
Miloslav Trmač 23d7e70104 Recognize "manifest unknown" errors reported by Harbor
... per data in https://github.com/containers/image/issues/2203 .

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2024-05-16 18:19:56 +02:00
Miloslav Trmač f2743a47eb Call .Validate() before digest.Digest.String() if necessary
... to prevent unexpected behavior on invalid values.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2024-05-09 15:59:42 +02:00
Miloslav Trmač 7677dfc084 Use the new built-in min operator
Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2024-04-22 20:24:17 +02:00
Giuseppe Scrivano 67a0466f82
docker: use fileutils.(Le|E)xists
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
2024-04-11 10:24:26 +02:00
Miloslav Trmač 77f9d7b585 Make sure we close the response body before retrying
Not doing so can keep the HTTP client code waiting forever,
keeping some goroutines running, and the socket open.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2024-04-05 18:50:41 +02:00
Miloslav Trmač 489cf6391f Exit early if we don't get a HTTP response at all
The idea of a StatusTooManyRequests retry loop,
or the needsRetryWithUpdatedScope logic,
only makes sense if we do get a response; on other errors,
we can exit immediately. So do that, and simplify the
code.

Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2024-04-05 18:50:28 +02:00
Miloslav Trmač 0889f390c3 Use multierr.Format where possible
This may make errors visible to errors.As/errors.Is

This commit, in general, attempts not to change the formatting;
only in newShortNameAliasCache, the order of the errors is no longer
reversed.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2024-04-03 15:31:49 +02:00
Miloslav Trmač 617cc82192 Use strings.CutPrefix and strings.CutSuffix
Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2024-03-09 22:37:40 +01:00
Miloslav Trmač 321d0ecc52 If we fail fetching a blob from external URLs, report all failures
Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2024-02-28 13:31:53 +01:00
Miloslav Trmač a37169cfb9 Return early in getExternalBlob
Simplify the possible states when we exit the loop

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2024-02-28 13:31:41 +01:00
Miloslav Trmač 6dd8c80a60 Don't ignore errors reaching out to external layer URLs
Instead, fail, as the code originally intended to do, before
this was broken in fa54b28a4d .

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2024-02-28 13:31:29 +01:00
Miloslav Trmač 5fa5fc7e2f Rename err to remoteErrors
... thus exposing that we never set this variable.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2024-02-28 13:31:09 +01:00
Boaz Shuster 31bd235848 Fix podman search for docker.io/library images
Signed-off-by: Boaz Shuster <boaz.shuster.github@gmail.com>
2023-10-10 11:00:40 +03:00
Miloslav Trmač 91536efe43 UNTESTED: Log warnings on a Warning: header
... as now requested by distribution-spec.

Untested apart from the added parser unit test.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2023-08-10 19:49:43 +02:00
Miloslav Trmač 62f49acd3e opencontainers/distribution-spec does not require errors to carry JSON
... so update one of our checks to rely on the specified status (only).

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2023-08-10 19:49:32 +02:00
Miloslav Trmač d2c9b633ef Inline serverDefault() into the only caller
... eliminating obsolete comments.

Alternatively, we could call tlsconfig.ServerDefault(),
but let's get closer to just delegating to the standard library
rather than managing TLS policy ourselves.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2023-06-13 02:24:17 +02:00
Miloslav Trmač 272a5cecee Don't specify tls.Config.MinVersion: tls.VersionTLS10
As of Go 1.18 (which we require), this effectively bumps the minimum to TLS 1.2.

Compare 626c097f8c
updating to TLS 1.2; it is similarly not configurable.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2023-06-13 02:24:17 +02:00
Giuseppe Scrivano d59be6c43e
client: enable HTTP(S) keep-alive
Enable HTTP(S) keep-alive to improve network performance and reduce
latency.  We need several HTTP(S) requests before we get to request the
blob and each of them requires a new HTTP(S) connection and that slows
down significantly pulling images, especially on networks with a
higher latency (e.g. wifi).
This will allow multiple requests to be sent over a single connection,
reducing the overhead of establishing new connections for each
request.

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
2023-02-28 10:16:35 +01:00
Miloslav Trmač bca868f393 Fix various unused parameters
Usually by removing them, sometimes by actually using an already-available value.

golangci-lint linter: unparam

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2023-02-14 19:46:41 +01:00
Daniel J Walsh 30568e81f8
Run codespell on codebase
Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
2023-02-09 09:12:11 -05:00
Miloslav Trmač e24c75a02d Reconnecting blob reader
This is quite loud in case it decides not to reconnect,
so that we can have an idea of the failing situations.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2023-02-07 03:16:35 +01:00
Miloslav Trmač fe61085215 Split dockerClient.resolveRequestURL from makeRequest
Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2023-02-07 03:16:35 +01:00
Miloslav Trmač f2c0a16b78 Use short-form assignments in various places
golangci-lint linter: gocritic

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2023-02-06 21:23:14 +01:00
Miloslav Trmač 546a218a9c Use strings.Cut instead of strings.SplitN
Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2023-02-03 18:33:20 +01:00
Miloslav Trmač 9352751cab Move the docker client User-Agent value to a shared subpackage
... to be also used by Fulcio.

Note that the atomic: transport uses a skopeo/... user agent,
we don't care to change that.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2023-01-11 11:23:59 +01:00
Miloslav Trmač b73674f854 Fix comments about exponential backoff with Retry-After
Clarify that exponential backoff only happens if the registry
does not specify otherwise.

And in parseRetryAfter , do not talk about backoff at all, because
that function is not involved in that.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-12-09 04:36:05 +01:00
Miloslav Trmač fc2d96959d Rename all "url" variables to something else
... to minimize the risk of calling url.Parse on the wrong thing.

Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-10-26 16:13:05 +02:00
Miloslav Trmač 524ce57987 Recognize invalid error responses of registry.redhat.io
... when checking for missing images.

In particular, this is necessary for use-sigstore-attachments not to
cause failures when pulling from registry.redhat.io.

Red Hat internal reference: RITM1310318

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-10-13 22:21:34 +02:00
Miloslav Trmač 5b6c858c67 Use registryHttpResponseToError in many more places
... instead of httpResponseToError, or even raw manual error
logging.

NOTE: This breaks status-based checks, like 401 and 429.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-10-12 21:48:04 +02:00
Miloslav Trmač 5283de11ce Discard any but the first element of errcode.Errors
... to simplify user-visible error messages, and to make the
errors less ambiguous for errcode.ErrorCoder testing.

NOTE: This may break callers that expect the full errcode.Errors.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-10-12 21:48:04 +02:00
Miloslav Trmač d112de37a2 Consolidate handleErrorResponse calls to registryHTTPResponseToError
... so that we can modify the handleErrorResponse consumption
logic in one place.

Note that this may change the user-visible error message.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-10-12 21:48:04 +02:00
Paul Holzinger 49113724f1
Remove github.com/docker/distribution/registry/client package
Using the github.com/docker/distribution/registry/client package will
import many huge prometheus dependencies, e.g.
 * github.com/prometheus/client_golang/prometheus/promhttp
 * github.com/prometheus/client_golang/prometheus
 * github.com/prometheus/procfs
and even more...

All of these dependencies are completely unused AFAICT but will still end
up in a binary because they are imported transitive.

github.com/docker/distribution/registry/client is only used to check
http errors so I think it makes sense to copy only the required code
into the docker package.

I vendored this commit into podman and it saves over 700KB in binary
size.

Signed-off-by: Paul Holzinger <pholzing@redhat.com>
2022-09-06 18:40:49 +02:00
Ralf Haferkamp 3ce7f05c93
docker_client: Handle "invalid_scope" errors
By default docker_client just uses the auth challenges from the /v2/
ping request to request a Bearer Token. For some requests (e.g. for
/v2/_catalog on some registries) this might not be sufficient and return a
a HTTP Unauthorized Error with the "www-authenticate" header including
an "insufficient_scope" error. In that case the client will now retry
the request and fetch a new token with updated challenges to have the
"scope" matching for what the endpoint needs.

This fixes https://github.com/containers/image/issues/1478

Signed-off-by: Ralf Haferkamp <rhafer@suse.com>
Signed-off-by: Ralf Haferkamp <ralf@h4kamp.de>
Signed-off-by: Dan Čermák <dcermak@suse.com>
Signed-off-by: Miloslav Trmač <mitr@redhat.com>

Co-authored-by: Miloslav Trmač <mitr@redhat.com>
Co-authored-by: Ralf Haferkamp <ralf@h4kamp.de>
2022-08-30 09:02:36 +02: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č df1b3a7d24 Refer to sigstore instead of cosign in most places
Note that this involves an incompatible signature binary format change.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-07-12 13:11:29 +02:00
Miloslav Trmač c1a12dccd3 Refer to lookasideStorage instead of signatureStorage in code
... to be consistent and specifically refer to that mechanism
now that there are several.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-07-11 22:05:13 +02:00
Miloslav Trmač 68d7040269 Add support for reading and writing Cosign attachments, incl. signatures
NOTE design decisions:
- We can read Cosign data from lookaside
- We ONLY write Cosign data to Cosign attachments, never
  to lookaside; because lookaside is set up by default, that
  would be too confusing.
- We ONLY use Cosign attachments at all if the user opts in
  via registries.d.

  One concern is performance impact of the extra round-trip
  for large-scale operations like (skopeo sync).

  Short-term, a much more worrying is the risk that we probably
  have the "is this failure just a missing atachment manifest,
  or a real failure reading it?" heuristic wrong, so without an
  opt-in, _all_ image reads are going to fail.  This might eventually
  go away after more testing.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-07-07 14:53:16 +02:00