Skip to content
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

[Backport release-1.28] Cleanup unknown Helm chart manifest files #4762

Merged
merged 4 commits into from
Jul 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion cmd/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,6 @@ func (c *command) start(ctx context.Context) error {
}
clusterComponents.Add(ctx, controller.NewCRD(helmSaver, []string{"helm"}))
clusterComponents.Add(ctx, controller.NewExtensionsController(
helmSaver,
c.K0sVars,
adminClientFactory,
leaderElector,
Expand Down
66 changes: 57 additions & 9 deletions inttest/addons/addons_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"context"
"errors"
"fmt"
"slices"
"strings"
"testing"
"time"
Expand All @@ -29,8 +30,11 @@ import (

"github.com/k0sproject/k0s/internal/pkg/templatewriter"
"github.com/k0sproject/k0s/inttest/common"
"github.com/k0sproject/k0s/pkg/apis/helm/v1beta1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
helmv1beta1 "github.com/k0sproject/k0s/pkg/apis/helm/v1beta1"
k0sv1beta1 "github.com/k0sproject/k0s/pkg/apis/k0s/v1beta1"
k0sclientset "github.com/k0sproject/k0s/pkg/client/clientset"
"github.com/k0sproject/k0s/pkg/constant"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/wait"
k8s "k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/scheme"
Expand All @@ -43,12 +47,14 @@ type AddonsSuite struct {
}

func (as *AddonsSuite) TestHelmBasedAddons() {
ctx := as.Context()

addonName := "test-addon"
ociAddonName := "oci-addon"
fileAddonName := "tgz-addon"
as.PutFile(as.ControllerNode(0), "/tmp/k0s.yaml", fmt.Sprintf(k0sConfigWithAddon, addonName))
as.pullHelmChart(as.ControllerNode(0))
as.Require().NoError(as.InitController(0, "--config=/tmp/k0s.yaml"))
as.Require().NoError(as.InitController(0, "--config=/tmp/k0s.yaml", "--enable-dynamic-config"))
as.NoError(as.RunWorkers())
kc, err := as.KubeClient(as.ControllerNode(0))
as.Require().NoError(err)
Expand All @@ -60,6 +66,8 @@ func (as *AddonsSuite) TestHelmBasedAddons() {

as.AssertSomeKubeSystemPods(kc)

as.Run("Rename chart in Helm extension", func() { as.renameChart(ctx) })

values := map[string]interface{}{
"replicaCount": 2,
"image": map[string]interface{}{
Expand All @@ -86,7 +94,47 @@ func (as *AddonsSuite) pullHelmChart(node string) {
as.Require().NoError(err)
}

func (as *AddonsSuite) deleteRelease(chart *v1beta1.Chart) {
func (as *AddonsSuite) renameChart(ctx context.Context) {
restConfig, err := as.GetKubeConfig(as.ControllerNode(0))
as.Require().NoError(err)
k0sClients, err := k0sclientset.NewForConfig(restConfig)
as.Require().NoError(err)

configs := k0sClients.K0sV1beta1().ClusterConfigs(constant.ClusterConfigNamespace)
cfg, err := configs.Get(ctx, constant.ClusterConfigObjectName, metav1.GetOptions{})
as.Require().NoError(err)

i := slices.IndexFunc(cfg.Spec.Extensions.Helm.Charts, func(c k0sv1beta1.Chart) bool {
return c.Name == "tgz-addon"
})
as.Require().GreaterOrEqual(i, 0, "Didn't find tgz-addon in %v", cfg.Spec.Extensions.Helm.Charts)
cfg.Spec.Extensions.Helm.Charts[i].Name = "tgz-renamed-addon"

cfg, err = configs.Update(ctx, cfg, metav1.UpdateOptions{FieldManager: as.T().Name()})
as.Require().NoError(err)
if data, err := yaml.Marshal(cfg); as.NoError(err) {
as.T().Logf("%s", data)
}

as.Require().NoError(wait.PollUntilContextCancel(ctx, 350*time.Millisecond, true, func(ctx context.Context) (bool, error) {
charts, err := k0sClients.HelmV1beta1().Charts(constant.ClusterConfigNamespace).List(ctx, metav1.ListOptions{})
if err != nil {
return false, nil
}

hasChart := func(name string) bool {
return slices.IndexFunc(charts.Items, func(c helmv1beta1.Chart) bool {
return c.Name == name
}) >= 0
}

return !hasChart("k0s-addon-chart-tgz-addon") && hasChart("k0s-addon-chart-tgz-renamed-addon"), nil
}), "While waiting for Chart resource to be swapped")

as.waitForTestRelease("tgz-renamed-addon", "0.6.0", "kube-system", 1)
}

func (as *AddonsSuite) deleteRelease(chart *helmv1beta1.Chart) {
ctx := as.Context()
as.T().Logf("Deleting chart %s/%s", chart.Namespace, chart.Name)
ssh, err := as.SSH(ctx, as.ControllerNode(0))
Expand All @@ -100,7 +148,7 @@ func (as *AddonsSuite) deleteRelease(chart *v1beta1.Chart) {
as.Require().NoError(err)
as.Require().NoError(wait.PollUntilContextCancel(ctx, 1*time.Second, true, func(pollCtx context.Context) (done bool, err error) {
as.T().Logf("Expecting have no secrets left for release %s/%s", chart.Namespace, chart.Name)
items, err := k8sclient.CoreV1().Secrets("default").List(pollCtx, v1.ListOptions{
items, err := k8sclient.CoreV1().Secrets("default").List(pollCtx, metav1.ListOptions{
LabelSelector: fmt.Sprintf("name=%s", chart.Name),
})
if err != nil {
Expand All @@ -118,19 +166,19 @@ func (as *AddonsSuite) deleteRelease(chart *v1beta1.Chart) {
}))
}

func (as *AddonsSuite) waitForTestRelease(addonName, appVersion string, namespace string, rev int64) *v1beta1.Chart {
func (as *AddonsSuite) waitForTestRelease(addonName, appVersion string, namespace string, rev int64) *helmv1beta1.Chart {
ctx := as.Context()
as.T().Logf("waiting to see %s release ready in kube API, generation %d", addonName, rev)

cfg, err := as.GetKubeConfig(as.ControllerNode(0))
as.Require().NoError(err)
err = v1beta1.AddToScheme(scheme.Scheme)
err = helmv1beta1.AddToScheme(scheme.Scheme)
as.Require().NoError(err)
chartClient, err := client.New(cfg, client.Options{
Scheme: scheme.Scheme,
})
as.Require().NoError(err)
var chart v1beta1.Chart
var chart helmv1beta1.Chart
var lastResourceVersion string
as.Require().NoError(wait.PollUntilContextCancel(ctx, 1*time.Second, true, func(pollCtx context.Context) (done bool, err error) {
err = chartClient.Get(pollCtx, client.ObjectKey{
Expand Down Expand Up @@ -189,7 +237,7 @@ func (as *AddonsSuite) checkCustomValues(releaseName string) error {
}
return wait.PollUntilContextCancel(ctx, 1*time.Second, true, func(pollCtx context.Context) (done bool, err error) {
serverDeployment := fmt.Sprintf("%s-echo-server", releaseName)
d, err := kc.AppsV1().Deployments("default").Get(pollCtx, serverDeployment, v1.GetOptions{})
d, err := kc.AppsV1().Deployments("default").Get(pollCtx, serverDeployment, metav1.GetOptions{})
if err != nil {
if ctxErr := context.Cause(ctx); ctxErr != nil {
return false, errors.Join(err, ctxErr)
Expand Down
6 changes: 0 additions & 6 deletions pkg/apis/k0s/v1beta1/extensions.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ package v1beta1

import (
"errors"
"fmt"
"time"

"helm.sh/helm/v3/pkg/chartutil"
Expand Down Expand Up @@ -99,11 +98,6 @@ type Chart struct {
Order int `json:"order"`
}

// ManifestFileName returns filename to use for the crd manifest
func (c Chart) ManifestFileName() string {
return fmt.Sprintf("%d_helm_extension_%s.yaml", c.Order, c.Name)
}

// Validate performs validation
func (c Chart) Validate() error {
if c.Name == "" {
Expand Down
26 changes: 0 additions & 26 deletions pkg/apis/k0s/v1beta1/extenstions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,30 +81,4 @@ func TestValidation(t *testing.T) {
})

})

t.Run("chart_manifest_name", func(t *testing.T) {
chart := Chart{
Name: "release",
ChartName: "k0s/chart",
TargetNS: "default",
}

chart1 := Chart{
Name: "release",
ChartName: "k0s/chart",
TargetNS: "default",
Order: 1,
}

chart2 := Chart{
Name: "release",
ChartName: "k0s/chart",
TargetNS: "default",
Order: 2,
}
assert.Equal(t, chart.ManifestFileName(), "0_helm_extension_release.yaml")
assert.Equal(t, chart1.ManifestFileName(), "1_helm_extension_release.yaml")
assert.Equal(t, chart2.ManifestFileName(), "2_helm_extension_release.yaml")
})

}
Loading
Loading