Skip to content

Add an option which builds recursively the dependent charts#4468

Closed
ccojocar wants to merge 6 commits intohelm:masterfrom
ccojocar:recursive-build
Closed

Add an option which builds recursively the dependent charts#4468
ccojocar wants to merge 6 commits intohelm:masterfrom
ccojocar:recursive-build

Conversation

@ccojocar
Copy link

This is based on PR #2278.

The recursive build is now implemented iteratively and also some tests are added.

It was also tested manually on a more complex chart https://github.com/ccojocar/environment-scalewalnut-staging/tree/master/env.

fixes #2247

cc @jstrachan

@ccojocar
Copy link
Author

cc @technosophos @thomastaylor312

@thomastaylor312
Copy link
Contributor

Hey @ccojocar. Thanks for the PR! I'll try to take a look at this tomorrow

@thomastaylor312 thomastaylor312 self-requested a review August 16, 2018 17:24
@merqurio
Copy link

Is there something I can do to help this PR make it into 2.11.0 ? I was going to implement this feature when I found the PR. Thanks @ccojocar 👍

Maybe adding some information about this feature on Complex Charts with Many Dependencies section might be useful for others looking into this kind of charts that might need recursive builds.

@merqurio
Copy link

merqurio commented Aug 21, 2018

Tested and worked like a charm. Thanks @ccojocar

Copy link
Contributor

@thomastaylor312 thomastaylor312 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logic here is looking pretty good! I just have one concern about a breaking change of the API

