Skip to content

Commit 768f631

Browse files
committed
Eviction: Use hypervisor cro instead of searching
The hypervisor cro has the hypervisor-id, so let's use that one instead of looking it up via the name.
1 parent 94973f2 commit 768f631

File tree

3 files changed

+178
-166
lines changed

3 files changed

+178
-166
lines changed

internal/controller/eviction_controller.go

Lines changed: 21 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ import (
2929
"github.com/gophercloud/gophercloud/v2/openstack/compute/v2/hypervisors"
3030
"github.com/gophercloud/gophercloud/v2/openstack/compute/v2/servers"
3131
"github.com/gophercloud/gophercloud/v2/openstack/compute/v2/services"
32-
corev1 "k8s.io/api/core/v1"
3332
"k8s.io/apimachinery/pkg/api/meta"
3433
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3534
"k8s.io/apimachinery/pkg/runtime"
@@ -40,7 +39,6 @@ import (
4039
logger "sigs.k8s.io/controller-runtime/pkg/log"
4140

4241
kvmv1 "github.com/cobaltcore-dev/openstack-hypervisor-operator/api/v1"
43-
"github.com/cobaltcore-dev/openstack-hypervisor-operator/internal/global"
4442
"github.com/cobaltcore-dev/openstack-hypervisor-operator/internal/openstack"
4543
)
4644

@@ -61,7 +59,7 @@ const (
6159
// +kubebuilder:rbac:groups=kvm.cloud.sap,resources=evictions,verbs=get;list;watch;create;update;patch;delete
6260
// +kubebuilder:rbac:groups=kvm.cloud.sap,resources=evictions/status,verbs=get;update;patch
6361
// +kubebuilder:rbac:groups=kvm.cloud.sap,resources=evictions/finalizers,verbs=update
64-
// +kubebuilder:rbac:groups="",resources=nodes,verbs=get;list;watch
62+
// +kubebuilder:rbac:groups=kvm.cloud.sap,resources=hypervisors,verbs=get;list;watch
6563

6664
// Reconcile is part of the main kubernetes reconciliation loop which aims to
6765
// move the current state of the cluster closer to the desired state.
@@ -72,12 +70,11 @@ func (r *EvictionReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
7270
return ctrl.Result{}, client.IgnoreNotFound(err)
7371
}
7472

75-
if global.LabelSelector != "" {
76-
// This test-fetch the Node assigned to the eviction, it won't be cached if it's not part of our partition so
77-
// we won't reconcile evictions for nodes outside our partition
78-
if err := r.Get(ctx, types.NamespacedName{Name: eviction.Spec.Hypervisor}, &corev1.Node{}); err != nil {
79-
return ctrl.Result{}, client.IgnoreNotFound(err)
80-
}
73+
hv := &kvmv1.Hypervisor{}
74+
// Let's fetch the Hypervisor assigned to the eviction, it won't be cached if it's not part of our partition so
75+
// we won't reconcile evictions for nodes outside our partition
76+
if err := r.Get(ctx, types.NamespacedName{Name: eviction.Spec.Hypervisor}, hv); err != nil {
77+
return ctrl.Result{}, client.IgnoreNotFound(err)
8178
}
8279

8380
log := logger.FromContext(ctx).
@@ -87,7 +84,7 @@ func (r *EvictionReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
8784

8885
// Being deleted
8986
if !eviction.DeletionTimestamp.IsZero() {
90-
err := r.handleFinalizer(ctx, eviction)
87+
err := r.handleFinalizer(ctx, eviction, hv)
9188
if err != nil {
9289
if errors.Is(err, ErrRetry) {
9390
return ctrl.Result{RequeueAfter: defaultWaitTime}, nil
@@ -114,7 +111,7 @@ func (r *EvictionReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
114111
switch statusCondition.Status {
115112
case metav1.ConditionTrue:
116113
// We are running, so we need to evict the next instance
117-
return r.handleRunning(ctx, eviction)
114+
return r.handleRunning(ctx, eviction, hv)
118115
case metav1.ConditionFalse:
119116
// We are done, so we can just return
120117
log.Info("finished")
@@ -129,10 +126,10 @@ func (r *EvictionReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
129126
return ctrl.Result{}, nil
130127
}
131128

132-
func (r *EvictionReconciler) handleRunning(ctx context.Context, eviction *kvmv1.Eviction) (ctrl.Result, error) {
129+
func (r *EvictionReconciler) handleRunning(ctx context.Context, eviction *kvmv1.Eviction, hypervisor *kvmv1.Hypervisor) (ctrl.Result, error) {
133130
if !meta.IsStatusConditionTrue(eviction.Status.Conditions, kvmv1.ConditionTypePreflight) {
134131
// Ensure the hypervisor is disabled and we have the preflight condition
135-
return r.handlePreflight(ctx, eviction)
132+
return r.handlePreflight(ctx, eviction, hypervisor)
136133
}
137134

138135
// That should leave us with "Running" and the hypervisor should be deactivated
@@ -158,30 +155,22 @@ func (r *EvictionReconciler) updateStatus(ctx context.Context, eviction, base *k
158155
client.MergeFromWithOptimisticLock{}), client.FieldOwner(EvictionControllerName))
159156
}
160157

161-
func (r *EvictionReconciler) handlePreflight(ctx context.Context, eviction *kvmv1.Eviction) (ctrl.Result, error) {
158+
func (r *EvictionReconciler) handlePreflight(ctx context.Context, eviction *kvmv1.Eviction, hv *kvmv1.Hypervisor) (ctrl.Result, error) {
162159
base := eviction.DeepCopy()
163-
hypervisorName := eviction.Spec.Hypervisor
164-
160+
expectHypervisor := HasStatusCondition(hv.Status.Conditions, kvmv1.ConditionTypeOnboarding)
165161
// Does the hypervisor even exist? Is it enabled/disabled?
166-
hypervisor, err := openstack.GetHypervisorByName(ctx, r.computeClient, hypervisorName, false)
162+
hypervisor, err := hypervisors.Get(ctx, r.computeClient, hv.Status.HypervisorID).Extract()
167163
if err != nil {
168-
expectHypervisor := true
169-
hv := &kvmv1.Hypervisor{}
170-
if err := r.Get(ctx, client.ObjectKey{Name: eviction.Spec.Hypervisor}, hv); client.IgnoreNotFound(err) != nil {
164+
if !gophercloud.ResponseCodeIs(err, http.StatusNotFound) {
171165
return ctrl.Result{}, err
172166
}
173167

174-
if hv.Name != "" {
175-
expectHypervisor = HasStatusCondition(hv.Status.Conditions, kvmv1.ConditionTypeOnboarding)
176-
}
177-
178168
if expectHypervisor {
179169
// Abort eviction
180-
err = fmt.Errorf("failed to get hypervisor %w", err)
181170
meta.SetStatusCondition(&eviction.Status.Conditions, metav1.Condition{
182171
Type: kvmv1.ConditionTypeEvicting,
183172
Status: metav1.ConditionFalse,
184-
Message: err.Error(),
173+
Message: fmt.Sprintf("failed to get hypervisor %v", err),
185174
Reason: kvmv1.ConditionReasonFailed,
186175
})
187176
return ctrl.Result{}, r.updateStatus(ctx, eviction, base)
@@ -201,27 +190,14 @@ func (r *EvictionReconciler) handlePreflight(ctx context.Context, eviction *kvmv
201190
}
202191
}
203192

204-
log := logger.FromContext(ctx)
205-
currentHypervisor, _, _ := strings.Cut(hypervisor.HypervisorHostname, ".")
206-
if currentHypervisor != hypervisorName {
207-
err = fmt.Errorf("hypervisor name %q does not match spec %q", currentHypervisor, hypervisorName)
208-
log.Error(err, "Hypervisor name mismatch")
209-
meta.SetStatusCondition(&eviction.Status.Conditions, metav1.Condition{
210-
Type: kvmv1.ConditionTypeEvicting,
211-
Status: metav1.ConditionFalse,
212-
Message: err.Error(),
213-
Reason: kvmv1.ConditionReasonFailed,
214-
})
215-
return ctrl.Result{}, r.updateStatus(ctx, eviction, base)
216-
}
217-
218193
if !meta.IsStatusConditionTrue(eviction.Status.Conditions, kvmv1.ConditionTypeHypervisorDisabled) {
219194
// Hypervisor is not disabled/ensured, so we need to disable it
220195
return ctrl.Result{}, r.disableHypervisor(ctx, hypervisor, eviction)
221196
}
222197

223198
// Fetch all virtual machines on the hypervisor
224-
hypervisor, err = openstack.GetHypervisorByName(ctx, r.computeClient, hypervisorName, true)
199+
trueVal := true
200+
hypervisor, err = hypervisors.GetExt(ctx, r.computeClient, hv.Status.HypervisorID, hypervisors.GetOpts{WithServers: &trueVal}).Extract()
225201
if err != nil {
226202
return ctrl.Result{}, err
227203
}
@@ -386,7 +362,7 @@ func (r *EvictionReconciler) evictionReason(eviction *kvmv1.Eviction) string {
386362
return fmt.Sprintf("Eviction %v/%v: %v", eviction.Namespace, eviction.Name, eviction.Spec.Reason)
387363
}
388364

389-
func (r *EvictionReconciler) handleFinalizer(ctx context.Context, eviction *kvmv1.Eviction) error {
365+
func (r *EvictionReconciler) handleFinalizer(ctx context.Context, eviction *kvmv1.Eviction, hypervisor *kvmv1.Hypervisor) error {
390366
if !controllerutil.ContainsFinalizer(eviction, evictionFinalizerName) {
391367
return nil
392368
}
@@ -395,7 +371,7 @@ func (r *EvictionReconciler) handleFinalizer(ctx context.Context, eviction *kvmv
395371
// - the hypervisor being gone, because it has been torn down
396372
// - the hypervisor having been enabled by someone else
397373
if !meta.IsStatusConditionTrue(eviction.Status.Conditions, kvmv1.ConditionTypeHypervisorReEnabled) {
398-
err := r.enableHypervisorService(ctx, eviction)
374+
err := r.enableHypervisorService(ctx, eviction, hypervisor)
399375
if err != nil {
400376
return err
401377
}
@@ -406,10 +382,10 @@ func (r *EvictionReconciler) handleFinalizer(ctx context.Context, eviction *kvmv
406382
return r.Patch(ctx, eviction, client.MergeFromWithOptions(base, client.MergeFromWithOptimisticLock{}))
407383
}
408384

409-
func (r *EvictionReconciler) enableHypervisorService(ctx context.Context, eviction *kvmv1.Eviction) error {
385+
func (r *EvictionReconciler) enableHypervisorService(ctx context.Context, eviction *kvmv1.Eviction, hv *kvmv1.Hypervisor) error {
410386
log := logger.FromContext(ctx)
411387

412-
hypervisor, err := openstack.GetHypervisorByName(ctx, r.computeClient, eviction.Spec.Hypervisor, false)
388+
hypervisor, err := hypervisors.Get(ctx, r.computeClient, hv.Status.HypervisorID).Extract()
413389
if err != nil {
414390
if errors.Is(err, openstack.ErrNoHypervisor) {
415391
base := eviction.DeepCopy()

0 commit comments

Comments
 (0)