* Modified raise statements to raise nova defined Exceptions.

* Fixed Console errors and in network utils using HostSystem instead of Datacenter to fetch network list
* Added support for vmwareapi module in nova/virt/connection.py so that vmware hypervisor is supported by nova
* Removing self.loop to achieve synchronization
This commit is contained in:
sateesh 2011-03-11 20:02:21 +05:30
parent 3e97dc4722
commit 7f28cb611c
8 changed files with 105 additions and 70 deletions

View File

@ -19,10 +19,13 @@
VMRC console drivers.
"""
import base64
import json
from nova import exception
from nova import flags
from nova import log as logging
from nova.virt.vmwareapi import vim_util
from nova.virt.vmwareapi_conn import VMWareAPISession
flags.DEFINE_integer('console_vmrc_port',
443,
@ -65,23 +68,34 @@ class VMRCConsole(object):
#TODO:Encrypt pool password
return password
def generate_password(self, address, username, password, instance_name):
def generate_password(self, vim_session, pool, instance_name):
"""Returns a VMRC Connection credentials
Return string is of the form '<VM MOID>:<ESX Username>@<ESX Password>'.
Return string is of the form '<VM PATH>:<ESX Username>@<ESX Password>'.
"""
vim_session = VMWareAPISession(address,
username,
password,
FLAGS.console_vmrc_error_retries)
username, password = pool['username'], pool['password']
vms = vim_session._call_method(vim_util, "get_objects",
"VirtualMachine", ["name"])
"VirtualMachine", ["name", "config.files.vmPathName"])
vm_ds_path_name = None
vm_ref = None
for vm in vms:
if vm.propSet[0].val == instance_name:
vm_name = None
ds_path_name = None
for prop in vm.propSet:
if prop.name == "name":
vm_name = prop.val
elif prop.name == "config.files.vmPathName":
ds_path_name = prop.val
if vm_name == instance_name:
vm_ref = vm.obj
vm_ds_path_name = ds_path_name
break
if vm_ref is None:
raise Exception(_("instance - %s not present") % instance_name)
return str(vm_ref) + ":" + username + "@" + password
raise exception.NotFound(_("instance - %s not present") %
instance_name)
json_data = json.dumps({"vm_id": vm_ds_path_name,
"username": username,
"password": password})
return base64.b64encode(json_data)
def is_otp(self):
"""Is one time password."""
@ -98,14 +112,10 @@ class VMRCSessionConsole(VMRCConsole):
def console_type(self):
return 'vmrc+session'
def generate_password(self, address, username, password, instance_name):
def generate_password(self, vim_session, pool, instance_name):
"""Returns a VMRC Session
Return string is of the form '<VM MOID>:<VMRC Ticket>'.
"""
vim_session = VMWareAPISession(address,
username,
password,
FLAGS.console_vmrc_error_retries)
vms = vim_session._call_method(vim_util, "get_objects",
"VirtualMachine", ["name"])
vm_ref = None
@ -113,13 +123,17 @@ class VMRCSessionConsole(VMRCConsole):
if vm.propSet[0].val == instance_name:
vm_ref = vm.obj
if vm_ref is None:
raise Exception(_("instance - %s not present") % instance_name)
raise exception.NotFound(_("instance - %s not present") %
instance_name)
virtual_machine_ticket = \
vim_session._call_method(
vim_session._get_vim(),
"AcquireCloneTicket",
vim_session._get_vim().get_service_content().sessionManager)
return str(vm_ref.value) + ":" + virtual_machine_ticket
json_data = json.dumps({"vm_id": str(vm_ref.value),
"username": virtual_machine_ticket,
"password": virtual_machine_ticket})
return base64.b64encode(json_data)
def is_otp(self):
"""Is one time password."""

View File

@ -52,19 +52,19 @@ def ensure_vlan_bridge(vlan_num, bridge, net_attrs=None):
#Check if the vlan_interface physical network adapter exists on the host
if not NetworkHelper.check_if_vlan_interface_exists(session,
vlan_interface):
raise Exception(_("There is no physical network adapter with the name"
" %s on the ESX host") % vlan_interface)
#check whether bridge already exists and retrieve the the ref of the
#network whose name_label is "bridge"
network_ref = NetworkHelper.get_network_with_the_name(session, bridge)
raise exception.NotFound(_("There is no physical network adapter with "
"the name %s on the ESX host") % vlan_interface)
#Get the vSwitch associated with the Physical Adapter
vswitch_associated = NetworkHelper.get_vswitch_for_vlan_interface(
session, vlan_interface)
if vswitch_associated is None:
raise Exception(_("There is no virtual switch associated with "
"the physical network adapter with name %s") %
raise exception.NotFound(_("There is no virtual switch associated "
"with the physical network adapter with name %s") %
vlan_interface)
#check whether bridge already exists and retrieve the the ref of the
#network whose name_label is "bridge"
network_ref = NetworkHelper.get_network_with_the_name(session, bridge)
if network_ref == None:
#Create a port group on the vSwitch associated with the vlan_interface
#corresponding physical network adapter on the ESX host
@ -77,7 +77,7 @@ def ensure_vlan_bridge(vlan_num, bridge, net_attrs=None):
#Check if the vsiwtch associated is proper
if pg_vswitch != vswitch_associated:
raise Exception(_("vSwitch which contains the port group "
raise exception.Invalid(_("vSwitch which contains the port group "
"%(bridge)s is not associated with the desired "
"physical adapter. Expected vSwitch is "
"%(vswitch_associated)s, but the one associated"
@ -88,8 +88,8 @@ def ensure_vlan_bridge(vlan_num, bridge, net_attrs=None):
#Check if the vlan id is proper for the port group
if pg_vlanid != vlan_num:
raise Exception(_("VLAN tag is not appropriate for the port "
"group %(bridge)s. Expected VLAN tag is "
raise exception.Invalid(_("VLAN tag is not appropriate for the "
"port group %(bridge)s. Expected VLAN tag is "
"%(vlan_num)s, but the one associated with the "
"port group is %(pg_vlanid)s") %\
{"bridge": bridge,

View File

@ -24,9 +24,10 @@ import sys
from nova import flags
from nova import log as logging
from nova.virt import fake
from nova.virt import libvirt_conn
from nova.virt import xenapi_conn
from nova.virt import hyperv
from nova.virt import libvirt_conn
from nova.virt import vmwareapi_conn
from nova.virt import xenapi_conn
LOG = logging.getLogger("nova.virt.connection")
@ -66,6 +67,8 @@ def get_connection(read_only=False):
conn = xenapi_conn.get_connection(read_only)
elif t == 'hyperv':
conn = hyperv.get_connection(read_only)
elif t == 'vmwareapi':
conn = vmwareapi_conn.get_connection(read_only)
else:
raise Exception('Unknown connection type "%s"' % t)

View File

@ -131,7 +131,7 @@ class ManagedObject(object):
for elem in self.propSet:
if elem.name == attr:
return elem.val
raise Exception(_("Property %(attr)s not set for the managed "
raise exception.Error(_("Property %(attr)s not set for the managed "
"object %(objName)s") %
{'attr': attr,
'objName': self.objName})
@ -272,6 +272,13 @@ class HostSystem(ManagedObject):
host_net_sys = _db_content["HostNetworkSystem"][host_net_key].obj
self.set("configManager.networkSystem", host_net_sys)
if _db_content.get("Network", None) is None:
create_network()
net_ref = _db_content["Network"][_db_content["Network"].keys()[0]].obj
network_do = DataObject()
network_do.ManagedObjectReference = [net_ref]
self.set("network", network_do)
vswitch_do = DataObject()
vswitch_do.pnic = ["vmnic0"]
vswitch_do.name = "vSwitch0"
@ -390,12 +397,12 @@ def _add_file(file_path):
def _remove_file(file_path):
""" Removes a file reference from the db """
if _db_content.get("files", None) is None:
raise Exception(_("No files have been added yet"))
raise exception.NotFound(_("No files have been added yet"))
#Check if the remove is for a single file object or for a folder
if file_path.find(".vmdk") != -1:
if file_path not in _db_content.get("files"):
raise Exception(_("File- '%s' is not there in the datastore") %\
file_path)
raise exception.NotFound(_("File- '%s' is not there in the "
"datastore") % file_path)
_db_content.get("files").remove(file_path)
else:
#Removes the files in the folder and the folder too from the db
@ -430,10 +437,10 @@ def fake_get_vmdk_size_and_properties(image_id, instance):
def _get_vm_mdo(vm_ref):
""" Gets the Virtual Machine with the ref from the db """
if _db_content.get("VirtualMachine", None) is None:
raise Exception(_("There is no VM registered"))
raise exception.NotFound(_("There is no VM registered"))
if vm_ref not in _db_content.get("VirtualMachine"):
raise Exception(_("Virtual Machine with ref %s is not there") %\
vm_ref)
raise exception.NotFound(_("Virtual Machine with ref %s is not "
"there") % vm_ref)
return _db_content.get("VirtualMachine")[vm_ref]
@ -584,7 +591,7 @@ class FakeVim(object):
""" Searches the datastore for a file """
ds_path = kwargs.get("datastorePath")
if _db_content.get("files", None) is None:
raise Exception(_("No files have been added yet"))
raise exception.NotFound(_("No files have been added yet"))
for file in _db_content.get("files"):
if file.find(ds_path) != -1:
task_mdo = create_task(method, "success")
@ -596,16 +603,17 @@ class FakeVim(object):
""" Creates a directory in the datastore """
ds_path = kwargs.get("name")
if _db_content.get("files", None) is None:
raise Exception(_("No files have been added yet"))
raise exception.NotFound(_("No files have been added yet"))
_db_content["files"].append(ds_path)
def _set_power_state(self, method, vm_ref, pwr_state="poweredOn"):
""" Sets power state for the VM """
if _db_content.get("VirtualMachine", None) is None:
raise Exception(_(" No Virtual Machine has been registered yet"))
raise exception.NotFound(_(" No Virtual Machine has been "
"registered yet"))
if vm_ref not in _db_content.get("VirtualMachine"):
raise Exception(_("Virtual Machine with ref %s is not there") %\
vm_ref)
raise exception.NotFound(_("Virtual Machine with ref %s is not "
"there") % vm_ref)
vm_mdo = _db_content.get("VirtualMachine").get(vm_ref)
vm_mdo.set("runtime.powerState", pwr_state)
task_mdo = create_task(method, "success")

View File

@ -19,6 +19,7 @@
Utility functions for ESX Networking
"""
from nova import exception
from nova import log as logging
from nova.virt.vmwareapi import error_util
from nova.virt.vmwareapi import vim_util
@ -33,9 +34,9 @@ class NetworkHelper:
def get_network_with_the_name(cls, session, network_name="vmnet0"):
""" Gets reference to the network whose name is passed as the
argument. """
datacenters = session._call_method(vim_util, "get_objects",
"Datacenter", ["network"])
vm_networks_ret = datacenters[0].propSet[0].val
hostsystems = session._call_method(vim_util, "get_objects",
"HostSystem", ["network"])
vm_networks_ret = hostsystems[0].propSet[0].val
#Meaning there are no networks on the host. suds responds with a ""
#in the parent property field rather than a [] in the
#ManagedObjectRefernce property field of the parent
@ -103,7 +104,7 @@ class NetworkHelper:
excep = ("ESX SOAP server returned an empty port group "
"for the host system in its response")
LOG.exception(excep)
raise Exception(_(excep))
raise exception.Error(_(excep))
port_grps_on_host = port_grps_on_host_ret.HostPortGroup
for p_gp in port_grps_on_host:
if p_gp.spec.name == pg_name:
@ -138,6 +139,6 @@ class NetworkHelper:
#concerned with the port group being created, which is done
#by the other call, we can ignore the exception.
if error_util.FAULT_ALREADY_EXISTS not in exc.fault_list:
raise Exception(exc)
raise exception.Error(exc)
LOG.debug(_("Created Port Group with name %s on "
"the ESX host") % pg_name)

View File

@ -100,8 +100,8 @@ class VMWareVMOps(object):
"""
vm_ref = self._get_vm_ref_from_the_name(instance.name)
if vm_ref:
raise Exception(_("Attempted to create a VM with a name %s, "
"but that already exists on the host") % instance.name)
raise exception.Duplicate(_("Attempted to create a VM with a name"
" %s, but that already exists on the host") % instance.name)
client_factory = self._session._get_vim().client.factory
service_content = self._session._get_vim().get_service_content()
@ -116,8 +116,8 @@ class VMWareVMOps(object):
NetworkHelper.get_network_with_the_name(self._session,
net_name)
if network_ref is None:
raise Exception(_("Network with the name '%s' doesn't exist on"
" the ESX host") % net_name)
raise exception.NotFound(_("Network with the name '%s' doesn't"
" exist on the ESX host") % net_name)
_check_if_network_bridge_exists()
@ -141,7 +141,7 @@ class VMWareVMOps(object):
if data_store_name is None:
msg = _("Couldn't get a local Datastore reference")
LOG.exception(msg)
raise Exception(msg)
raise exception.Error(msg)
data_store_name = _get_datastore_ref()
@ -329,7 +329,8 @@ class VMWareVMOps(object):
"""
vm_ref = self._get_vm_ref_from_the_name(instance.name)
if vm_ref is None:
raise Exception(_("instance - %s not present") % instance.name)
raise exception.NotFound(_("instance - %s not present") %
instance.name)
client_factory = self._session._get_vim().client.factory
service_content = self._session._get_vim().get_service_content()
@ -379,8 +380,8 @@ class VMWareVMOps(object):
"VirtualMachine",
"datastore")
if not ds_ref_ret:
raise Exception(_("Failed to get the datastore reference(s) "
"which the VM uses"))
raise exception.NotFound(_("Failed to get the datastore "
"reference(s) which the VM uses"))
ds_ref = ds_ref_ret.ManagedObjectReference[0]
ds_browser = vim_util.get_dynamic_property(
self._session._get_vim(),
@ -467,7 +468,8 @@ class VMWareVMOps(object):
""" Reboot a VM instance """
vm_ref = self._get_vm_ref_from_the_name(instance.name)
if vm_ref is None:
raise Exception(_("instance - %s not present") % instance.name)
raise exception.NotFound(_("instance - %s not present") %
instance.name)
lst_properties = ["summary.guest.toolsStatus", "runtime.powerState"]
props = self._session._call_method(vim_util, "get_object_properties",
None, vm_ref, "VirtualMachine",
@ -483,8 +485,8 @@ class VMWareVMOps(object):
#Raise an exception if the VM is not powered On.
if pwr_state not in ["poweredOn"]:
raise Exception(_("instance - %s not poweredOn. So can't be "
"rebooted.") % instance.name)
raise exception.Invalid(_("instance - %s not poweredOn. So can't "
"be rebooted.") % instance.name)
#If vmware tools are installed in the VM, then do a guest reboot.
#Otherwise do a hard reset.
@ -585,7 +587,8 @@ class VMWareVMOps(object):
""" Suspend the specified instance """
vm_ref = self._get_vm_ref_from_the_name(instance.name)
if vm_ref is None:
raise Exception(_("instance - %s not present") % instance.name)
raise exception.NotFound(_("instance - %s not present") %
instance.name)
pwr_state = self._session._call_method(vim_util,
"get_dynamic_property", vm_ref,
@ -599,8 +602,8 @@ class VMWareVMOps(object):
LOG.debug(_("Suspended the VM %s ") % instance.name)
#Raise Exception if VM is poweredOff
elif pwr_state == "poweredOff":
raise Exception(_("instance - %s is poweredOff and hence can't "
"be suspended.") % instance.name)
raise exception.Invalid(_("instance - %s is poweredOff and hence "
" can't be suspended.") % instance.name)
LOG.debug(_("VM %s was already in suspended state. So returning "
"without doing anything") % instance.name)
@ -608,7 +611,8 @@ class VMWareVMOps(object):
""" Resume the specified instance """
vm_ref = self._get_vm_ref_from_the_name(instance.name)
if vm_ref is None:
raise Exception(_("instance - %s not present") % instance.name)
raise exception.NotFound(_("instance - %s not present") %
instance.name)
pwr_state = self._session._call_method(vim_util,
"get_dynamic_property", vm_ref,
@ -621,14 +625,15 @@ class VMWareVMOps(object):
self._wait_with_callback(instance.id, suspend_task, callback)
LOG.debug(_("Resumed the VM %s ") % instance.name)
else:
raise Exception(_("instance - %s not in Suspended state and hence "
"can't be Resumed.") % instance.name)
raise exception.Invalid(_("instance - %s not in Suspended state "
"and hence can't be Resumed.") % instance.name)
def get_info(self, instance_name):
""" Return data about the VM instance """
vm_ref = self._get_vm_ref_from_the_name(instance_name)
if vm_ref is None:
raise Exception(_("instance - %s not present") % instance_name)
raise exception.NotFound(_("instance - %s not present") %
instance_name)
lst_properties = ["summary.config.numCpu",
"summary.config.memorySizeMB",
@ -664,7 +669,8 @@ class VMWareVMOps(object):
""" Return snapshot of console """
vm_ref = self._get_vm_ref_from_the_name(instance.name)
if vm_ref is None:
raise Exception(_("instance - %s not present") % instance.name)
raise exception.NotFound(_("instance - %s not present") %
instance.name)
param_list = {"id": str(vm_ref)}
base_url = "%s://%s/screen?%s" % (self._session._scheme,
self._session._host_ip,
@ -690,7 +696,8 @@ class VMWareVMOps(object):
the IP """
vm_ref = self._get_vm_ref_from_the_name(instance.name)
if vm_ref is None:
raise Exception(_("instance - %s not present") % instance.name)
raise exception.NotFound(_("instance - %s not present") %
instance.name)
network = db.network_get_by_instance(context.get_admin_context(),
instance['id'])
mac_addr = instance.mac_address

View File

@ -20,6 +20,7 @@ Utility functions for Image transfer
import time
from nova import exception
from nova import flags
from nova import log as logging
from nova.virt.vmwareapi import io_util
@ -58,10 +59,10 @@ def start_transfer(read_file_handle, write_file_handle, data_size):
write_excep = write_thread.get_exception()
if read_excep is not None:
LOG.exception(str(read_excep))
raise Exception(read_excep)
raise exception.Error(read_excep)
if write_excep is not None:
LOG.exception(str(write_excep))
raise Exception(write_excep)
raise exception.Error(write_excep)
time.sleep(2)
LOG.debug(_("Finished image file transfer and closing the file handles"))
#Close the file handles

View File

@ -37,6 +37,7 @@ from eventlet import event
from nova import context
from nova import db
from nova import exception
from nova import flags
from nova import log as logging
from nova import utils
@ -228,7 +229,7 @@ class VMWareAPISession(object):
except Exception, excep:
LOG.critical(_("In vmwareapi:_create_session, "
"got this exception: %s") % excep)
raise Exception(excep)
raise exception.Error(excep)
def __del__(self):
"""Logs-out the session."""