Commit Graph

158 Commits

Author SHA1 Message Date
Paul Holzinger 3948fe04a0 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
Giuseppe Scrivano 8a17b37f3d docker: add check for too many parts
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
2024-11-05 10:38:16 +01:00
Daniel J Walsh 720cfdf6c3 Merge pull request #2550 from mtrmac/go1.22
Update to Go 1.22
2024-09-05 14:48:52 -04:00
Miloslav Trmač 2c6f8ce1e4 Iterate over a subslice instead of manually indexing
Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2024-09-05 20:06:37 +02:00
Miloslav Trmač d5751c03c8 Avoid unnecessary array copies when reading signatures
Append the result directly into the returned array,
instead of assembling it from partial pieces.

Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2024-09-05 20:05:55 +02:00
Miloslav Trmač 179c7f5e94 Use for range-over-integers
Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2024-09-05 20:00:25 +02:00
Kohei Tokunaga 1222f85001 Support Additional Layer Store's authenticaiton helper
Signed-off-by: Kohei Tokunaga <ktokunaga.mail@gmail.com>
2024-06-05 15:09:45 +02:00
Giuseppe Scrivano dba3f805d6 docker: support for requesting chunks without end offset
if the specified length for the range is set to -1, then request all
the data possible by using the "Range: <unit>=<range-start>-" syntax
for the HTTP range.

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
2024-05-14 10:37:08 +02:00
Miloslav Trmač 0e36d27572 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č 4d9602260a 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
Urvashi Mohnani b105ca3a66 Add support for pushing image with unknown digest
Add support to push image with unknown digest and no tag to
a registry. This will be used by farm build to construct a list
of multi arch builds after pushing images built on each node.

Signed-off-by: Urvashi Mohnani <umohnani@redhat.com>
2023-12-05 10:48:40 -05:00
Giuseppe Scrivano b910c308d4 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č 1d706db04d Pre-allocate arrays of known size
golangci-lint linter: prealloc

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2023-02-06 21:24:57 +01:00
Miloslav Trmač f37b48d928 Use struct{} instead of interface{} for close-only channels
Let's not even suggset that it it might be necessary to
allocate memory for a value.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2023-02-03 18:34:27 +01:00
Daniel J Walsh 42fe90f92d Do not preallocate regex in init program
We are trying to speed up startup time of apps based on
containers/image regex takes some time on every start
when in init. Moving this to a sync.Once should not
effect any change on the system.

Only changing internal regexp, since changing external would be a
breaking change to the library.

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
2023-01-13 16:49:57 -05:00
Miloslav Trmač d57af9afff 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č bab460d174 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č 7ef62496e4 Add a limit for the total number of signatures in lookaside
... in case a server somehow kept serving an infinite number of valid
signatures.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-10-06 19:12:29 +02:00
Miloslav Trmač f0dd923c65 Heuristically warn about lookaside servers serving HTML
Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-10-06 19:01:24 +02:00
Miloslav Trmač 37eee4cd8d Avoid confusion about 404 on lookaside
Make it explicit in debug logs that 404 on lookaside happened,
and is expected.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-10-06 18:50:25 +02:00
Sascha Grunert 68739a0dc5 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č a1483bc3f2 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č 1e18077ec6 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č f4ae864a5d 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
Miloslav Trmač db2fe3393e Move most of dockerImageSource.GetBlob to dockerClient.getBlob
We need it for writing signatures.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-07-07 14:53:16 +02:00
Miloslav Trmač dd7d5fd4e2 Make most of dockerImageSource.fetchManifest available in dockerClient.fetchManifest
Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-07-07 14:53:16 +02:00
Miloslav Trmač e722902e6a Move loading registries.d from newDockerClientForRef
This is a bit more repetitive in most callers.  The benefit is
that we only read the files once per newImageSource, even if there
are multiple mirrors.

We will also read more items from the config.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-07-07 14:39:50 +02:00
Miloslav Trmač ea74ee6c1c Introduce ImageSource.GetSignaturesWithFormat
Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-07-07 13:44:22 +02:00
Miloslav Trmač 0753e49103 Add impl.DoesNotAffectLayerInfosForCopy, use it to reduce boilerplate
Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-07-05 17:02:24 +02:00
Miloslav Trmač eb05303efe Add stubs.ImplementsGetBlobAt
This is not locally worth it, but it is a proof of the concept,
and consistent with stubs.ImplementsPutBlobPartial.

Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-07-05 17:02:24 +02:00
Miloslav Trmač ea5d182575 Add internal/imagesource/impl.Properties, use it to reduce boilerplate
This matches internal/imagedestination/impl.Properties; it's not
quite worth it for the single value, but the consistency is
attractive.

Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-07-05 17:02:24 +02:00
Miloslav Trmač af3a7a59dd 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č a43a945f93 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č 564fc01baf 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
Giuseppe Scrivano 127b2d579f 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 aa4c5701ca 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č 412b1d40b2 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č b7dab11635 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č 70c841142c 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č ad4e7c3ebd 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č ab22ff6657 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č 1a063d516d 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č 7693db479d 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 6b052ba96b 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č b9021c96eb 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č 85301597b8 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 a61fc0d528 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 d29a50567a 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č 294dd931e5 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č 2e0df2b2b8 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