Skip to content

Commit

Permalink
vmware: Delete duplicate DRS rules
Browse files Browse the repository at this point in the history
Cross-cluster vMotion creates DRS rules in the target cluster, if the VM
was part of them in the source cluster. This can create duplicate DRS
rules (by name), as it seems VMware looks at the UUID of the rule not
the name.

Since multiple rules for the same VM cannot be enabled at the same time
and `cluster_util.get_rule()` only returns the first matching rule, Nova
might update the wrong rule and the anti-affinity might not actually
work.

To fix this, we get all the rules with the same name during
`_update_rule()` to check for duplicates. We keep the first rule we find
and delete all others. If the rule is disabled, Nova will enable it
already. Since Nova always updates its rule with the VMs that should be
in there, any VM being in a deleted duplicate rule is handled, too.

Change-Id: Ie5958a1645e8133f303e386353526ec83e646882
  • Loading branch information
joker-at-work committed Aug 3, 2023
1 parent 045e331 commit 7517f80
Showing 1 changed file with 17 additions and 2 deletions.
19 changes: 17 additions & 2 deletions nova/virt/vmwareapi/vmops.py
Original file line number Diff line number Diff line change
Expand Up @@ -4332,8 +4332,23 @@ def _sync_sync_server_group(context, sg_uuid):
LOG.debug('Sync for server-group %s done', sg_uuid)

def _update_rule(rule_name, expected_members, sg):
rule = cluster_util.get_rule(
self._session, self._cluster, rule_name)
# we need to get by "prefix", to get all rules matching our name,
# as there can be duplication happening with automatically
# vSphere-created rules during vMotion
rules = [r for r in cluster_util.get_rules_by_prefix(
self._session, self._cluster, rule_name)
if r.name == rule_name]

rule = rules[0] if rules else None

# if we have duplicates (with the same name), delete them
for dupl_rule in rules[1:]:
LOG.debug('Deleting DRS rule %s with key %s as duplicate',
dupl_rule.name, dupl_rule.key)
cluster_util.delete_rule(
self._session, self._cluster, dupl_rule)
LOG.info('Deleted rule %s with key %s as duplicate',
dupl_rule.name, dupl_rule.key)

if not rule:
if len(expected_members) < 2 or sg.policy == 'soft-affinity':
Expand Down

0 comments on commit 7517f80

Please sign in to comment.