Skip to content

Commit 0b17af6

Browse files
schrejmetal3-io-bot
authored andcommitted
use label selector on list call during host selection
drops the request limit of 200 on the same call fixes available hosts not getting selected in some cases when more than 200 BMHs reside in the same namespace Signed-off-by: Jakob Schrettenbrunner <[email protected]>
1 parent 49c0bbb commit 0b17af6

File tree

1 file changed

+55
-58
lines changed

1 file changed

+55
-58
lines changed

baremetal/metal3machine_manager.go

Lines changed: 55 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -797,50 +797,19 @@ func getHost(ctx context.Context, m3Machine *infrav1.Metal3Machine, cl client.Cl
797797
// associated with the metal3 machine. It searches all hosts in case one already has an
798798
// association with this metal3 machine.
799799
func (m *MachineManager) chooseHost(ctx context.Context) (*bmov1alpha1.BareMetalHost, *v1beta1patch.Helper, error) {
800-
// get list of BMH.
801-
hosts := bmov1alpha1.BareMetalHostList{}
802-
// without this ListOption, all namespaces would be including in the listing.
803-
opts := &client.ListOptions{
804-
Namespace: m.Metal3Machine.Namespace,
805-
Limit: DefaultListLimit,
806-
}
807-
808-
err := m.client.List(ctx, &hosts, opts)
800+
labelSelector, err := hostLabelSelectorForMachine(m.Metal3Machine, m.Log)
809801
if err != nil {
810802
return nil, nil, err
811803
}
812804

813-
// Using the label selector on ListOptions above doesn't seem to work.
814-
// I think it's because we have a local cache of all BareMetalHosts.
815-
labelSelector := labels.NewSelector()
816-
var reqs labels.Requirements
817-
var r *labels.Requirement
818-
819-
for labelKey, labelVal := range m.Metal3Machine.Spec.HostSelector.MatchLabels {
820-
m.Log.Info("Adding requirement to match label",
821-
"label key", labelKey,
822-
"label value", labelVal)
823-
r, err = labels.NewRequirement(labelKey, selection.Equals, []string{labelVal})
824-
if err != nil {
825-
m.Log.Error(err, "Failed to create MatchLabel requirement, not choosing host")
826-
return nil, nil, err
827-
}
828-
reqs = append(reqs, *r)
829-
}
830-
for _, req := range m.Metal3Machine.Spec.HostSelector.MatchExpressions {
831-
m.Log.Info("Adding requirement to match label",
832-
"label key", req.Key,
833-
"label operator", req.Operator,
834-
"label value", req.Values)
835-
lowercaseOperator := selection.Operator(strings.ToLower(string(req.Operator)))
836-
r, err = labels.NewRequirement(req.Key, lowercaseOperator, req.Values)
837-
if err != nil {
838-
m.Log.Error(err, "Failed to create MatchExpression requirement, not choosing host")
839-
return nil, nil, err
840-
}
841-
reqs = append(reqs, *r)
805+
hosts := bmov1alpha1.BareMetalHostList{}
806+
err = m.client.List(ctx, &hosts,
807+
client.InNamespace(m.Metal3Machine.Namespace),
808+
client.MatchingLabelsSelector{Selector: labelSelector},
809+
)
810+
if err != nil {
811+
return nil, nil, err
842812
}
843-
labelSelector = labelSelector.Add(reqs...)
844813

845814
availableHosts := []*bmov1alpha1.BareMetalHost{}
846815
availableHostsWithNodeReuse := []*bmov1alpha1.BareMetalHost{}
@@ -875,26 +844,22 @@ func (m *MachineManager) chooseHost(ctx context.Context) (*bmov1alpha1.BareMetal
875844
}
876845
}
877846

878-
if labelSelector.Matches(labels.Set(host.ObjectMeta.Labels)) {
879-
if m.nodeReuseLabelExists(ctx, &host) && m.nodeReuseLabelMatches(ctx, &host) {
880-
m.Log.Info("Found host with nodeReuseLabelName and it matches, adding it to availableHostsWithNodeReuse list", "host", host.Name)
881-
availableHostsWithNodeReuse = append(availableHostsWithNodeReuse, &hosts.Items[i])
882-
} else if !m.nodeReuseLabelExists(ctx, &host) {
883-
switch host.Status.Provisioning.State {
884-
case bmov1alpha1.StateReady, bmov1alpha1.StateAvailable:
885-
// Break out of the switch
886-
case bmov1alpha1.StateNone, bmov1alpha1.StateUnmanaged, bmov1alpha1.StateRegistering, bmov1alpha1.StateMatchProfile,
887-
bmov1alpha1.StatePreparing, bmov1alpha1.StateProvisioning, bmov1alpha1.StateProvisioned, bmov1alpha1.StateExternallyProvisioned,
888-
bmov1alpha1.StateDeprovisioning, bmov1alpha1.StateInspecting, bmov1alpha1.StatePoweringOffBeforeDelete, bmov1alpha1.StateDeleting:
889-
continue
890-
default:
891-
continue
892-
}
893-
m.Log.Info("Host matched hostSelector for Metal3Machine, adding it to availableHosts list", "host", host.Name)
894-
availableHosts = append(availableHosts, &hosts.Items[i])
847+
if m.nodeReuseLabelExists(ctx, &host) && m.nodeReuseLabelMatches(ctx, &host) {
848+
m.Log.Info("Found host with nodeReuseLabelName and it matches, adding it to availableHostsWithNodeReuse list", "host", host.Name)
849+
availableHostsWithNodeReuse = append(availableHostsWithNodeReuse, &hosts.Items[i])
850+
} else if !m.nodeReuseLabelExists(ctx, &host) {
851+
switch host.Status.Provisioning.State {
852+
case bmov1alpha1.StateReady, bmov1alpha1.StateAvailable:
853+
// Break out of the switch
854+
case bmov1alpha1.StateNone, bmov1alpha1.StateUnmanaged, bmov1alpha1.StateRegistering, bmov1alpha1.StateMatchProfile,
855+
bmov1alpha1.StatePreparing, bmov1alpha1.StateProvisioning, bmov1alpha1.StateProvisioned, bmov1alpha1.StateExternallyProvisioned,
856+
bmov1alpha1.StateDeprovisioning, bmov1alpha1.StateInspecting, bmov1alpha1.StatePoweringOffBeforeDelete, bmov1alpha1.StateDeleting:
857+
continue
858+
default:
859+
continue
895860
}
896-
} else {
897-
m.Log.Info("Host did not match hostSelector for Metal3Machine", "host", host.Name)
861+
m.Log.Info("Host matched hostSelector for Metal3Machine, adding it to availableHosts list", "host", host.Name)
862+
availableHosts = append(availableHosts, &hosts.Items[i])
898863
}
899864
}
900865

@@ -945,6 +910,38 @@ func (m *MachineManager) chooseHost(ctx context.Context) (*bmov1alpha1.BareMetal
945910
return chosenHost, helper, err
946911
}
947912

913+
// hostLabelSelectorForMachine builds a label selector from the Metal3Machine's host selector.
914+
func hostLabelSelectorForMachine(machine *infrav1.Metal3Machine, log logr.Logger) (labels.Selector, error) {
915+
labelSelector := labels.NewSelector()
916+
917+
for labelKey, labelVal := range machine.Spec.HostSelector.MatchLabels {
918+
log.Info("Adding requirement to match label",
919+
"label key", labelKey,
920+
"label value", labelVal)
921+
r, err := labels.NewRequirement(labelKey, selection.Equals, []string{labelVal})
922+
if err != nil {
923+
log.Error(err, "Failed to create MatchLabel requirement, not choosing host")
924+
return nil, err
925+
}
926+
labelSelector = labelSelector.Add(*r)
927+
}
928+
929+
for _, req := range machine.Spec.HostSelector.MatchExpressions {
930+
log.Info("Adding requirement to match label",
931+
"label key", req.Key,
932+
"label operator", req.Operator,
933+
"label value", req.Values)
934+
lowercaseOperator := selection.Operator(strings.ToLower(string(req.Operator)))
935+
r, err := labels.NewRequirement(req.Key, lowercaseOperator, req.Values)
936+
if err != nil {
937+
log.Error(err, "Failed to create MatchExpression requirement, not choosing host")
938+
return nil, err
939+
}
940+
labelSelector = labelSelector.Add(*r)
941+
}
942+
return labelSelector, nil
943+
}
944+
948945
// consumerRefMatches returns a boolean based on whether the consumer
949946
// reference and bare metal machine metadata match.
950947
func consumerRefMatches(consumer *corev1.ObjectReference, m3machine *infrav1.Metal3Machine) bool {

0 commit comments

Comments
 (0)