-
Notifications
You must be signed in to change notification settings - Fork 7.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve helm dependency update performance #11726
Conversation
What this PR does / why we need it: This PR was created to improve performance of the dependency update command by skipping unnecessary downloading and loading of index files that have already been downloaded and loaded I believe this would close refs helm#9865 Signed-off-by: Jeff van Dam <[email protected]>
290ca29
to
8c80f58
Compare
Changed the milestone because this isn't a bug fix or security issue. |
Could I motivate people to review this? It would be much appreciated. |
pkg/downloader/manager.go
Outdated
baseChartUrls[repoURL] = strings.Join(slice[:len(slice)-1], "") | ||
} | ||
} else { | ||
url = fmt.Sprintf("%s%s-%s.tgz", baseURL, name, version) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes assumptions about the structure of the chart URL, are we sure the assumptions are correct?
An alternative suggestion:
The chart URL is knowable earlier in the flow, in Resolve (resolver.go) at the point where we set the version (inside loop on lines 197-200), the url is available from ver.URLs[0]. We could store (perhaps in a map also returned from the method) the chart URLs which can be used during the download rather than using additional logic to again find the url
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool, yeah makes more sense to do it that way. Have that updated now
What this PR does / why we need it: This PR was created to improve performance of the dependency update command by skipping unnecessary downloading and loading of index files that have already been downloaded and loaded I believe this would close refs helm#9865 Signed-off-by: Jeff van Dam <[email protected]>
Signed-off-by: Jeff van Dam <[email protected]>
Hey @joejulian any plan to merge this anytime soon? Happy to make any changes if necessary |
Sorry to bother again @joejulian but is there any chance of this being merged anytime soon? |
Thank you @JvD-Ericsson for your work. We have currently a lot of performance problemen with ArgoCD in combination with Helm. We have investigated the performance problems and we found out that this is due the helm dependencies. We have tested this pr and it will improve the performance a lot! @joejulian can you merge this pr ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm. I've tried some manual testing and everything seems to work. I don't have any examples that take a long time, but at least everything I use regularly seems to keep working.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This mostly makes sense from a performance perspective.
The one issue I found is a way to possibly send credentials to the wrong URL by including the URL the credentials are associated with in an annotation or description in a malicious index.yaml file. I think that part needs to be walked back for the sake of security.
@@ -52,21 +52,23 @@ func New(chartpath, cachepath string, registryClient *registry.Client) *Resolver | |||
} | |||
|
|||
// Resolve resolves dependencies and returns a lock file with the resolution. | |||
func (r *Resolver) Resolve(reqs []*chart.Dependency, repoNames map[string]string) (*chart.Lock, error) { | |||
func (r *Resolver) Resolve(reqs []*chart.Dependency, repoNames map[string]string) (*chart.Lock, map[string]string, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note, since this is in internal
it's not part of the public API so a change is ok.
pkg/downloader/chart_downloader.go
Outdated
file := string(yamlFile[:]) | ||
if strings.Contains(file, u) { | ||
return rc, nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure about this change. The string.Contains
is run over a file with annotations and descriptions. The u
could be in one of those fields which would return an improper result. While this is unlikely, the code that calls scanReposForURL
grabs the credentials if there are any to pass on. I wonder if there is an edge case that could leak credentials with misuse of this change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have that reverted now, so hopefully it can be merged now! If anything else needs changing let me know
Signed-off-by: Jeff van Dam <[email protected]>
It would be great to get this PR merged! |
Should be fixed now |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Thanks a million for reviewing @sabre1041, @scottrigby , can this now be merged as it has 2 maintainer approvals |
@MichaelMorrisEst 3.15.0 was already released, so I just moved this PR to the 3.16.0 milestone. |
@@ -191,13 +191,13 @@ func (m *Manager) Update() error { | |||
|
|||
// Now we need to find out which version of a chart best satisfies the | |||
// dependencies in the Chart.yaml | |||
lock, err := m.resolve(req, repoNames) | |||
lock, urls, err := m.resolve(req, repoNames) | |||
if err != nil { | |||
return err | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to check that urls
is empty?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
urls
is ultimately read on line 756, if it is empty the key will not be found and the flow will proceed to the else statement and proceed as per existing implementation without any issues, so I am not seeing a reason to check for empty
Signed-off-by: MichaelMorris <[email protected]>
Hi @joejulian I believe the 'needs-rebase' label can be removed again now. If there is anything else needed from my side let me know |
@joejulian @scottrigby @sabre1041 can you re-review since new changes were pushed? |
Thanks @joejulian for reviewing/merging and also everyone else who reviewed. |
Awesome |
The change in helm#11726 caused a regression where `helm dependency udpate` stopped working. The format of the internal representation of the data changed causing errors of "non-absolute URLs should be in form of repo_name/path_to_chart". See helm#13324 for more details. Since this change is in released Helm and it's a regression, reverting the original change was the fastest and safest route to deliver a fix as quickly as possible. Closes helm#13324 Signed-off-by: Matt Farina <[email protected]>
Can the tests be improved to cover the unexpected problems and retry this PR? |
I updated my helm version to 3.16.1, tried out |
Oh so it was reverted, so I'll try 3.16.0 |
or could it be that it hasn't been released in any of the versions? |
It was in 3.16.0 but reverted in 3.16.1 (see #13327 for details) |
Is a fix / new version of these performance improvements planned with better test coverage? |
A new PR has been created to re-introduce the change and fix the issue found in the reverted change. This is waiting for review. See: #13342 |
What this PR does / why we need it:
This PR was created to improve performance of the dependency update command by skipping unnecessary downloading and loading of index files that have already been downloaded and loaded
I believe this would close refs #9865
Signed-off-by: Jeff van Dam [email protected]