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
}