Files
Olares/framework/app-service/pkg/appinstaller/v2/helm_ops_upgrade.go
dkeven 7f09420bdf fix(appservice): update depedencies to fix some vulnerabilities (#2314)
* refactor(appservice): rename go module to fit into the main repo (#2311)

* fix(appservice): update depedencies to fix some vulnerabilities (#2313)
2025-12-25 11:30:55 +08:00

189 lines
5.2 KiB
Go

package v2
import (
"errors"
"fmt"
appv1alpha1 "github.com/beclab/Olares/framework/app-service/api/app.bytetrade.io/v1alpha1"
v1 "github.com/beclab/Olares/framework/app-service/pkg/appinstaller"
"github.com/beclab/Olares/framework/app-service/pkg/errcode"
"github.com/beclab/Olares/framework/app-service/pkg/helm"
"github.com/beclab/Olares/framework/app-service/pkg/kubesphere"
helmrelease "helm.sh/helm/v3/pkg/release"
"helm.sh/helm/v3/pkg/storage/driver"
"k8s.io/klog/v2"
)
func (h *HelmOpsV2) Upgrade() error {
if !h.isMultiCharts() {
return h.HelmOps.Upgrade()
}
if h.isMultiCharts() && !h.hasClusterSharedCharts() {
err := errors.New("multi-charts app must have at least one cluster shared chart")
klog.Error(err)
return err
}
// We just need to check the status of the main chart,
// as the upgrade operation will be applied to all sub-charts.
status, err := h.status(h.App().AppName)
if err != nil {
klog.Errorf("get release status failed %v", err)
return err
}
if status.Info.Status == helmrelease.StatusDeployed {
values, err := h.SetValues()
if err != nil {
klog.Errorf("set values err %v", err)
return err
}
// in v2, if app is multi-charts and has a cluster shared chart,
// middleware namespace is always os-platform
middlewareNamespace := "os-platform"
err = h.TaprApply(values, middlewareNamespace)
if err != nil {
klog.Errorf("tapr apply err %v", err)
return err
}
err = h.upgrade(values)
if err != nil {
klog.Errorf("Failed to upgrade app %s err=%v", h.App().AppName, err)
return err
}
// just need to add labels to the main ( client ) chart's deployment
err = h.AddApplicationLabelsToDeployment()
if err != nil {
klog.Errorf("Failed to add application labels to deployment for app %s err=%v", h.App().AppName, err)
return err
}
// add application labels to shared namespace
err = h.addApplicationLabelsToSharedNamespace()
if err != nil {
klog.Errorf("Failed to add application labels to shared namespace err=%v", err)
return err
}
// v2 && multi-charts app, add labels to namespace for cluster scoped apps
err = h.AddLabelToNamespaceForDependClusterApp()
if err != nil {
return err
}
if h.App().Type == appv1alpha1.Middleware.String() {
return nil
}
err = h.UpdatePolicy()
if err != nil {
klog.Errorf("Failed to update policy for app %s err=%v", h.App().AppName, err)
return err
}
if err = h.RegisterOrUnregisterAppProvider(v1.Register); err != nil {
klog.Errorf("Failed to register app provider err=%v", err)
return err
}
ok, err := h.WaitForStartUp()
if err != nil && errors.Is(err, errcode.ErrPodPending) {
return err
}
if !ok {
klog.Errorf("Failed to wait for app %s startup", h.App().AppName)
return fmt.Errorf("app %s failed to start up", h.App().AppName)
}
klog.Infof("App (V2) %s upgraded successfully", h.App().AppName)
return nil
}
return fmt.Errorf("cannot upgrade release %s/%s, current state is %s", h.App().Namespace, h.App().AppName, status.Info.Status)
}
func (h *HelmOpsV2) upgrade(values map[string]interface{}) error {
for _, chart := range h.App().SubCharts {
if chart.Shared {
isAdmin, err := kubesphere.IsAdmin(h.Context(), h.KubeConfig(), h.App().OwnerName)
if err != nil {
klog.Errorf("Failed to check if user is admin for chart %s: %v", chart.Name, err)
return err
}
if !isAdmin {
klog.Infof("Skipping upgrading of shared chart %s for non-admin user %s", chart.Name, h.App().OwnerName)
continue
}
}
status, err := h.status(chart.Name)
if err != nil {
if errors.Is(err, driver.ErrReleaseNotFound) && chart.Shared {
// upgrading single chart to multi-charts app,
klog.Infof("[upgrading] chart %s not found, installing it", chart.Name)
actionConfig, settings, err := helm.InitConfig(h.KubeConfig(), chart.Namespace(h.App().OwnerName))
if err != nil {
klog.Errorf("Failed to create action config for shared chart %s: %v", chart.Name, err)
return err
}
err = helm.InstallCharts(
h.Context(),
actionConfig,
settings,
chart.Name,
chart.ChartPath(h.App().AppName),
h.App().RepoURL,
chart.Namespace(h.App().OwnerName),
values,
)
if err != nil {
klog.Errorf("Failed to install chart %s: %v", chart.Name, err)
return err
}
}
klog.Errorf("Failed to get status for chart %s: %v", chart.Name, err)
return err
}
if status.Info.Status == helmrelease.StatusDeployed {
actionConfig := h.ActionConfig()
settings := h.Settings()
if chart.Shared {
// re-create action config for shared chart
actionConfig, settings, err = helm.InitConfig(h.KubeConfig(), chart.Namespace(h.App().OwnerName))
if err != nil {
klog.Errorf("Failed to create action config for shared chart %s: %v", chart.Name, err)
return err
}
}
err = helm.UpgradeCharts(
h.Context(),
actionConfig,
settings,
chart.Name,
chart.ChartPath(h.App().AppName),
h.App().RepoURL,
h.App().Namespace,
values,
true,
)
if err != nil {
klog.Errorf("Failed to upgrade chart name=%s err=%v", chart.Name, err)
return err
}
} else {
return fmt.Errorf("chart %s is not deployed, cannot upgrade", chart.Name)
}
}
return nil
}