Skip to content

Commit 91381b4

Browse files
authored
[chore] ignore absent chart file (#686)
Signed-off-by: Stepan Paksashvili <stepan.paksashvili@flant.com>
1 parent 3fc2315 commit 91381b4

File tree

3 files changed

+134
-68
lines changed

3 files changed

+134
-68
lines changed

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+
`, 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/nelm/nelm.go

Lines changed: 39 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -181,10 +181,10 @@ func (c *NelmClient) LastReleaseStatus(releaseName string) (string, string, erro
181181
return strconv.FormatInt(int64(releaseGetResult.Release.Revision), 10), releaseGetResult.Release.Status.String(), nil
182182
}
183183

184-
func (c *NelmClient) UpgradeRelease(releaseName, chartName string, valuesPaths []string, setValues []string, releaseLabels map[string]string, namespace string) error {
184+
func (c *NelmClient) UpgradeRelease(releaseName, modulePath string, valuesPaths []string, setValues []string, releaseLabels map[string]string, namespace string) error {
185185
logger := c.logger.With(
186186
slog.String("release_name", releaseName),
187-
slog.String("chart", chartName),
187+
slog.String("chart", modulePath),
188188
slog.String("namespace", namespace),
189189
)
190190

@@ -220,26 +220,29 @@ func (c *NelmClient) UpgradeRelease(releaseName, chartName string, valuesPaths [
220220
}
221221

222222
if err := c.actions.ReleaseInstall(context.TODO(), releaseName, namespace, action.ReleaseInstallOptions{
223-
Chart: chartName,
224-
ExtraLabels: c.labels,
225-
ExtraAnnotations: extraAnnotations,
226-
KubeContext: c.opts.KubeContext,
227-
NoInstallCRDs: true,
228-
ReleaseHistoryLimit: int(c.opts.HistoryMax),
229-
ReleaseLabels: releaseLabels,
230-
ReleaseStorageDriver: c.opts.HelmDriver,
231-
Timeout: c.opts.Timeout,
232-
ValuesFilesPaths: valuesPaths,
233-
ValuesSets: setValues,
234-
ForceAdoption: true,
235-
NoPodLogs: true,
223+
Chart: modulePath,
224+
DefaultChartName: releaseName,
225+
DefaultChartVersion: "0.2.0",
226+
DefaultChartAPIVersion: "v2",
227+
ExtraLabels: c.labels,
228+
ExtraAnnotations: extraAnnotations,
229+
KubeContext: c.opts.KubeContext,
230+
NoInstallCRDs: true,
231+
ReleaseHistoryLimit: int(c.opts.HistoryMax),
232+
ReleaseLabels: releaseLabels,
233+
ReleaseStorageDriver: c.opts.HelmDriver,
234+
Timeout: c.opts.Timeout,
235+
ValuesFilesPaths: valuesPaths,
236+
ValuesSets: setValues,
237+
ForceAdoption: true,
238+
NoPodLogs: true,
236239
}); err != nil {
237240
return fmt.Errorf("install nelm release %q: %w", releaseName, err)
238241
}
239242

240243
logger.Info("Nelm upgrade successful",
241244
slog.String("release", releaseName),
242-
slog.String("chart", chartName),
245+
slog.String("chart", modulePath),
243246
slog.String("namespace", namespace))
244247

245248
return nil
@@ -360,9 +363,9 @@ func (c *NelmClient) ListReleasesNames() ([]string, error) {
360363
return releaseNames, nil
361364
}
362365

363-
func (c *NelmClient) Render(releaseName, chartName string, valuesPaths, setValues []string, releaseLabels map[string]string, namespace string, debug bool) (string, error) {
366+
func (c *NelmClient) Render(releaseName, modulePath string, valuesPaths, setValues []string, releaseLabels map[string]string, namespace string, debug bool) (string, error) {
364367
c.logger.Debug("Render nelm templates for chart ...",
365-
slog.String("chart", chartName),
368+
slog.String("chart", modulePath),
366369
slog.String("namespace", namespace))
367370

368371
// Add client annotations
@@ -378,27 +381,30 @@ func (c *NelmClient) Render(releaseName, chartName string, valuesPaths, setValue
378381
}
379382

380383
chartRenderResult, err := c.actions.ChartRender(context.TODO(), action.ChartRenderOptions{
381-
OutputFilePath: "/dev/null", // No output file, we want to return the manifest as a string
382-
Chart: chartName,
383-
ExtraLabels: c.labels,
384-
ExtraAnnotations: extraAnnotations,
385-
KubeContext: c.opts.KubeContext,
386-
ReleaseName: releaseName,
387-
ReleaseNamespace: namespace,
388-
ReleaseStorageDriver: c.opts.HelmDriver,
389-
Remote: true,
390-
ValuesFilesPaths: valuesPaths,
391-
ValuesSets: setValues,
392-
ForceAdoption: true,
384+
OutputFilePath: "/dev/null", // No output file, we want to return the manifest as a string
385+
Chart: modulePath,
386+
DefaultChartName: releaseName,
387+
DefaultChartVersion: "0.2.0",
388+
DefaultChartAPIVersion: "v2",
389+
ExtraLabels: c.labels,
390+
ExtraAnnotations: extraAnnotations,
391+
KubeContext: c.opts.KubeContext,
392+
ReleaseName: releaseName,
393+
ReleaseNamespace: namespace,
394+
ReleaseStorageDriver: c.opts.HelmDriver,
395+
Remote: true,
396+
ValuesFilesPaths: valuesPaths,
397+
ValuesSets: setValues,
398+
ForceAdoption: true,
393399
})
394400
if err != nil {
395401
if !debug {
396-
return "", fmt.Errorf("render nelm chart %q: %w\n\nUse --debug flag to render out invalid YAML", chartName, err)
402+
return "", fmt.Errorf("render nelm chart %q: %w\n\nUse --debug flag to render out invalid YAML", modulePath, err)
397403
}
398-
return "", fmt.Errorf("render nelm chart %q: %w", chartName, err)
404+
return "", fmt.Errorf("render nelm chart %q: %w", modulePath, err)
399405
}
400406

401-
c.logger.Info("Render nelm templates for chart was successful", slog.String("chart", chartName))
407+
c.logger.Info("Render nelm templates for chart was successful", slog.String("chart", modulePath))
402408

403409
var result strings.Builder
404410
for _, resource := range chartRenderResult.Resources {

pkg/module_manager/models/modules/helm.go

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import (
2121
"github.com/flant/addon-operator/pkg"
2222
"github.com/flant/addon-operator/pkg/helm"
2323
"github.com/flant/addon-operator/pkg/helm/client"
24-
helm3lib "github.com/flant/addon-operator/pkg/helm/helm3lib"
24+
"github.com/flant/addon-operator/pkg/helm/helm3lib"
2525
"github.com/flant/addon-operator/pkg/utils"
2626
"github.com/flant/kube-client/manifest"
2727
"github.com/flant/shell-operator/pkg/utils/measure"
@@ -143,7 +143,7 @@ func (hm *HelmModule) isHelmChart() (bool, error) {
143143
// check that templates/ dir exists
144144
_, err = os.Stat(filepath.Join(hm.path, "templates"))
145145
if err == nil {
146-
return true, hm.createChartYaml(chartPath)
146+
return true, nil
147147
}
148148
if os.IsNotExist(err) {
149149
// if templates not exists - it's not a helm module
@@ -154,16 +154,6 @@ func (hm *HelmModule) isHelmChart() (bool, error) {
154154
return false, err
155155
}
156156

157-
func (hm *HelmModule) createChartYaml(chartPath string) error {
158-
// we already have versions like 0.1.0 or 0.1.1
159-
// to keep helm updatable, we have to increment this version
160-
// new minor version of addon-operator seems reasonable to increase minor version of a helm chart
161-
data := fmt.Sprintf(`name: %s
162-
version: 0.2.0`, hm.name)
163-
164-
return os.WriteFile(chartPath, []byte(data), 0o644)
165-
}
166-
167157
// checkHelmValues returns error if there is a wrong patch or values are not satisfied
168158
// a Helm values contract defined by schemas in 'openapi' directory.
169159
func (hm *HelmModule) checkHelmValues() error {

0 commit comments

Comments
 (0)