Skip to content

Conversation

@sallyom
Copy link
Contributor

@sallyom sallyom commented Nov 6, 2020

Allow for multiple image source options when retrieving repository (from icsp, from mirrored)

There may be multiple image source options (from icsp, mirrored) rather than a single image source.
This PR adds registry client Context interface and methods to gather ICSP sources for a given Context.

/cc @smarterclayton
/cc @soltysh

fake bump here: openshift/oc#439

@soltysh
Copy link

soltysh commented Nov 9, 2020

/assign @dmage
who is also looking at the other PR

Copy link
Contributor

@dmage dmage left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, RepositoryList cannot exist.

To create an instance of distribution.Repository, the client sends an HTTP request to the /v2/ endpoint. If the first mirror is available and has all necessary images, the client shouldn't try to access other mirrors nor the original repository. It means distribution.Repository for the second mirror shouldn't be created until the client has checked the first mirror.

On disconnected clusters firewall can drop requests to external registries, i.e. attempt to connect to an external registry can take few minutes. So this extra action may be very time consuming.

@sallyom sallyom force-pushed the alternate-lookup-registry branch 2 times, most recently from 1bc35ad to 4c38c9d Compare November 9, 2020 16:25
@sallyom sallyom force-pushed the alternate-lookup-registry branch 5 times, most recently from b8e5e9e to cae89d2 Compare November 12, 2020 07:07
@sallyom sallyom changed the title registry client: return repository list with multiple image source options (from icsp, mirrored) rather than a single registry client: add RepositoryRetriever interface for choosing repo from multiple image source options (from icsp, mirrored) rather than a single Nov 12, 2020
@sallyom sallyom force-pushed the alternate-lookup-registry branch from 1c57118 to c343a9c Compare November 12, 2020 23:56
@sallyom
Copy link
Contributor Author

sallyom commented Nov 13, 2020

/retest

@sallyom sallyom force-pushed the alternate-lookup-registry branch from c343a9c to 9d13369 Compare November 16, 2020 16:35
@smarterclayton
Copy link
Contributor

Some high level comments:

If we're making a client-specific tradeoff, I think it's best to have that functionality only in oc, since library-go is so widely used.

This is not desirable - it needs to be part of library-go and the general client implementation because the behavior of ICSP is general to all OpenShift clusters, and ICSP is useful to both OpenShift specific commands (oc adm release) and generic registry commands (oc image), and in general no oc command really cares about the details or should have to care.

Oleg raised the point about explicit request to use cluster ICSP vs implicit - and that's a good distinction to make. oc image does not talk to a cluster by default, and should not, because it's generic to registries. A user may want to tell the command to use a cluster ICSP, but that has to be opt in, so it's reasonable to support --use-cluster-icsp on the oc image * commands. Conversely, oc adm release * should be able to honor the cluster ICSP implicitly (because a user can run oc adm release extract --tools and expects the that to succeed regardless). However, for a lot of frequent interactions with the server the contract of oc adm release * in general needs to be fast and looking up the cluster ICSP is not appropriate by default. In a node context ICSP is opinionated and tries to access the exact list order to allow admins to optimize - but when implicitly retrieving a cluster ICSP we can't say for certain that's the best outcome for the user. In specific commands we may very well do so - such as oc adm release mirror or oc adm release new where the ICSP likely has the most performant entry first - because that benefits the admin on an expensive call. However, another goal of ICSP is to improve resiliency, so we have to keep consulting the list of repositories even on subsequent calls to the same distribution.Repository object (i.e. the shim we provide has to have some dynamism).

@sallyom sallyom force-pushed the alternate-lookup-registry branch 4 times, most recently from a3bac30 to 43a99f6 Compare November 20, 2020 00:39
@sallyom sallyom changed the title registry client: add RepositoryRetriever interface for choosing repo from multiple image source options (from icsp, mirrored) rather than a single registry client: add interface for choosing repo from multiple image source options (from icsp, mirrored) rather than a single Nov 20, 2020
@sallyom sallyom force-pushed the alternate-lookup-registry branch from 43a99f6 to f3ae645 Compare November 20, 2020 14:31
@sallyom sallyom force-pushed the alternate-lookup-registry branch from f3ae645 to 043d5bf Compare December 3, 2020 04:59
@sallyom sallyom changed the title registry client: add interface for choosing repo from multiple image source options (from icsp, mirrored) rather than a single registry client: Add AlternativeSources interface and methods to gather sources from ImageContentSourcePolicies Dec 3, 2020
Copy link

@soltysh soltysh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also seem my comments in openshift/oc#439

@sallyom sallyom force-pushed the alternate-lookup-registry branch from 043d5bf to 84548ee Compare December 4, 2020 00:17

alternates []reference.DockerImageReference
icspFile string
icspClient operatorv1alpha1client.ImageContentSourcePolicyInterface
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be in a separate package as discussed before

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cleaned up commits & cherry-picks

"github.com/docker/distribution/registry/client/auth/challenge"
"github.com/docker/distribution/registry/client/transport"
"github.com/opencontainers/go-digest"
imagereference "github.com/openshift/library-go/pkg/image/reference"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This commit merged already - surprised it still shows up here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i cleaned up the commits & cherry-picks, it's no longer there

@sallyom sallyom force-pushed the alternate-lookup-registry branch 2 times, most recently from b436f08 to 0e622f2 Compare April 6, 2021 17:23
@sallyom
Copy link
Contributor Author

sallyom commented Apr 6, 2021

@smarterclayton the small modifications from your commits are in 0e622f2 , otherwise I picked yours and updated the commit msgs

@sallyom sallyom force-pushed the alternate-lookup-registry branch from 0e622f2 to 4acafb6 Compare April 6, 2021 17:28
@sallyom
Copy link
Contributor Author

sallyom commented Apr 6, 2021

@ricardomaraschini can you please run with this PR to detect issues? Thank you, reach out on slack if needed.

@openshift-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: sallyom, soltysh
To complete the pull request process, please assign sttts after the PR has been reviewed.
You can assign the PR to them by writing /assign @sttts in a comment when ready.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@sallyom
Copy link
Contributor Author

sallyom commented Apr 8, 2021

I'm fine with this approach because I can make it work to solve the oc issue, but I prefer the simpler solution https://github.com/openshift/library-go/compare/master...sallyom:icsp_old?expand=1 integrated with oc. @ricardomaraschini afaict verified that solution works for image-registry, however, I don't know if this mirrored_client has been tested with image-registry. oc is not using the majority of the changes introduced here, so I cannot verify them.

// is true, HTTP connections are allowed and HTTPS certificate verification errors will be ignored. The returned
// Repository instance is threadsafe but the ManifestService, TagService, or BlobService are not. Note - the caller
// is responsible for providing a valid registry url for docker.io - use RepositoryForRef() to avoid that.
func (c *Context) Repository(ctx context.Context, registry *url.URL, repoName string, insecure bool) (RepositoryWithLocation, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change made *Context to stop implementing RepositoryRetriever interface. Was that expected?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you currently using that interface? I'm wondering if anybody uses it. I can update the interface though.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, image registry repository leverages this interface in a few places.

@sallyom
Copy link
Contributor Author

sallyom commented Apr 14, 2021

@ricardomaraschini I was able to add back to oc the ICSP logic, so I am now using more of the mirrored_client. Have you tried to run w/ it yet? I don't have it working quite yet, so I think perhaps something in the mirrored_client might need to be tweaked. Or, maybe I have to update my implementation of it in oc - if you have it working it will help! If not, I'll keep working on it.

@sallyom
Copy link
Contributor Author

sallyom commented Apr 14, 2021

@smarterclayton @ricardomaraschini I have the ICSP stuff working w/ the mirrored_client now- using the *WithLocation fns, I'll push to the oc PR so you can check it out I have cleanup w/ that PR but it's working

@ricardomaraschini
Copy link
Contributor

@ricardomaraschini I was able to add back to oc the ICSP logic, so I am now using more of the mirrored_client. Have you tried to run w/ it yet? I don't have it working quite yet, so I think perhaps something in the mirrored_client might need to be tweaked. Or, maybe I have to update my implementation of it in oc - if you have it working it will help! If not, I'll keep working on it.

I have managed to make it work this morning. The problem now (for the image registry) is the one related to the interface I mentioned here.

Other problem I can solve later on is the fact that simpleLookupICSP prefers to try the original repository first before moving to the mirrors and we would like to go for the mirrors first. I can solve that by providing a new implementation of AlternateBlobSourceStrategy.

smarterclayton and others added 6 commits April 22, 2021 12:25
Implements the core of the discussion around supporting multiple
sources of input. Each wrapped method in the mirroredRepository
structure that needs to check alternates (methods that invoke digest
lookups) will use that structure. Methods that cannot be retried
will use the first alternative that has a working client (such as
ServeBlob). Methods that must always use the source (mutable calls
or those that don't deal with a digest) will only look at the
original source, although the logic is structured so we can use
data about these requests in the future.

The strategy is clarified to call either FirstRequest and OnFailure,
or just FirstRequest. Each repository will make a single call to the
strategy, and it's up to the strategy to include the original source
when invoking FirstRequest.
@sallyom
Copy link
Contributor Author

sallyom commented Apr 24, 2021

@ricardomaraschini I was able to add back to oc the ICSP logic, so I am now using more of the mirrored_client. Have you tried to run w/ it yet? I don't have it working quite yet, so I think perhaps something in the mirrored_client might need to be tweaked. Or, maybe I have to update my implementation of it in oc - if you have it working it will help! If not, I'll keep working on it.

I have managed to make it work this morning. The problem now (for the image registry) is the one related to the interface I mentioned here.

Other problem I can solve later on is the fact that simpleLookupICSP prefers to try the original repository first before moving to the mirrors and we would like to go for the mirrors first. I can solve that by providing a new implementation of AlternateBlobSourceStrategy.

Right, preferring the original allows oc to implicitly lookup alternate sources, but only if the original cannot be fetched. This is what is required of oc, but i see this is the opposite of image-registry. We can add another strategy in a follow-up PR, or, can keep the new strategy local to image-registry/not in lib-go, or, can add to this PR.

I updated the Repository method in the RepositoryRetriever interface, ptal.

@sallyom sallyom force-pushed the alternate-lookup-registry branch from 4acafb6 to 3defb0b Compare April 24, 2021 13:11
@ricardomaraschini
Copy link
Contributor

@ricardomaraschini I was able to add back to oc the ICSP logic, so I am now using more of the mirrored_client. Have you tried to run w/ it yet? I don't have it working quite yet, so I think perhaps something in the mirrored_client might need to be tweaked. Or, maybe I have to update my implementation of it in oc - if you have it working it will help! If not, I'll keep working on it.

I have managed to make it work this morning. The problem now (for the image registry) is the one related to the interface I mentioned here.
Other problem I can solve later on is the fact that simpleLookupICSP prefers to try the original repository first before moving to the mirrors and we would like to go for the mirrors first. I can solve that by providing a new implementation of AlternateBlobSourceStrategy.

Right, preferring the original allows oc to implicitly lookup alternate sources, but only if the original cannot be fetched. This is what is required of oc, but i see this is the opposite of image-registry. We can add another strategy in a follow-up PR, or, can keep the new strategy local to image-registry/not in lib-go, or, can add to this PR.

I updated the Repository method in the RepositoryRetriever interface, ptal.

We can do that in another PR for sure. As long as the interface has been updated I am OK with it :-)

@ricardomaraschini
Copy link
Contributor

Could we get this in? I have dependent work waiting to be done in openshift/image-registry#267

@@ -0,0 +1,159 @@
package strategy
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

discussed with maciej:

  1. move to oc (logic isn't generic to all callers and is more structured towards the "run once" behavior of oc, whereas controllers + registry are more informer driven)
  2. needs to be "lookup once and cache" to match the general behavior of oc (at the time you invoke oc any assumptions are in place)
  3. would like a unit test that verifies only one load is done of either file or client

@@ -1,8 +1,9 @@
package registryclient

import (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More extensive integration / unit style testing should happen in oc, which also helps us test the standard shared code. Mock testing and some basic integration testing can happen here, but oc will need to test the strategy coupled to the caller code.

Longer term there should probably a shim / stub / helper http serve function that makes it easier to stub out faking returning images (the hard bits) and inject errors and http status code. Can be longer term.

@soltysh soltysh mentioned this pull request May 20, 2021
@soltysh
Copy link

soltysh commented May 20, 2021

Replaced with #1084
/close

@openshift-ci openshift-ci bot closed this May 20, 2021
@openshift-ci
Copy link
Contributor

openshift-ci bot commented May 20, 2021

@soltysh: Closed this PR.

Details

In response to this:

Replaced with #1084
/close

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants