From 7f28cb611c6bc802ad78242275b18bb0278e43bd Mon Sep 17 00:00:00 2001 From: sateesh Date: Fri, 11 Mar 2011 20:02:21 +0530 Subject: [PATCH] * 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 --- nova/console/vmrc.py | 50 ++++++++++++++++++---------- nova/network/vmwareapi_net.py | 20 +++++------ nova/virt/connection.py | 7 ++-- nova/virt/vmwareapi/fake.py | 32 +++++++++++------- nova/virt/vmwareapi/network_utils.py | 11 +++--- nova/virt/vmwareapi/vmops.py | 47 +++++++++++++++----------- nova/virt/vmwareapi/vmware_images.py | 5 +-- nova/virt/vmwareapi_conn.py | 3 +- 8 files changed, 105 insertions(+), 70 deletions(-) diff --git a/nova/console/vmrc.py b/nova/console/vmrc.py index 9c5e3b444398..f448d094b543 100644 --- a/nova/console/vmrc.py +++ b/nova/console/vmrc.py @@ -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 ':@'. + Return string is of the form ':@'. """ - 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 ':'. """ - 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.""" diff --git a/nova/network/vmwareapi_net.py b/nova/network/vmwareapi_net.py index 1bda1702a258..13b619df56b9 100644 --- a/nova/network/vmwareapi_net.py +++ b/nova/network/vmwareapi_net.py @@ -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, diff --git a/nova/virt/connection.py b/nova/virt/connection.py index 13181b7303aa..8b950b430358 100644 --- a/nova/virt/connection.py +++ b/nova/virt/connection.py @@ -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) diff --git a/nova/virt/vmwareapi/fake.py b/nova/virt/vmwareapi/fake.py index 909d1a6cfe0f..e03d74cf89e0 100644 --- a/nova/virt/vmwareapi/fake.py +++ b/nova/virt/vmwareapi/fake.py @@ -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") diff --git a/nova/virt/vmwareapi/network_utils.py b/nova/virt/vmwareapi/network_utils.py index f271210712cd..36fa989968db 100644 --- a/nova/virt/vmwareapi/network_utils.py +++ b/nova/virt/vmwareapi/network_utils.py @@ -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) diff --git a/nova/virt/vmwareapi/vmops.py b/nova/virt/vmwareapi/vmops.py index 344c4518b937..2d87a627d741 100644 --- a/nova/virt/vmwareapi/vmops.py +++ b/nova/virt/vmwareapi/vmops.py @@ -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 diff --git a/nova/virt/vmwareapi/vmware_images.py b/nova/virt/vmwareapi/vmware_images.py index f2a7c3b33b22..2b389987ebb2 100644 --- a/nova/virt/vmwareapi/vmware_images.py +++ b/nova/virt/vmwareapi/vmware_images.py @@ -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 diff --git a/nova/virt/vmwareapi_conn.py b/nova/virt/vmwareapi_conn.py index a2609278db5a..92cd83ed1c02 100644 --- a/nova/virt/vmwareapi_conn.py +++ b/nova/virt/vmwareapi_conn.py @@ -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."""