Skip to content

Support Resolvers in OCM Configuration through ocm.config.ocm.software #513

@jakobmoellerdev

Description

@jakobmoellerdev

Description

As a user, I don't only want to work with component versions that contain references to component versions in the repository im contained in. Instead, I also want to reference components in other repositories. To successfully add and resolve those, I need to be able to use resolvers that contain information on how to retrieve / resolve such component versions.

Resolvers are already available in OCM v1:

  - «ocm.config.ocm.software»
    The config type «ocm.config.ocm.software» can be used to set some
    configurations for an OCM context;
    
        type: ocm.config.ocm.software
        aliases:
           myrepo: 
              type: <any repository type>
              <specification attributes>
              ...
        resolvers:
          - repository:
              type: <any repository type>
              <specification attributes>
              ...
            prefix: ghcr.io/open-component-model/ocm
            priority: 10

    With aliases repository alias names can be mapped to a repository specification.
    The alias name can be used in a string notation for an OCM repository.
    
    Resolvers define a list of OCM repository specifications to be used to resolve
    dedicated component versions. These settings are used to compose a standard
    component version resolver provided for an OCM context. Optionally, a component
    name prefix can be given. It limits the usage of the repository to resolve only
    components with the given name prefix (always complete name segments).
    An optional priority can be used to influence the lookup order. Larger value
    means higher priority (default 10).
    
    All matching entries are tried to lookup a component version in the following
    order:
    - highest priority first
    - longest matching sequence of component name segments first.
    If resolvers are defined, it is possible to use component version names on the
    command line without a repository. The names are resolved with the specified
    resolution rule.
    They are also used as default lookup repositories to lookup component references
    for recursive operations on component versions («--lookup» option).

The goal is to support resolver configurations based on these config elements as well and make them available in the commandline via config parsing.

Scope:
The resolvers should:

  • Support Recursive Lookups by supporting the existing resolver config data structure
  • Support prioritization and prefix lookups for OCI / CTF paths (URL / Path based matching)

Out-of-Scope / Deprecated with v2

  • Support Aliases in component references (which so far are unsupported in the CLI)
  • Regex / Globbing Resolver (see important notes below)

This will move us closer to feature parity in OCM CLI

Important Notes

  • The current fallback concepts (thus, iterating through a list of resolvers until one is found that works/does not fail) is very inefficient
  • Short-Term: We implement this concept to be backwards compatible and to not break users immediately.
  • Long-Term: We implement a RegexResolver and/or GlobbingResolver. There will be a mapping regex/glob -> repository. They will match on <componentName>:<componentVersion>. There will be no fallback mechanism. The repository corresponding to the first matching regex/glob will be used - if it fails, the resolving process fails.
  • RegexResolver / GlobbingResolver will get an own config type, so the entire current config type can be deprecated.
  • The Long-Term is out-of-scope and a follow up issue will be created.

Fallback mechanism of legacy ocm cli
api/ocm/internal/resolver.go

func (r *MatchingResolver) LookupComponentVersion(name string, version string) (ComponentVersionAccess, error) {
	r.lock.Lock()
	defer r.lock.Unlock()

	for _, rule := range r.rules {
		if rule.Match(name) {
			repo, err := r.resolveRepository(rule)
			if err != nil {
				return nil, err
			}
			cv, err := repo.LookupComponentVersion(name, version)
			if err == nil && cv != nil {
				return cv, nil
			}
			if !errors.IsErrNotFoundKind(err, KIND_COMPONENTVERSION) {
				return nil, err
			}
		}
	}
	return nil, errors.ErrNotFound(KIND_COMPONENTVERSION, common.NewNameVersion(name, version).String())
}

Done Criteria

  • Code has been reviewed by other team members
  • Analysis of existing tests (Unit and Integration)
  • Unit Tests created for new code or existing Unit Tests updated
  • Integration Test Suite updated (includes deletion of existing unnecessary Integration Test and/or creation of new ones if required)
  • Enduser Documentation updated (if applicable)
  • Internal technical Documentation created/updated (if applicable)
  • Successful demonstration in Review
  • Follo-Up Issue has been created

Metadata

Metadata

Assignees

Labels

kind/tasksmall task, normally part of feature or epic

Type

No fields configured for Task.

Projects

Status
🍺 Done

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions