Skip to content

Commit 3b8bc95

Browse files
authored
Add digest check for chart download (#46)
1 parent 5f53e44 commit 3b8bc95

File tree

5 files changed

+64
-118
lines changed

5 files changed

+64
-118
lines changed

controllers/chartrepo_controller.go

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,7 @@ func ignoreNotFound(err error) error {
104104

105105
// syncChartRepo sync ChartRepo to helm repo store
106106
func (r *ChartRepoReconciler) syncChartRepo(cr *alaudaiov1alpha1.ChartRepo, ctx context.Context) error {
107-
return r.createCharts(cr, ctx)
108-
107+
return r.syncCharts(cr, ctx)
109108
}
110109

111110
// DownloadIndexFile fetches the index from a repository.
@@ -175,12 +174,14 @@ func loadIndex(data []byte) (*repo.IndexFile, error) {
175174
return i, nil
176175
}
177176

178-
// createCharts create charts resource for a repo
177+
// syncCharts create charts resource for a repo
179178
// TODO: ace.ACE
180-
func (r *ChartRepoReconciler) createCharts(cr *alaudaiov1alpha1.ChartRepo, ctx context.Context) error {
179+
func (r *ChartRepoReconciler) syncCharts(cr *alaudaiov1alpha1.ChartRepo, ctx context.Context) error {
181180
log := r.Log.WithValues("chartrepo", cr.GetName())
182181

183182
checked := map[string]bool{}
183+
existCharts := map[string]alaudaiov1alpha1.Chart{}
184+
184185
index, err := r.GetIndex(cr, ctx)
185186
if err != nil {
186187
return err
@@ -190,17 +191,13 @@ func (r *ChartRepoReconciler) createCharts(cr *alaudaiov1alpha1.ChartRepo, ctx c
190191
checked[strings.ToLower(name)] = true
191192
}
192193

193-
existCharts := map[string]alaudaiov1alpha1.Chart{}
194-
195194
var charts alaudaiov1alpha1.ChartList
196195
labels := client.MatchingLabels{
197196
"repo": cr.GetName(),
198197
}
199-
200198
if err := r.List(ctx, &charts, labels, client.InNamespace(r.Namespace)); err != nil {
201199
return err
202200
}
203-
204201
for _, item := range charts.Items {
205202
name := strings.Split(item.GetName(), ".")[0]
206203
existCharts[name] = item
@@ -222,12 +219,12 @@ func (r *ChartRepoReconciler) createCharts(cr *alaudaiov1alpha1.ChartRepo, ctx c
222219
}
223220

224221
old := existCharts[name]
225-
226222
if compareChart(old, chart) {
227223
chart.SetResourceVersion(old.GetResourceVersion())
228224
if err := r.Update(ctx, chart); err != nil {
229225
return err
230226
}
227+
log.Info("update chart", "name", old.Name, "repo", cr.Name)
231228
}
232229

233230
}
@@ -241,18 +238,28 @@ func (r *ChartRepoReconciler) createCharts(cr *alaudaiov1alpha1.ChartRepo, ctx c
241238
}
242239
log.Info("delete charts", "name", item.GetName())
243240
}
244-
245241
}
246242

247243
return nil
248-
249244
}
250245

251-
// compareChart simply compare versions list length
246+
// compareChart compare if a Chart need update
247+
// 1. If length not equal, update
248+
// 2. compare all digest
249+
252250
func compareChart(old alaudaiov1alpha1.Chart, new *alaudaiov1alpha1.Chart) bool {
253251
if len(old.Spec.Versions) != len(new.Spec.Versions) {
254252
return true
255253
}
254+
255+
for _, o := range old.Spec.Versions {
256+
for _, n := range new.Spec.Versions {
257+
if o.Version == n.Version && o.Digest != n.Digest {
258+
return true
259+
}
260+
}
261+
}
262+
256263
return false
257264
}
258265

@@ -330,6 +337,10 @@ func (r *ChartRepoReconciler) updateChartRepoStatus(ctx context.Context, cr *ala
330337
func (r *ChartRepoReconciler) isReadyForResync(cr *alaudaiov1alpha1.ChartRepo) bool {
331338
log := r.Log.WithValues("chartrepo", cr.GetName())
332339

340+
if cr.Status.Phase != "Synced" {
341+
return true
342+
}
343+
333344
if cr.GetAnnotations() != nil && cr.GetAnnotations()["alauda.io/last-sync-at"] != "" {
334345
last := cr.GetAnnotations()["alauda.io/last-sync-at"]
335346
// see: https://stackoverflow.com/questions/25845172/parsing-date-string-in-go

pkg/chartrepo/list.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -118,23 +118,23 @@ func GetChartRepo(name string, ns string, cfg *rest.Config) (*repo.Entry, error)
118118

119119
}
120120

121-
// get chart
122-
func GetChart(name, version, ns string, cfg *rest.Config) (string, error) {
121+
// get chart info, url and digest is the info we want
122+
func GetChart(name, version, ns string, cfg *rest.Config) (*repo.ChartVersion, error) {
123123
client, err := clientset.NewForConfig(cfg)
124124
if err != nil {
125-
return "", err
125+
return nil, err
126126
}
127127

128128
chart, err := client.AppV1alpha1().Charts(ns).Get(name, metav1.GetOptions{})
129129
if err != nil {
130-
return "", err
130+
return nil, err
131131
}
132132

133133
for _, item := range chart.Spec.Versions {
134134
if version == "" || version == item.Version {
135-
return item.URLs[0], nil
135+
return &item.ChartVersion, nil
136136
}
137137
}
138-
return "", errors.New(fmt.Sprintf("cannot find version %s for chart %s", version, name))
138+
return nil, errors.New(fmt.Sprintf("cannot find version %s for chart %s", version, name))
139139

140140
}

pkg/helm/download.go

Lines changed: 15 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -62,57 +62,41 @@ func (d *Downloader) getRepoInfo(name string, ns string) (*repo.Entry, error) {
6262
return entry, err
6363
}
6464

65-
// cal the local path for a chart
66-
// name: <repo>/<name>
67-
func getChartPath(name, version string) string {
68-
new := strings.Replace(name, "/", "-", -1)
69-
return fmt.Sprintf("%s/%s-%s.tgz", ChartsDir, new, version)
70-
}
71-
65+
// downloadChart download a chart from helm repo to local disk and return the path
66+
// name: <repo>/<chart>
7267
func (d *Downloader) downloadChart(name string, version string) (string, error) {
7368
log := d.log
7469

75-
repo, chart := getRepoAndChart(name)
76-
if repo == "" && chart == "" {
70+
repoName, chart := getRepoAndChart(name)
71+
if repoName == "" && chart == "" {
7772
return "", errors.New("cannot parse chart name")
7873
}
79-
8074
log.Info("get chart", "name", name, "version", version)
8175

8276
dir := ChartsDir
83-
84-
if version != "" {
85-
// we can check the path now
86-
checkPath := getChartPath(name, version)
87-
if _, err := os.Stat(checkPath); !os.IsNotExist(err) {
88-
log.Info("chart already downloaded, use it", "path", checkPath)
89-
return checkPath, nil
77+
if _, err := os.Stat(dir); os.IsNotExist(err) {
78+
if err = os.MkdirAll(dir, 0755); err != nil {
79+
return "", err
9080
}
81+
log.Info("helm charts dir not exist, create it: ", "dir", dir)
9182
}
9283

93-
entry, err := d.getRepoInfo(repo, d.ns)
84+
entry, err := d.getRepoInfo(repoName, d.ns)
9485
if err != nil {
9586
log.Error(err, "get chartrepo error")
9687
return "", err
9788
}
9889

99-
chartResourceName := fmt.Sprintf("%s.%s", strings.ToLower(chart), repo)
100-
101-
path, err := chartrepo.GetChart(chartResourceName, version, d.ns, d.cfg)
90+
chartResourceName := fmt.Sprintf("%s.%s", strings.ToLower(chart), repoName)
91+
cv, err := chartrepo.GetChart(chartResourceName, version, d.ns, d.cfg)
10292
if err != nil {
10393
log.Error(err, "get chart error")
10494
return "", err
10595
}
10696

107-
if _, err := os.Stat(dir); os.IsNotExist(err) {
108-
if err = os.MkdirAll(dir, 0755); err != nil {
109-
return "", err
110-
}
111-
log.Info("dir not exist, create it: ", "dir", dir)
112-
}
113-
97+
path := cv.URLs[0]
11498
fileName := strings.Split(path, "/")[1]
115-
filePath := fmt.Sprintf("%s/%s-%s", dir, repo, fileName)
99+
filePath := fmt.Sprintf("%s/%s-%s-%s", dir, repoName, cv.Digest, fileName)
116100

117101
if _, err := os.Stat(filePath); !os.IsNotExist(err) {
118102
log.Info("chart already downloaded, use it", "path", filePath)
@@ -124,6 +108,8 @@ func (d *Downloader) downloadChart(name string, version string) (string, error)
124108
return "", err
125109
}
126110

111+
log.Info("download chart to disk", "path", filePath)
112+
127113
return filePath, nil
128114

129115
}

pkg/helm/install.go

Lines changed: 10 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -54,42 +54,18 @@ func (d *Deploy) install() (*release.Release, error) {
5454
}
5555
}
5656

57-
//cp, err := client.ChartPathOptions.LocateChart(chrt, settings)
58-
//if err != nil {
59-
// klog.Errorf("locate chart %s error: %s", cp, err.Error())
60-
// // a simple string match
61-
// if client.Version == "" && strings.Contains(err.Error(), " no chart version found for") {
62-
// klog.Info("no normal version found, try using devel flag")
63-
// client.Version = ">0.0.0-0"
64-
// cp, err = client.ChartPathOptions.LocateChart(chrt, settings)
65-
// if err != nil {
66-
// return nil, err
67-
// }
68-
// } else {
69-
// return nil, err
70-
// }
71-
//}
72-
7357
// load from cache first, then from disk
7458
var chartRequested *chart.Chart
75-
chartPath := getChartPath(hr.Spec.Chart, hr.Spec.Version)
76-
d.Log.Info("chart path", "path", chartPath)
77-
result, ok := chartCache.Get(chartPath)
78-
if ok {
79-
log.Info("load charts from cache", "path", chartPath)
80-
chartRequested = result.(*chart.Chart)
81-
} else {
82-
dl := NewDownloader(systemNamespace, inCluster.ToRestConfig(), d.Log)
83-
chartPath, err := dl.downloadChart(hr.Spec.Chart, hr.Spec.Version)
84-
if err != nil {
85-
return nil, err
86-
}
87-
log.Info("load charts from disk", "path", chartPath)
88-
chartRequested, err = loader.Load(chartPath)
89-
if err != nil {
90-
return nil, err
91-
}
92-
chartCache.SetDefault(chartPath, chartRequested)
59+
60+
dl := NewDownloader(systemNamespace, inCluster.ToRestConfig(), d.Log)
61+
chartPath, err := dl.downloadChart(hr.Spec.Chart, hr.Spec.Version)
62+
if err != nil {
63+
return nil, err
64+
}
65+
log.Info("load charts from disk", "path", chartPath)
66+
chartRequested, err = loader.Load(chartPath)
67+
if err != nil {
68+
return nil, err
9369
}
9470

9571
values, err := getValues(hr, inCluster.ToRestConfig())
@@ -98,7 +74,6 @@ func (d *Deploy) install() (*release.Release, error) {
9874
}
9975

10076
client.Namespace = hr.Spec.Namespace
101-
// klog.Infof("load chart request: %s client: %+v", chartRequested.Name(), client)
10277
validInstallableChart, err := isChartInstallable(chartRequested)
10378
if !validInstallableChart {
10479
log.Error(err, "not installable error")

pkg/helm/sync.go

Lines changed: 10 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -88,44 +88,18 @@ func (d *Deploy) Sync() (*release.Release, error) {
8888
}
8989
client.ResetValues = true
9090

91-
// locate chart
92-
//chrt := hr.Spec.Chart
93-
//chartPath, err := client.ChartPathOptions.LocateChart(chrt, settings)
94-
//if err != nil {
95-
// klog.Errorf("locate chart %s error: %s", chartPath, err.Error())
96-
// // a simple string match
97-
// if client.Version == "" && strings.Contains(err.Error(), " no chart version found for") {
98-
// klog.Info("no normal version found, try using devel flag")
99-
// client.Version = ">0.0.0-0"
100-
// chartPath, err = client.ChartPathOptions.LocateChart(chrt, settings)
101-
// if err != nil {
102-
// return nil, err
103-
// }
104-
// } else {
105-
// return nil, err
106-
// }
107-
//}
108-
10991
// load from cache first, then from disk
11092
var ch *chart.Chart
111-
chartPath := getChartPath(hr.Spec.Chart, hr.Spec.Version)
112-
log.Info("chart path", "path", chartPath)
113-
result, ok := chartCache.Get(chartPath)
114-
if ok {
115-
log.Info("load charts from cache", "path", chartPath)
116-
ch = result.(*chart.Chart)
117-
} else {
118-
downloader := NewDownloader(d.SystemNamespace, d.InCluster.ToRestConfig(), d.Log)
119-
chartPath, err := downloader.downloadChart(hr.Spec.Chart, hr.Spec.Version)
120-
if err != nil {
121-
return nil, err
122-
}
123-
log.Info("load charts from disk", "path", chartPath)
124-
ch, err = loader.Load(chartPath)
125-
if err != nil {
126-
return nil, err
127-
}
128-
chartCache.SetDefault(chartPath, ch)
93+
94+
downloader := NewDownloader(d.SystemNamespace, d.InCluster.ToRestConfig(), d.Log)
95+
chartPath, err := downloader.downloadChart(hr.Spec.Chart, hr.Spec.Version)
96+
if err != nil {
97+
return nil, err
98+
}
99+
log.Info("load charts from disk", "path", chartPath)
100+
ch, err = loader.Load(chartPath)
101+
if err != nil {
102+
return nil, err
129103
}
130104

131105
if req := ch.Metadata.Dependencies; req != nil {

0 commit comments

Comments
 (0)