122 lines
3.7 KiB
Go
122 lines
3.7 KiB
Go
/*
|
|
* Copyright 2024 the KubeSphere Authors.
|
|
* Please refer to the LICENSE file in the root directory of the project.
|
|
* https://github.com/kubesphere/kubesphere/blob/master/LICENSE
|
|
*/
|
|
|
|
package application
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
|
|
"github.com/go-logr/logr"
|
|
|
|
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
|
|
|
"kubesphere.io/utils/s3"
|
|
|
|
"kubesphere.io/kubesphere/pkg/simple/client/application"
|
|
|
|
clusterv1alpha1 "kubesphere.io/api/cluster/v1alpha1"
|
|
|
|
kscontroller "kubesphere.io/kubesphere/pkg/controller"
|
|
|
|
appv2 "kubesphere.io/api/application/v2"
|
|
ctrl "sigs.k8s.io/controller-runtime"
|
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
|
"sigs.k8s.io/controller-runtime/pkg/reconcile"
|
|
)
|
|
|
|
const (
|
|
appVersionController = "appversion"
|
|
)
|
|
|
|
var _ reconcile.Reconciler = &AppVersionReconciler{}
|
|
var _ kscontroller.Controller = &AppVersionReconciler{}
|
|
|
|
type AppVersionReconciler struct {
|
|
client.Client
|
|
ossStore s3.Interface
|
|
cmStore s3.Interface
|
|
logger logr.Logger
|
|
}
|
|
|
|
func (r *AppVersionReconciler) Name() string {
|
|
return appVersionController
|
|
}
|
|
|
|
func (r *AppVersionReconciler) Enabled(clusterRole string) bool {
|
|
return strings.EqualFold(clusterRole, string(clusterv1alpha1.ClusterRoleHost))
|
|
}
|
|
|
|
func (r *AppVersionReconciler) SetupWithManager(mgr *kscontroller.Manager) (err error) {
|
|
r.Client = mgr.GetClient()
|
|
r.logger = ctrl.Log.WithName("controllers").WithName(appVersionController)
|
|
r.cmStore, r.ossStore, err = application.InitStore(mgr.Options.S3Options, r.Client)
|
|
if err != nil {
|
|
r.logger.Error(err, "failed to init store")
|
|
return err
|
|
}
|
|
return ctrl.NewControllerManagedBy(mgr).
|
|
Named(appVersionController).
|
|
For(&appv2.ApplicationVersion{}).
|
|
Complete(r)
|
|
}
|
|
|
|
func (r *AppVersionReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
|
|
|
|
appVersion := &appv2.ApplicationVersion{}
|
|
if err := r.Client.Get(ctx, req.NamespacedName, appVersion); err != nil {
|
|
return reconcile.Result{}, client.IgnoreNotFound(err)
|
|
}
|
|
logger := r.logger.WithValues("application version", appVersion.Name)
|
|
if !controllerutil.ContainsFinalizer(appVersion, appv2.CleanupFinalizer) {
|
|
controllerutil.RemoveFinalizer(appVersion, appv2.StoreCleanFinalizer)
|
|
controllerutil.AddFinalizer(appVersion, appv2.CleanupFinalizer)
|
|
return ctrl.Result{}, r.Update(ctx, appVersion)
|
|
}
|
|
|
|
//Delete app files, non-important logic, errors will not affect the main process
|
|
if !appVersion.ObjectMeta.DeletionTimestamp.IsZero() {
|
|
err := r.deleteFile(ctx, appVersion)
|
|
if err != nil {
|
|
logger.Error(err, "Failed to clean file")
|
|
}
|
|
}
|
|
|
|
return ctrl.Result{}, nil
|
|
}
|
|
|
|
func (r *AppVersionReconciler) deleteFile(ctx context.Context, appVersion *appv2.ApplicationVersion) error {
|
|
logger := r.logger.WithValues("application version", appVersion.Name)
|
|
defer func() {
|
|
controllerutil.RemoveFinalizer(appVersion, appv2.CleanupFinalizer)
|
|
err := r.Update(ctx, appVersion)
|
|
if err != nil {
|
|
logger.Error(err, "Failed to remove finalizer from application version")
|
|
}
|
|
logger.V(4).Info("Remove finalizer from application version %s successfully")
|
|
}()
|
|
|
|
logger.V(4).Info("ApplicationVersion has been deleted, try to clean file")
|
|
id := []string{appVersion.Name}
|
|
apprls := &appv2.ApplicationReleaseList{}
|
|
err := r.Client.List(ctx, apprls, client.MatchingLabels{appv2.AppVersionIDLabelKey: appVersion.Name})
|
|
if err != nil {
|
|
logger.Error(err, "Failed to list ApplicationRelease")
|
|
return err
|
|
}
|
|
if len(apprls.Items) > 0 {
|
|
logger.V(4).Info("ApplicationVersion is still in use, keep file in store")
|
|
return nil
|
|
}
|
|
err = application.FailOverDelete(r.cmStore, r.ossStore, id)
|
|
if err != nil {
|
|
logger.Error(err, "Fail to delete application version from store")
|
|
return err
|
|
}
|
|
logger.V(4).Info("Delete file from store successfully")
|
|
return nil
|
|
}
|