diff --git a/common-powervc/powervc/common/client/extensions/nova.py b/common-powervc/powervc/common/client/extensions/nova.py index 4d575d3..4cceade 100644 --- a/common-powervc/powervc/common/client/extensions/nova.py +++ b/common-powervc/powervc/common/client/extensions/nova.py @@ -15,6 +15,7 @@ from powervc.common.gettextutils import _ from powervc.common import utils from webob import exc import logging +import json LOG = logging.getLogger(__name__) @@ -266,6 +267,11 @@ class PVCServerManager(servers.ServerManager): if key_name: body["server"]["key_name"] = key_name if scheduler_hints: + try: + scheduler_hints = json.loads(scheduler_hints) + except: + LOG.info(_("cannot convert s_hints to json object %s" % + scheduler_hints)) body['os:scheduler_hints'] = scheduler_hints if config_drive: body["server"]["config_drive"] = config_drive @@ -348,6 +354,8 @@ class PVCServerManager(servers.ServerManager): all_net_data.append(net_data) body['server']['networks'] = all_net_data + LOG.info(_("boot vm from pvc driver, body str is %s" % body)) + return self._create(resource_url, body, response_key, return_raw=return_raw, **kwargs) diff --git a/nova-powervc/powervc/nova/driver/virt/powervc/driver.py b/nova-powervc/powervc/nova/driver/virt/powervc/driver.py index c4aa2bf..d5da966 100644 --- a/nova-powervc/powervc/nova/driver/virt/powervc/driver.py +++ b/nova-powervc/powervc/nova/driver/virt/powervc/driver.py @@ -243,6 +243,9 @@ class PowerVCDriver(driver.ComputeDriver): # check if the host selection will be defer to PowerVC isDefer = self._check_defer_placement(instance) + # get scheduler hint if set in metadata + scheduler_hints = self._get_scheduler_hints(instance) + # If hosting OS decide to select one host, # get the PowerVC Hypervisor host name # else the host name will be ignore @@ -275,7 +278,8 @@ class PowerVCDriver(driver.ComputeDriver): nics=pvc_nics, hypervisorID=pvcHypervisor, availability_zone=pvcAvailabilityZone, - isDefer=isDefer) + isDefer=isDefer, + scheduler_hints=scheduler_hints) except BadRequest as e1: with excutils.save_and_reraise_exception(): self._clean_vm_and_save_fault_message(e1, e1.message, @@ -1469,6 +1473,36 @@ class PowerVCDriver(driver.ComputeDriver): return isDefer + def _get_scheduler_hints(self, instance): + """ + Get instance meta data from instance + such as "powervm:scheduler_hints" : "xxx" + """ + # The instance metatdata can be of multiple forms. + # Handle cases : dict, list of class InstanceMetadata + def get_scheduler_hints_key_value(meta): + if isinstance(meta, dict): + for key in meta: + scheduler_hints_val = meta[key] + if key == u'powervm:scheduler_hints': + return scheduler_hints_val + else: + for entry in meta: + scheduler_hints_key = entry.get('key', None) + scheduler_hints_val = entry.get('value', None) + if scheduler_hints_key == u'powervm:scheduler_hints': + return scheduler_hints_val + + scheduler_hints = None + # During spawn a vm, by default is defer=true + meta = instance.get('metadata', None) + if meta: + scheduler_hints = get_scheduler_hints_key_value(meta) + + if scheduler_hints: + LOG.info(_("Boot Scheduler hints: %s.") % scheduler_hints) + return scheduler_hints + def get_pvc_flavor_by_flavor_id(self, flavor): """ Get detailed info of the flavor from the PowerVC diff --git a/nova-powervc/powervc/nova/driver/virt/powervc/service.py b/nova-powervc/powervc/nova/driver/virt/powervc/service.py index f2363b8..81318d8 100644 --- a/nova-powervc/powervc/nova/driver/virt/powervc/service.py +++ b/nova-powervc/powervc/nova/driver/virt/powervc/service.py @@ -615,7 +615,8 @@ class PowerVCService(object): orig_instance) def spawn(self, context, instance, injected_files, name, imageUUID, - flavorDict, nics, hypervisorID, availability_zone, isDefer): + flavorDict, nics, hypervisorID, availability_zone, isDefer, + scheduler_hints): """Call pvcnovaclient to boot a VM on powerVC :param context: admin context :param instance: passed-in instance @@ -671,7 +672,8 @@ class PowerVCService(object): config_drive=config_drive, nics=nics, hypervisor=hypervisorID, - availability_zone=availability_zone) + availability_zone=availability_zone, + scheduler_hints=scheduler_hints) LOG.debug(_('Exit to invoke powervc api to deploy instance of %s,' 'isDefer status is %s') % (name, isDefer)) else: @@ -688,7 +690,8 @@ class PowerVCService(object): # support key_data, # key_data = key_data, config_drive=config_drive, - nics=nics) + nics=nics, + scheduler_hints=scheduler_hints) LOG.debug(_('Exit to invoke powervc api to deploy instance of %s,' 'isDefer status is %s') % (name, isDefer))