helm源码分析-downloader


| 阅读 |,阅读约 3 分钟
| 复制链接:

Overview

helm源码分析-downloader

downloader模块主要负责

目录结构

源码位置:pkg/downloader

1➜  helm git:(041ce5a2) ✗ tree pkg/downloader 
2pkg/downloader
3├── chart_downloader.go
4├── chart_downloader_test.go
5├── doc.go
6├── manager.go
7├── manager_test.go
8└── testdata

chart_download

  • chart_download负责下载chart包
 1type ChartDownloader struct {
 2	// Out is the location to write warning and info messages.
 3	Out io.Writer
 4	// Verify indicates what verification strategy to use.
 5	Verify VerificationStrategy
 6	// Keyring is the keyring file used for verification.
 7	Keyring string
 8	// Getter collection for the operation
 9	Getters getter.Providers
10	// Options provide parameters to be passed along to the Getter being initialized.
11	Options          []getter.Option
12	RegistryClient   *registry.Client
13	RepositoryConfig string
14	RepositoryCache  string
15}

VerifyChart

DownloadTo

下载chart包到指定目录

 1func (c *ChartDownloader) DownloadTo(ref, version, dest string) (string, *provenance.Verification, error) {
 2	// 获取URL地址
 3  u, err := c.ResolveChartVersion(ref, version)
 4	...
 5  // 根据scheme得到处理请求的实现类
 6	g, err := c.Getters.ByScheme(u.Scheme)
 7	...
 8  // 处理请求,并返回数据
 9	data, err := g.Get(u.String(), c.Options...)
10	...
11	//将数据写入目的文件
12	destfile := filepath.Join(dest, name)
13	if err := fileutil.AtomicWriteFile(destfile, data, 0644); err != nil {
14		return destfile, nil, err
15	}
16  // 后面的都是校验相关逻辑
17  ...
18}

ResolveChartVersion

  • 解析chart为一个URL地址
  1func (c *ChartDownloader) ResolveChartVersion(ref, version string) (*url.URL, error) {
  2	u, err := url.Parse(ref)
  3	if err != nil {
  4		return nil, errors.Errorf("invalid chart URL format: %s", ref)
  5	}
  6	c.Options = append(c.Options, getter.WithURL(ref))
  7
  8  // 加载本地存储的repository.yaml文件为File对象
  9	rf, err := loadRepoConfig(c.RepositoryConfig)
 10	if err != nil {
 11		return u, err
 12	}
 13
 14	if u.IsAbs() && len(u.Host) > 0 && len(u.Path) > 0 {
 15		// In this case, we have to find the parent repo that contains this chart
 16		// URL. And this is an unfortunate problem, as it requires actually going
 17		// through each repo cache file and finding a matching URL. But basically
 18		// we want to find the repo in case we have special SSL cert config
 19		// for that repo.
 20
 21		rc, err := c.scanReposForURL(ref, rf)
 22		if err != nil {
 23			// If there is no special config, return the default HTTP client and
 24			// swallow the error.
 25			if err == ErrNoOwnerRepo {
 26				return u, nil
 27			}
 28			return u, err
 29		}
 30
 31		// If we get here, we don't need to go through the next phase of looking
 32		// up the URL. We have it already. So we just set the parameters and return.
 33		c.Options = append(
 34			c.Options,
 35			getter.WithURL(rc.URL),
 36		)
 37		if rc.CertFile != "" || rc.KeyFile != "" || rc.CAFile != "" {
 38			c.Options = append(c.Options, getter.WithTLSClientConfig(rc.CertFile, rc.KeyFile, rc.CAFile))
 39		}
 40		if rc.Username != "" && rc.Password != "" {
 41			c.Options = append(
 42				c.Options,
 43				getter.WithBasicAuth(rc.Username, rc.Password),
 44			)
 45		}
 46		return u, nil
 47	}
 48
 49	// See if it's of the form: repo/path_to_chart
 50	p := strings.SplitN(u.Path, "/", 2)
 51	if len(p) < 2 {
 52		return u, errors.Errorf("non-absolute URLs should be in form of repo_name/path_to_chart, got: %s", u)
 53	}
 54
 55	repoName := p[0]
 56	chartName := p[1]
 57	rc, err := pickChartRepositoryConfigByName(repoName, rf.Repositories)
 58
 59	if err != nil {
 60		return u, err
 61	}
 62
 63	r, err := repo.NewChartRepository(rc, c.Getters)
 64	if err != nil {
 65		return u, err
 66	}
 67
 68	if r != nil && r.Config != nil {
 69		if r.Config.CertFile != "" || r.Config.KeyFile != "" || r.Config.CAFile != "" {
 70			c.Options = append(c.Options, getter.WithTLSClientConfig(r.Config.CertFile, r.Config.KeyFile, r.Config.CAFile))
 71		}
 72		if r.Config.Username != "" && r.Config.Password != "" {
 73			c.Options = append(c.Options, getter.WithBasicAuth(r.Config.Username, r.Config.Password))
 74		}
 75	}
 76
 77	// Next, we need to load the index, and actually look up the chart.
 78	idxFile := filepath.Join(c.RepositoryCache, helmpath.CacheIndexFile(r.Config.Name))
 79	i, err := repo.LoadIndexFile(idxFile)
 80	if err != nil {
 81		return u, errors.Wrap(err, "no cached repo found. (try 'helm repo update')")
 82	}
 83
 84	cv, err := i.Get(chartName, version)
 85	if err != nil {
 86		return u, errors.Wrapf(err, "chart %q matching %s not found in %s index. (try 'helm repo update')", chartName, version, r.Config.Name)
 87	}
 88
 89	if len(cv.URLs) == 0 {
 90		return u, errors.Errorf("chart %q has no downloadable URLs", ref)
 91	}
 92
 93	// TODO: Seems that picking first URL is not fully correct
 94	u, err = url.Parse(cv.URLs[0])
 95	if err != nil {
 96		return u, errors.Errorf("invalid chart URL format: %s", ref)
 97	}
 98
 99	// If the URL is relative (no scheme), prepend the chart repo's base URL
100	if !u.IsAbs() {
101		repoURL, err := url.Parse(rc.URL)
102		if err != nil {
103			return repoURL, err
104		}
105		q := repoURL.Query()
106		// We need a trailing slash for ResolveReference to work, but make sure there isn't already one
107		repoURL.Path = strings.TrimSuffix(repoURL.Path, "/") + "/"
108		u = repoURL.ResolveReference(u)
109		u.RawQuery = q.Encode()
110		// TODO add user-agent
111		if _, err := getter.NewHTTPGetter(getter.WithURL(rc.URL)); err != nil {
112			return repoURL, err
113		}
114		return u, err
115	}
116
117	// TODO add user-agent
118	return u, nil
119}

manager

manager负责处理chart包下载、处理、存储依赖的生命周期

 1type Manager struct {
 2	// Out is used to print warnings and notifications.
 3	Out io.Writer
 4	// ChartPath is the path to the unpacked base chart upon which this operates.
 5	ChartPath string
 6	// Verification indicates whether the chart should be verified.
 7	Verify VerificationStrategy
 8	// Debug is the global "--debug" flag
 9	Debug bool
10	// Keyring is the key ring file.
11	Keyring string
12	// SkipUpdate indicates that the repository should not be updated first.
13	SkipUpdate bool
14	// Getter collection for the operation
15	Getters          []getter.Provider
16	RegistryClient   *registry.Client
17	RepositoryConfig string
18	RepositoryCache  string
19}

Build

Update

UpdateRepositories