def delete_network(self, net_id): try: LOG.info(_("Delete %s network: %s"), self.os, net_id) return self.client.delete_network(net_id) except exceptions.NeutronClientException as e: LOG.exception(_("Error deleting network: %s"), e) return e
def _dispatch(self, message): ''' Dispatch a message to its specific handler. :param: message A dictionary containing the OpenStack message notification attributes (event_type, timestamp, message_id, priority, publisher_id, payload) ''' event_type = message.get('event_type') handlers = self._get_handlers(event_type) log_ = self.qpid_connection.log self._count_since_acknowledge += 1 try: if handlers: log(log_, 'debug', _('Dispatching message to handlers')) log(log_, 'info', _('Qpid listener received ' 'message of event type: %s' % message['event_type'])) for handler in handlers: handler(self.qpid_connection.context, message) except Exception, e: log(log_, 'error', _('Error handling message: %s: %s. Message: ' '%s.') % (Exception, e, message)) # Print stack trace exc_type, exc_value, exc_traceback = sys.exc_info() log(log_, 'error', _('error type %s') % (exc_type)) log(log_, 'error', _('error object %s') % (exc_value)) log(log_, 'error', ''.join(traceback.format_tb(exc_traceback)))
def do_host_maintenance(cs, args): """Enable maintenance mode for a hypervisor.""" if not args.set_status: if args.migrate or args.target_host: raise exceptions.CommandError( _("Need to set --set-status " "to 'enable' when --migrate " "or --target-host specified.")) else: return _show_maintenance_status(cs, args.host) if "disable" == args.set_status.lower(): if args.migrate or args.target_host: raise exceptions.CommandError( _("No need to specify migrate or " "target-host when disabling the " "host maintenance mode.")) hv = cs.host_maintenance.update(args.host, args.set_status, args.migrate, args.target_host) host = HostMaintenanceResource(HostMaintenanceManager, hv.hypervisor_maintenance) utils.print_list( [host], ['hypervisor_hostname', 'status', 'migrate', 'target-host'])
def fill_metadata_dict_by_pvc_instance(metadata, pvc_instance): """ This common method help to get PowerVC unique property into metadata """ if pvc_instance is None or not isinstance(pvc_instance, dict): LOG.warning('pvc instance is not a dict: %s' % pvc_instance) return {} if metadata is None: metadata = {} LOG.debug(_('metadata before filled: %s') % metadata) health_value = None health_status = pvc_instance.get('health_status') if health_status is not None: health_value = health_status.get('health_value') metadata[constants.PVC_ID] = pvc_instance['id'] # The value 'None' of the dict type instance metadata is reserved # by the Nova framework. # Can not set the value of the instance metadata when it's 'None'. if health_value is not None: metadata[constants.gen_pvc_key('health_status.health_value')] \ = health_value pvc_attrs = ['cpus', 'min_cpus', 'max_cpus', 'cpu_utilization', 'min_vcpus', 'max_vcpus', 'min_memory_mb', 'max_memory_mb', 'root_gb'] for attr in pvc_attrs: val = pvc_instance.get(attr) if val is not None: metadata[constants.gen_pvc_key(attr)] = val LOG.debug(_('metadata after filled: %s') % metadata) return metadata
def do_host_maintenance(cs, args): """Enable maintenance mode for a hypervisor.""" if not args.set_status: if args.migrate or args.target_host: raise exceptions.CommandError(_("Need to set --set-status " "to 'enable' when --migrate " "or --target-host specified.")) else: return _show_maintenance_status(cs, args.host) if "disable" == args.set_status.lower(): if args.migrate or args.target_host: raise exceptions.CommandError(_("No need to specify migrate or " "target-host when disabling the " "host maintenance mode.")) hv = cs.host_maintenance.update(args.host, args.set_status, args.migrate, args.target_host) host = HostMaintenanceResource(HostMaintenanceManager, hv.hypervisor_maintenance) utils.print_list([host], ['hypervisor_hostname', 'status', 'migrate', 'target-host'])
def delete_port(self, port_id): try: LOG.info(_("Delete %s port: %s"), self.os, port_id) return self.client.delete_port(port_id) except exceptions.NeutronClientException as e: LOG.exception(_("Error deleting port: %s"), e) return e
def initialize_local_servicecatalog(): global LOCAL if LOCAL: return def new_local_servicecatalog(): LOG.info(_('start to new local keystone client')) keystone_version = CONF['openstack']['keystone_version'] keystone = service.KeystoneService(str(SERVICE_TYPES.identity), keystone_version, OS_OPTS['auth_url'], OS_OPTS, None).new_client() servicecatalog = service.ClientServiceCatalog(OS_OPTS, keystone) LOG.info(_('finish to new local keystone client')) return servicecatalog count = 0 while count < CONF['openstack']['keystone_max_try_times']: try: if LOCAL: return LOCAL = new_local_servicecatalog() return except Exception, e: LOG.info(_('Keystone service is not ready. %s ') % unicode(e)) count += 1 if count == CONF['openstack']['keystone_max_try_times']: LOG.error( _('Keystone service is not ready eventually after' ' retries!')) raise e time.sleep(CONF['openstack']['keystone_retry_interval'])
def create_port(self, port): net_id = utils.translate_net_id(self.db, port.get('network_id'), self.os) if not net_id: return None body = {} body['network_id'] = net_id body['fixed_ips'] = [] for field in constants.PORT_CREATE_FIELDS: if field in port: body[field] = port[field] if self.os == POWERVC_OS: body['device_owner'] = constants.POWERVC_DEVICE_OWNER # Set device id to powervc locked when this port is bound to # non PowerVC instances if port.get('device_id'): body['device_id'] = constants.POWERVC_LOCKDEVICE_ID elif port.get('device_id'): dev_id = port['device_id'] if dev_id == constants.POWERVC_LOCKDEVICE_ID: # PowerVC locked port, simply synchronize them to local body['device_id'] = dev_id if port.get('device_owner'): body['device_owner'] = port['device_owner'] else: # If we are creating a local port and the PowerVC port has a # device id, then set the device id of the new local port to be # "pvc:" + PowerVC device id. body['device_id'] = constants.RSVD_PORT_PREFIX + dev_id fixed_ips = port.get('fixed_ips') if not fixed_ips: return None for ip in fixed_ips: ip_addr = ip.get('ip_address') if not ip_addr or ':' in ip_addr: continue sub_id = utils.translate_subnet_id(self.db, ip.get('subnet_id'), self.os) if not sub_id: LOG.warning(_("%s subnet does not exist for: %s"), self.os, ip_addr) continue new_ip = {} new_ip['ip_address'] = ip_addr new_ip['subnet_id'] = sub_id body['fixed_ips'].append(new_ip) if len(body['fixed_ips']) == 0: return None request = {} request['port'] = body try: LOG.info(_("Create %s port: %s"), self.os, body) response = self.client.create_port(request) if response and 'port' in response: return response.get('port') return None except exceptions.NeutronClientException as e: LOG.exception(_("Error creating port: %s\nError message: %s"), body, e) return None
def create_port(self, port): net_id = utils.translate_net_id(self.db, port.get('network_id'), self.os) if not net_id: return None body = {} body['network_id'] = net_id body['fixed_ips'] = [] for field in constants.PORT_CREATE_FIELDS: if field in port: body[field] = port[field] if self.os == POWERVC_OS: body['device_owner'] = constants.POWERVC_DEVICE_OWNER # Set device id to powervc locked when this port is bound to # non PowerVC instances if port.get('device_id'): body['device_id'] = constants.POWERVC_LOCKDEVICE_ID elif port.get('device_id'): dev_id = port['device_id'] if dev_id == constants.POWERVC_LOCKDEVICE_ID: # PowerVC locked port, simply synchronize them to local body['device_id'] = dev_id if port.get('device_owner'): body['device_owner'] = port['device_owner'] else: # If we are creating a local port and the PowerVC port has a # device id, then set the device id of the new local port to be # "pvc:" + PowerVC device id. body['device_id'] = constants.RSVD_PORT_PREFIX + dev_id fixed_ips = port.get('fixed_ips') if not fixed_ips: return None for ip in fixed_ips: ip_addr = ip.get('ip_address') if not ip_addr or ':' in ip_addr: continue sub_id = utils.translate_subnet_id(self.db, ip.get('subnet_id'), self.os) if not sub_id: LOG.warning(_("%s subnet does not exist for: %s"), self.os, ip_addr) continue new_ip = {} new_ip['ip_address'] = ip_addr new_ip['subnet_id'] = sub_id body['fixed_ips'].append(new_ip) if len(body['fixed_ips']) == 0: return None request = {} request['port'] = body try: LOG.info(_("Create %s port: %s"), self.os, body) response = self.client.create_port(request) if response and 'port' in response: return response.get('port') return None except exceptions.NeutronClientException as e: LOG.exception(_("Error creating port: %s\nError message: %s"), body, e) return None
def get_our_scg_list(self): """ If SCG names are specified in our configuration, see if the scgs exist. If they do not exist, raise an exception. If they exist, return the scg list for the name specified. If no SCG name is specified, return [] for the scg list. :returns: The StorageConnectivityGroup object list if found, else [] :raise StorageConnectivityGroupNotFound: if the Storage Connectivity Groups could not be found on PowerVC """ our_scg_list = [] scg_to_use_list = CONF['powervc'].storage_connectivity_group for scg_to_use in scg_to_use_list: if scg_to_use: scg = self.scg_cache.by_name(scg_to_use) if scg is not None: LOG.debug(_('PowerVC Storage Connectivity Group \'%s\' ' 'found.'), scg.display_name) our_scg = scg our_scg_list.append(our_scg) else: # If a SCG is specified and it's not found on the PowerVC, # raise an exception. LOG.error(_('The PowerVC Storage Connectivity Group' ' \'%s\' was not found.'), scg_to_use) raise StorageConnectivityGroupNotFound(scg=scg_to_use) else: LOG.error(_('No Storage Connectivity Group is specified in ' 'the configuration settings.')) return our_scg_list
def synchronize_flavors(self, ctx): """ Get a list of all public flavors from PowerVC. If it is in configuration white list, and not in black list, insert it. if it is already in local tables, ignore it. """ LOG.info(_("Flavors synchronization starts.")) # Get all public flavors. By default, detail and public is set. pvcFlavors = self.driver.list_flavors() # Sync flavors in list for flavor in pvcFlavors: LOG.info(_("Flavor:%s") % str(flavor)) greenthread.sleep(0) # This check is added to eliminate sync of private flavors # Can be removed once PowerVC fixes to return only public flavors # by default. if not(flavor.__dict__.get(constants.IS_PUBLIC)): continue if (self._check_for_sync(flavor.name)): response = self._check_for_extraspecs(flavor) if response is not None: self._sync_flavor(ctx, flavor, response[1]) LOG.info(_("Flavors synchronization ends."))
def delete_volume(self, volume): """ Deletes the specfied volume from powervc """ try: LOG.info(_("Deleting volume %s."), self._get_vol_name(volume)) pvc_volume_id = None for metaDataItem in volume.volume_metadata: if metaDataItem.key == constants.LOCAL_PVC_PREFIX + 'id': pvc_volume_id = metaDataItem.value break if pvc_volume_id is not None: self._service.delete_volume(pvc_volume_id) else: LOG.warning(_("Volume metadata does not " "contain a powervc volume identifier.")) except NotFound: LOG.debug(_("Volume id %s was already deleted on powervc"), pvc_volume_id) LOG.info(_("Volume %s deleted."), self._get_vol_name(volume)) except Exception as e: if CONF.powervc.volume_driver_ignore_delete_error: LOG.error(_("Volume %s deleted, however the following " "error occurred " "which prevented the backing volume in PowerVC " "from being deleted: %s"), self._get_vol_name(volume), str(e)) else: raise
def get_local_staging_project_id(self): """ Get the local hosting OS staging project Id. If a staging project name is not found, a exception.StagingProjectNotFound exception will be raised. If no staging project is specified in the conf, the default value will be used as specified in constants. :returns: The local hosting OS staging project Id """ ks_client = self._localkeystoneclient stagingname = CONF.powervc.staging_project_name or \ constants.DEFAULT_STAGING_PROJECT_NAME try: projects = [] if hasattr(ks_client, 'version') and (ks_client.version in ['v2', 'v2.0']): # For keystone v2 version projects = ks_client.tenants.list() elif hasattr(ks_client, 'version') and (ks_client.version in ['v3', 'v3.0']): # For keystone v3 version projects = ks_client.projects.list() for tenant in projects: projectname = tenant.name projectid = tenant.id if projectname == stagingname: LOG.debug(_('The staging_project_name %s has id %s'), stagingname, projectid) return projectid except Exception as e: LOG.debug(_('An error occurred getting the tenant list: %s.'), e) LOG.debug(_('Unable to find staging project: %s'), stagingname) raise exception.StagingProjectNotFound(name=stagingname)
def delete_port(self, port_id): try: LOG.info(_("Delete %s port: %s"), self.os, port_id) return self.client.delete_port(port_id) except exceptions.NeutronClientException as e: LOG.exception(_("Error deleting port: %s"), e) return e
def delete_subnet(self, sub_id): try: LOG.info(_("Delete %s subnet: %s"), self.os, sub_id) return self.client.delete_subnet(sub_id) except exceptions.NeutronClientException as e: LOG.exception(_("Error deleting subnet: %s"), e) return e
def delete_network(self, net_id): try: LOG.info(_("Delete %s network: %s"), self.os, net_id) return self.client.delete_network(net_id) except exceptions.NeutronClientException as e: LOG.exception(_("Error deleting network: %s"), e) return e
def synchronize_flavors(self, ctx): """ Get a list of all public flavors from PowerVC. If it is in configuration white list, and not in black list, insert it. if it is already in local tables, ignore it. """ LOG.info(_("Flavors synchronization starts.")) # Get all public flavors. By default, detail and public is set. pvcFlavors = self.driver.list_flavors() # Sync flavors in list for flavor in pvcFlavors: LOG.info(_("Flavor:%s") % str(flavor)) greenthread.sleep(0) # This check is added to eliminate sync of private flavors # Can be removed once PowerVC fixes to return only public flavors # by default. if not (flavor.__dict__.get(constants.IS_PUBLIC)): continue if (self._check_for_sync(flavor.name)): response = self._check_for_extraspecs(flavor) if response is not None: self._sync_flavor(ctx, flavor, response[1]) LOG.info(_("Flavors synchronization ends."))
def delete_subnet(self, sub_id): try: LOG.info(_("Delete %s subnet: %s"), self.os, sub_id) return self.client.delete_subnet(sub_id) except exceptions.NeutronClientException as e: LOG.exception(_("Error deleting subnet: %s"), e) return e
def get_pvc_id_from_metadata(metadata): """ This method helps to get pvc_id from a list or dict type metadata. This util method handles the following situation of metadata: Type of list sample 1: metadata = [ {'key': 'powervm:defer_placement', 'value': 'true'}, {'key': 'pvc_id', 'value': '40e2d7c9-b510-4e10-8986-057800117714'} ] Type of list sample 2: metadata = [{ "powervm:health_status.health_value": "OK", "pvc_id": "40e2d7c9-b510-4e10-8986-057800117714" }] Type of dict sample: metadata = { "powervm:health_status.health_value": "OK", "pvc_id": "40e2d7c9-b510-4e10-8986-057800117714", "powervm:defer_placement": "Fale", "powervm:max_cpus": "1" } If none of above types match and pvc_id found, return None """ if not metadata: return None pvc_id = None if (isinstance(metadata, list)): # Try to get pvc_id from list type 1 for meta_list in metadata: if meta_list.get('key') == constants.PVC_ID: pvc_id = meta_list.get('value') LOG.info(_('Found the pvc_id from the list type 1 metadata:%s') % pvc_id) return pvc_id # If pvc_id not found in list type 1, try list type 2 for meta_dict in metadata: if constants.PVC_ID in meta_dict.keys(): pvc_id = meta_dict.get(constants.PVC_ID) LOG.info(_('Found the pvc_id from the list type 2 metadata:%s') % pvc_id) return pvc_id # If still not found pvc_id in list, return None LOG.info(_('Not found the pvc_id from the list type metadata.')) return None if (isinstance(metadata, dict)): # Try to get pvc_id from dict type if constants.PVC_ID in metadata.keys(): pvc_id = metadata.get(constants.PVC_ID) LOG.info(_('Find the pvc_id from the dict type metadata: %s') % pvc_id) return pvc_id else: LOG.info(_('Not found the pvc_id from the dict type metadata.')) return None
def get_by_id(self, pvc_id, default=None): self._cache_resources() if (len(self._cache) != 0): if pvc_id in self._cache: LOG.info(_("Found volume id equals: '%s'" % pvc_id)) return self._cache[pvc_id] LOG.info(_("No volume found which equals: '%s'" % pvc_id)) return default
def new_local_servicecatalog(): LOG.info(_('start to new local keystone client')) keystone_version = CONF['openstack']['keystone_version'] keystone = service.KeystoneService(str(SERVICE_TYPES.identity), keystone_version, OS_OPTS['auth_url'], OS_OPTS, None).new_client() servicecatalog = service.ClientServiceCatalog(OS_OPTS, keystone) LOG.info(_('finish to new local keystone client')) return servicecatalog
def by_name(self, name, default=None): """ Returns the SCG by name """ self._cache_resources() if (len(self._cache) != 0): if name in self._cache: LOG.info(_("Found scg which name equals: '%s'" % name)) return self._cache[name] LOG.info(_("No scg found which equals name: '%s'" % name)) return default
def _handle_subnet_create(self, context, message): event, payload = self._extact_event_payload(message) subnet = payload.get('subnet') subnet_id = subnet.get('id') if not utils.is_subnet_mappable(subnet): LOG.info(_("Subnet %s is not mappable"), subnet_id) return db_sub = self.db.get_subnet(pvc_id=subnet_id) if db_sub: LOG.info(_("DB entry for subnet %s already exists"), subnet_id) return self.agent.queue_event(self.os, event, subnet)
def set_port_device_id(self, port, device_id): body = {} body['device_id'] = device_id request = {} request['port'] = body try: LOG.info(_("Update %s port: %s"), self.os, body) return self.client.update_port(port['id'], request) except exceptions.NeutronClientException as e: LOG.exception(_("Error updating port: %s"), e) return None return None
def _handle_network_create(self, context, message): event, payload = self._extact_event_payload(message) network = payload.get('network') network_id = network.get('id') if not utils.is_network_mappable(network): LOG.info(_("Network %s is not mappable"), network_id) return db_net = self.db.get_network(pvc_id=network_id) if db_net: LOG.info(_("DB entry for network %s already exists"), network_id) return self.agent.queue_event(self.os, event, network)
def by_id(self, scg_id, default=None): """ Returns the SCG by id """ self._cache_resources() if (len(self._cache) != 0): for scg in self.list(): if scg.id == scg_id: LOG.info(_("Found scg which equals id: '%s'" % scg_id)) return scg LOG.info(_("No scg found which equals id: '%s'" % scg_id)) return default
def set_port_device_id(self, port, device_id): body = {} body['device_id'] = device_id request = {} request['port'] = body try: LOG.info(_("Update %s port: %s"), self.os, body) return self.client.update_port(port['id'], request) except exceptions.NeutronClientException as e: LOG.exception(_("Error updating port: %s"), e) return None return None
def _handle_port_create(self, context, message): event, payload = self._extact_event_payload(message) port = payload.get('port') port_id = port.get('id') if not utils.is_port_mappable(port): LOG.info(_("Port %s is not mappable"), port_id) return db_port = self.db.get_port(pvc_id=port_id) if db_port: LOG.info(_("DB entry for port %s already exists"), port_id) return self.agent.queue_event(self.os, event, port)
def get_scg_accessible_volumes(self, scgUUID=None, scgName=None, detailed=True, search_opts=None): """ Get SCG accessible volumes providers by specified SCG UUID or scgName, If both SCG UUID and SCG Name are specified specified, UUID is prior, If none of SCG UUID and Name specified, get the first SCG from powerVC """ scg = None # If no scgUUID specified. if not scgUUID: if scgName: # If scgName specified, then search by scgName scg = self.get_scg_by_scgName(scgName) else: # If scgName not specified, get the SCG from the value # configured in powervc.conf scg = self.get_configured_scg() else: LOG.debug(_("Specified scgUUID: '%s'" % scgUUID)) # retrieve scg by scgUUID scg = self.scg_cache.by_id(scgUUID) if not scg: # If no scg, then it's a IVM based PowerVC, # return all volumes return (self._cinderclient.volumes.list_all_volumes()) # accessible_storage_volumes to return accessible_storage_volumes = [] volumes = scg.list_all_volumes() volume_ids = [] for vol in volumes: volume_ids.append(vol.__dict__.get("id")) all_volumes = \ self._cinderclient.volumes.list_all_volumes(detailed, search_opts) for storage_volume in all_volumes: if(storage_volume.__dict__.get("id") in volume_ids): metadata = storage_volume.__dict__.get("metadata") if(metadata is not None): is_boot_volume = metadata.get("is_boot_volume") is_image_volume = metadata.get("is_image_volume") # Filter out the boot volumes if(is_boot_volume != "True" or is_image_volume == "True"): accessible_storage_volumes.append(storage_volume) else: accessible_storage_volumes.append(storage_volume) LOG.info(_('accessible_storage_volumes: %s' % ( accessible_storage_volumes))) return accessible_storage_volumes
def is_instance_on_power(self, uuid): """ Return True if an instance is hosted on power. """ # Verify uuid is valid if not uuid or len(uuid) == 0: return False if not self.nova: self.nova = factory.LOCAL.get_client(str(SERVICE_TYPES.compute)) try: inst = self.nova.manager.get(uuid) except Exception as e: """ If the instance can not be found, exception will be thrown. These exceptions should be caught and not break the agent. """ LOG.exception(_("Exception occurred getting server %s: %s"), uuid, e) return False if inst: metadata = inst._info[constants.METADATA] if constants.PVC_ID in metadata: # Return true if we have pvc_id for this instance. return True else: img_uuid = inst.image.get('id', '') if img_uuid in self.power_image_cache: return True else: # Check if the image is hosted on power. if not self.glance: self.glance = factory.LOCAL.\ get_client(str(SERVICE_TYPES.image)) try: img = self.glance.getImage(img_uuid) except Exception as e: LOG.exception( _("Exception occurred getting image " "%s: %s"), img_uuid, e) return False if constants.POWERVM == img.get(constants.HYPERVISOR_TYPE, ''): self.power_image_cache.append(img_uuid) return True return False # Return false if we can't find this instance locally. return False
def _handle_network_create(self, context=None, ctxt=None, event_type=None, payload=None): network = payload.get('network') network_id = network.get('id') if not utils.is_network_mappable(network): LOG.info(_("Network %s is not mappable"), network_id) return db_net = self.db.get_network(local_id=network_id) if db_net: LOG.info(_("DB entry for network %s already exists"), network_id) return self.agent.queue_event(self.os, event_type, network)
def _handle_network_create(self, context=None, ctxt=None, event_type=None, payload=None): network = payload.get('network') network_id = network.get('id') if not utils.is_network_mappable(network): LOG.info(_("Network %s is not mappable"), network_id) return db_net = self.db.get_network(local_id=network_id) if db_net: LOG.info(_("DB entry for network %s already exists"), network_id) return self.agent.queue_event(self.os, event_type, network)
def is_instance_valid(self, uuid): """ Check if this VM instance is still valid. Call nova client to retrieve the VM information. """ # Verify uuid is valid if not uuid or len(uuid) == 0: return False # Check to see if this is a reserved port that we created while we # are waiting for the PowerVC side to go away if uuid.startswith(constants.RSVD_PORT_PREFIX)\ or uuid == constants.POWERVC_LOCKDEVICE_ID: return False if not self.nova: self.nova = factory.LOCAL.get_client(str(SERVICE_TYPES.compute)) try: inst = self.nova.manager.get(uuid) except Exception as e: """ If the instance can not be found, exception will be thrown. These exceptions should be caught and not break the agent. """ LOG.exception(_("Exception occurred getting server %s: %s"), uuid, e) return False if inst: return True return False
def _handle_port_create(self, context=None, ctxt=None, event_type=None, payload=None): port = payload.get('port') port_id = port.get('id') if not utils.is_port_mappable(port): LOG.info(_("Port %s is not mappable"), port_id) return db_port = self.db.get_port(local_id=port_id) if db_port: LOG.info(_("DB entry for port %s already exists"), port_id) return self.agent.queue_event(self.os, event_type, port)
def _handle_subnet_create(self, context=None, ctxt=None, event_type=None, payload=None): subnet = payload.get('subnet') subnet_id = subnet.get('id') if not utils.is_subnet_mappable(subnet): LOG.info(_("Subnet %s is not mappable"), subnet_id) return db_sub = self.db.get_subnet(local_id=subnet_id) if db_sub: LOG.info(_("DB entry for subnet %s already exists"), subnet_id) return self.agent.queue_event(self.os, event_type, subnet)
def _create_amqp_listeners(self): """Listen for AMQP messages from PowerVC""" LOG.debug(_('Creating AMQP listeners')) def reconnect(): LOG.info(_('Re-established connection to PowerVC Qpid broker')) self.agent.queue_event(self.os, constants.EVENT_FULL_SYNC, None) connection = messaging.PowerVCConnection(log=logging, reconnect_handler=reconnect) listener = connection.create_listener(constants.QPID_EXCHANGE, constants.QPID_TOPIC) listener.register_handler(constants.EVENT_NETWORK_CREATE, self._handle_network_create) listener.register_handler(constants.EVENT_NETWORK_UPDATE, self._handle_network_update) listener.register_handler(constants.EVENT_NETWORK_DELETE, self._handle_network_delete) listener.register_handler(constants.EVENT_SUBNET_CREATE, self._handle_subnet_create) listener.register_handler(constants.EVENT_SUBNET_UPDATE, self._handle_subnet_update) listener.register_handler(constants.EVENT_SUBNET_DELETE, self._handle_subnet_delete) listener.register_handler(constants.EVENT_PORT_CREATE, self._handle_port_create) listener.register_handler(constants.EVENT_PORT_UPDATE, self._handle_port_update) listener.register_handler(constants.EVENT_PORT_DELETE, self._handle_port_delete) connection.start()
def get_host_maintenance_mode(self, hostname): """Get host maintenance mode by host name from PowerVC driver """ # If cannot find hypervisor by hostname, will raise # itemNotFoundException from novaclient, just raise # to upper layer to handle. hypervisors = self.search(hostname) if not hypervisors[0] or not self.get(hypervisors[0]): raise exc.HTTPNotFound(_("No hypervisor matching '%s' could be" " found.") % hostname) try: hypervisor = self.get(hypervisors[0]) except Exception as ex: raise exc.HTTPNotFound(explanation=six.text_type(ex)) # Either "ok" (maintenance off), "entering", "on" or "error" # compatible with previous powervc version, if no such property # set as "ok" maintenance_status = getattr(hypervisor, "maintenance_status", "ok") # Either the empty string (i.e., not in maintenance), # "none": dont migrate anything # "active-only": migrate active-only vm # "all": migrate all vm maintenance_migration_action = \ getattr(hypervisor, "maintenance_migration_action", "none") return {"maintenance_status": maintenance_status, "maintenance_migration_action": maintenance_migration_action}
def start(self): """ This method retrieves all services from PowerVC and for each service it creates a local nova-compute service. """ try: remote_services = self._get_filtered_remote_services() for remote_service in remote_services: eventlet.greenthread.sleep(0) self.new_compute_service(remote_service) if self.auto_refresh: refresher = loopingcall.FixedIntervalLoopingCall(self.refresh) refresher.start( interval=CONF.powervc.hypervisor_refresh_interval) LOG.info(_('The PowerVC compute service manager is running.')) self.running = True except Exception: LOG.exception("exception during startup. Stopping compute" "driver") traceback.print_exc() sys.exit(1)
def update_host_maintenance_mode(self, hostname, enabled, migrate=None, target_host=None): """Update host maintenance mode status. :hostname: The hostname of the hypervisor :enabled: should be "enable" or "disable" :migrate: should be "none", do not migrate any vm "active-only", migrate only active vm "all", migrate all vm """ # Refer to PowerVC HLD host maintenance mode chapter url = "/ego/prs/hypervisor_maintenance/%s" % hostname if not migrate: body = {"status": enabled} else: if target_host: body = {"status": enabled, "migrate": migrate, "target_host": target_host} else: body = {"status": enabled, "migrate": migrate} # send set maintenance mode request by put http method try: _resp, resp_body = self.api.client.put(url, body=body) except Exception as ex: raise exc.HTTPBadRequest(explanation=six.text_type(ex)) # check response content if "hypervisor_maintenance" not in resp_body: raise exceptions.NotFound(_("response body doesn't contain " "maintenance status info for %s.") % hostname) return resp_body
def _update_volume_status(self): """ Retrieve volumes stats info from powervc. For now just make something up """ LOG.debug(_("Getting volume stats from powervc")) # get accessible storage providers list sp_list = self._list_storage_providers() free_capacity_gb = 0 total_capacity_gb = 0 for sp in sp_list: free_capacity_gb += getattr(sp, 'free_capacity_gb', 0) total_capacity_gb += getattr(sp, 'total_capacity_gb', 0) data = {} data["volume_backend_name"] = constants.POWERVC_VOLUME_BACKEND data["vendor_name"] = 'IBM' data["driver_version"] = 1.0 data["storage_protocol"] = 'Openstack' data['total_capacity_gb'] = total_capacity_gb data['free_capacity_gb'] = free_capacity_gb data['reserved_percentage'] = 0 data['QoS_support'] = False self._stats = data LOG.debug(self._stats)
def get_pvc_network_uuid(self, network_id): LOG.info(_('get_pvc_network_uuid')) result = self.call(self.context, self.make_msg('get_pvc_network_uuid', network_id=network_id), topic=self.topic) return result
def _create_flavor(self, context, flavor): """ Create and insert the flavor """ flavor_dict = flavor.__dict__ name = self.prefix + flavor.name flavorid = self.prefix + flavor.id memory = flavor.ram vcpus = flavor.vcpus root_gb = flavor.disk ephemeral_gb = flavor_dict.get('OS-FLV-EXT-DATA:ephemeral', 0) u_swap = flavor_dict.get('swap', 0) rxtx_factor = flavor_dict.get('rxtx_factor', 1.0) is_public = flavor_dict.get('os-flavor-access:is_public', True) if u_swap == "": swap = 0 else: swap = int(u_swap) try: return flavors.create(name, memory, vcpus, root_gb, ephemeral_gb=ephemeral_gb, flavorid=flavorid, swap=swap, rxtx_factor=rxtx_factor, is_public=is_public) except Exception as exc: LOG.error(_("Unable to sync flavor " + str(name) + ". " + str(exc.format_message()))) return None
def register_models(self): """Register Models and create properties.""" try: engine = db_api.get_engine() model.PowerVCMapping.metadata.create_all(engine) except sql.exc.OperationalError as e: LOG.info(_("Database registration exception: %s"), e)
def get_pvc_network_uuid(self, network_id): LOG.debug(_('get_pvc_network_uuid')) result = self.call(self.context, self.make_msg('get_pvc_network_uuid', network_id=network_id), topic=self.topic) print 'Result from RPC call:', result
def __init__(self, context): LOG.info(_('__init__')) self.topic = 'powervcrpc' self.context = context self.host = cfg.CONF.host super(RpcClient, self).__init__( topic=self.topic, default_version=self.BASE_RPC_API_VERSION)
def fix_incorrect_state(self, obj): """Correct state error on the database entry""" LOG.warning(_("DB entry is not in correct state: %s"), obj) if not obj: return try: obj_id = obj['id'] obj = (self.session.query(model.PowerVCMapping). filter_by(id=obj_id).one()) if obj['pvc_id'] and obj['local_id']: obj['status'] = constants.STATUS_ACTIVE LOG.info(_("Updated DB entry state: %s"), obj) self.session.merge(obj) self.session.flush except exc.NoResultFound: LOG.warning(_("Object not found")) return None
def set_pvc_id_to_port(self, context, local_port_id, pvc_port_id): LOG.info(_("Neutron Agent RPC: start set pvc id to port:")) # Sometimes for db session data delay, repeat 3 times to get the # latest port info from local neutron db. local_port = None fetchTimes = 0 while True: local_port = self.db.get_port(local_id=local_port_id) # Delay 3 times, each 10 sec to fetch the local port db obj if local_port or fetchTimes >= 2: break fetchTimes += 1 LOG.info(_("Cannot get port from local temporarily, wait 10sec..")) time.sleep(10) self.db.set_port_pvc_id(local_port, pvc_port_id) LOG.info(_("End of set powervc uuid to port."))
def main(): try: config.parse_power_config(sys.argv, 'powervc-neutron') logging_config.setup_logging(cfg.CONF) LOG.info(_('Create RPC interface')) ctx = context.get_admin_context_without_session() rpc = RpcClient(ctx) LOG.info(_('Calling RPC method')) result = rpc.get_pvc_network_uuid('abc') LOG.info(_('Result from RPC call: %s'), result) sys.exit(0) except Exception: traceback.print_exc() raise
def update_network(self, net_dest, net_src): body = {} request = None for field in constants.NETWORK_UPDATE_FIELDS: if net_src[field] != net_dest[field]: body[field] = net_src[field] if not request: request = {} request['network'] = body if request: try: LOG.info(_("Update %s network: %s"), self.os, body) return self.client.update_network(net_dest['id'], request) except exceptions.NeutronClientException as e: LOG.exception(_("Error updating network: %s"), e) return None return None
class StagingUserNotFound(CommonException): """ Exception thrown when the staging user specified in the conf cannot be found. :param name: The name of the staging user which was not found. """ message = _('The staging user \'%(name)s\' was not found.')
def update_subnet(self, sub_dest, sub_src): body = {} request = None for field in constants.SUBNET_UPDATE_FIELDS: if sub_src[field] != sub_dest[field]: body[field] = sub_src[field] if not request: request = {} request['subnet'] = body if request: try: LOG.info(_("Update %s subnet: %s"), self.os, body) return self.client.update_subnet(sub_dest['id'], request) except exceptions.NeutronClientException as e: LOG.exception(_("Error updating subnet: %s"), e) return None return None
def create_network(self, net): body = {} for field in constants.NETWORK_CREATE_FIELDS: if field in net: body[field] = net[field] request = {} request['network'] = body try: LOG.info(_("Create %s network: %s"), self.os, body) response = self.client.create_network(request) if response and 'network' in response: return response.get('network') return None except exceptions.NeutronClientException as e: LOG.exception(_("Error creating network: %s\nError message: %s"), body, e) return None
def update_port(self, port_dest, port_src): body = {} request = None for field in constants.PORT_UPDATE_FIELDS: if port_src[field] != port_dest[field]: body[field] = port_src[field] if not request: request = {} request['port'] = body if request: try: LOG.info(_("Update %s port: %s"), self.os, body) return self.client.update_port(port_dest['id'], request) except exceptions.NeutronClientException as e: LOG.exception(_("Error updating port: %s"), e) return None return None
class StorageConnectivityGroupNotFound(CommonException): """ Exception thrown when the PowerVC Storage Connectivity Group specified cannot be found. :param scg: The PowerVC Storage Connectivity Group name or id """ message = _('The PowerVC Storage Connectivity Group \'%(scg)s\' was not ' 'found.')
def set_device_id_on_port_by_pvc_instance_uuid(self, context, device_id, pvc_ins_uuid): """ Query the ports by pvc instance uuid, and set its local instance id(device_id). """ LOG.info(_("Neutron Agent RPC: " "set_device_id_on_port_by_pvc_instance_uuid:")) LOG.info(_("- device_id: %s"), device_id) LOG.info(_("- pvc_ins_uuid: %s"), pvc_ins_uuid) local_ids = self.agent.\ set_device_id_on_port_by_pvc_instance_uuid(self.db, device_id, pvc_ins_uuid) LOG.info(_("- local_ids: %s"), local_ids) return local_ids