Skip to content

Commit 308f730

Browse files
committed
Use Helm binary instead of the Go SDK to manage charts
1 parent b25cb49 commit 308f730

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+2446
-657
lines changed

Makefile

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,23 @@ output/bins/kubectl-support_bundle-%:
104104
rm -rf output/tmp
105105
touch $@
106106

107+
.PHONY: cmd/installer/goods/bins/helm
108+
cmd/installer/goods/bins/helm:
109+
$(MAKE) output/bins/helm-$(HELM_VERSION)-$(ARCH)
110+
cp output/bins/helm-$(HELM_VERSION)-$(ARCH) $@
111+
touch $@
112+
113+
output/bins/helm-%:
114+
mkdir -p output/bins
115+
mkdir -p output/tmp
116+
curl --retry 5 --retry-all-errors -fL -o output/tmp/helm.tar.gz \
117+
https://get.helm.sh/helm-$(call split-hyphen,$*,1)-$(OS)-$(call split-hyphen,$*,2).tar.gz
118+
tar -xzf output/tmp/helm.tar.gz -C output/tmp
119+
mv output/tmp/$(OS)-$(call split-hyphen,$*,2)/helm $@
120+
rm -rf output/tmp
121+
chmod +x $@
122+
touch $@
123+
107124
.PHONY: cmd/installer/goods/bins/kubectl-preflight
108125
cmd/installer/goods/bins/kubectl-preflight:
109126
$(MAKE) output/bins/kubectl-preflight-$(TROUBLESHOOT_VERSION)-$(ARCH)
@@ -229,6 +246,7 @@ static: cmd/installer/goods/bins/k0s \
229246
cmd/installer/goods/bins/kubectl-support_bundle \
230247
cmd/installer/goods/bins/local-artifact-mirror \
231248
cmd/installer/goods/bins/fio \
249+
cmd/installer/goods/bins/helm \
232250
cmd/installer/goods/internal/bins/kubectl-kots
233251

234252
.PHONY: static-dryrun
@@ -238,6 +256,7 @@ static-dryrun:
238256
cmd/installer/goods/bins/kubectl-support_bundle \
239257
cmd/installer/goods/bins/local-artifact-mirror \
240258
cmd/installer/goods/bins/fio \
259+
cmd/installer/goods/bins/helm \
241260
cmd/installer/goods/internal/bins/kubectl-kots
242261

243262
.PHONY: embedded-cluster-linux-amd64

api/controllers/app/install/controller.go

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import (
1616
"github.com/replicatedhq/embedded-cluster/pkg/release"
1717
kotsv1beta1 "github.com/replicatedhq/kotskinds/apis/kots/v1beta1"
1818
"github.com/sirupsen/logrus"
19-
"k8s.io/cli-runtime/pkg/genericclioptions"
19+
helmcli "helm.sh/helm/v3/pkg/cli"
2020
kyaml "sigs.k8s.io/yaml"
2121
)
2222

@@ -49,8 +49,7 @@ type InstallController struct {
4949
airgapBundle string
5050
privateCACertConfigMapName string
5151
k8sVersion string
52-
restClientGetter genericclioptions.RESTClientGetter
53-
kubeConfigPath string
52+
kubernetesEnvSettings *helmcli.EnvSettings
5453
}
5554

5655
type InstallControllerOption func(*InstallController)
@@ -139,15 +138,9 @@ func WithK8sVersion(k8sVersion string) InstallControllerOption {
139138
}
140139
}
141140

142-
func WithRESTClientGetter(restClientGetter genericclioptions.RESTClientGetter) InstallControllerOption {
141+
func WithKubernetesEnvSettings(envSettings *helmcli.EnvSettings) InstallControllerOption {
143142
return func(c *InstallController) {
144-
c.restClientGetter = restClientGetter
145-
}
146-
}
147-
148-
func WithKubeConfigPath(kubeConfigPath string) InstallControllerOption {
149-
return func(c *InstallController) {
150-
c.kubeConfigPath = kubeConfigPath
143+
c.kubernetesEnvSettings = envSettings
151144
}
152145
}
153146

@@ -229,8 +222,7 @@ func NewInstallController(opts ...InstallControllerOption) (*InstallController,
229222
appinstallmanager.WithAirgapBundle(controller.airgapBundle),
230223
appinstallmanager.WithAppInstallStore(controller.store.AppInstallStore()),
231224
appinstallmanager.WithK8sVersion(controller.k8sVersion),
232-
appinstallmanager.WithRESTClientGetter(controller.restClientGetter),
233-
appinstallmanager.WithKubeConfigPath(controller.kubeConfigPath),
225+
appinstallmanager.WithKubernetesEnvSettings(controller.kubernetesEnvSettings),
234226
)
235227
if err != nil {
236228
return nil, fmt.Errorf("create app install manager: %w", err)

api/controllers/kubernetes/install/controller.go

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import (
1818
"github.com/replicatedhq/embedded-cluster/pkg/release"
1919
"github.com/sirupsen/logrus"
2020
helmcli "helm.sh/helm/v3/pkg/cli"
21-
"k8s.io/cli-runtime/pkg/genericclioptions"
2221
)
2322

2423
type Controller interface {
@@ -34,22 +33,22 @@ type Controller interface {
3433
var _ Controller = (*InstallController)(nil)
3534

3635
type InstallController struct {
37-
installationManager installation.InstallationManager
38-
infraManager infra.InfraManager
39-
metricsReporter metrics.ReporterInterface
40-
k8sVersion string
41-
restClientGetter genericclioptions.RESTClientGetter
42-
releaseData *release.ReleaseData
43-
password string
44-
tlsConfig types.TLSConfig
45-
license []byte
46-
airgapBundle string
47-
configValues types.AppConfigValues
48-
endUserConfig *ecv1beta1.Config
49-
store store.Store
50-
ki kubernetesinstallation.Installation
51-
stateMachine statemachine.Interface
52-
logger logrus.FieldLogger
36+
installationManager installation.InstallationManager
37+
infraManager infra.InfraManager
38+
metricsReporter metrics.ReporterInterface
39+
k8sVersion string
40+
kubernetesEnvSettings *helmcli.EnvSettings
41+
releaseData *release.ReleaseData
42+
password string
43+
tlsConfig types.TLSConfig
44+
license []byte
45+
airgapBundle string
46+
configValues types.AppConfigValues
47+
endUserConfig *ecv1beta1.Config
48+
store store.Store
49+
ki kubernetesinstallation.Installation
50+
stateMachine statemachine.Interface
51+
logger logrus.FieldLogger
5352
// App controller composition
5453
*appcontroller.InstallController
5554
}
@@ -80,9 +79,9 @@ func WithK8sVersion(k8sVersion string) InstallControllerOption {
8079
}
8180
}
8281

83-
func WithRESTClientGetter(restClientGetter genericclioptions.RESTClientGetter) InstallControllerOption {
82+
func WithKubernetesEnvSettings(envSettings *helmcli.EnvSettings) InstallControllerOption {
8483
return func(c *InstallController) {
85-
c.restClientGetter = restClientGetter
84+
c.kubernetesEnvSettings = envSettings
8685
}
8786
}
8887

@@ -176,9 +175,9 @@ func NewInstallController(opts ...InstallControllerOption) (*InstallController,
176175
controller.stateMachine = NewStateMachine(WithStateMachineLogger(controller.logger))
177176
}
178177

179-
// If none is provided, use the default env settings from helm to create a RESTClientGetter
180-
if controller.restClientGetter == nil {
181-
controller.restClientGetter = helmcli.New().RESTClientGetter()
178+
// If none is provided, use the default env settings from helm
179+
if controller.kubernetesEnvSettings == nil {
180+
controller.kubernetesEnvSettings = helmcli.New()
182181
}
183182

184183
if controller.installationManager == nil {
@@ -200,7 +199,7 @@ func NewInstallController(opts ...InstallControllerOption) (*InstallController,
200199
appcontroller.WithAirgapBundle(controller.airgapBundle),
201200
appcontroller.WithPrivateCACertConfigMapName(""), // Private CA ConfigMap functionality not yet implemented for Kubernetes installations
202201
appcontroller.WithK8sVersion(controller.k8sVersion), // Used to determine the kubernetes version for the helm client
203-
appcontroller.WithRESTClientGetter(controller.restClientGetter),
202+
appcontroller.WithKubernetesEnvSettings(controller.kubernetesEnvSettings),
204203
)
205204
if err != nil {
206205
return nil, fmt.Errorf("create app install controller: %w", err)
@@ -212,7 +211,7 @@ func NewInstallController(opts ...InstallControllerOption) (*InstallController,
212211
infraManager, err := infra.NewInfraManager(
213212
infra.WithLogger(controller.logger),
214213
infra.WithInfraStore(controller.store.KubernetesInfraStore()),
215-
infra.WithRESTClientGetter(controller.restClientGetter),
214+
infra.WithKubernetesEnvSettings(controller.kubernetesEnvSettings),
216215
infra.WithPassword(controller.password),
217216
infra.WithTLSConfig(controller.tlsConfig),
218217
infra.WithLicense(controller.license),

api/controllers/linux/install/controller.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ func NewInstallController(opts ...InstallControllerOption) (*InstallController,
268268
appcontroller.WithAirgapBundle(controller.airgapBundle),
269269
appcontroller.WithPrivateCACertConfigMapName(adminconsole.PrivateCASConfigMapName), // Linux installations use the ConfigMap
270270
appcontroller.WithK8sVersion(versions.K0sVersion), // Used to determine the kubernetes version for the helm client
271-
appcontroller.WithKubeConfigPath(controller.rc.PathToKubeConfig()),
271+
appcontroller.WithKubernetesEnvSettings(controller.rc.GetKubernetesEnvSettings()),
272272
)
273273
if err != nil {
274274
return nil, fmt.Errorf("create app install controller: %w", err)

api/integration/app/install/config_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"github.com/stretchr/testify/assert"
2525
"github.com/stretchr/testify/require"
2626
"github.com/stretchr/testify/suite"
27+
helmcli "helm.sh/helm/v3/pkg/cli"
2728
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2829
)
2930

@@ -1069,6 +1070,7 @@ func TestAppInstallSuite(t *testing.T) {
10691070
kubernetesinstall.WithLicense([]byte("spec:\n licenseID: test-license\n")),
10701071
kubernetesinstall.WithConfigValues(configValues),
10711072
kubernetesinstall.WithK8sVersion("v1.33.0"),
1073+
kubernetesinstall.WithKubernetesEnvSettings(helmcli.New()),
10721074
)
10731075
require.NoError(t, err)
10741076
// Create the API with the install controller

api/integration/kubernetes/install/apppreflight_test.go

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import (
2626
"github.com/stretchr/testify/assert"
2727
"github.com/stretchr/testify/mock"
2828
"github.com/stretchr/testify/require"
29-
"k8s.io/cli-runtime/pkg/genericclioptions"
3029
)
3130

3231
// Test the getAppPreflightsStatus endpoint returns app preflights status correctly
@@ -246,8 +245,7 @@ func TestPostRunAppPreflights(t *testing.T) {
246245
InstallTarget: types.InstallTargetKubernetes,
247246
Password: "password",
248247
KubernetesConfig: types.KubernetesConfig{
249-
RESTClientGetter: &genericclioptions.ConfigFlags{},
250-
Installation: mockInstallation,
248+
Installation: mockInstallation,
251249
},
252250
ReleaseData: integration.DefaultReleaseData(),
253251
},
@@ -299,8 +297,7 @@ func TestPostRunAppPreflights(t *testing.T) {
299297
InstallTarget: types.InstallTargetKubernetes,
300298
Password: "password",
301299
KubernetesConfig: types.KubernetesConfig{
302-
RESTClientGetter: &genericclioptions.ConfigFlags{},
303-
Installation: mockInstallation,
300+
Installation: mockInstallation,
304301
},
305302
ReleaseData: integration.DefaultReleaseData(),
306303
},
@@ -346,8 +343,7 @@ func TestPostRunAppPreflights(t *testing.T) {
346343
InstallTarget: types.InstallTargetKubernetes,
347344
Password: "password",
348345
KubernetesConfig: types.KubernetesConfig{
349-
RESTClientGetter: &genericclioptions.ConfigFlags{},
350-
Installation: mockInstallation,
346+
Installation: mockInstallation,
351347
},
352348
ReleaseData: integration.DefaultReleaseData(),
353349
},

api/internal/handlers/kubernetes/kubernetes.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"github.com/replicatedhq/embedded-cluster/api/types"
99
"github.com/replicatedhq/embedded-cluster/pkg/metrics"
1010
"github.com/sirupsen/logrus"
11+
"k8s.io/cli-runtime/pkg/genericclioptions"
1112
)
1213

1314
type Handler struct {
@@ -52,7 +53,11 @@ func New(cfg types.APIConfig, opts ...Option) (*Handler, error) {
5253

5354
// TODO (@team): discuss which of these should / should not be pointers
5455
if h.installController == nil {
55-
k8sVersion, err := getK8sVersion(h.cfg.RESTClientGetter)
56+
var restClientGetter genericclioptions.RESTClientGetter
57+
if ks := h.cfg.Installation.GetKubernetesEnvSettings(); ks != nil {
58+
restClientGetter = ks.RESTClientGetter()
59+
}
60+
k8sVersion, err := getK8sVersion(restClientGetter)
5661
if err != nil {
5762
return nil, fmt.Errorf("get k8s version: %w", err)
5863
}
@@ -61,7 +66,7 @@ func New(cfg types.APIConfig, opts ...Option) (*Handler, error) {
6166
install.WithLogger(h.logger),
6267
install.WithMetricsReporter(h.metricsReporter),
6368
install.WithK8sVersion(k8sVersion),
64-
install.WithRESTClientGetter(h.cfg.RESTClientGetter),
69+
install.WithKubernetesEnvSettings(h.cfg.Installation.GetKubernetesEnvSettings()),
6570
install.WithReleaseData(h.cfg.ReleaseData),
6671
install.WithConfigValues(h.cfg.ConfigValues),
6772
install.WithEndUserConfig(h.cfg.EndUserConfig),

api/internal/managers/app/install/install_test.go

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import (
2222
"github.com/stretchr/testify/assert"
2323
"github.com/stretchr/testify/mock"
2424
"github.com/stretchr/testify/require"
25-
helmrelease "helm.sh/helm/v3/pkg/release"
2625
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2726
kyaml "sigs.k8s.io/yaml"
2827
)
@@ -97,7 +96,7 @@ func TestAppInstallManager_Install(t *testing.T) {
9796
return vals["repository"] == "nginx" && vals["tag"] == "latest" && opts.Values["replicas"] == 3
9897
}
9998
return false
100-
})).Return(&helmrelease.Release{Name: "web-server"}, nil)
99+
})).Return("Release \"web-server\" has been installed.", nil)
101100

102101
// Chart 2 installation (database chart)
103102
databaseCall := mockHelmClient.On("Install", mock.Anything, mock.MatchedBy(func(opts helm.InstallOptions) bool {
@@ -112,7 +111,7 @@ func TestAppInstallManager_Install(t *testing.T) {
112111
return vals["host"] == "postgres.example.com" && vals["password"] == "secret"
113112
}
114113
return false
115-
})).Return(&helmrelease.Release{Name: "database"}, nil)
114+
})).Return("Release \"database\" has been installed.", nil)
116115

117116
// Verify installation order
118117
mock.InOrder(
@@ -205,7 +204,7 @@ func TestAppInstallManager_Install(t *testing.T) {
205204
mockHelmClient := &helm.MockClient{}
206205
mockHelmClient.On("Install", mock.Anything, mock.MatchedBy(func(opts helm.InstallOptions) bool {
207206
return opts.ChartPath != "" && opts.ReleaseName == "prometheus" && opts.Namespace == "monitoring"
208-
})).Return(&helmrelease.Release{Name: "prometheus"}, nil)
207+
})).Return("Release \"prometheus\" has been installed.", nil)
209208

210209
// Create mock installer that succeeds
211210
mockInstaller := &MockKotsCLIInstaller{}
@@ -255,7 +254,7 @@ func TestAppInstallManager_Install(t *testing.T) {
255254
mockHelmClient := &helm.MockClient{}
256255
mockHelmClient.On("Install", mock.Anything, mock.MatchedBy(func(opts helm.InstallOptions) bool {
257256
return opts.ChartPath != "" && opts.ReleaseName == "fluentd" && opts.Namespace == "logging"
258-
})).Return((*helmrelease.Release)(nil), assert.AnError)
257+
})).Return("", assert.AnError)
259258

260259
// Create mock installer that succeeds (so we get to Helm charts)
261260
mockInstaller := &MockKotsCLIInstaller{}
@@ -433,12 +432,12 @@ func TestComponentStatusTracking(t *testing.T) {
433432
// Database chart installation (should be first due to lower weight)
434433
mockHelmClient.On("Install", mock.Anything, mock.MatchedBy(func(opts helm.InstallOptions) bool {
435434
return opts.ReleaseName == "postgres" && opts.Namespace == "data"
436-
})).Return(&helmrelease.Release{Name: "postgres"}, nil).Once()
435+
})).Return("Release \"postgres\" has been installed.", nil).Once()
437436

438437
// Web chart installation (should be second due to higher weight)
439438
mockHelmClient.On("Install", mock.Anything, mock.MatchedBy(func(opts helm.InstallOptions) bool {
440439
return opts.ReleaseName == "nginx" && opts.Namespace == "web"
441-
})).Return(&helmrelease.Release{Name: "nginx"}, nil).Once()
440+
})).Return("Release \"nginx\" has been installed.", nil).Once()
442441

443442
// Create mock KOTS installer
444443
mockInstaller := &MockKotsCLIInstaller{}
@@ -495,7 +494,7 @@ func TestComponentStatusTracking(t *testing.T) {
495494
mockHelmClient := &helm.MockClient{}
496495
mockHelmClient.On("Install", mock.Anything, mock.MatchedBy(func(opts helm.InstallOptions) bool {
497496
return opts.ReleaseName == "failing-app"
498-
})).Return((*helmrelease.Release)(nil), errors.New("helm install failed"))
497+
})).Return("", errors.New("helm install failed"))
499498

500499
// Create mock installer that succeeds (so we get to Helm charts)
501500
mockInstaller := &MockKotsCLIInstaller{}

api/internal/managers/app/install/manager.go

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import (
1212
"github.com/replicatedhq/embedded-cluster/pkg/release"
1313
kotsv1beta1 "github.com/replicatedhq/kotskinds/apis/kots/v1beta1"
1414
"github.com/sirupsen/logrus"
15-
"k8s.io/cli-runtime/pkg/genericclioptions"
15+
helmcli "helm.sh/helm/v3/pkg/cli"
1616
)
1717

1818
var _ AppInstallManager = &appInstallManager{}
@@ -32,17 +32,16 @@ type AppInstallManager interface {
3232

3333
// appInstallManager is an implementation of the AppInstallManager interface
3434
type appInstallManager struct {
35-
appInstallStore appinstallstore.Store
36-
releaseData *release.ReleaseData
37-
license []byte
38-
clusterID string
39-
airgapBundle string
40-
kotsCLI KotsCLIInstaller
41-
logger logrus.FieldLogger
42-
hcli helm.Client
43-
k8sVersion string
44-
kubeConfigPath string
45-
restClientGetter genericclioptions.RESTClientGetter
35+
appInstallStore appinstallstore.Store
36+
releaseData *release.ReleaseData
37+
license []byte
38+
clusterID string
39+
airgapBundle string
40+
kotsCLI KotsCLIInstaller
41+
logger logrus.FieldLogger
42+
hcli helm.Client
43+
k8sVersion string
44+
kubernetesEnvSettings *helmcli.EnvSettings
4645
}
4746

4847
type AppInstallManagerOption func(*appInstallManager)
@@ -102,15 +101,9 @@ func WithK8sVersion(k8sVersion string) AppInstallManagerOption {
102101
}
103102
}
104103

105-
func WithKubeConfigPath(path string) AppInstallManagerOption {
104+
func WithKubernetesEnvSettings(envSettings *helmcli.EnvSettings) AppInstallManagerOption {
106105
return func(m *appInstallManager) {
107-
m.kubeConfigPath = path
108-
}
109-
}
110-
111-
func WithRESTClientGetter(restClientGetter genericclioptions.RESTClientGetter) AppInstallManagerOption {
112-
return func(m *appInstallManager) {
113-
m.restClientGetter = restClientGetter
106+
m.kubernetesEnvSettings = envSettings
114107
}
115108
}
116109

0 commit comments

Comments
 (0)