Skip to content

Commit

Permalink
[Cluster launcher] [vSphere] fix bug: only deploy ovf to first host o…
Browse files Browse the repository at this point in the history
…f cluster (ray-project#42258)

When deploy ovf to datastore which is on the second host, it errors. 
That's because we fetch first host from cluster, which is host1. But datastore is on host2.

Solution
It should choose the common host of datastore and cluster, which is host2 on this scenario.

Signed-off-by: Chen Hui <huchen@vmware.com>
  • Loading branch information
huchen2021 authored and vickytsang committed Jan 12, 2024
1 parent 08b330f commit b4a5b76
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 21 deletions.
12 changes: 9 additions & 3 deletions python/ray/autoscaler/_private/vsphere/node_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,9 +277,15 @@ def create_frozen_vm_from_ovf(self, node_config, vm_name_target):
"The cluster name must be provided when deploying a single frozen"
" VM from OVF"
)
node_config[
"host_id"
] = self.get_pyvmomi_sdk_provider().get_host_id_in_cluster(cluster_name)

host_id = self.get_pyvmomi_sdk_provider().get_host_id_of_datastore_cluster(
datastore_name, cluster_name
)
if not host_id:
raise ValueError("No available host to be assigned")

logger.info("Found a host {}".format(host_id))
node_config["host_id"] = host_id
resource_pool_id = (
self.get_pyvmomi_sdk_provider().get_resource_pool_id_in_cluster(
cluster_name
Expand Down
35 changes: 17 additions & 18 deletions python/ray/autoscaler/_private/vsphere/pyvmomi_sdk_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class ObjectType(Enum):
VirtualMachine = "VirtualMachine"
Datastore = "Datastore"
ClusterComputeResource = "ClusterComputeResource"
HostSystem = "HostSystem"


class KeyType(Enum):
Expand All @@ -36,6 +37,8 @@ def get_object_type(vimtype):
return ObjectType.Datastore
elif vimtype == [vim.ClusterComputeResource]:
return ObjectType.ClusterComputeResource
elif vimtype == [vim.HostSystem]:
return ObjectType.HostSystem
else:
raise ValueError("Invalid Object Type")

Expand Down Expand Up @@ -73,20 +76,6 @@ def __init__(

# Instance parameters
self.timeout = 0
self.cached = {
KeyType.Name: {
ObjectType.ResourcePool: {},
ObjectType.VirtualMachine: {},
ObjectType.Datastore: {},
ObjectType.ClusterComputeResource: {},
},
KeyType.ObjectID: {
ObjectType.ResourcePool: {},
ObjectType.VirtualMachine: {},
ObjectType.Datastore: {},
ObjectType.ClusterComputeResource: {},
},
}

# Add cache to cache all fetched object
self.cached = {
Expand All @@ -95,12 +84,14 @@ def __init__(
ObjectType.VirtualMachine: {},
ObjectType.Datastore: {},
ObjectType.ClusterComputeResource: {},
ObjectType.HostSystem: {},
},
KeyType.ObjectID: {
ObjectType.ResourcePool: {},
ObjectType.VirtualMachine: {},
ObjectType.Datastore: {},
ObjectType.ClusterComputeResource: {},
ObjectType.HostSystem: {},
},
}

Expand Down Expand Up @@ -168,7 +159,8 @@ def put_obj_in_cache(self, vimtype, obj):
def get_pyvmomi_obj(self, vimtype, name=None, obj_id=None):
"""
This function will return the vSphere object.
The argument for `vimtype` can be "vim.VM", "vim.Host", "vim.Datastore", etc.
The argument for `vimtype` can be "vim.VirtualMachine", "vim.HostSystem",
"vim.Datastore", etc.
Then either the name or the object id need to be provided.
To check all such object information, you can go to the managed object board
page of your vCenter Server, such as: https://<your_vc_ip/mob
Expand Down Expand Up @@ -302,12 +294,19 @@ def get_vm_external_ip(self, vm_id):
logger.warning(f"External IPv4 address of VM {vm.name} is not available")
return None

def get_host_id_in_cluster(self, cluster_name):
def get_host_id_of_datastore_cluster(self, datastore_name, cluster_name):
"""
The function return the id of first host in cluster
The function return the host id of first common host in cluster and datastore
"""
cluster = self.get_pyvmomi_obj([vim.ClusterComputeResource], cluster_name)
return cluster.host[0]._moId
cluster_host_ids = [host._moId for host in cluster.host]

datastore = self.get_pyvmomi_obj([vim.Datastore], datastore_name)
datastore_host_ids = [host.key._moId for host in datastore.host]

common = set(cluster_host_ids) & set(datastore_host_ids)

return common.pop() if common else None

def get_resource_pool_id_in_cluster(self, cluster_name):
"""
Expand Down

0 comments on commit b4a5b76

Please sign in to comment.