Skip to content

Commit 58a56ec

Browse files
authored
Set VM placement result from group if applicable (vmware-tanzu#1058)
This PR updates the `vmCreateDoPlacement()` function to use VM Group placement results when `vm.spec.groupName` is specified. VMs without a group continue to use the existing placement logic.
1 parent d3a5dad commit 58a56ec

File tree

2 files changed

+321
-43
lines changed

2 files changed

+321
-43
lines changed

pkg/providers/vsphere/vmprovider_vm.go

Lines changed: 134 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1533,7 +1533,8 @@ func verifyResourcePool(vmCtx pkgctx.VirtualMachineContext) error {
15331533
return nil
15341534
}
15351535

1536-
// vmCreateDoPlacement determines placement of the VM prior to creating the VM on VC.
1536+
// vmCreateDoPlacement determines placement of the VM prior to creating the VM
1537+
// on VC. If VM has a group name specified, placement is determined by group.
15371538
func (vs *vSphereVMProvider) vmCreateDoPlacement(
15381539
vmCtx pkgctx.VirtualMachineContext,
15391540
vcClient *vcclient.Client,
@@ -1546,9 +1547,23 @@ func (vs *vSphereVMProvider) vmCreateDoPlacement(
15461547
vmopv1.VirtualMachineConditionPlacementReady,
15471548
"NotReady",
15481549
retErr)
1550+
} else {
1551+
pkgcnd.MarkTrue(
1552+
vmCtx.VM,
1553+
vmopv1.VirtualMachineConditionPlacementReady)
15491554
}
15501555
}()
15511556

