feat: glob resolver repo impl#844
Conversation
On-behalf-of: SAP <matthias.bruns@sap.com> Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
…-model into feat/575_regex_glob_resolver_repository Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
On-behalf-of: SAP <matthias.bruns@sap.com> Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
…matthiasbruns/open-component-model into feat/575_regex_glob_resolver_repository Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
7ffbbd8 to
7d6a9a1
Compare
On-behalf-of: SAP <matthias.bruns@sap.com> Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
On-behalf-of: SAP <matthias.bruns@sap.com> Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
…:matthiasbruns/open-component-model into feat/575_regex_glob_resolver_repository
On-behalf-of: SAP <matthias.bruns@sap.com> Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
…matthiasbruns/open-component-model into feat/575_regex_glob_resolver_repository
On-behalf-of: SAP <matthias.bruns@sap.com> Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
|
@jakobmoellerdev ping |
On-behalf-of: SAP <matthias.bruns@sap.com> Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
On-behalf-of: SAP <matthias.bruns@sap.com> Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
…matthiasbruns/open-component-model into feat/575_regex_glob_resolver_repository
On-behalf-of: SAP <matthias.bruns@sap.com> Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
|
@fabianburth ping :) |
|
@matthiasbruns please do not merge if we are still pending on other reviewers next time. |
| // GetComponentVersion retrieves a component version from the first repository | ||
| // that matches the component name. If no repository matches the component name, | ||
| // or if the component version is not found in any matching repository, an error | ||
| // is returned. | ||
| func (r *ResolverRepository) GetComponentVersion(ctx context.Context, component, version string) (*descriptor.Descriptor, error) { | ||
| repos := r.RepositoriesForComponentIterator(ctx, component) | ||
| for repo, err := range repos { | ||
| if err != nil { | ||
| return nil, fmt.Errorf("getting repository for component %s failed: %w", component, err) | ||
| } | ||
| desc, err := repo.GetComponentVersion(ctx, component, version) | ||
| if errors.Is(err, repository.ErrNotFound) { | ||
| slog.DebugContext(ctx, "component version not found in repository", "realm", Realm, "repository", repo, "component", component, "version", version) | ||
| continue // try the next repository | ||
| } | ||
| if err != nil { | ||
| return nil, fmt.Errorf("getting component version %s/%s from repository %v failed: %w", component, version, repo, err) | ||
| } | ||
| return desc, nil | ||
| } | ||
| return nil, fmt.Errorf("component version %s/%s not found in any repository", component, version) | ||
| } |
There was a problem hiding this comment.
I'm a little confused, tbh. I think our goal was specifically to create a resolver WITHOUT fallback behaviour - both because its more efficient and easier to maintain.
But if I understand this correctly, we now have an even more complex fallback resolver, right?
| for repo, err := range repos { | ||
| errGroup.Go(func() error { | ||
| if err != nil { | ||
| return fmt.Errorf("getting repository for component %s failed: %w", component, err) | ||
| } | ||
| var versions []string | ||
| versions, err = repo.ListComponentVersions(ctx, component) | ||
| if err != nil { | ||
| return fmt.Errorf("listing component versions for %s failed: %w", component, err) | ||
| } | ||
| if len(versions) == 0 { | ||
| slog.DebugContext(ctx, "no versions found for component", "component", component, "repository", repo) | ||
| return nil | ||
| } | ||
| slog.DebugContext(ctx, "found versions for component", "component", component, "versions", versions, "repository", repo) | ||
| versionsMu.Lock() | ||
| defer versionsMu.Unlock() | ||
| for _, version := range versions { | ||
| if r.matchesAnyResolver(component) { | ||
| accumulatedVersions[version] = struct{}{} | ||
| } | ||
| } | ||
| return nil | ||
| }) | ||
| } |
There was a problem hiding this comment.
We do not want to accumulate the versions from all matching repositories anymore.
| func (r *ResolverRepository) RepositoriesForComponentIterator(ctx context.Context, component string) iter.Seq2[repository.ComponentVersionRepository, error] { | ||
| return func(yield func(repository.ComponentVersionRepository, error) bool) { | ||
| r.matchersMu.RLock() | ||
| defer r.matchersMu.RUnlock() | ||
| for index, resolver := range r.resolvers { | ||
| if !r.matchers[index].Match(component, "") { | ||
| continue | ||
| } | ||
|
|
||
| repo, err := r.getRepositoryForSpecification(ctx, resolver.Repository) | ||
| if err != nil { | ||
| yield(nil, fmt.Errorf("getting repository for resolver %v failed: %w", resolver, err)) | ||
| return | ||
| } | ||
|
|
||
| slog.DebugContext(ctx, "yielding repository for component", "realm", Realm, "component", component, "repository", resolver.Repository) | ||
| if !yield(repo, nil) { | ||
| return | ||
| } | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Iterator should not be necessary anymore, as the matching would not include fallback behaviour. Instead, this would rather be a GetComponentVersionRepositoryForComponent.
Thinking about whether this resolver should even implement the ComponentVersionRepository interface. A RepositoryProvider like interface feels like a better fit here.
There was a problem hiding this comment.
I think what we want is a
type RepositorySpecProvider interface {
GetRepositorySpec(ctx context.Context, componentIdentity runtime.Identity) (runtime.Typed, error)
}
This can then be used in combination with a ComponentVersionRepositoryProvider to get an actual ComponentVersionRepository.
type ComponentVersionRepositoryProvider interface {
GetComponentVersionRepositoryCredentialConsumerIdentity(ctx context.Context, repositorySpecification runtime.Typed) (runtime.Identity, error)
GetComponentVersionRepository(ctx context.Context, repositorySpecification runtime.Typed, credentials map[string]string) (ComponentVersionRepository, error)
}
What this PR does / why we need it
In #780 we implemented a new configuration resolver implementation that resolves components with a glob matcher. This PR implement the repository that uses the new matcher
Which issue(s) this PR fixes
Contributes open-component-model/ocm-project#575