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)
if u.Scheme == registry.OCIScheme {
idx := strings.LastIndexByte(name, ':')
name = fmt.Sprintf("%s-%s.tgz", name[:idx], name[idx+1:])
}
name := c.getChartName(u.String())
destfile := filepath.Join(dest, name)
if err := fileutil.AtomicWriteFile(destfile, data, 0644); err != nil {
return destfile, nil, err
@ -353,11 +348,12 @@ func (c *ChartDownloader) DownloadToCache(ref, version string) (string, *provena
//
// TODO: support OCI hash
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 {
return "", nil, fmt.Errorf("invalid chart URL format: %s", ref)
return "", u, err
}
if registry.IsOCI(u.String()) {
if c.RegistryClient == nil {
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
}
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) {
r, err := repo.LoadFile(file)
if err != nil && !errors.Is(err, fs.ErrNotExist) {

@ -328,16 +328,14 @@ func (m *Manager) downloadAll(deps []*chart.Dependency) error {
continue
}
if m.SkipDownloadIfExists {
name := filepath.Base(churl)
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
version := ""
if registry.IsOCI(churl) {
churl, version, err = parseOCIRef(churl)
if err != nil {
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{
Out: m.Out,
Verify: m.Verify,
@ -355,7 +353,6 @@ func (m *Manager) downloadAll(deps []*chart.Dependency) error {
},
}
version := ""
if registry.IsOCI(churl) {
churl, version, err = parseOCIRef(churl)
if err != nil {
@ -366,6 +363,21 @@ func (m *Manager) downloadAll(deps []*chart.Dependency) error {
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 {
saveError = fmt.Errorf("could not download %s: %w", churl, err)
break

Loading…
Cancel
Save