Skip to content

Commit fd36d2d

Browse files
committed
Allow overwriting chart values from HelmRepository
1 parent 2e0b6cb commit fd36d2d

File tree

1 file changed

+82
-14
lines changed

1 file changed

+82
-14
lines changed

controllers/helmchart_controller.go

Lines changed: 82 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -283,10 +283,77 @@ func (r *HelmChartReconciler) reconcileFromHelmRepository(ctx context.Context,
283283
return sourcev1.HelmChartNotReady(chart, sourcev1.ChartPullFailedReason, err.Error()), err
284284
}
285285

286-
// Write the artifact to storage
287-
if err := r.Storage.AtomicWriteFile(&artifact, res, 0644); err != nil {
288-
err = fmt.Errorf("unable to write chart file: %w", err)
289-
return sourcev1.HelmChartNotReady(chart, sourcev1.StorageOperationFailedReason, err.Error()), err
286+
switch {
287+
case chart.Spec.ValuesFile != "" && chart.Spec.ValuesFile != chartutil.ValuesfileName:
288+
// Create temporary working directory
289+
tmpDir, err := ioutil.TempDir("", fmt.Sprintf("%s-%s-", chart.Namespace, chart.Name))
290+
if err != nil {
291+
err = fmt.Errorf("tmp dir error: %w", err)
292+
return sourcev1.HelmChartNotReady(chart, sourcev1.StorageOperationFailedReason, err.Error()), err
293+
}
294+
defer os.RemoveAll(tmpDir)
295+
296+
// Untar chart into working directory
297+
if _, err = untar.Untar(res, tmpDir); err != nil {
298+
err = fmt.Errorf("chart untar error: %w", err)
299+
return sourcev1.HelmChartNotReady(chart, sourcev1.StorageOperationFailedReason, err.Error()), err
300+
}
301+
302+
// Overwrite values file
303+
chartPath := path.Join(tmpDir, cv.Name)
304+
srcPath := path.Join(chartPath, chart.Spec.ValuesFile)
305+
if f, err := os.Stat(srcPath); os.IsNotExist(err) || !f.Mode().IsRegular() {
306+
err = fmt.Errorf("invalid values file: %s", chart.Spec.ValuesFile)
307+
return sourcev1.HelmChartNotReady(chart, sourcev1.ChartPackageFailedReason, err.Error()), err
308+
}
309+
src, err := os.Open(srcPath)
310+
if err != nil {
311+
err = fmt.Errorf("failed to open values file '%s': %w", chart.Spec.ValuesFile, err)
312+
return sourcev1.HelmChartNotReady(chart, sourcev1.ChartPackageFailedReason, err.Error()), err
313+
}
314+
t, err := os.OpenFile(path.Join(chartPath, chartutil.ValuesfileName), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
315+
if err != nil {
316+
src.Close()
317+
err = fmt.Errorf("failed to open default values: %w", err)
318+
return sourcev1.HelmChartNotReady(chart, sourcev1.ChartPackageFailedReason, err.Error()), err
319+
}
320+
if _, err := io.Copy(t, src); err != nil {
321+
t.Close()
322+
src.Close()
323+
err = fmt.Errorf("failed to overwrite default values with '%s: %w", chart.Spec.ValuesFile, err)
324+
return sourcev1.HelmChartNotReady(chart, sourcev1.ChartPackageFailedReason, err.Error()), err
325+
}
326+
t.Close()
327+
src.Close()
328+
329+
// Package the chart, we use the action here instead of relying on the
330+
// chartutil.Save method as the action performs a dependency check for us
331+
pkg := action.NewPackage()
332+
pkg.Destination = tmpDir
333+
pkgPath, err := pkg.Run(chartPath, nil)
334+
if err != nil {
335+
err = fmt.Errorf("chart package error: %w", err)
336+
return sourcev1.HelmChartNotReady(chart, sourcev1.ChartPackageFailedReason, err.Error()), err
337+
}
338+
339+
// Copy the packaged chart to the artifact path
340+
cf, err := os.Open(pkgPath)
341+
if err != nil {
342+
err = fmt.Errorf("failed to open chart package: %w", err)
343+
return sourcev1.HelmChartNotReady(chart, sourcev1.StorageOperationFailedReason, err.Error()), err
344+
}
345+
if err := r.Storage.Copy(&artifact, cf); err != nil {
346+
cf.Close()
347+
err = fmt.Errorf("failed to copy chart package to storage: %w", err)
348+
return sourcev1.HelmChartNotReady(chart, sourcev1.StorageOperationFailedReason, err.Error()), err
349+
}
350+
cf.Close()
351+
default:
352+
// Write artifact to storage
353+
if err := r.Storage.AtomicWriteFile(&artifact, res, 0644); err != nil {
354+
err = fmt.Errorf("unable to write chart file: %w", err)
355+
return sourcev1.HelmChartNotReady(chart, sourcev1.StorageOperationFailedReason, err.Error()), err
356+
}
290357
}
291358

292359
// Update symlink
@@ -330,7 +397,7 @@ func (r *HelmChartReconciler) getChartRepositoryWithArtifact(ctx context.Context
330397
func (r *HelmChartReconciler) reconcileFromGitRepository(ctx context.Context,
331398
repository sourcev1.GitRepository, chart sourcev1.HelmChart) (sourcev1.HelmChart, error) {
332399
// Create temporary working directory
333-
tmpDir, err := ioutil.TempDir("", fmt.Sprintf("%s-%s", chart.Namespace, chart.Name))
400+
tmpDir, err := ioutil.TempDir("", fmt.Sprintf("%s-%s-", chart.Namespace, chart.Name))
334401
if err != nil {
335402
err = fmt.Errorf("tmp dir error: %w", err)
336403
return sourcev1.HelmChartNotReady(chart, sourcev1.StorageOperationFailedReason, err.Error()), err
@@ -365,7 +432,8 @@ func (r *HelmChartReconciler) reconcileFromGitRepository(ctx context.Context,
365432
}
366433

367434
// Return early if the revision is still the same as the current chart artifact
368-
artifact := r.Storage.NewArtifactFor(chart.Kind, chart.ObjectMeta.GetObjectMeta(), chartMetadata.Version, fmt.Sprintf("%s-%s.tgz", chartMetadata.Name, chartMetadata.Version))
435+
artifact := r.Storage.NewArtifactFor(chart.Kind, chart.ObjectMeta.GetObjectMeta(), chartMetadata.Version,
436+
fmt.Sprintf("%s-%s.tgz", chartMetadata.Name, chartMetadata.Version))
369437
if chart.GetArtifact() != nil && chart.GetArtifact().Revision == chartMetadata.Version {
370438
if artifact.URL != repository.GetArtifact().URL {
371439
r.Storage.SetArtifactURL(repository.GetArtifact())
@@ -375,28 +443,28 @@ func (r *HelmChartReconciler) reconcileFromGitRepository(ctx context.Context,
375443
}
376444

377445
// Overwrite default values if instructed to
378-
if chart.Spec.ValuesFile != "" {
379-
srcPath := path.Join(tmpDir, chart.Spec.ValuesFile)
446+
if chart.Spec.ValuesFile != "" && chart.Spec.ValuesFile != chartutil.ValuesfileName {
447+
srcPath := path.Join(chartPath, chart.Spec.ValuesFile)
380448
if f, err := os.Stat(srcPath); os.IsNotExist(err) || !f.Mode().IsRegular() {
381449
err = fmt.Errorf("invalid values file path: %s", chart.Spec.ValuesFile)
382-
return chart, err
450+
return sourcev1.HelmChartNotReady(chart, sourcev1.ChartPackageFailedReason, err.Error()), err
383451
}
384452
src, err := os.Open(srcPath)
385453
if err != nil {
386454
err = fmt.Errorf("failed to open values file '%s': %w", chart.Spec.ValuesFile, err)
387-
return chart, err
455+
return sourcev1.HelmChartNotReady(chart, sourcev1.ChartPackageFailedReason, err.Error()), err
388456
}
389457
t, err := os.OpenFile(path.Join(tmpDir, chartutil.ValuesfileName), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
390458
if err != nil {
391459
src.Close()
392460
err = fmt.Errorf("failed to open values file '%s': %w", chartutil.ValuesfileName, err)
393-
return chart, err
461+
return sourcev1.HelmChartNotReady(chart, sourcev1.ChartPackageFailedReason, err.Error()), err
394462
}
395463
if _, err := io.Copy(t, src); err != nil {
396464
t.Close()
397465
src.Close()
398466
err = fmt.Errorf("failed to copy values file '%s' to '%s: %w", chart.Spec.ValuesFile, chartutil.ValuesfileName, err)
399-
return chart, err
467+
return sourcev1.HelmChartNotReady(chart, sourcev1.ChartPackageFailedReason, err.Error()), err
400468
}
401469
t.Close()
402470
src.Close()
@@ -421,14 +489,14 @@ func (r *HelmChartReconciler) reconcileFromGitRepository(ctx context.Context,
421489
// chartutil.Save method as the action performs a dependency check for us
422490
pkg := action.NewPackage()
423491
pkg.Destination = tmpDir
424-
src, err := pkg.Run(chartPath, nil)
492+
pkgPath, err := pkg.Run(chartPath, nil)
425493
if err != nil {
426494
err = fmt.Errorf("chart package error: %w", err)
427495
return sourcev1.HelmChartNotReady(chart, sourcev1.ChartPackageFailedReason, err.Error()), err
428496
}
429497

430498
// Copy the packaged chart to the artifact path
431-
cf, err := os.Open(src)
499+
cf, err := os.Open(pkgPath)
432500
if err != nil {
433501
err = fmt.Errorf("failed to open chart package: %w", err)
434502
return sourcev1.HelmChartNotReady(chart, sourcev1.StorageOperationFailedReason, err.Error()), err

0 commit comments

Comments
 (0)