-
Notifications
You must be signed in to change notification settings - Fork 17
Ignore soft dependencies of LCM and chart prioritization #559
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,127 @@ | ||
| /* | ||
| Copyright © 2025-2026 SUSE LLC | ||
| SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||
| you may not use this file except in compliance with the License. | ||
| You may obtain a copy of the License at | ||
|
|
||
| http://www.apache.org/licenses/LICENSE-2.0 | ||
|
|
||
| Unless required by applicable law or agreed to in writing, software | ||
| distributed under the License is distributed on an "AS IS" BASIS, | ||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| See the License for the specific language governing permissions and | ||
| limitations under the License. | ||
| */ | ||
|
|
||
| package config | ||
|
|
||
| import ( | ||
| "fmt" | ||
| "slices" | ||
|
|
||
| "github.com/suse/elemental/v3/internal/image/release" | ||
| "github.com/suse/elemental/v3/pkg/helm" | ||
| "github.com/suse/elemental/v3/pkg/manifest/api" | ||
| "github.com/suse/elemental/v3/pkg/manifest/api/core" | ||
| "go.yaml.in/yaml/v3" | ||
| ) | ||
|
|
||
| const ( | ||
| elementalLifecycleManager = "elemental-lifecycle-manager" | ||
| rancher = "rancher" | ||
| systemUpgradeController = "system-upgrade-controller" | ||
| certManager = "cert-manager" | ||
| ) | ||
|
|
||
| // lcmWebhookValues is used to marshal data from values file for LCM chart | ||
| type lcmWebhookValues struct { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I do not foresee this type being every used outside of Also we could maybe simplify the struct itself to something like: var lcmWebhookValues struct {
Webhook struct {
Cert *struct {
CreateDefault bool `yaml:"createDefault"`
} `yaml:"cert"`
} `yaml:"webhook"`
}And then check against the Cert struct pointer and the CreateDefault field themselves. That would be enough, as if the user has continuously provided the "cert:" field with a non-true |
||
| Webhook struct { | ||
| Cert struct { | ||
| CreateDefault bool `yaml:"createDefault"` | ||
| ExistingSecret string `yaml:"existingSecret"` | ||
| CABundle string `yaml:"caBundle"` | ||
| } `yaml:"cert"` | ||
| } `yaml:"webhook"` | ||
| } | ||
|
|
||
| // evaluateLCMDeps removes dependencies of LCM if they are satisfied separately, i.e., | ||
| // - if Rancher chart is enabled in release.yaml, it removes dependency on system-upgrade-controller | ||
| // - if the values files contains custom certificate configuration, it removes dependency on cert-manager | ||
| func evaluateLCMDeps(enabled []release.HelmChart, corePlatform *core.ReleaseManifest, valueFiles map[string]string, valuesResolver helmValuesResolver) error { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A couple of suggestions here:
|
||
| var lcmChart *api.HelmChart | ||
|
|
||
| var ( | ||
| lcmEnabled = false | ||
| rancherEnabled = false | ||
| ) | ||
| for _, chart := range enabled { | ||
| if chart.Name == rancher { | ||
| rancherEnabled = true | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This may be a personal preference, but instead of populating boolean values, would it make sense to convert the enabled slice to a map and check against the map keys. That way we could do the dependency removal in the same block that we check whether the chart is enabled. |
||
| continue | ||
| } | ||
| if chart.Name == elementalLifecycleManager { | ||
| lcmEnabled = true | ||
| } | ||
| } | ||
| if !lcmEnabled { | ||
| // nothing to do! | ||
| return nil | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't we error out here? IIRC, we agreed that LCM is a required chart that should be specified by the user under |
||
| } | ||
|
|
||
| coreCharts := corePlatform.Components.Helm | ||
| for _, chart := range coreCharts.Charts { | ||
| if chart.GetName() == elementalLifecycleManager { | ||
| lcmChart = chart | ||
| break | ||
| } | ||
| } | ||
|
|
||
| if lcmChart == nil { | ||
| // this could be the case if using core manifest that doesn't contain LCM charts which is the case currently | ||
| // TODO (dharmit): remove this check once the core manifest includes LCM chart by default | ||
| return nil // nothing to do! | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't we also error out here as well? My main thinking is that LCM will always be a part of the core manifest, so it not being present in the parsed Or did you want to make the |
||
| } | ||
|
|
||
| if rancherEnabled { | ||
| // remove system-upgrade-controller from list of dependencies | ||
| for i, dep := range lcmChart.DependsOn { | ||
| if dep.Name == systemUpgradeController { | ||
| lcmChart.DependsOn = slices.Delete(lcmChart.DependsOn, i, i+1) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This may be a personal preference, so feel free to ignore, but would it make sense to use the lcmChart.DependsOn = slices.DeleteFunc(lcmChart.DependsOn,
func(d api.HelmChartDependency) bool { return d.Name == systemUpgradeController }) |
||
| break | ||
| } | ||
| } | ||
|
|
||
| } | ||
|
|
||
| _, ok := valueFiles[elementalLifecycleManager] | ||
| if !ok { | ||
| // values.yaml equivalent for LCM isn't provided; cert-manager dependency to be kept as-is | ||
| return nil | ||
| } | ||
|
|
||
| source := &helm.ValueSource{Inline: lcmChart.GetInlineValues(), File: valueFiles[lcmChart.GetName()]} | ||
| values, err := valuesResolver.Resolve(source) | ||
| if err != nil { | ||
| return fmt.Errorf("resolving values for chart %s: %w", lcmChart.GetName(), err) | ||
| } | ||
|
|
||
| var lcmValues lcmWebhookValues | ||
| err = yaml.Unmarshal(values, &lcmValues) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| if !lcmValues.Webhook.Cert.CreateDefault && lcmValues.Webhook.Cert.ExistingSecret != "" { | ||
| // checking only createDefault and existingSecret because caBundle could be an empty string | ||
| for i, dep := range lcmChart.DependsOn { | ||
| if dep.Name == certManager { | ||
| lcmChart.DependsOn = slices.Delete(lcmChart.DependsOn, i, i+1) | ||
| break | ||
| } | ||
| } | ||
| } | ||
|
|
||
| return 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.
Since this file consists of a single function and is doing essentially a helm chart configuration, would it make sense to merge its logic and its
_test.gowith thehelm.gofile? That way we would have all the chart handling logic at a single place and will keep the number of files for this package to a minimum.