Skip to content

Commit e69ad33

Browse files
authored
[Feature] Improve Helm Chart Manager (#1792)
1 parent 3bbe1c5 commit e69ad33

File tree

6 files changed

+296
-158
lines changed

6 files changed

+296
-158
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
- (Feature) Deprecate AF Mode
4343
- (Maintenance) Switch License to 2025
4444
- (Feature) Migrate Storage V1 to CE
45+
- (Feature) Improve Helm Chart Manager
4546

4647
## [1.2.43](https://github.com/arangodb/kube-arangodb/tree/1.2.43) (2024-10-14)
4748
- (Feature) ArangoRoute CRD

pkg/util/http/downloader.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2025 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
21+
package http
22+
23+
import (
24+
"context"
25+
"fmt"
26+
"io"
27+
"net/http"
28+
29+
"github.com/arangodb/kube-arangodb/pkg/util/errors"
30+
)
31+
32+
func Download(ctx context.Context, client *http.Client, format string, args ...interface{}) ([]byte, error) {
33+
if client == nil {
34+
client = http.DefaultClient
35+
}
36+
37+
url := fmt.Sprintf(format, args...)
38+
39+
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
40+
if err != nil {
41+
return nil, err
42+
}
43+
44+
resp, err := client.Do(req)
45+
if err != nil {
46+
return nil, err
47+
}
48+
49+
data, err := io.ReadAll(resp.Body)
50+
if err != nil {
51+
if err := resp.Body.Close(); err != nil {
52+
return nil, err
53+
}
54+
55+
return nil, err
56+
}
57+
58+
if err := resp.Body.Close(); err != nil {
59+
return nil, err
60+
}
61+
62+
if resp.StatusCode != 200 {
63+
return nil, errors.Errorf("Unexpected code: %d for `%s`", resp.StatusCode, url)
64+
}
65+
66+
return data, nil
67+
}

pkg/util/k8sutil/helm/chart_manager.go

Lines changed: 15 additions & 149 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// DISCLAIMER
33
//
4-
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
4+
// Copyright 2024-2025 ArangoDB GmbH, Cologne, Germany
55
//
66
// Licensed under the Apache License, Version 2.0 (the "License");
77
// you may not use this file except in compliance with the License.
@@ -23,25 +23,24 @@ package helm
2323
import (
2424
"context"
2525
"fmt"
26-
"io"
2726
"net/http"
2827
"sort"
2928
"sync"
3029

3130
"helm.sh/helm/v3/pkg/repo"
3231

3332
"github.com/arangodb/kube-arangodb/pkg/util"
34-
"github.com/arangodb/kube-arangodb/pkg/util/errors"
33+
operatorHTTP "github.com/arangodb/kube-arangodb/pkg/util/http"
3534
)
3635

37-
func NewChartManager(ctx context.Context, client *http.Client, url string) (ChartManager, error) {
36+
func NewChartManager(ctx context.Context, client *http.Client, format string, args ...interface{}) (ChartManager, error) {
3837
if client == nil {
3938
client = http.DefaultClient
4039
}
4140

4241
m := manager{
4342
client: client,
44-
url: url,
43+
url: fmt.Sprintf(format, args...),
4544
}
4645

4746
if err := m.Reload(ctx); err != nil {
@@ -55,9 +54,8 @@ type ChartManager interface {
5554
Reload(ctx context.Context) error
5655

5756
Repositories() []string
58-
Versions(repo string) []string
59-
Latest(repo string) (string, bool)
60-
Chart(ctx context.Context, repo, version string) (Chart, error)
57+
58+
Get(name string) (ChartManagerRepo, bool)
6159
}
6260

6361
type manager struct {
@@ -70,125 +68,17 @@ type manager struct {
7068
index *repo.IndexFile
7169
}
7270

73-
func (m *manager) Latest(repoName string) (string, bool) {
74-
m.lock.Lock()
75-
defer m.lock.Unlock()
76-
77-
if v := m.latest(repoName); v == nil {
78-
return "", false
79-
} else {
80-
return v.Version, true
81-
}
82-
}
83-
84-
func (m *manager) latest(repoName string) *repo.ChartVersion {
85-
r, ok := m.index.Entries[repoName]
86-
if !ok {
87-
return nil
88-
}
89-
90-
if len(r) == 0 {
91-
return nil
92-
}
93-
94-
if len(r) == 1 {
95-
return r[0]
96-
}
97-
98-
var p = 0
99-
100-
for id := range r {
101-
if id == p {
102-
continue
71+
func (m *manager) Get(name string) (ChartManagerRepo, bool) {
72+
for entry := range m.index.Entries {
73+
if entry == name {
74+
return chartManagerRepo{
75+
manager: m,
76+
name: name,
77+
}, true
10378
}
104-
105-
if r[id].Created.After(r[p].Created) {
106-
p = id
107-
}
108-
}
109-
110-
if p == -1 {
111-
return nil
112-
}
113-
114-
return r[p]
115-
}
116-
117-
func (m *manager) Chart(ctx context.Context, repoName, version string) (Chart, error) {
118-
m.lock.Lock()
119-
defer m.lock.Unlock()
120-
121-
r, ok := m.index.Entries[repoName]
122-
if !ok {
123-
return nil, errors.Errorf("Repo `%s` not found", repoName)
124-
}
125-
126-
var ver *repo.ChartVersion
127-
128-
if version == "latest" {
129-
ver = m.latest(repoName)
130-
} else {
131-
vs, ok := util.PickFromList(r, func(v *repo.ChartVersion) bool {
132-
if v == nil {
133-
return false
134-
}
135-
136-
return v.Version == version
137-
})
138-
if !ok {
139-
return nil, errors.Errorf("Repo `%s` does not contains version `%s`", repoName, version)
140-
}
141-
ver = vs
142-
}
143-
144-
if len(ver.URLs) == 0 {
145-
return nil, errors.Errorf("Chart `%s-%s` does not have any urls defined", repoName, version)
146-
}
147-
148-
var errs = make([]error, len(ver.URLs))
149-
150-
for id, url := range ver.URLs {
151-
data, err := m.download(ctx, url)
152-
if err != nil {
153-
errs[id] = err
154-
continue
155-
}
156-
157-
return data, nil
15879
}
15980

160-
return nil, errors.Errors(errs...)
161-
}
162-
163-
func (m *manager) download(ctx context.Context, url string) ([]byte, error) {
164-
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
165-
if err != nil {
166-
return nil, err
167-
}
168-
169-
resp, err := m.client.Do(req)
170-
if err != nil {
171-
return nil, err
172-
}
173-
174-
data, err := io.ReadAll(resp.Body)
175-
if err != nil {
176-
if err := resp.Body.Close(); err != nil {
177-
return nil, err
178-
}
179-
180-
return nil, err
181-
}
182-
183-
if err := resp.Body.Close(); err != nil {
184-
return nil, err
185-
}
186-
187-
if resp.StatusCode != 200 {
188-
return nil, errors.Errorf("Unexpected code: %d", resp.StatusCode)
189-
}
190-
191-
return data, nil
81+
return nil, false
19282
}
19383

19484
func (m *manager) Repositories() []string {
@@ -206,35 +96,11 @@ func (m *manager) Repositories() []string {
20696
return s
20797
}
20898

209-
func (m *manager) Versions(repo string) []string {
210-
m.lock.Lock()
211-
defer m.lock.Unlock()
212-
213-
r, ok := m.index.Entries[repo]
214-
if !ok {
215-
return nil
216-
}
217-
218-
if len(r) == 0 {
219-
return []string{}
220-
}
221-
222-
s := make([]string, 0, len(r))
223-
224-
for _, v := range r {
225-
s = append(s, v.Version)
226-
}
227-
228-
sort.Strings(s)
229-
230-
return s
231-
}
232-
23399
func (m *manager) Reload(ctx context.Context) error {
234100
m.lock.Lock()
235101
defer m.lock.Unlock()
236102

237-
data, err := m.download(ctx, fmt.Sprintf("%s/index.yaml", m.url))
103+
data, err := operatorHTTP.Download(ctx, m.client, fmt.Sprintf("%s/index.yaml", m.url))
238104
if err != nil {
239105
return err
240106
}

0 commit comments

Comments
 (0)