1557+
if pkgcfg.FromContext(vmCtx).Features.VMGroups &&
1558+
vmCtx.VM.Spec.GroupName != "" {
1559+
vmCtx.Logger.Info(
1560+
"Getting VM placement result from its group",
1561+
"groupName", vmCtx.VM.Spec.GroupName,
1562+
)
1563+
1564+
return vs.vmCreateDoPlacementByGroup(vmCtx, vcClient, createArgs)
1565+
}
1566+
15521567
placementConfigSpec, err := virtualmachine.CreateConfigSpecForPlacement(
15531568
vmCtx,
15541569
createArgs.ConfigSpec,
@@ -1580,6 +1595,124 @@ func (vs *vSphereVMProvider) vmCreateDoPlacement(
15801595
return err
15811596
}
15821597

1598+
return processPlacementResult(vmCtx, vcClient, createArgs, *result)
1599+
}
1600+
1601+
// vmCreateDoPlacementByGroup places the VM from the group's placement result.
1602+
func (vs *vSphereVMProvider) vmCreateDoPlacementByGroup(
1603+
vmCtx pkgctx.VirtualMachineContext,
1604+
vcClient *vcclient.Client,
1605+
createArgs *VMCreateArgs) error {
1606+
1607+
// Should never happen when this function is called, check just in case.
1608+
if vmCtx.VM.Spec.GroupName == "" {
1609+
return fmt.Errorf("VM.Spec.GroupName is empty")
1610+
}
1611+
1612+
var vmg vmopv1.VirtualMachineGroup
1613+
if err := vs.k8sClient.Get(
1614+
vmCtx,
1615+
ctrlclient.ObjectKey{
1616+
Namespace: vmCtx.VM.Namespace,
1617+
Name: vmCtx.VM.Spec.GroupName,
1618+
},
1619+
&vmg,
1620+
); err != nil {
1621+
return fmt.Errorf("failed to get VM Group object: %w", err)
1622+
}
1623+
1624+
var memberStatus vmopv1.VirtualMachineGroupMemberStatus
1625+
for _, m := range vmg.Status.Members {
1626+
if m.Kind == vmCtx.VM.Kind && m.Name == vmCtx.VM.Name {
1627+
memberStatus = m
1628+
break
1629+
}
1630+
}
1631+
1632+
if !pkgcnd.IsTrue(
1633+
&memberStatus,
1634+
vmopv1.VirtualMachineGroupMemberConditionGroupLinked,
1635+
) {
1636+
return fmt.Errorf("VM is not linked to its group")
1637+
}
1638+
1639+
if !pkgcnd.IsTrue(
1640+
&memberStatus,
1641+
vmopv1.VirtualMachineGroupMemberConditionPlacementReady,
1642+
) {
1643+
return fmt.Errorf("VM Group placement is not ready")
1644+
}
1645+
1646+
placementStatus := memberStatus.Placement
1647+
if placementStatus == nil {
1648+
return fmt.Errorf("VM Group placement is empty")
1649+
}
1650+
1651+
vmCtx.Logger.V(6).Info(
1652+
"VM Group placement is ready",
1653+
"placement", placementStatus,
1654+
)
1655+
1656+
// Create a placement result from the group's placement status.
1657+
var result placement.Result
1658+
1659+
if placementStatus.Zone != "" {
1660+
result.ZonePlacement = true
1661+
result.ZoneName = placementStatus.Zone
1662+
}
1663+
1664+
if placementStatus.Node != "" {
1665+
result.HostMoRef = &vimtypes.ManagedObjectReference{
1666+
Type: string(vimtypes.ManagedObjectTypesHostSystem),
1667+
Value: placementStatus.Node,
1668+
}
1669+
}
1670+
1671+
if placementStatus.Pool != "" {
1672+
result.PoolMoRef = vimtypes.ManagedObjectReference{
1673+
Type: string(vimtypes.ManagedObjectTypesResourcePool),
1674+
Value: placementStatus.Pool,
1675+
}
1676+
}
1677+
1678+
result.Datastores = make([]placement.DatastoreResult, len(placementStatus.Datastores))
1679+
for i, ds := range placementStatus.Datastores {
1680+
if val := ds.DiskKey; val != nil {
1681+
result.Datastores[i].DiskKey = *val
1682+
result.Datastores[i].ForDisk = true
1683+
}
1684+
1685+
result.Datastores[i].MoRef = vimtypes.ManagedObjectReference{
1686+
Type: string(vimtypes.ManagedObjectTypesDatastore),
1687+
Value: ds.ID,
1688+
}
1689+
1690+
result.Datastores[i].Name = ds.Name
1691+
result.Datastores[i].URL = ds.URL
1692+
result.Datastores[i].DiskFormats = ds.SupportedDiskFormats
1693+
}
1694+
1695+
// InstanceStoragePlacement flag is needed to update the VM's annotations
1696+
// with the selected host for VMs that have instance storage backed volumes.
1697+
// They're likely not supported for group placement. Leave it here for now
1698+
// to keep consistent with the single VM placement workflow.
1699+
if pkgcfg.FromContext(vmCtx).Features.InstanceStorage {
1700+
if vmopv1util.IsInstanceStoragePresent(vmCtx.VM) {
1701+
result.InstanceStoragePlacement = true
1702+
}
1703+
}
1704+
1705+
return processPlacementResult(vmCtx, vcClient, createArgs, result)
1706+
}
1707+
1708+
// processPlacementResult updates the createArgs and VM annotations/labels with
1709+
// the given placement result.
1710+
func processPlacementResult(
1711+
vmCtx pkgctx.VirtualMachineContext,
1712+
vcClient *vcclient.Client,
1713+
createArgs *VMCreateArgs,
1714+
result placement.Result) error {
1715+
15831716
if result.PoolMoRef.Value != "" {
15841717
createArgs.ResourcePoolMoID = result.PoolMoRef.Value
15851718
}
@@ -1633,8 +1766,6 @@ func (vs *vSphereVMProvider) vmCreateDoPlacement(
16331766
}
16341767
}
16351768

1636-
pkgcnd.MarkTrue(vmCtx.VM, vmopv1.VirtualMachineConditionPlacementReady)
1637-
16381769
return nil
16391770
}
16401771

0 commit comments

Comments
 (0)