Skip to content

Commit

Permalink
fix: cpl cant uninstall when component not found
Browse files Browse the repository at this point in the history
Signed-off-by: Abirdcfly <[email protected]>
  • Loading branch information
Abirdcfly committed Oct 19, 2023
1 parent 3d25e65 commit 6ebbb28
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 52 deletions.
1 change: 1 addition & 0 deletions config/samples/example-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ function waitPodReady() {
error "Timeout reached"
kubectl describe po -n${namespace} -l ${podLabel}
kubectl get po -n${namespace} --show-labels
helm list -A -a
exit 1
fi
sleep 5
Expand Down
90 changes: 45 additions & 45 deletions controllers/componentplan_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,47 +88,6 @@ func (r *ComponentPlanReconciler) Reconcile(ctx context.Context, req ctrl.Reques
logger = logger.WithValues("Generation", plan.GetGeneration(), "ObservedGeneration", plan.Status.ObservedGeneration, "creator", plan.Spec.Creator)
logger.V(1).Info("Get ComponentPlan instance")

if plan.Spec.ComponentRef == nil || plan.Spec.ComponentRef.Namespace == "" || plan.Spec.ComponentRef.Name == "" {
logger.Info("Failed to get Componentplan's Component ref, stop")
return reconcile.Result{}, nil
}
logger = logger.WithValues("Component.Namespace", plan.Spec.ComponentRef.Namespace, "Component.Name", plan.Spec.ComponentRef.Name)

// Get related component
component := &corev1alpha1.Component{}
err = r.Get(ctx, types.NamespacedName{Namespace: plan.Spec.ComponentRef.Namespace, Name: plan.Spec.ComponentRef.Name}, component)
if err != nil {
msg := fmt.Sprintf("Failed to get Component, wait %s for Component to be found", waitLonger)
if apierrors.IsNotFound(err) {
logger.Info(msg, "Component.Namespace", plan.Spec.ComponentRef.Namespace, "Component.Name", plan.Spec.ComponentRef.Name)
} else {
logger.Error(err, msg, "Component.Namespace", plan.Spec.ComponentRef.Namespace, "Component.Name", plan.Spec.ComponentRef.Name)
}
return reconcile.Result{RequeueAfter: waitLonger}, utils.IgnoreNotFound(err)
}
if component.Status.RepositoryRef == nil || component.Status.RepositoryRef.Name == "" || component.Status.RepositoryRef.Namespace == "" {
logger.Info(fmt.Sprintf("Failed to get Component.Status.RepositoryRef, wait %s to retry", waitLonger), "obj", klog.KObj(component))
return reconcile.Result{RequeueAfter: waitLonger}, nil
}
logger.V(1).Info("Get Component instance", "Component", klog.KObj(component))

if plan.Labels[corev1alpha1.ComponentPlanReleaseNameLabel] != plan.Spec.Name {
if plan.GetLabels() == nil {
plan.Labels = make(map[string]string)
}
plan.Labels[corev1alpha1.ComponentPlanReleaseNameLabel] = plan.Spec.Name
err = r.Update(ctx, plan)
if err != nil {
logger.Error(err, "Failed to update ComponentPlan release label")
}
return ctrl.Result{}, err
}

// Set the status as Unknown when no status are available.
if len(plan.Status.Conditions) == 0 {
return ctrl.Result{}, r.PatchCondition(ctx, plan, logger, revisionNoExist, false, false, plan.InitCondition()...)
}

// Add a finalizer. Then, we can define some operations which should
// occur before the ComponentPlan to be deleted.
// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/finalizers
Expand All @@ -142,9 +101,6 @@ func (r *ComponentPlanReconciler) Reconcile(ctx context.Context, req ctrl.Reques
return ctrl.Result{}, nil
}

// updateLatest try to update all componentplan's status.Latest
go r.updateLatest(ctx, logger, plan)

// Check if the ComponentPlan instance is marked to be deleted, which is
// indicated by the deletion timestamp being set.
isPlanMarkedToBeDeleted := plan.GetDeletionTimestamp() != nil
Expand Down Expand Up @@ -178,13 +134,57 @@ func (r *ComponentPlanReconciler) Reconcile(ctx context.Context, req ctrl.Reques
return ctrl.Result{}, r.PatchCondition(ctx, plan, logger, revisionNoExist, true, false, corev1alpha1.ComponentPlanUninstallSuccess())
}

if plan.Spec.ComponentRef == nil || plan.Spec.ComponentRef.Namespace == "" || plan.Spec.ComponentRef.Name == "" {
logger.Info("Failed to get Componentplan's Component ref, stop")
return reconcile.Result{}, nil
}
logger = logger.WithValues("Component.Namespace", plan.Spec.ComponentRef.Namespace, "Component.Name", plan.Spec.ComponentRef.Name)

// Get related component
component := &corev1alpha1.Component{}
err = r.Get(ctx, types.NamespacedName{Namespace: plan.Spec.ComponentRef.Namespace, Name: plan.Spec.ComponentRef.Name}, component)
if err != nil {
msg := fmt.Sprintf("Failed to get Component, wait %s for Component to be found", waitLonger)
if apierrors.IsNotFound(err) {
logger.Info(msg, "Component.Namespace", plan.Spec.ComponentRef.Namespace, "Component.Name", plan.Spec.ComponentRef.Name)
} else {
logger.Error(err, msg, "Component.Namespace", plan.Spec.ComponentRef.Namespace, "Component.Name", plan.Spec.ComponentRef.Name)
}
return reconcile.Result{RequeueAfter: waitLonger}, utils.IgnoreNotFound(err)
}
if component.Status.RepositoryRef == nil || component.Status.RepositoryRef.Name == "" || component.Status.RepositoryRef.Namespace == "" {
logger.Info(fmt.Sprintf("Failed to get Component.Status.RepositoryRef, wait %s to retry", waitLonger), "obj", klog.KObj(component))
return reconcile.Result{RequeueAfter: waitLonger}, nil
}
logger.V(1).Info("Get Component instance", "Component", klog.KObj(component))

if plan.Labels[corev1alpha1.ComponentPlanReleaseNameLabel] != plan.Spec.Name {
if plan.GetLabels() == nil {
plan.Labels = make(map[string]string)
}
plan.Labels[corev1alpha1.ComponentPlanReleaseNameLabel] = plan.Spec.Name
err = r.Update(ctx, plan)
if err != nil {
logger.Error(err, "Failed to update ComponentPlan release label")
}
return ctrl.Result{}, err
}

// Set the status as Unknown when no status are available.
if len(plan.Status.Conditions) == 0 {
return ctrl.Result{}, r.PatchCondition(ctx, plan, logger, revisionNoExist, false, false, plan.InitCondition()...)
}

// updateLatest try to update all componentplan's status.Latest
go r.updateLatest(ctx, logger, plan)

if plan.Status.GetCondition(corev1alpha1.ComponentPlanTypeSucceeded).Status == corev1.ConditionTrue {
switch {
case r.isGenerationUpdate(plan):
logger.Info("ComponentPlan.Spec is changed, need to install or upgrade ...")
return ctrl.Result{}, r.PatchCondition(ctx, plan, logger, revisionNoExist, false, false, plan.InitCondition()...)
case r.needRetry(plan):
logger.Info("ComponentPlan need to rollback...")
logger.Info("ComponentPlan need to retry...")
default:
logger.Info("ComponentPlan is unchanged and has been successful, no need to reconcile")
return ctrl.Result{}, nil
Expand Down
24 changes: 17 additions & 7 deletions pkg/helm/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,9 @@ var settings = cli.New()

// HelmWrapper is a wrapper for helm command
type HelmWrapper struct {
config *action.Configuration
buf *bytes.Buffer
config *action.Configuration
buf *bytes.Buffer
namespace string
}

// NewHelmWrapper returns a new helmWrapper instance
Expand All @@ -88,7 +89,7 @@ func NewHelmWrapper(getter genericclioptions.RESTClientGetter, namespace string,
}); err != nil {
return nil, err
}
settings.SetNamespace(namespace)
// settings.SetNamespace(namespace)
buf := new(bytes.Buffer)
registryClient, err := registry.NewClient(
registry.ClientOptDebug(settings.Debug),
Expand All @@ -102,13 +103,15 @@ func NewHelmWrapper(getter genericclioptions.RESTClientGetter, namespace string,
cfg.RegistryClient = registryClient

return &HelmWrapper{
config: cfg,
buf: buf,
config: cfg,
buf: buf,
namespace: namespace,
}, nil
}

func (h *HelmWrapper) GetDefaultInstallCfg() *action.Install {
client := action.NewInstall(h.config)
client.Namespace = h.namespace
client.CreateNamespace = false // helm install --create-namespace
client.DryRun = false // helm install --dry-run
client.DisableHooks = false // helm install --no-hooks
Expand Down Expand Up @@ -235,8 +238,11 @@ func (h *HelmWrapper) Install(ctx context.Context, logger logr.Logger, client *a
}
}

client.Namespace = settings.Namespace()
if client.Namespace == "" {
client.Namespace = "default"
}

// client.Namespace = settings.Namespace()
// Create context and prepare the handle of SIGTERM
// ctx := context.Background()
// ctx, cancel := context.WithCancel(ctx)
Expand Down Expand Up @@ -279,6 +285,7 @@ func checkIfInstallable(ch *chart.Chart) error {

func (h *HelmWrapper) GetDefaultUpgradeCfg() (upgradeCfg *action.Upgrade, createNamespace bool) {
client := action.NewUpgrade(h.config)
client.Namespace = h.namespace
client.Install = false // helm upgrade --install
client.Devel = false // helm upgrade --devel
client.DryRun = false // helm upgrade --dry-run
Expand Down Expand Up @@ -306,7 +313,10 @@ func (h *HelmWrapper) GetDefaultUpgradeCfg() (upgradeCfg *action.Upgrade, create
// Upgrade [RELEASE] [CHART]
// createNamespace: helm upgrade --create-namespace
func (h *HelmWrapper) Upgrade(ctx context.Context, logger logr.Logger, client *action.Upgrade, valueOpts *values.Options, releaseName, chart string, createNamespace bool) (rel *release.Release, out string, err error) {
client.Namespace = settings.Namespace()
if client.Namespace == "" {
client.Namespace = "default"
}
// client.Namespace = settings.Namespace()
// Fixes #7002 - Support reading values from STDIN for `upgrade` command
// Must load values AFTER determining if we have to call install so that values loaded from stdin are not read twice
if client.Install {
Expand Down

0 comments on commit 6ebbb28

Please sign in to comment.