Skip to content

Commit 8ac5b20

Browse files
committed
[chore] ignore absent chart file
Signed-off-by: Stepan Paksashvili <stepan.paksashvili@flant.com>
1 parent 6ae3a66 commit 8ac5b20

File tree

5 files changed

+153
-74
lines changed

5 files changed

+153
-74
lines changed

pkg/helm/client/client.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import (
66

77
type HelmClient interface {
88
LastReleaseStatus(releaseName string) (string, string, error)
9-
UpgradeRelease(releaseName string, chart string, valuesPaths []string, setValues []string, releaseLabels map[string]string, namespace string) error
10-
Render(releaseName string, chart string, valuesPaths []string, setValues []string, releaseLabels map[string]string, namespace string, debug bool) (string, error)
9+
UpgradeRelease(releaseName, modulePath string, valuesPaths []string, setValues []string, releaseLabels map[string]string, namespace string) error
10+
Render(releaseName, modulePath string, valuesPaths []string, setValues []string, releaseLabels map[string]string, namespace string, debug bool) (string, error)
1111
GetReleaseValues(releaseName string) (utils.Values, error)
1212
GetReleaseChecksum(releaseName string) (string, error)
1313
GetReleaseLabels(releaseName, labelName string) (string, error)

pkg/helm/helm3lib/helm3lib.go

Lines changed: 93 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import (
66
"fmt"
77
"log/slog"
88
"os"
9+
"path/filepath"
10+
"slices"
911
"sort"
1012
"strconv"
1113
"strings"
@@ -14,6 +16,7 @@ import (
1416
"github.com/deckhouse/deckhouse/pkg/log"
1517
logContext "github.com/deckhouse/deckhouse/pkg/log/context"
1618
"helm.sh/helm/v3/pkg/action"
19+
"helm.sh/helm/v3/pkg/chart"
1720
"helm.sh/helm/v3/pkg/chart/loader"
1821
"helm.sh/helm/v3/pkg/chartutil"
1922
"helm.sh/helm/v3/pkg/cli"
@@ -164,15 +167,15 @@ func (h *LibClient) LastReleaseStatus(releaseName string) (string /*revision*/,
164167
return strconv.FormatInt(int64(lastRelease.Version), 10), lastRelease.Info.Status.String(), nil
165168
}
166169

167-
func (h *LibClient) UpgradeRelease(releaseName string, chartName string, valuesPaths []string, setValues []string, labels map[string]string, namespace string) error {
168-
err := h.upgradeRelease(releaseName, chartName, valuesPaths, setValues, labels, namespace)
170+
func (h *LibClient) UpgradeRelease(releaseName, modulePath string, valuesPaths []string, setValues []string, labels map[string]string, namespace string) error {
171+
err := h.upgradeRelease(releaseName, modulePath, valuesPaths, setValues, labels, namespace)
169172
if err != nil {
170173
// helm validation can fail because FeatureGate was enabled for example
171174
// handling this case we can reinitialize kubeClient and repeat one more time by backoff
172175
if err := actionConfigInit(h.Logger); err != nil {
173176
return err
174177
}
175-
return h.upgradeRelease(releaseName, chartName, valuesPaths, setValues, labels, namespace)
178+
return h.upgradeRelease(releaseName, modulePath, valuesPaths, setValues, labels, namespace)
176179
}
177180
h.Logger.Debug("helm release upgraded", slog.String("version", releaseName))
178181
return nil
@@ -182,7 +185,7 @@ func (h *LibClient) hasLabelsToApply() bool {
182185
return len(h.labels) > 0
183186
}
184187

185-
func (h *LibClient) upgradeRelease(releaseName string, chartName string, valuesPaths []string, setValues []string, labels map[string]string, namespace string) error {
188+
func (h *LibClient) upgradeRelease(releaseName, modulePath string, valuesPaths []string, setValues []string, labels map[string]string, namespace string) error {
186189
upg := action.NewUpgrade(actionConfig)
187190
if namespace != "" {
188191
upg.Namespace = namespace
@@ -197,11 +200,6 @@ func (h *LibClient) upgradeRelease(releaseName string, chartName string, valuesP
197200
upg.Timeout = options.Timeout
198201
upg.Labels = labels
199202

200-
chart, err := loader.Load(chartName)
201-
if err != nil {
202-
return err
203-
}
204-
205203
var resultValues chartutil.Values
206204

207205
for _, vp := range valuesPaths {
@@ -224,9 +222,14 @@ func (h *LibClient) upgradeRelease(releaseName string, chartName string, valuesP
224222
resultValues = chartutil.CoalesceTables(resultValues, m)
225223
}
226224

225+
loaded, err := loadChart(releaseName, modulePath)
226+
if err != nil {
227+
return err
228+
}
229+
227230
h.Logger.Info("Running helm upgrade for release",
228231
slog.String("release", releaseName),
229-
slog.String("chart", chartName),
232+
slog.String("chart", modulePath),
230233
slog.String("namespace", namespace))
231234
histClient := action.NewHistory(actionConfig)
232235
// Max is not working!!! Sort the final of releases by your own
@@ -247,7 +250,7 @@ func (h *LibClient) upgradeRelease(releaseName string, chartName string, valuesP
247250
instClient.UseReleaseName = true
248251
instClient.Labels = labels
249252

250-
_, err = instClient.Run(chart, resultValues)
253+
_, err = instClient.Run(loaded, resultValues)
251254
return err
252255
}
253256
h.Logger.Debug("old releases found", slog.Int("count", len(releases)))
@@ -306,13 +309,13 @@ func (h *LibClient) upgradeRelease(releaseName string, chartName string, valuesP
306309
}
307310
}
308311

309-
_, err = upg.Run(releaseName, chart, resultValues)
312+
_, err = upg.Run(releaseName, loaded, resultValues)
310313
if err != nil {
311314
return fmt.Errorf("helm upgrade failed: %s\n", err)
312315
}
313316
h.Logger.Info("Helm upgrade successful",
314317
slog.String("release", releaseName),
315-
slog.String("chart", chartName),
318+
slog.String("chart", modulePath),
316319
slog.String("namespace", namespace))
317320

318321
return nil
@@ -451,12 +454,7 @@ func (h *LibClient) ListReleasesNames() ([]string, error) {
451454
return releases, nil
452455
}
453456

454-
func (h *LibClient) Render(releaseName, chartName string, valuesPaths, setValues []string, _ map[string]string, namespace string, debug bool) (string, error) {
455-
chart, err := loader.Load(chartName)
456-
if err != nil {
457-
return "", err
458-
}
459-
457+
func (h *LibClient) Render(releaseName, modulePath string, valuesPaths, setValues []string, _ map[string]string, namespace string, debug bool) (string, error) {
460458
var resultValues chartutil.Values
461459

462460
for _, vp := range valuesPaths {
@@ -480,19 +478,24 @@ func (h *LibClient) Render(releaseName, chartName string, valuesPaths, setValues
480478
}
481479

482480
h.Logger.Debug("Render helm templates for chart ...",
483-
slog.String("chart", chartName),
481+
slog.String("chart", modulePath),
484482
slog.String("namespace", namespace))
485483

484+
loaded, err := loadChart(releaseName, modulePath)
485+
if err != nil {
486+
return "", err
487+
}
488+
486489
inst := h.newDryRunInstAction(namespace, releaseName)
487490

488-
rs, err := inst.Run(chart, resultValues)
491+
rs, err := inst.Run(loaded, resultValues)
489492
if err != nil {
490493
// helm render can fail because the CRD were previously created
491494
// handling this case we can reinitialize RESTClient and repeat one more time by backoff
492495
_ = actionConfigInit(h.Logger)
493496
inst = h.newDryRunInstAction(namespace, releaseName)
494497

495-
rs, err = inst.Run(chart, resultValues)
498+
rs, err = inst.Run(loaded, resultValues)
496499
}
497500

498501
if err != nil {
@@ -506,7 +509,7 @@ func (h *LibClient) Render(releaseName, chartName string, valuesPaths, setValues
506509
rs.Manifest += fmt.Sprintf("\n\n\n%v", err)
507510
}
508511

509-
h.Logger.Info("Render helm templates for chart was successful", slog.String("chart", chartName))
512+
h.Logger.Info("Render helm templates for chart was successful", slog.String("chart", modulePath))
510513

511514
return rs.Manifest, nil
512515
}
@@ -543,3 +546,70 @@ func (h *LibClient) ListReleases() ([]*release.Release, error) {
543546

544547
return list, nil
545548
}
549+
550+
func loadChart(moduleName, modulePath string) (*chart.Chart, error) {
551+
if _, err := os.Stat(filepath.Join(modulePath, "Chart.yaml")); err == nil {
552+
return loader.Load(modulePath)
553+
}
554+
555+
var files []*loader.BufferedFile
556+
557+
chartYaml := fmt.Sprintf(`
558+
name: %s
559+
version: 0.2.0
560+
apiVersion: v2`, moduleName)
561+
562+
files = append(files, &loader.BufferedFile{
563+
Name: "Chart.yaml",
564+
Data: []byte(chartYaml),
565+
})
566+
567+
ignored := []string{
568+
"crds",
569+
"docs",
570+
"hooks",
571+
"images",
572+
"lib",
573+
}
574+
575+
err := filepath.Walk(modulePath, func(path string, info os.FileInfo, err error) error {
576+
if err != nil {
577+
return err
578+
}
579+
580+
if info.IsDir() {
581+
if slices.Contains(ignored, info.Name()) {
582+
return filepath.SkipDir
583+
}
584+
585+
return nil
586+
}
587+
588+
relPath, err := filepath.Rel(modulePath, path)
589+
if err != nil {
590+
return err
591+
}
592+
593+
data, err := os.ReadFile(path)
594+
if err != nil {
595+
return err
596+
}
597+
598+
files = append(files, &loader.BufferedFile{
599+
Name: relPath,
600+
Data: data,
601+
})
602+
603+
return nil
604+
})
605+
if err != nil {
606+
return nil, fmt.Errorf("read module files: %w", err)
607+
}
608+
609+
loaded, err := loader.LoadFiles(files)
610+
if err != nil {
611+
return nil, fmt.Errorf("load chart from files: %w", err)
612+
}
613+
614+
return loaded, nil
615+
}

pkg/helm/helm3lib/helm3lib_test.go

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"github.com/deckhouse/deckhouse/pkg/log"
88
. "github.com/onsi/gomega"
99
"helm.sh/helm/v3/pkg/action"
10+
"helm.sh/helm/v3/pkg/chart/loader"
1011
"helm.sh/helm/v3/pkg/chartutil"
1112
"helm.sh/helm/v3/pkg/cli"
1213
kubefake "helm.sh/helm/v3/pkg/kube/fake"
@@ -47,7 +48,10 @@ func TestHelm3LibUpgradeDelete(t *testing.T) {
4748
g.Expect(err).ShouldNot(HaveOccurred())
4849
g.Expect(releases).To(BeEmpty(), "should get empty list of releases")
4950

50-
err = cl.UpgradeRelease("test-release", "testdata/chart", nil, nil, map[string]string{"key": "value"}, cl.Namespace)
51+
chart, err := loader.Load("testdata/chart")
52+
g.Expect(err).ShouldNot(HaveOccurred())
53+
54+
err = cl.UpgradeRelease("test-release", chart, nil, nil, map[string]string{"key": "value"}, cl.Namespace)
5155
g.Expect(err).ShouldNot(HaveOccurred())
5256

5357
releasesNames, err := cl.ListReleasesNames()
@@ -91,7 +95,10 @@ func TestReleaseExistsReturnsTrueForExistingRelease(t *testing.T) {
9195
g.Expect(err).ShouldNot(HaveOccurred())
9296
g.Expect(releases).To(BeEmpty(), "should get empty list of releases")
9397

94-
err = cl.UpgradeRelease("existing-release", "testdata/chart", nil, nil, nil, cl.Namespace)
98+
chart, err := loader.Load("testdata/chart")
99+
g.Expect(err).ShouldNot(HaveOccurred())
100+
101+
err = cl.UpgradeRelease("existing-release", chart, nil, nil, nil, cl.Namespace)
95102
g.Expect(err).ShouldNot(HaveOccurred())
96103

97104
releases, err = cl.ListReleases()
@@ -129,7 +136,10 @@ func TestDeleteReleaseRemovesExistingRelease(t *testing.T) {
129136
g.Expect(err).ShouldNot(HaveOccurred())
130137
g.Expect(releases).To(BeEmpty(), "should get empty list of releases")
131138

132-
err = cl.UpgradeRelease("release-to-delete", "testdata/chart", nil, nil, nil, cl.Namespace)
139+
chart, err := loader.Load("testdata/chart")
140+
g.Expect(err).ShouldNot(HaveOccurred())
141+
142+
err = cl.UpgradeRelease("release-to-delete", chart, nil, nil, nil, cl.Namespace)
133143
g.Expect(err).ShouldNot(HaveOccurred())
134144

135145
releases, err = cl.ListReleases()
@@ -157,7 +167,10 @@ func TestLastReleaseStatusReturnsCorrectStatusForExistingRelease(t *testing.T) {
157167
g := NewWithT(t)
158168
cl := initHelmClient(t)
159169

160-
err := cl.UpgradeRelease("status-release", "testdata/chart", nil, nil, nil, cl.Namespace)
170+
chart, err := loader.Load("testdata/chart")
171+
g.Expect(err).ShouldNot(HaveOccurred())
172+
173+
err = cl.UpgradeRelease("status-release", chart, nil, nil, nil, cl.Namespace)
161174
g.Expect(err).ShouldNot(HaveOccurred())
162175

163176
revision, status, err := cl.LastReleaseStatus("status-release")

0 commit comments

Comments
 (0)