//
// If SkipUpdate is set, this will not update the repository.
func (m *Manager) Build() error {
func (m *Manager) Build() ([]*chartutil.Dependency, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is breaking a publicly exposed API. Anyway you can change this to avoid the breaking change?

return err
}

m.SkipUpdate = true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I would recommend adding a comment here for anyone else who edits this code in the future about why SkipUpdate is set to true

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would also set SkipUpdate back to its original value at the end of this function. I am afraid of weird side effects down the road

@ccojocar
Copy link
Author

@thomastaylor312 Thanks for review! I addressed all the issues. Please have a look again. Thanks

@thomastaylor312
Copy link
Contributor

@ccojocar So I was doing some manual validation on this and it wouldn't work for me. I used the nginx chart found in docs/examples and added a requirements file to it that looked like this:

dependencies:
    - name: redis
      version: "3.6.4"
      repository: "@stable"
    - name: alpine
      version: "0.1.0"
      repository: "file://../alpine"

This includes the alpine chart from the same directory, where I had also added a requirements file with a chart from the stable repo. This failed with the following output:

Hang tight while we grab the latest from your chart repositories...
...Unable to get an update from the "local" chart repository (http://127.0.0.1:8879/charts):
	Get http://127.0.0.1:8879/charts/index.yaml: dial tcp 127.0.0.1:8879: connect: connection refused
...Successfully got an update from the "incubator" chart repository
...Successfully got an update from the "stable" chart repository
Update Complete. ⎈Happy Helming!⎈
Saving 2 charts
Downloading redis from repo https://kubernetes-charts.storage.googleapis.com
Unpacking: charts/redis-3.6.4.tgz
Deleting outdated charts
No requirements found in charts/redis/charts.
Error: could not find charts/alpine: stat charts/alpine: no such file or directory

It looks like the downloadAll function is for some reason not unpacking the alpine tarball. Let me know if I wasn't clear with any of the reproduction steps here

@ccojocar
Copy link
Author

This includes the alpine chart from the same directory, where I had also added a requirements file with a chart from the stable repo. This failed with the following output:

@thomastaylor312 Thanks for catching the issue. It is fixed now. The dependencies are also resolved for charts which are downloaded from a local repository.

@ccojocar
Copy link
Author

/check-cla

@merqurio
Copy link

merqurio commented Sep 4, 2018

I think I found a bug, but I'm not completely sure. I have a complex chart, with a dependency that i want to disable.

├── Chart.yaml
├── charts
│   ├── subchart
│   │   ├── Chart.yaml
│   │   ├── charts
…
│   │   │   ├── subsubchart        <-- The chart I want to disable
│   │   │   │   ├── Chart.yaml

Although my values.yaml in the root chart, disables the subsubchart, the resources are rendered anyway, even if the computed values (helm install --debug …) are the expected ones.

subchart:
  values: 
  subsubchart:
    enabled: false

I'm happy to share more details if you think this might be a bug.

@bacongobbler
Copy link
Member

@merqurio I think that could be related to #4490 but that bug may be irrelevant to this PR in particular. Am I right with that assumption?

@bacongobbler
Copy link
Member

bacongobbler commented Sep 5, 2018

After doing a helm dep build --recursive it looks like both the packed and unpacked version of the chart is in the charts/ directory. Would you mind taking a look into that?

><> cat requirements.yaml
dependencies:
  - name: wordpress
    version: "2.1.10"
    repository: "@stable"
  - name: alpine
    version: "0.1.0"
    repository: "file://../alpine"

><> ../../../bin/helm dep build --recursive
Hang tight while we grab the latest from your chart repositories...
...Unable to get an update from the "local" chart repository (http://127.0.0.1:8879/charts):
        Get http://127.0.0.1:8879/charts/index.yaml: dial tcp 127.0.0.1:8879: connect: connection refused
...Successfully got an update from the "stable" chart repository
Update Complete. ⎈Happy Helming!⎈
Saving 2 charts
Downloading wordpress from repo https://kubernetes-charts.storage.googleapis.com
Unpacking: charts/wordpress-2.1.10.tgz
Unpacking: charts/alpine-0.1.0.tgz
Deleting outdated charts
Saving 1 charts
Downloading mariadb from repo https://kubernetes-charts.storage.googleapis.com/
Unpacking: charts/wordpress/charts/mariadb-4.3.1.tgz
Deleting outdated charts
No requirements found in charts/alpine/charts.
No requirements found in charts/wordpress/charts/mariadb/charts.

><> ls -p charts/
alpine/  alpine-0.1.0.tgz  wordpress/  wordpress-2.1.10.tgz

I also notice that the lockfile only shows child dependencies but not subchart dependencies. Is that intentional?

dep.Version = ver
if m.Recursive {
fmt.Fprintln(m.Out, "Unpacking:", archiveFile)
err := chartutil.ExpandFile(destPath, archiveFile)
Copy link
Member

@bacongobbler bacongobbler Sep 5, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is probably where we'd want to os.Remove the archiveFile here.

This actually poses another interesting design question though: if the design of helm dep build is to store the tarballed charts in charts/, wouldn't the user also expect the same from helm dep build --recursive? If so, would it be convenient if we parsed the tree, but laid it out as a flat file structure like

><> ls -p charts/
alpine-0.1.0.tgz
wordpress-2.1.0.tgz
mariadb-4.3.1.tgz

That way, it'd be simpler overall to manage these resources in the umbrella chart, as you could reference mariadb configuration as --set mariadb.foo=bar. It would also mean that there's only one version of any given chart as part of the dependency tree rather than subtree A installing mariadb 4.3.1 and subtree B installing mariadb 4.4.0.

What do you think?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think, it's a good idea to flatten the tree but then there is the limitation which you just described.

Maybe after building the tree, it can be traversed again to delete all the source files and just keep the Charts with the archive files. Something like:

alpine-0.1.0.tgz
charts/
  wordpress-2.1.0.tgz
  mariadb-4.3.1.tgz

@bacongobbler
Copy link
Member

due to ongoing discussion/design questions around this feature, we're going to bump this off the 2.11 milestone.

@bacongobbler bacongobbler removed this from the 2.11.0 - Features milestone Sep 7, 2018
@merqurio
Copy link

merqurio commented Sep 23, 2018

@merqurio I think that could be related to #4490 but that bug may be irrelevant to this PR in particular. Am I right with that assumption?

You were right about that @bacongobbler ! thanks for the tip

@ccojocar
Copy link
Author

I also notice that the lockfile only shows child dependencies but not subchart dependencies. Is that intentional?

@bacongobbler It's not. Isn't enough to have the first level of dependencies in the lockfile? They will have their own lockfile anyhow. I don't think, it would make a difference to keep the entire dependency tree in the lockfile.

@merqurio
Copy link

@ccojocar @thomastaylor312 a friendly ping to don't let this stale. May I help somehow, please let me know.

@ccojocar
Copy link
Author

@thomastaylor312 @merqurio @bacongobbler Please could you clarify which issue is preventing to get this merged? Thanks

@helm-bot helm-bot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Feb 24, 2019
@helm-bot helm-bot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Feb 24, 2019
@ccojocar
Copy link
Author

@bacongobbler @thomastaylor312 I pushed a fix to keep only the packed dependencies in the charts folder as suggested in your comment. Also now the dependencies tree is flatten.

The lock file right now keeps track only of the child dependencies. Should we add the entire dependencies tree? I think, this is not really required because they can be deduced when traversing the tree starting from the first dependencies level, if each of these dependencies has a lock file.

@bacongobbler
Copy link
Member

bacongobbler commented Mar 1, 2019

Should we add the entire dependencies tree? I think, this is not really required because they can be deduced when traversing the tree starting from the first dependencies level, if each of these dependencies has a lock file.

Yes. The entire point of a lockfile is to lock down what the package manager determined as the right dependency tree at a particular point in time. In our case, it was the last time the user ran helm dep up. Lockfiles are not intended to be used as a dependency resolver. That is the job of requirements.yaml.

An example use case:

Chart A has a lockfile that depends on Charts B and C.
Chart B has a lockfile that depends on Chart D, pinned to v1.1.0.
Chart C has a lockfile that also depends on Chart D, but it's pinned to v1.2.0.

When I call helm dep build on chart A, how can it resolve the dependency tree for Chart D? Each lockfile is pinned to a particular version so there's no way Helm could perform the dependency resolution necessary to target the right version.

Therefore, once you call helm dep up, you need to store the entire dependency tree in Chart A's lockfile. That way, helm dep build can rebuild the dependency tree. It cannot perform dependency resolution between two conflicting dependency trees.

ccojocar added 6 commits March 5, 2019 10:25
Signed-off-by: Cosmin Cojocar <cosmin.cojocar@gmx.ch>
…he recursive build and also add some comments

Signed-off-by: Cosmin Cojocar <cosmin.cojocar@gmx.ch>
Signed-off-by: Cosmin Cojocar <cosmin.cojocar@gmx.ch>
Signed-off-by: Cosmin Cojocar <cosmin.cojocar@gmx.ch>
… dependencies tree

Signed-off-by: Cosmin Cojocar <cosmin.cojocar@gmx.ch>
Signed-off-by: Cosmin Cojocar <cosmin.cojocar@gmx.ch>
@helm-bot helm-bot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Mar 5, 2019
@allen-servedio
Copy link

It looks like @thomastaylor312 had requested changes - are these now resolved and can this be released for the community to use? Thank you all for your efforts with this!

@ccojocar
Copy link
Author

Therefore, once you call helm dep up, you need to store the entire dependency tree in Chart A's lockfile. That way, helm dep build can rebuild the dependency tree. It cannot perform dependency resolution between two conflicting dependency trees.

@bacongobbler After looking at the install code, I am a bit confused. It seems that only helm dep build loads the dependencies from lockfile. The helm install --dep-up calls the Manager.Update method which reads the dependencies only from requirements file.

I think, the entire dependency tree has to be also updated in the requirements file of Chart A, otherwise the install will update only the direct dependencies of Chart A.

The current implementation is downloading all charts from dependency tree, without reflecting this flatten hierarchy in the requirements file.

What is your opinion on this?

@kvolkovich-sc
Copy link

Any updates? Really must-have feature.

@ccojocar
Copy link
Author

ccojocar commented May 3, 2019

I am wait for feedback to be able to rework the PR.

@ccojocar
Copy link
Author

Closing this due to lack of feedback from Helm's maintainers. It seems to be stuck in this state since quite a long time. Thanks

@ccojocar ccojocar closed this May 16, 2019
@omerxx
Copy link

omerxx commented May 16, 2019

@bacongobbler @thomastaylor312 @merqurio
Can you guys please assist? This is a feature many of us are waiting for.
Please help @ccojocar so this can be reopened and worked on!
If you need any help please let us know

@DASXCE
Copy link

DASXCE commented Aug 26, 2021

Waiting for this too... The workaround to manually(or to automate) helm dep update does not work with GitOps tools like ArgoCD.

@zenntrix
Copy link

Prod, can we bring this back to life and consider it or at least get a reason why it can't be merged?

@samuellvicente
Copy link

Adding interest on this issue, is there a change it might actually be merged?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature in progress size/L Denotes a PR that changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Recursive dependency handling for charts.