Skip to content

feat: glob resolver repo impl#844

Merged
matthiasbruns merged 23 commits into
open-component-model:mainfrom
matthiasbruns:feat/575_regex_glob_resolver_repository
Sep 12, 2025
Merged

feat: glob resolver repo impl#844
matthiasbruns merged 23 commits into
open-component-model:mainfrom
matthiasbruns:feat/575_regex_glob_resolver_repository

Conversation

@matthiasbruns

@matthiasbruns matthiasbruns commented Sep 9, 2025

Copy link
Copy Markdown
Contributor

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

  • the cli integration will be implemented in a follow up pr

Which issue(s) this PR fixes

Contributes open-component-model/ocm-project#575

On-behalf-of: SAP <matthias.bruns@sap.com>

Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
@github-actions github-actions Bot added kind/feature new feature, enhancement, improvement, extension size/l Large labels Sep 9, 2025
matthiasbruns and others added 6 commits September 9, 2025 09:05
…-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>
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>
@matthiasbruns matthiasbruns force-pushed the feat/575_regex_glob_resolver_repository branch from 7ffbbd8 to 7d6a9a1 Compare September 10, 2025 06:49
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 matthiasbruns marked this pull request as ready for review September 10, 2025 06:52
@matthiasbruns matthiasbruns requested a review from a team as a code owner September 10, 2025 06:52
matthiasbruns and others added 4 commits September 10, 2025 08:52
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
Comment thread bindings/go/repository/component/fallback/v1/doc.go Outdated
Comment thread bindings/go/repository/component/resolver/v1/doc.go Outdated
Comment thread bindings/go/repository/component/resolver/v1/repository.go Outdated
Comment thread bindings/go/repository/component/resolver/v1/repository.go Outdated
Comment thread bindings/go/repository/component/resolver/v1/repository.go Outdated
Comment thread bindings/go/repository/component/resolver/v1/repository.go Outdated
Comment thread bindings/go/repository/component/resolver/v1/repository.go
Comment thread bindings/go/repository/component/resolver/v1/repository.go
matthiasbruns and others added 5 commits September 10, 2025 11:56
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>
On-behalf-of: SAP <matthias.bruns@sap.com>

Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
@matthiasbruns

Copy link
Copy Markdown
Contributor Author

@jakobmoellerdev ping

Comment thread bindings/go/repository/component/resolver/v1alpha1/repository.go
Comment thread bindings/go/repository/component/resolver/v1alpha1/repository_test.go Outdated
Comment thread bindings/go/repository/component/resolver/v1alpha1/repository_test.go Outdated
Comment thread bindings/go/repository/component/resolver/v1alpha1/repository.go Outdated
Comment thread bindings/go/repository/component/resolver/v1alpha1/repository.go Outdated
Comment thread bindings/go/repository/component/resolver/v1alpha1/repository.go Outdated
Comment thread bindings/go/repository/component/resolver/v1alpha1/repository.go Outdated
Comment thread bindings/go/repository/component/resolver/v1alpha1/repository.go
Comment thread bindings/go/repository/component/resolver/v1alpha1/repository_test.go Outdated
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

Copy link
Copy Markdown
Contributor Author

@fabianburth ping :)

@matthiasbruns matthiasbruns merged commit 29f9aaa into open-component-model:main Sep 12, 2025
16 checks passed
@matthiasbruns matthiasbruns deleted the feat/575_regex_glob_resolver_repository branch September 12, 2025 06:55
@jakobmoellerdev

Copy link
Copy Markdown
Member

@matthiasbruns please do not merge if we are still pending on other reviewers next time.

@fabianburth fabianburth left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We need to revert this and remove the fallback behaviour (Thereby, you can also get rid of the iterator in this implementation).

Sorry, for the delayed review though!

Comment on lines +103 to +124
// 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)
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Comment on lines +141 to +165
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
})
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We do not want to accumulate the versions from all matching repositories anymore.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Comment on lines +177 to +198
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
}
}
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

@fabianburth fabianburth Sep 12, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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)
}

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

Labels

kind/feature new feature, enhancement, improvement, extension size/l Large

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants