helm源码分析-downloader
| 阅读 | 共 1198 字,阅读约
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}