Add `--skip-refresh` flag to the build command (#444)

This improves the `helmfile sync` performance.

From the code: `BuildDeps` is used only by `runHelmDepBuilds`, which
only is used by `PrepareCharts` which is finally only used by
`withPreparedCharts`.

`withPreparedCharts` already does `SyncReposOnce` which means we do not
have to refresh the local repository cache on each chart build.

This is only supported in Helm v3.

This seems to be mostly affecting helmfiles which have a lot of releases
and those release charts use sub dependencies.

I saw significant performance improvements for a helmfile with 45
releases, 2 repositories, and most of the charts also had their own
dependencies. Results:

Before the patch:
* real  9m10.565s
* real  9m38.335s
* real  9m14.941s
* real  5m13.106s (with cache)

After the patch:
* real  6m51.965s
* real  6m36.605s
* real  6m31.685s
* real  3m0.271s (with cache)

These were tested with:
```
rm -rf ~/.cache/helmfile ~/.cache/helm ~/.config/helm/repositories.* && helmfile sync ...
```

The result with `(with cache)` was without deleting the caches first.

From these metrics it seems that the sync duration decreased 20-45%
depending on the run, release count, dependencies and if the cache was
used or not.

As far as I understand, this should be backward-compatible change.

Signed-off-by: Indrek Juhkam <indrek@urgas.eu>

Signed-off-by: Indrek Juhkam <indrek@urgas.eu>
This commit is contained in:
Indrek Juhkam 2022-10-20 03:03:08 +03:00 committed by GitHub
parent f2be4861d5
commit a409b450cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 4 deletions

View File

@ -218,7 +218,17 @@ func (helm *execer) RegistryLogin(repository string, username string, password s
func (helm *execer) BuildDeps(name, chart string) error { func (helm *execer) BuildDeps(name, chart string) error {
helm.logger.Infof("Building dependency release=%v, chart=%v", name, chart) helm.logger.Infof("Building dependency release=%v, chart=%v", name, chart)
out, err := helm.exec([]string{"dependency", "build", chart}, map[string]string{}, nil) args := []string{
"dependency",
"build",
chart,
}
if helm.IsHelm3() {
args = append(args, "--skip-refresh")
}
out, err := helm.exec(args, map[string]string{}, nil)
helm.info(out) helm.info(out)
return err return err
} }

View File

@ -337,10 +337,12 @@ exec: helm --kube-context dev dependency update ./chart/foo --verify
func Test_BuildDeps(t *testing.T) { func Test_BuildDeps(t *testing.T) {
var buffer bytes.Buffer var buffer bytes.Buffer
logger := NewLogger(&buffer, "debug") logger := NewLogger(&buffer, "debug")
helm := MockExecer(logger, "dev") helm3Runner := mockRunner{output: []byte("v3.2.4+ge29ce2a")}
helm := New("helm", false, logger, "dev", &helm3Runner)
err := helm.BuildDeps("foo", "./chart/foo") err := helm.BuildDeps("foo", "./chart/foo")
expected := `Building dependency release=foo, chart=./chart/foo expected := `Building dependency release=foo, chart=./chart/foo
exec: helm --kube-context dev dependency build ./chart/foo exec: helm --kube-context dev dependency build ./chart/foo --skip-refresh
v3.2.4+ge29ce2a
` `
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
@ -353,7 +355,23 @@ exec: helm --kube-context dev dependency build ./chart/foo
helm.SetExtraArgs("--verify") helm.SetExtraArgs("--verify")
err = helm.BuildDeps("foo", "./chart/foo") err = helm.BuildDeps("foo", "./chart/foo")
expected = `Building dependency release=foo, chart=./chart/foo expected = `Building dependency release=foo, chart=./chart/foo
exec: helm --kube-context dev dependency build ./chart/foo --verify exec: helm --kube-context dev dependency build ./chart/foo --skip-refresh --verify
v3.2.4+ge29ce2a
`
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if buffer.String() != expected {
t.Errorf("helmexec.BuildDeps()\nactual = %v\nexpect = %v", buffer.String(), expected)
}
buffer.Reset()
helm2Runner := mockRunner{output: []byte("Client: v2.16.1+ge13bc94")}
helm = New("helm", false, logger, "dev", &helm2Runner)
err = helm.BuildDeps("foo", "./chart/foo")
expected = `Building dependency release=foo, chart=./chart/foo
exec: helm --kube-context dev dependency build ./chart/foo
Client: v2.16.1+ge13bc94
` `
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)