Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
308f730
Use Helm binary instead of the Go SDK to manage charts
sgalsaleh Aug 28, 2025
c468582
Merge branch 'milestone-7-redo' into salah/sc-128058/use-helm-binary-…
sgalsaleh Aug 30, 2025
1f5e68f
pass version to helm show command
sgalsaleh Sep 2, 2025
660e317
add helm to operator image
sgalsaleh Sep 2, 2025
75554c5
fix tests
sgalsaleh Sep 2, 2025
2a20b7c
feedback
sgalsaleh Sep 3, 2025
b62ca4d
feedback
sgalsaleh Sep 3, 2025
fd1e5bb
fix web lint
sgalsaleh Sep 3, 2025
274df3f
remove todo
sgalsaleh Sep 3, 2025
cdbf5ce
fix tests and logs
sgalsaleh Sep 3, 2025
659ab3a
move env flags
sgalsaleh Sep 3, 2025
c0296f9
add helm log prefix
sgalsaleh Sep 3, 2025
e6bdbe1
try fixing integration test
sgalsaleh Sep 4, 2025
23fa025
return context error
sgalsaleh Sep 4, 2025
1da7636
one more try
sgalsaleh Sep 4, 2025
79ba2bc
revert
sgalsaleh Sep 4, 2025
f8c9b38
debug logs
sgalsaleh Sep 4, 2025
5ee5bcf
debug logs
sgalsaleh Sep 4, 2025
accb891
no-op
sgalsaleh Sep 4, 2025
b782156
one more try
sgalsaleh Sep 4, 2025
e5b7a8b
use helm history
sgalsaleh Sep 4, 2025
bc7f393
override cmd cancel function
sgalsaleh Sep 4, 2025
d2f4a72
auto rollback
sgalsaleh Sep 4, 2025
1bf3835
remove modify cmd
sgalsaleh Sep 4, 2025
091260d
tests
sgalsaleh Sep 4, 2025
6845b48
put log back
sgalsaleh Sep 4, 2025
aa3b01c
remove debug log
sgalsaleh Sep 4, 2025
4eae495
remove debug log
sgalsaleh Sep 4, 2025
d07ecfa
err msg
sgalsaleh Sep 4, 2025
69c69b2
err msgs
sgalsaleh Sep 4, 2025
ae78ea9
refactor
sgalsaleh Sep 4, 2025
65bfda3
rename
sgalsaleh Sep 4, 2025
ffefb6c
set helm HOME env vars
sgalsaleh Sep 5, 2025
dba5fec
rename tmp dir
sgalsaleh Sep 5, 2025
d458620
update comment
sgalsaleh Sep 5, 2025
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
8 changes: 8 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,14 @@ jobs:
int-tests-kind:
name: Integration tests (kind)
runs-on: ubuntu-latest
needs:
- should-run-int-tests-kind
if: needs.should-run-int-tests-kind.outputs.run == 'true'
steps:
- name: Checkout
uses: actions/checkout@v5
with:
fetch-depth: 0 # necessary for getting the last tag
- name: Setup go
uses: actions/setup-go@v5
with:
Expand All @@ -178,10 +182,14 @@ jobs:
int-tests-kind-ha-registry:
name: Integration tests (kind) HA registry
runs-on: ubuntu-latest
needs:
- should-run-int-tests-kind
if: needs.should-run-int-tests-kind.outputs.run == 'true'
steps:
- name: Checkout
uses: actions/checkout@v5
with:
fetch-depth: 0 # necessary for getting the last tag
- name: Setup go
uses: actions/setup-go@v5
with:
Expand Down
7 changes: 7 additions & 0 deletions .github/workflows/dependencies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ jobs:
version=$(gh release list --repo axboe/fio --json name,isLatest | jq -r '.[] | select(.isLatest)|.name' | cut -d- -f2)
echo "fio version: $version"
sed -i "/^FIO_VERSION/c\FIO_VERSION = $version" versions.mk
- name: Helm
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
version=$(gh release list --repo helm/helm --json tagName,isLatest | jq -r '.[] | select(.isLatest) | .tagName')
echo "helm version: $version"
sed -i "/^HELM_VERSION/c\HELM_VERSION = $version" versions.mk
- name: Create Pull Request
uses: peter-evans/create-pull-request@v7
with:
Expand Down
19 changes: 19 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,23 @@ output/bins/kubectl-support_bundle-%:
rm -rf output/tmp
touch $@

