func()

in oracle/controllers/instancecontroller/utils.go [766:840]


func (r *InstanceReconciler) handleResize(ctx context.Context, inst *v1alpha1.Instance, instanceReadyCond *v1.Condition, dbInstanceCond *v1.Condition, sp controllers.StsParams, applyOpts []client.PatchOption, log logr.Logger) (ctrl.Result, error) {

	if !k8s.ConditionStatusEquals(instanceReadyCond, v1.ConditionTrue) && !k8s.ConditionStatusEquals(dbInstanceCond, v1.ConditionTrue) && !k8s.ConditionReasonEquals(instanceReadyCond, k8s.ResizingInProgress) {
		return ctrl.Result{}, nil
	}
	sts := &appsv1.StatefulSet{
		ObjectMeta: metav1.ObjectMeta{
			Name:      sp.StsName,
			Namespace: inst.Namespace,
		},
	}

	if err := r.Get(ctx, client.ObjectKeyFromObject(sts), sts); err != nil && !apierrors.IsNotFound(err) {
		return ctrl.Result{}, fmt.Errorf("failed to get statefulset: %v", err)
	} else if apierrors.IsNotFound(err) {
		log.Info("Recreating Stateful set")
		k8s.InstanceUpsertCondition(&inst.Status, k8s.Ready, v1.ConditionFalse, k8s.ResizingInProgress, "Recreating statefulset")
		if _, err := r.createStatefulSet(ctx, inst, sp, applyOpts, log); err != nil {
			return ctrl.Result{}, err
		}
		return ctrl.Result{RequeueAfter: 5 * time.Second}, nil
	}

	dbContainer := findContainer(sts.Spec.Template.Spec.Containers, controllers.DatabaseContainerName)
	if dbContainer == nil {
		return ctrl.Result{}, fmt.Errorf("could not find database container in pod template")
	}

	// CPU/Memory resize
	if !cmp.Equal(inst.Spec.DatabaseResources, dbContainer.Resources) {
		log.Info("Instance CPU/MEM resize required")
		k8s.InstanceUpsertCondition(&inst.Status, k8s.Ready, v1.ConditionFalse, k8s.ResizingInProgress, "Resizing cpu/memory")

		_, err := ctrl.CreateOrUpdate(ctx, r.Client, sts, func() error {
			dbContainer := findContainer(sts.Spec.Template.Spec.Containers, controllers.DatabaseContainerName)
			if dbContainer == nil {
				return fmt.Errorf("could not find database container in pod temmplate")
			}
			dbContainer.Resources = inst.Spec.DatabaseResources
			return nil
		})
		if err != nil {
			return ctrl.Result{}, fmt.Errorf("failed to update statefulset resources: %v", err)
		}
		return ctrl.Result{RequeueAfter: 5 * time.Second}, nil
	}

	newSts, err := r.buildStatefulSet(ctx, inst, sp, nil, log)
	if err != nil {
		return ctrl.Result{}, err
	}
	done, err := tryResizeDisksOf(ctx, r.Client, newSts, log)
	if err != nil {
		return ctrl.Result{}, err
	} else if !done {
		k8s.InstanceUpsertCondition(&inst.Status, k8s.Ready, v1.ConditionFalse, k8s.ResizingInProgress, "Resizing disk")
		return ctrl.Result{RequeueAfter: 10 * time.Second}, nil
	}

	if k8s.ConditionReasonEquals(instanceReadyCond, k8s.ResizingInProgress) {
		ready, msg := IsReadyWithObj(sts)
		if ready && cmp.Equal(inst.Spec.DatabaseResources, dbContainer.Resources) {
			k8s.InstanceUpsertCondition(&inst.Status, k8s.Ready, v1.ConditionTrue, k8s.CreateComplete, msg)
			return ctrl.Result{Requeue: true}, nil
		}

		if err := utils.VerifyPodsStatus(ctx, r.Client, sts); errors.Is(err, utils.ErrPodUnschedulable) {
			return ctrl.Result{}, fmt.Errorf("Unschedulable pod %v", err)
		} else if errors.Is(err, utils.ErrNoResources) {
			return ctrl.Result{}, fmt.Errorf("Insufficient Resources %v", err)
		}
		return ctrl.Result{}, err
	}
	return ctrl.Result{}, nil
}