diff --git a/internal/resolver/resolver.go b/internal/resolver/resolver.go index 70ce6a55bfa..7fc27acac89 100644 --- a/internal/resolver/resolver.go +++ b/internal/resolver/resolver.go @@ -139,6 +139,20 @@ func (r *Resolver) Resolve(reqs []*chart.Dependency, repoNames map[string]string return nil, errors.Wrapf(FeatureGateOCI.Error(), "repository %s is an OCI registry", d.Repository) } + + // This works, fake it to test mocking the version + // tags := []string{"0.1.0", "0.1.1", "0.2.0"} + tags := d.OCITagVersions + vs = make(repo.ChartVersions, len(tags)) + for ti, t := range tags { + // Mock chart version objects + version := &repo.ChartVersion{ + Metadata: &chart.Metadata{ + Version: t, + }, + } + vs[ti] = version + } } locked[i] = &chart.Dependency{ @@ -149,7 +163,8 @@ func (r *Resolver) Resolve(reqs []*chart.Dependency, repoNames map[string]string // The version are already sorted and hence the first one to satisfy the constraint is used for _, ver := range vs { v, err := semver.NewVersion(ver.Version) - if err != nil || len(ver.URLs) == 0 { + // OCI does not need URLs + if err != nil || (!registry.IsOCI(d.Repository) && len(ver.URLs) == 0) { // Not a legit entry. continue } diff --git a/pkg/chart/dependency.go b/pkg/chart/dependency.go index b2819f373a3..890fa971f8c 100644 --- a/pkg/chart/dependency.go +++ b/pkg/chart/dependency.go @@ -47,6 +47,10 @@ type Dependency struct { ImportValues []interface{} `json:"import-values,omitempty"` // Alias usable alias to be used for the chart Alias string `json:"alias,omitempty"` + // OCI tag versions available to check against the constraint when Version + // contains a semantic version range. + // See (*Manager).resolve. + OCITagVersions []string `json:"-"` } // Validate checks for common problems with the dependency datastructure in diff --git a/pkg/downloader/manager.go b/pkg/downloader/manager.go index 52f1a1312e6..d8c0eeb9c0f 100644 --- a/pkg/downloader/manager.go +++ b/pkg/downloader/manager.go @@ -233,6 +233,26 @@ func (m *Manager) loadChartDir() (*chart.Chart, error) { // This returns a lock file, which has all of the dependencies normalized to a specific version. func (m *Manager) resolve(req []*chart.Dependency, repoNames map[string]string) (*chart.Lock, error) { res := resolver.New(m.ChartPath, m.RepositoryCache) + // NOTE: When OCI dependencies specify a semver range in Version, + // (*Resolver).Resolve must somehow get the list of OCI tag versions + // available to check against this constraint. However for backward + // compatibility we can not change that function signature to pass a + // *registry.Client required to get tags from the ORAS tag listing API. + // However we can add a new backward compatible struct field to + // *chart.Dependency, so that we can pass these along to + // (*Resolver).resolve from here through reqs []*chart.Dependency. + for i, d := range req { + if registry.IsOCI(d.Repository) { + // TODO(scottrigby): fix HTTP error + // > Error: Get "https://localhost:5000/v2/helm-charts/tags/list": http: server gave HTTP response to HTTPS client + ref := strings.Trim(d.Repository, "oci://") + tags, err := m.RegistryClient.Tags(ref) + if err != nil { + return nil, err + } + req[i].OCITagVersions = tags + } + } return res.Resolve(req, repoNames) }