.PHONY: cmd/installer/goods/bins/helm
cmd/installer/goods/bins/helm:
$(MAKE) output/bins/helm-$(HELM_VERSION)-$(ARCH)
cp output/bins/helm-$(HELM_VERSION)-$(ARCH) $@
touch $@

output/bins/helm-%:
mkdir -p output/bins
mkdir -p output/tmp
curl --retry 5 --retry-all-errors -fL -o output/tmp/helm.tar.gz \
https://get.helm.sh/helm-$(call split-hyphen,$*,1)-$(OS)-$(call split-hyphen,$*,2).tar.gz
tar -xzf output/tmp/helm.tar.gz -C output/tmp
mv output/tmp/$(OS)-$(call split-hyphen,$*,2)/helm $@
rm -rf output/tmp
chmod +x $@
touch $@

.PHONY: cmd/installer/goods/bins/kubectl-preflight
cmd/installer/goods/bins/kubectl-preflight:
$(MAKE) output/bins/kubectl-preflight-$(TROUBLESHOOT_VERSION)-$(ARCH)
Expand Down Expand Up @@ -229,6 +246,7 @@ static: cmd/installer/goods/bins/k0s \
cmd/installer/goods/bins/kubectl-support_bundle \
cmd/installer/goods/bins/local-artifact-mirror \
cmd/installer/goods/bins/fio \
cmd/installer/goods/bins/helm \
cmd/installer/goods/internal/bins/kubectl-kots

.PHONY: static-dryrun
Expand All @@ -238,6 +256,7 @@ static-dryrun:
cmd/installer/goods/bins/kubectl-support_bundle \
cmd/installer/goods/bins/local-artifact-mirror \
cmd/installer/goods/bins/fio \
cmd/installer/goods/bins/helm \
cmd/installer/goods/internal/bins/kubectl-kots

.PHONY: embedded-cluster-linux-amd64
Expand Down
13 changes: 13 additions & 0 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
linuxinstall "github.com/replicatedhq/embedded-cluster/api/controllers/linux/install"
"github.com/replicatedhq/embedded-cluster/api/pkg/logger"
"github.com/replicatedhq/embedded-cluster/api/types"
"github.com/replicatedhq/embedded-cluster/pkg/helm"
"github.com/replicatedhq/embedded-cluster/pkg/metrics"
"github.com/replicatedhq/embedded-cluster/pkg/runtimeconfig"
"github.com/sirupsen/logrus"
Expand Down Expand Up @@ -37,6 +38,7 @@ import (
type API struct {
cfg types.APIConfig

hcli helm.Client
logger logrus.FieldLogger
metricsReporter metrics.ReporterInterface

Expand Down Expand Up @@ -93,6 +95,13 @@ func WithMetricsReporter(metricsReporter metrics.ReporterInterface) Option {
}
}

// WithHelmClient configures the helm client for the API.
func WithHelmClient(hcli helm.Client) Option {
return func(a *API) {
a.hcli = hcli
}
}

// New creates a new API instance.
func New(cfg types.APIConfig, opts ...Option) (*API, error) {
if cfg.InstallTarget == "" {
Expand All @@ -119,6 +128,10 @@ func New(cfg types.APIConfig, opts ...Option) (*API, error) {
api.logger = l
}

if err := api.initClients(); err != nil {
return nil, fmt.Errorf("init clients: %w", err)
}

if err := api.initHandlers(); err != nil {
return nil, fmt.Errorf("init handlers: %w", err)
}
Expand Down
88 changes: 88 additions & 0 deletions api/clients.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package api

import (
"fmt"

"github.com/replicatedhq/embedded-cluster/api/internal/clients"
"github.com/replicatedhq/embedded-cluster/api/types"
"github.com/replicatedhq/embedded-cluster/pkg/helm"
"github.com/replicatedhq/embedded-cluster/pkg/versions"
)

func (a *API) initClients() error {
if a.hcli == nil {
if err := a.initHelmClient(); err != nil {
return fmt.Errorf("init helm client: %w", err)
}
}
return nil
}

// initHelmClient initializes the Helm client based on the installation target
func (a *API) initHelmClient() error {
switch a.cfg.InstallTarget {
case types.InstallTargetLinux:
return a.initLinuxHelmClient()
case types.InstallTargetKubernetes:
return a.initKubernetesHelmClient()
default:
return fmt.Errorf("unsupported install target: %s", a.cfg.InstallTarget)
}
}

// initLinuxHelmClient initializes the Helm client for Linux installations
func (a *API) initLinuxHelmClient() error {
airgapPath := ""
if a.cfg.AirgapBundle != "" {
airgapPath = a.cfg.RuntimeConfig.EmbeddedClusterChartsSubDir()
}

hcli, err := helm.NewClient(helm.HelmOptions{
HelmPath: a.cfg.RuntimeConfig.PathToEmbeddedClusterBinary("helm"),
KubernetesEnvSettings: a.cfg.RuntimeConfig.GetKubernetesEnvSettings(),
K8sVersion: versions.K0sVersion,
AirgapPath: airgapPath,
})
if err != nil {
return fmt.Errorf("create linux helm client: %w", err)
}

a.hcli = hcli
return nil
}

// initKubernetesHelmClient initializes the Helm client for Kubernetes installations
func (a *API) initKubernetesHelmClient() error {
// get the kubernetes version
kcli, err := clients.NewDiscoveryClient(clients.KubeClientOptions{
RESTClientGetter: a.cfg.Installation.GetKubernetesEnvSettings().RESTClientGetter(),
})
if err != nil {
return fmt.Errorf("create discovery client: %w", err)
}
k8sVersion, err := kcli.ServerVersion()
if err != nil {
return fmt.Errorf("get server version: %w", err)
}

// get the helm binary path
helmPath, err := a.cfg.Installation.PathToEmbeddedBinary("helm")
if err != nil {
return fmt.Errorf("get helm path: %w", err)
}

// create the helm client
hcli, err := helm.NewClient(helm.HelmOptions{
HelmPath: helmPath,
KubernetesEnvSettings: a.cfg.Installation.GetKubernetesEnvSettings(),
// TODO: how can we support airgap?
AirgapPath: "",
K8sVersion: k8sVersion.String(),
})
if err != nil {
return fmt.Errorf("create kubernetes helm client: %w", err)
}

a.hcli = hcli
return nil
}
28 changes: 6 additions & 22 deletions api/controllers/app/install/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ import (
"github.com/replicatedhq/embedded-cluster/api/internal/store"
"github.com/replicatedhq/embedded-cluster/api/pkg/logger"
"github.com/replicatedhq/embedded-cluster/api/types"
"github.com/replicatedhq/embedded-cluster/pkg/helm"
"github.com/replicatedhq/embedded-cluster/pkg/release"
kotsv1beta1 "github.com/replicatedhq/kotskinds/apis/kots/v1beta1"
"github.com/sirupsen/logrus"
"k8s.io/cli-runtime/pkg/genericclioptions"
kyaml "sigs.k8s.io/yaml"
)

Expand Down Expand Up @@ -48,9 +48,7 @@ type InstallController struct {
clusterID string
airgapBundle string
privateCACertConfigMapName string
k8sVersion string
restClientGetter genericclioptions.RESTClientGetter
kubeConfigPath string
hcli helm.Client
}

type InstallControllerOption func(*InstallController)
Expand Down Expand Up @@ -133,21 +131,9 @@ func WithPrivateCACertConfigMapName(configMapName string) InstallControllerOptio
}
}

func WithK8sVersion(k8sVersion string) InstallControllerOption {
func WithHelmClient(hcli helm.Client) InstallControllerOption {
return func(c *InstallController) {
c.k8sVersion = k8sVersion
}
}

func WithRESTClientGetter(restClientGetter genericclioptions.RESTClientGetter) InstallControllerOption {
return func(c *InstallController) {
c.restClientGetter = restClientGetter
}
}

func WithKubeConfigPath(kubeConfigPath string) InstallControllerOption {
return func(c *InstallController) {
c.kubeConfigPath = kubeConfigPath
c.hcli = hcli
}
}

Expand Down Expand Up @@ -212,7 +198,7 @@ func NewInstallController(opts ...InstallControllerOption) (*InstallController,
appreleasemanager.WithReleaseData(controller.releaseData),
appreleasemanager.WithLicense(license),
appreleasemanager.WithPrivateCACertConfigMapName(controller.privateCACertConfigMapName),
appreleasemanager.WithK8sVersion(controller.k8sVersion),
appreleasemanager.WithHelmClient(controller.hcli),
)
if err != nil {
return nil, fmt.Errorf("create app release manager: %w", err)
Expand All @@ -228,9 +214,7 @@ func NewInstallController(opts ...InstallControllerOption) (*InstallController,
appinstallmanager.WithClusterID(controller.clusterID),
appinstallmanager.WithAirgapBundle(controller.airgapBundle),
appinstallmanager.WithAppInstallStore(controller.store.AppInstallStore()),
appinstallmanager.WithK8sVersion(controller.k8sVersion),
appinstallmanager.WithRESTClientGetter(controller.restClientGetter),
appinstallmanager.WithKubeConfigPath(controller.kubeConfigPath),
appinstallmanager.WithHelmClient(controller.hcli),
)
if err != nil {
return nil, fmt.Errorf("create app install manager: %w", err)
Expand Down
13 changes: 9 additions & 4 deletions api/controllers/app/install/test_suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/replicatedhq/embedded-cluster/api/internal/store"
"github.com/replicatedhq/embedded-cluster/api/types"
ecv1beta1 "github.com/replicatedhq/embedded-cluster/kinds/apis/v1beta1"
"github.com/replicatedhq/embedded-cluster/pkg/helm"
"github.com/replicatedhq/embedded-cluster/pkg/release"
kotsv1beta1 "github.com/replicatedhq/kotskinds/apis/kots/v1beta1"
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
Expand Down Expand Up @@ -132,6 +133,7 @@ func (s *AppInstallControllerTestSuite) TestPatchAppConfigValues() {
appPreflightManager := &apppreflightmanager.MockAppPreflightManager{}
appReleaseManager := &appreleasemanager.MockAppReleaseManager{}
appInstallManager := &appinstallmanager.MockAppInstallManager{}
mockHelmClient := &helm.MockClient{}
sm := s.CreateStateMachine(tt.currentState)

controller, err := NewInstallController(
Expand All @@ -142,7 +144,7 @@ func (s *AppInstallControllerTestSuite) TestPatchAppConfigValues() {
WithAppInstallManager(appInstallManager),
WithStore(&store.MockStore{}),
WithReleaseData(&release.ReleaseData{}),
WithK8sVersion("v1.33.0"),
WithHelmClient(mockHelmClient),
)
require.NoError(t, err, "failed to create install controller")

Expand Down Expand Up @@ -402,6 +404,7 @@ func (s *AppInstallControllerTestSuite) TestRunAppPreflights() {
appConfigManager := &appconfig.MockAppConfigManager{}
appPreflightManager := &apppreflightmanager.MockAppPreflightManager{}
appReleaseManager := &appreleasemanager.MockAppReleaseManager{}
mockHelmClient := &helm.MockClient{}
sm := s.CreateStateMachine(tt.currentState)
controller, err := NewInstallController(
WithStateMachine(sm),
Expand All @@ -410,7 +413,7 @@ func (s *AppInstallControllerTestSuite) TestRunAppPreflights() {
WithAppReleaseManager(appReleaseManager),
WithStore(&store.MockStore{}),
WithReleaseData(&release.ReleaseData{}),
WithK8sVersion("v1.33.0"),
WithHelmClient(mockHelmClient),
)
require.NoError(t, err, "failed to create install controller")

Expand Down Expand Up @@ -473,6 +476,7 @@ func (s *AppInstallControllerTestSuite) TestGetAppInstallStatus() {
appPreflightManager := &apppreflightmanager.MockAppPreflightManager{}
appReleaseManager := &appreleasemanager.MockAppReleaseManager{}
appInstallManager := &appinstallmanager.MockAppInstallManager{}
mockHelmClient := &helm.MockClient{}
sm := s.CreateStateMachine(states.StateNew)

controller, err := NewInstallController(
Expand All @@ -483,7 +487,7 @@ func (s *AppInstallControllerTestSuite) TestGetAppInstallStatus() {
WithAppInstallManager(appInstallManager),
WithStore(&store.MockStore{}),
WithReleaseData(&release.ReleaseData{}),
WithK8sVersion("v1.33.0"),
WithHelmClient(mockHelmClient),
)
require.NoError(t, err, "failed to create install controller")

Expand Down Expand Up @@ -685,6 +689,7 @@ func (s *AppInstallControllerTestSuite) TestInstallApp() {
appPreflightManager := &apppreflightmanager.MockAppPreflightManager{}
appReleaseManager := &appreleasemanager.MockAppReleaseManager{}
appInstallManager := &appinstallmanager.MockAppInstallManager{}
mockHelmClient := &helm.MockClient{}
sm := s.CreateStateMachine(tt.currentState)

controller, err := NewInstallController(
Expand All @@ -695,7 +700,7 @@ func (s *AppInstallControllerTestSuite) TestInstallApp() {
WithAppInstallManager(appInstallManager),
WithStore(&store.MockStore{}),
WithReleaseData(&release.ReleaseData{}),
WithK8sVersion("v1.33.0"),
WithHelmClient(mockHelmClient),
)
require.NoError(t, err, "failed to create install controller")

Expand Down
Loading