Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Supermiddleware #28

Merged
merged 1 commit into from
Dec 15, 2017
Merged

Conversation

dmage
Copy link
Contributor

@dmage dmage commented Dec 13, 2017

The intention of the changes is to move all magic for middlewares into a single package.

@openshift-ci-robot openshift-ci-robot added do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. labels Dec 13, 2017
@openshift-ci-robot openshift-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Dec 13, 2017
@dmage dmage requested review from miminar and legionus and removed request for mfojtik and soltysh December 13, 2017 15:32
@dmage dmage force-pushed the supermiddleware branch 4 times, most recently from c41baaa to ade8647 Compare December 14, 2017 13:38
@dmage
Copy link
Contributor Author

dmage commented Dec 14, 2017

flake openshift/origin#17786
/retest

repo *repository
}

func (r *repository) BlobDescriptorService(svc distribution.BlobDescriptorService) distribution.BlobDescriptorService {
Copy link
Contributor

Choose a reason for hiding this comment

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

Please move this function to repository.go

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'd like to move as few functions as possible in this PR.

}

if r.config.pullthrough {
if r.app.extraConfig.Pullthrough.Enabled {
Copy link
Contributor

Choose a reason for hiding this comment

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

Please use r.app.extraConfig instead of r.enabledMetrics as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

@@ -89,7 +89,8 @@ var (
ErrUnsupportedResource = errors.New("unsupported resource")
)

func (app *App) newAccessController(authcfg *configuration.Auth) (registryauth.AccessController, error) {
func (app *App) Auth(options map[string]interface{}) (registryauth.AccessController, error) {
authcfg := app.extraConfig.Auth
tokenRealm, err := configuration.TokenRealm(authcfg.TokenRealm)
Copy link
Contributor

Choose a reason for hiding this comment

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

- authcfg := app.extraConfig.Auth
- tokenRealm, err := configuration.TokenRealm(authcfg.TokenRealm)
+ tokenRealm, err := configuration.TokenRealm(app.extraConfig.Auth.TokenRealm)

?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

@@ -68,7 +68,7 @@ func (m *manifestService) Get(ctx context.Context, dgst digest.Digest, options .
ref := imageapi.DockerImageReference{
Namespace: m.repo.namespace,
Name: m.repo.name,
Registry: m.repo.config.registryAddr,
Registry: m.repo.app.extraConfig.Server.Addr,
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we rename extraConfig to config ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's a good idea for follow ups.

@legionus
Copy link
Contributor

@dmage can you add doc.go for supermiddleware ?

@dmage
Copy link
Contributor Author

dmage commented Dec 14, 2017

@legionus doc.go - done

@dmage dmage changed the title [WIP] Supermiddleware Supermiddleware Dec 14, 2017
@openshift-ci-robot openshift-ci-robot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Dec 14, 2017
Copy link
Contributor

@bparees bparees left a comment

Choose a reason for hiding this comment

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

What problem is solved by moving them into a single package?

return reg.inst.Repository(ctx, repo, false)
}

// HackRegistry must not be used.
Copy link
Contributor

Choose a reason for hiding this comment

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

so why is it here? can it be moved into a _test.go file?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's a huge hack and should be removed, it's here to make a private variable accessible from another module. We gave too much tasks to the type *repository. It implements distribution.Repository and it's responsible for getting data from the image stream. But, for example, pullthroughManifestService wants *repository and uses

  • m.repo.namespace
  • m.repo.name
  • m.repo.getImageOfImageStream
  • m.repo.rememberLayersOfManifest
  • m.repo.registryOSClient
  • m.repo.imageStreamGetter

In other words, it wants to fill cache and to get ImageStreamImage. But right now we can't get imageStreamGetter and cache without constructing entire *repository.

Splitting will be almost mechanical changes, but it will be pretty big and I don't want to mix it with this PR.

@dmage
Copy link
Contributor Author

dmage commented Dec 15, 2017

@bparees the main problem is BlobDescriptorService (it determines whether the blob exists in the repository). We can register only one implementation, which doesn't get any parameters.

func init() {
err := middleware.RegisterOptions(storage.BlobDescriptorServiceFactory(&blobDescriptorServiceFactory{}))
if err != nil {
logrus.Fatalf("Unable to register BlobDescriptorServiceFactory: %v", err)
}
}

However we need to access the image stream from this service. And we can get it from the context.

repo, found := repositoryFrom(ctx)
if !found || repo == nil {
err := fmt.Errorf("failed to retrieve repository from context")
context.GetLogger(ctx).Error(err)
return distribution.Descriptor{}, err
}

if !imageStreamHasBlob(repo, dgst) {

It's pretty ugly, but I don't see any better options. But how do we put the repository into the context? Basically we have withRepository(ctx, r.repo) all around the code. And recently I replaced all such calls with my generic wrapper.

https://github.com/openshift/image-registry/blob/c540fa0224d2028b9633a147c283fbf60d371ba9/pkg/dockerregistry/server/withrepository.go

So, the problem is solved, right? No, it isn't. :(

If BlobStore.Create(ctx, ...) is called with the WithMountFrom(src) option, we should be very careful with contexts, the upstream code may call Stat on the source repository with the context from the destination repository. We have a workaround for this

options = append(options, statCrossMountCreateOptions{
ctx: ctx,
destRepo: r.repo,
})

func statSourceRepository(
ctx context.Context,
destRepo *repository,
sourceRepoName reference.Named,
dgst digest.Digest,
) (desc distribution.Descriptor, err error) {
upstreamRepo, err := destRepo.app.registry.Repository(ctx, sourceRepoName)
if err != nil {
return distribution.Descriptor{}, err
}
namespace, name, err := getNamespaceName(sourceRepoName.Name())
if err != nil {
return distribution.Descriptor{}, err
}
repo := *destRepo
repo.namespace = namespace
repo.name = name
repo.Repository = upstreamRepo
return repo.Blobs(ctx).Stat(ctx, dgst)
}

But, unfortunately, it has a bug. The context isn't modified before calling Stat.

Back to the PR: writing middlewares for the blob descriptor service should be less intriguing and detective, so now we have the entire implementation of the blob descriptor service middleware in the context. And that allowed me to cover it with tests. Though, this PR is just refactoring, bug fixes will be made as follow ups.

@legionus
Copy link
Contributor

What problem is solved by moving them into a single package?

@bparees This is a very important change that corrects the current architecture. Our code will become more maintainable. Also it will allow us to change the caching.

@bparees
Copy link
Contributor

bparees commented Dec 15, 2017

@dmage thanks for the summary, that was very helpful.

@legionus
Copy link
Contributor

/lgtm

@openshift-ci-robot openshift-ci-robot added the lgtm Indicates that a PR is ready to be merged. label Dec 15, 2017
@openshift-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: dmage, legionus

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

Needs approval from an approver in each of these OWNERS Files:

You can indicate your approval by writing /approve in a comment
You can cancel your approval by writing /approve cancel in a comment

@legionus
Copy link
Contributor

/retest

@openshift-merge-robot openshift-merge-robot merged commit 249040b into openshift:master Dec 15, 2017
@dmage dmage deleted the supermiddleware branch January 29, 2018 14:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. lgtm Indicates that a PR is ready to be merged. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants