added oci support

Signed-off-by: Suleiman Dibirov <idsulik@gmail.com>
pull/13242/head
Suleiman Dibirov 1 year ago
parent 0cf7b19b21
commit f1d5437377

@ -149,12 +149,7 @@ func (c *ChartDownloader) DownloadTo(ref, version, dest string) (string, *proven
} }
} }
name := filepath.Base(u.Path) name := c.getChartName(u.String())
if u.Scheme == registry.OCIScheme {
idx := strings.LastIndexByte(name, ':')
name = fmt.Sprintf("%s-%s.tgz", name[:idx], name[idx+1:])
}
destfile := filepath.Join(dest, name) destfile := filepath.Join(dest, name)
if err := fileutil.AtomicWriteFile(destfile, data, 0644); err != nil { if err := fileutil.AtomicWriteFile(destfile, data, 0644); err != nil {
return destfile, nil, err return destfile, nil, err
@ -353,11 +348,12 @@ func (c *ChartDownloader) DownloadToCache(ref, version string) (string, *provena
// //
// TODO: support OCI hash // TODO: support OCI hash
func (c *ChartDownloader) ResolveChartVersion(ref, version string) (string, *url.URL, error) { func (c *ChartDownloader) ResolveChartVersion(ref, version string) (string, *url.URL, error) {
u, err := url.Parse(ref) u, err := c.parseChartURL(ref, version)
if err != nil { if err != nil {
return "", nil, fmt.Errorf("invalid chart URL format: %s", ref) return "", u, err
} }
if registry.IsOCI(u.String()) { if registry.IsOCI(u.String()) {
if c.RegistryClient == nil { if c.RegistryClient == nil {
return "", nil, fmt.Errorf("unable to lookup ref %s at version '%s', missing registry client", ref, version) return "", nil, fmt.Errorf("unable to lookup ref %s at version '%s', missing registry client", ref, version)
@ -574,6 +570,65 @@ func (c *ChartDownloader) scanReposForURL(u string, rf *repo.File) (*repo.Entry,
return nil, ErrNoOwnerRepo return nil, ErrNoOwnerRepo
} }
func (c *ChartDownloader) getChartName(url string) string {
name := filepath.Base(url)
if registry.IsOCI(url) {
idx := strings.LastIndexByte(name, ':')
name = fmt.Sprintf("%s-%s.tgz", name[:idx], name[idx+1:])
}
return name
}
func (c *ChartDownloader) parseChartURL(ref string, version string) (*url.URL, error) {
u, err := url.Parse(ref)
if err != nil {
return nil, errors.Errorf("invalid chart URL format: %s", ref)
}
if registry.IsOCI(u.String()) {
tag, err := c.getOciTag(ref, version)
if err != nil {
return nil, err
}
u.Path = fmt.Sprintf("%s:%s", u.Path, tag)
}
return u, nil
}
func (c *ChartDownloader) getOciTag(ref, version string) (string, error) {
var tag string
// Evaluate whether an explicit version has been provided. Otherwise, determine version to use
_, errSemVer := semver.NewVersion(version)
if errSemVer == nil {
tag = version
} else {
// Retrieve list of repository tags
tags, err := c.RegistryClient.Tags(strings.TrimPrefix(ref, fmt.Sprintf("%s://", registry.OCIScheme)))
if err != nil {
return "", err
}
if len(tags) == 0 {
return "", errors.Errorf("Unable to locate any tags in provided repository: %s", ref)
}
// Determine if version provided
// If empty, try to get the highest available tag
// If exact version, try to find it
// If semver constraint string, try to find a match
tag, err = registry.GetTagMatchingVersionOrConstraint(tags, version)
if err != nil {
return "", err
}
}
return tag, nil
}
func loadRepoConfig(file string) (*repo.File, error) { func loadRepoConfig(file string) (*repo.File, error) {
r, err := repo.LoadFile(file) r, err := repo.LoadFile(file)
if err != nil && !errors.Is(err, fs.ErrNotExist) { if err != nil && !errors.Is(err, fs.ErrNotExist) {

@ -328,16 +328,14 @@ func (m *Manager) downloadAll(deps []*chart.Dependency) error {
continue continue
} }
if m.SkipDownloadIfExists { version := ""
name := filepath.Base(churl) if registry.IsOCI(churl) {
if _, err = os.Stat(filepath.Join(destPath, name)); err == nil { churl, version, err = parseOCIRef(churl)
fmt.Fprintf(m.Out, "Already exists locally %s from repo %s\n", dep.Name, dep.Repository) if err != nil {
continue return errors.Wrapf(err, "could not parse OCI reference")
} }
} }
fmt.Fprintf(m.Out, "Downloading %s from repo %s\n", dep.Name, dep.Repository)
dl := ChartDownloader{ dl := ChartDownloader{
Out: m.Out, Out: m.Out,
Verify: m.Verify, Verify: m.Verify,
@ -355,7 +353,6 @@ func (m *Manager) downloadAll(deps []*chart.Dependency) error {
}, },
} }
version := ""
if registry.IsOCI(churl) { if registry.IsOCI(churl) {
churl, version, err = parseOCIRef(churl) churl, version, err = parseOCIRef(churl)
if err != nil { if err != nil {
@ -366,6 +363,21 @@ func (m *Manager) downloadAll(deps []*chart.Dependency) error {
getter.WithTagName(version)) getter.WithTagName(version))
} }
if m.SkipDownloadIfExists {
u, err := dl.parseChartURL(churl, version)
if err != nil {
return err
}
name := dl.getChartName(u.String())
if _, err = os.Stat(filepath.Join(destPath, name)); err == nil {
fmt.Fprintf(m.Out, "Already exists locally %s from repo %s\n", dep.Name, dep.Repository)
continue
}
}
fmt.Fprintf(m.Out, "Downloading %s from repo %s\n", dep.Name, dep.Repository)
if _, _, err = dl.DownloadTo(churl, version, tmpPath); err != nil { if _, _, err = dl.DownloadTo(churl, version, tmpPath); err != nil {
saveError = fmt.Errorf("could not download %s: %w", churl, err) saveError = fmt.Errorf("could not download %s: %w", churl, err)
break break

Loading…
Cancel
Save