uninstall helm app

This commit is contained in:
GLYASAI 2021-04-21 18:17:15 +08:00
parent 163b67fa6e
commit 185a5eee8b
8 changed files with 114 additions and 14 deletions

View File

@ -149,10 +149,10 @@ func (a *ApplicationController) ListComponents(w http.ResponseWriter, r *http.Re
// DeleteApp -
func (a *ApplicationController) DeleteApp(w http.ResponseWriter, r *http.Request) {
appID := chi.URLParam(r, "app_id")
app := r.Context().Value(middleware.ContextKey("application")).(*dbmodel.Application)
// Delete application
err := handler.GetApplicationHandler().DeleteApp(appID)
err := handler.GetApplicationHandler().DeleteApp(r.Context(), app)
if err != nil {
httputil.ReturnBcodeError(r, w, err)
return

View File

@ -41,7 +41,7 @@ type ApplicationHandler interface {
ListApps(tenantID, appName string, page, pageSize int) (*model.ListAppResponse, error)
GetAppByID(appID string) (*dbmodel.Application, error)
BatchBindService(appID string, req model.BindServiceRequest) error
DeleteApp(appID string) error
DeleteApp(ctx context.Context, app *dbmodel.Application) error
AddConfigGroup(appID string, req *model.ApplicationConfigGroup) (*model.ApplicationConfigGroupResp, error)
UpdateConfigGroup(appID, configGroupName string, req *model.UpdateAppConfigGroupReq) (*model.ApplicationConfigGroupResp, error)
@ -192,16 +192,31 @@ func (a *ApplicationAction) GetAppByID(appID string) (*dbmodel.Application, erro
}
// DeleteApp -
func (a *ApplicationAction) DeleteApp(appID string) error {
func (a *ApplicationAction) DeleteApp(ctx context.Context, app *dbmodel.Application) error {
// Get the number of services under the application
total, err := db.GetManager().TenantServiceDao().CountServiceByAppID(appID)
total, err := db.GetManager().TenantServiceDao().CountServiceByAppID(app.AppID)
if err != nil {
return err
}
if total != 0 {
return bcode.ErrDeleteDueToBindService
}
return db.GetManager().ApplicationDao().DeleteApp(appID)
ctx, cancel := context.WithTimeout(ctx, 5 * time.Second)
defer cancel()
return db.GetManager().DB().Transaction(func(tx *gorm.DB) error {
if err := db.GetManager().ApplicationDaoTransactions(tx).DeleteApp(app.AppID); err != nil {
return err
}
if err := a.rainbondClient.RainbondV1alpha1().HelmApps(app.TenantID).Delete(ctx, app.AppName, metav1.DeleteOptions{}); err != nil {
if !k8sErrors.IsNotFound(err) {
return err
}
}
return nil
})
}
// BatchUpdateComponentPorts -

View File

@ -13,25 +13,29 @@ type Controller struct {
storer Storer
stopCh chan struct{}
controlLoop *ControlLoop
finalizer *Finalizer
}
func NewController(stopCh chan struct{}, clientset versioned.Interface, resyncPeriod time.Duration,
repoFile, repoCache string) *Controller {
queue := workqueue.New()
storer := NewStorer(clientset, resyncPeriod, queue)
workQueue := workqueue.New()
finalizerQueue := workqueue.New()
storer := NewStorer(clientset, resyncPeriod, workQueue, finalizerQueue)
controlLoop := NewControlLoop(clientset, storer, queue, repoFile, repoCache)
controlLoop := NewControlLoop(clientset, storer, workQueue, repoFile, repoCache)
finalizer := NewFinalizer(clientset, finalizerQueue, repoFile, repoCache)
return &Controller{
storer: storer,
stopCh: stopCh,
controlLoop: controlLoop,
finalizer: finalizer,
}
}
func (c *Controller) Start() {
logrus.Info("start helm app controller")
go c.storer.Run(c.stopCh)
c.controlLoop.Run()
go c.controlLoop.Run()
c.finalizer.Run()
}

View File

@ -68,7 +68,7 @@ func (c *ControlLoop) run(obj interface{}) {
}
if err := c.Reconcile(helmApp); err != nil {
// ignore the error, informer will push the same time into workqueue later.
// ignore the error, informer will push the same time into queue later.
logrus.Warningf("[HelmAppController] [ControlLoop] [Reconcile]: %v", err)
return
}

View File

@ -0,0 +1,67 @@
package helmapp
import (
"github.com/goodrain/rainbond/pkg/apis/rainbond/v1alpha1"
"github.com/goodrain/rainbond/pkg/generated/clientset/versioned"
"github.com/goodrain/rainbond/worker/controllers/helmapp/helm"
"github.com/sirupsen/logrus"
"k8s.io/client-go/util/workqueue"
)
type Finalizer struct {
clientset versioned.Interface
queue workqueue.Interface
repoFile string
repoCache string
}
// NewControlLoop -
func NewFinalizer(clientset versioned.Interface,
workqueue workqueue.Interface,
repoFile string,
repoCache string,
) *Finalizer {
return &Finalizer{
clientset: clientset,
queue: workqueue,
repoFile: repoFile,
repoCache: repoCache,
}
}
func (c *Finalizer) Run() {
for {
obj, shutdown := c.queue.Get()
if shutdown {
return
}
err := c.run(obj)
if err != nil {
logrus.Warningf("[HelmAppFinalizer] run finalizer: %v", err)
continue
}
c.queue.Done(obj)
}
}
func (c *Finalizer) run(obj interface{}) error {
helmApp, ok := obj.(*v1alpha1.HelmApp)
if !ok {
return nil
}
logrus.Infof("start uninstall helm app: %s/%s", helmApp.Name, helmApp.Namespace)
appStore := helmApp.Spec.AppStore
app, err := helm.NewApp(helmApp.Name, helmApp.Namespace,
helmApp.Spec.TemplateName, appStore.Name, helmApp.Spec.Version,
helmApp.Spec.Values,
c.repoFile, c.repoCache)
if err != nil {
return err
}
return app.Uninstall()
}

View File

@ -205,3 +205,7 @@ func (a *App) parseServices(manifests string) ([]*corev1.Service, error) {
return services, nil
}
func (a *App) Uninstall() error {
return a.helm.Uninstall(a.name)
}

View File

@ -137,6 +137,12 @@ func (h *Helm) Status(name string) (*release.Release, error) {
return rel, errors.Wrap(err, "helm status")
}
func (h *Helm) Uninstall(name string) error {
uninstall := action.NewUninstall(h.cfg)
_, err := uninstall.Run(name)
return err
}
// checkIfInstallable validates if a chart can be installed
//
// Application chart type is only installable

View File

@ -28,7 +28,8 @@ type store struct {
func NewStorer(clientset versioned.Interface,
resyncPeriod time.Duration,
workqueue workqueue.Interface) Storer {
workqueue workqueue.Interface,
finalizerQueue workqueue.Interface) Storer {
// create informers factory, enable and assign required informers
sharedInformer := externalversions.NewSharedInformerFactoryWithOptions(clientset, resyncPeriod,
externalversions.WithNamespace(corev1.NamespaceAll))
@ -46,7 +47,10 @@ func NewStorer(clientset versioned.Interface,
workqueue.Add(k8sutil.ObjKey(helmApp))
},
DeleteFunc: func(obj interface{}) {
// Two purposes of using finalizerQueue
// 1. non-block DeleteFunc
// 2. retry if the finalizer is failed
finalizerQueue.Add(obj)
},
})