Added support for OpenStack Ocata to NovaManager
This commit updates NovaManager for supporting the Ocata version BUG: #1704801 Change-Id: Icad9c14b14f34d16861caf82845b0e847085556c Sem-Ver: feature
This commit is contained in:
parent
94456be8fc
commit
5f28805ca7
@ -11,12 +11,6 @@ rate = 1
|
|||||||
# this allows Synergy to not check the whole queue when looking for VMs to start
|
# this allows Synergy to not check the whole queue when looking for VMs to start
|
||||||
backfill_depth = 100
|
backfill_depth = 100
|
||||||
|
|
||||||
# set the notification topic used by Nova for informing listeners about the state
|
|
||||||
# changes of the VMs. In case some other service (e.g. Ceilometer) is listening
|
|
||||||
# on the default Nova topic (i.e. "notifications"), please define a new topic
|
|
||||||
specific for Synergy (e.g. notification_topics = notifications,synergy_notifications)
|
|
||||||
notification_topic = notifications
|
|
||||||
|
|
||||||
|
|
||||||
[FairShareManager]
|
[FairShareManager]
|
||||||
autostart = True
|
autostart = True
|
||||||
@ -139,7 +133,13 @@ conductor_topic = conductor
|
|||||||
compute_topic = compute
|
compute_topic = compute
|
||||||
|
|
||||||
# set the Nova scheduler topic (default: scheduler)
|
# set the Nova scheduler topic (default: scheduler)
|
||||||
|
|
||||||
scheduler_topic = scheduler
|
scheduler_topic = scheduler
|
||||||
|
# set the notification topic used by Nova for informing listeners about the state
|
||||||
|
# changes of the VMs. In case some other service (e.g. Ceilometer) is listening
|
||||||
|
# on the default Nova topic (i.e. "notifications"), please define a new topic
|
||||||
|
specific for Synergy (e.g. notification_topics = notifications,synergy_notifications)
|
||||||
|
notification_topic = notification
|
||||||
|
|
||||||
# set the Nova database connection
|
# set the Nova database connection
|
||||||
db_connection=DIALECT+DRIVER://USER:PASSWORD@DB_HOST/nova
|
db_connection=DIALECT+DRIVER://USER:PASSWORD@DB_HOST/nova
|
||||||
|
@ -26,160 +26,122 @@ permissions and limitations under the License."""
|
|||||||
class Request(object):
|
class Request(object):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
self.id = None
|
||||||
|
self.user_id = None
|
||||||
|
self.project_id = None
|
||||||
|
self.action = None
|
||||||
|
self.data = None
|
||||||
self.context = None
|
self.context = None
|
||||||
self.instance = None
|
self.server = None
|
||||||
self.image = None
|
self.retry = None
|
||||||
self.filter_properties = None
|
self.created_at = None
|
||||||
self.admin_password = None
|
|
||||||
self.injected_files = None
|
|
||||||
self.requested_networks = None
|
|
||||||
self.security_groups = None
|
|
||||||
self.block_device_mapping = None
|
|
||||||
self.legacy_bdm = None
|
|
||||||
|
|
||||||
def getAdminPassword(self):
|
def getAction(self):
|
||||||
return self.admin_password
|
return self.action
|
||||||
|
|
||||||
def getId(self):
|
|
||||||
if self.instance:
|
|
||||||
return self.instance["nova_object.data"]["uuid"]
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
def getInstance(self):
|
|
||||||
return self.instance
|
|
||||||
|
|
||||||
def getServer(self):
|
|
||||||
server = None
|
|
||||||
|
|
||||||
if self.instance:
|
|
||||||
instance_data = self.instance["nova_object.data"]
|
|
||||||
flavor_data = instance_data["flavor"]["nova_object.data"]
|
|
||||||
|
|
||||||
flavor = Flavor()
|
|
||||||
flavor.setId(flavor_data["flavorid"])
|
|
||||||
flavor.setName(flavor_data["name"])
|
|
||||||
flavor.setMemory(flavor_data["memory_mb"])
|
|
||||||
flavor.setVCPUs(flavor_data["vcpus"])
|
|
||||||
flavor.setStorage(flavor_data["root_gb"])
|
|
||||||
|
|
||||||
server = Server()
|
|
||||||
server.setFlavor(flavor)
|
|
||||||
server.setId(instance_data["uuid"])
|
|
||||||
server.setUserId(instance_data["user_id"])
|
|
||||||
server.setProjectId(instance_data["project_id"])
|
|
||||||
server.setCreatedAt(instance_data["created_at"])
|
|
||||||
server.setMetadata(instance_data["metadata"])
|
|
||||||
server.setKeyName(instance_data["key_name"])
|
|
||||||
|
|
||||||
if "user_data" in instance_data:
|
|
||||||
user_data = instance_data["user_data"]
|
|
||||||
if user_data:
|
|
||||||
server.setUserData(utils.decodeBase64(user_data))
|
|
||||||
|
|
||||||
return server
|
|
||||||
|
|
||||||
def getImage(self):
|
|
||||||
return self.image
|
|
||||||
|
|
||||||
def getUserId(self):
|
|
||||||
if self.instance:
|
|
||||||
return self.instance["nova_object.data"]["user_id"]
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
def getProjectId(self):
|
|
||||||
if self.instance:
|
|
||||||
return self.instance["nova_object.data"]["project_id"]
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
def getContext(self):
|
def getContext(self):
|
||||||
return self.context
|
return self.context
|
||||||
|
|
||||||
def getCreatedAt(self):
|
def getCreatedAt(self):
|
||||||
if self.instance:
|
return self.created_at
|
||||||
created_at = self.instance["nova_object.data"]["created_at"]
|
|
||||||
timestamp = datetime.strptime(created_at, "%Y-%m-%dT%H:%M:%SZ")
|
|
||||||
return timestamp
|
|
||||||
|
|
||||||
return 0
|
def getData(self):
|
||||||
|
return self.data
|
||||||
|
|
||||||
def getMetadata(self):
|
def getId(self):
|
||||||
if self.instance:
|
return self.id
|
||||||
return self.instance["nova_object.data"]["metadata"]
|
|
||||||
|
|
||||||
return None
|
def getServer(self):
|
||||||
|
return self.server
|
||||||
|
|
||||||
|
def getUserId(self):
|
||||||
|
return self.user_id
|
||||||
|
|
||||||
|
def getProjectId(self):
|
||||||
|
return self.project_id
|
||||||
|
|
||||||
def getRetry(self):
|
def getRetry(self):
|
||||||
if self.filter_properties:
|
return self.retry
|
||||||
return self.filter_properties.get("retry", None)
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
def getFilterProperties(self):
|
|
||||||
return self.filter_properties
|
|
||||||
|
|
||||||
def getInjectedFiles(self):
|
|
||||||
return self.injected_files
|
|
||||||
|
|
||||||
def getRequestedNetworks(self):
|
|
||||||
return self.requested_networks
|
|
||||||
|
|
||||||
def getSecurityGroups(self):
|
|
||||||
return self.security_groups
|
|
||||||
|
|
||||||
def getBlockDeviceMapping(self):
|
|
||||||
return self.block_device_mapping
|
|
||||||
|
|
||||||
def getLegacyBDM(self):
|
|
||||||
return self.legacy_bdm
|
|
||||||
|
|
||||||
def toDict(self):
|
def toDict(self):
|
||||||
request = {}
|
request = {}
|
||||||
|
request['action'] = self.action
|
||||||
request['context'] = self.context
|
request['context'] = self.context
|
||||||
request['instance'] = self.instance
|
request['data'] = self.data
|
||||||
request['image'] = self.image
|
|
||||||
request['filter_properties'] = self.filter_properties
|
|
||||||
request['admin_password'] = self.admin_password
|
|
||||||
request['injected_files'] = self.injected_files
|
|
||||||
request['requested_networks'] = self.requested_networks
|
|
||||||
request['security_groups'] = self.security_groups
|
|
||||||
request['block_device_mapping'] = self.block_device_mapping
|
|
||||||
request['legacy_bdm'] = self.legacy_bdm
|
|
||||||
|
|
||||||
return request
|
return request
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def fromDict(cls, request_dict):
|
def fromDict(cls, request_dict):
|
||||||
request = Request()
|
request = Request()
|
||||||
request.context = request_dict['context']
|
request.data = request_dict["data"]
|
||||||
request.instance = request_dict['instance']
|
request.action = request_dict["action"]
|
||||||
request.image = request_dict['image']
|
request.context = request_dict["context"]
|
||||||
request.filter_properties = request_dict['filter_properties']
|
|
||||||
request.admin_password = request_dict['admin_password']
|
if "instances" in request.data:
|
||||||
request.injected_files = request_dict['injected_files']
|
instance = request.data["instances"][0]
|
||||||
request.requested_networks = request_dict['requested_networks']
|
else:
|
||||||
request.security_groups = request_dict['security_groups']
|
build_request = request.data["build_requests"][0]
|
||||||
request.block_device_mapping = request_dict['block_device_mapping']
|
instance = build_request["nova_object.data"]["instance"]
|
||||||
request.legacy_bdm = request_dict['legacy_bdm']
|
|
||||||
|
instance_data = instance["nova_object.data"]
|
||||||
return request
|
|
||||||
|
request.id = instance_data["uuid"]
|
||||||
@classmethod
|
request.user_id = instance_data["user_id"]
|
||||||
def build(cls, context, instance, image, filter_properties,
|
request.project_id = instance_data["project_id"]
|
||||||
admin_password, injected_files, requested_networks,
|
|
||||||
security_groups, block_device_mapping=None, legacy_bdm=True):
|
created_at = instance_data["created_at"]
|
||||||
request = Request()
|
request.created_at = datetime.strptime(created_at,
|
||||||
request.context = context
|
"%Y-%m-%dT%H:%M:%SZ")
|
||||||
request.instance = instance
|
|
||||||
request.image = image
|
flavor_data = instance_data["flavor"]["nova_object.data"]
|
||||||
request.filter_properties = filter_properties
|
flavor = Flavor()
|
||||||
request.admin_password = admin_password
|
flavor.setId(flavor_data["flavorid"])
|
||||||
request.injected_files = injected_files
|
flavor.setName(flavor_data["name"])
|
||||||
request.requested_networks = requested_networks
|
flavor.setMemory(flavor_data["memory_mb"])
|
||||||
request.security_groups = security_groups
|
flavor.setVCPUs(flavor_data["vcpus"])
|
||||||
request.block_device_mapping = block_device_mapping
|
flavor.setStorage(flavor_data["root_gb"])
|
||||||
request.legacy_bdm = legacy_bdm
|
|
||||||
|
server = Server()
|
||||||
|
server.setFlavor(flavor)
|
||||||
|
server.setId(instance_data["uuid"])
|
||||||
|
server.setUserId(instance_data["user_id"])
|
||||||
|
server.setProjectId(instance_data["project_id"])
|
||||||
|
server.setCreatedAt(instance_data["created_at"])
|
||||||
|
server.setMetadata(instance_data["metadata"])
|
||||||
|
server.setKeyName(instance_data["key_name"])
|
||||||
|
|
||||||
|
user_data = instance_data.get("user_data", None)
|
||||||
|
if user_data:
|
||||||
|
try:
|
||||||
|
data = utils.decodeBase64(user_data)
|
||||||
|
quota = utils.getConfigParameter(data, "quota", "synergy")
|
||||||
|
if not quota:
|
||||||
|
quota = utils.getConfigParameter(data, "quota")
|
||||||
|
|
||||||
|
metadata = instance_data.get("metadata", {})
|
||||||
|
|
||||||
|
if quota is None or quota == "private" or quota != "shared":
|
||||||
|
server.setType("permanent")
|
||||||
|
metadata["quota"] = "private"
|
||||||
|
|
||||||
|
elif quota == "shared":
|
||||||
|
server.setType("ephemeral")
|
||||||
|
metadata["quota"] = "shared"
|
||||||
|
except Exception:
|
||||||
|
server.setType("permanent")
|
||||||
|
metadata["quota"] = "private"
|
||||||
|
request.server = server
|
||||||
|
|
||||||
|
if "filter_properties" in request.data:
|
||||||
|
filter_properties = request.data["filter_properties"]
|
||||||
|
request.retry = filter_properties["retry"]
|
||||||
|
else:
|
||||||
|
request_spec = request.data["request_specs"][0]
|
||||||
|
nova_object = request_spec["nova_object.data"]
|
||||||
|
request.retry = nova_object["retry"]
|
||||||
|
|
||||||
|
if not request.retry:
|
||||||
|
request.retry = {}
|
||||||
|
|
||||||
return request
|
return request
|
||||||
|
@ -42,18 +42,101 @@ LOG = logging.getLogger(__name__)
|
|||||||
CONF = cfg.CONF
|
CONF = cfg.CONF
|
||||||
|
|
||||||
|
|
||||||
|
class ServerEventHandler(object):
|
||||||
|
|
||||||
|
def __init__(self, nova_manager):
|
||||||
|
super(ServerEventHandler, self).__init__()
|
||||||
|
|
||||||
|
self.nova_manager = nova_manager
|
||||||
|
|
||||||
|
def _makeServer(self, server_info):
|
||||||
|
if not server_info:
|
||||||
|
return
|
||||||
|
|
||||||
|
flavor = Flavor()
|
||||||
|
flavor.setMemory(server_info["memory_mb"])
|
||||||
|
flavor.setVCPUs(server_info["vcpus"])
|
||||||
|
flavor.setStorage(server_info["root_gb"])
|
||||||
|
|
||||||
|
if "instance_type" in server_info:
|
||||||
|
flavor.setName(server_info["instance_type"])
|
||||||
|
|
||||||
|
server = Server()
|
||||||
|
server.setFlavor(flavor)
|
||||||
|
server.setUserId(server_info["user_id"])
|
||||||
|
server.setMetadata(server_info["metadata"])
|
||||||
|
server.setDeletedAt(server_info["deleted_at"])
|
||||||
|
server.setTerminatedAt(server_info["terminated_at"])
|
||||||
|
|
||||||
|
if "host" in server_info:
|
||||||
|
server.setHost(server_info["host"])
|
||||||
|
|
||||||
|
if "uuid" in server_info:
|
||||||
|
server.setId(server_info["uuid"])
|
||||||
|
elif "instance_id" in server_info:
|
||||||
|
server.setId(server_info["instance_id"])
|
||||||
|
|
||||||
|
if "project_id" in server_info:
|
||||||
|
server.setProjectId(server_info["project_id"])
|
||||||
|
elif "tenant_id" in server_info:
|
||||||
|
server.setProjectId(server_info["tenant_id"])
|
||||||
|
|
||||||
|
if "vm_state" in server_info:
|
||||||
|
server.setState(server_info["vm_state"])
|
||||||
|
elif "state" in server_info:
|
||||||
|
server.setState(server_info["state"])
|
||||||
|
|
||||||
|
return server
|
||||||
|
|
||||||
|
def info(self, ctxt, publisher_id, event_type, payload, metadata):
|
||||||
|
LOG.debug("Notification INFO: event_type=%s payload=%s"
|
||||||
|
% (event_type, payload))
|
||||||
|
|
||||||
|
if payload is None or "state" not in payload:
|
||||||
|
return
|
||||||
|
|
||||||
|
state = payload["state"]
|
||||||
|
|
||||||
|
event_types = ["compute.instance.create.end",
|
||||||
|
"compute.instance.delete.end",
|
||||||
|
"compute.instance.update",
|
||||||
|
"scheduler.run_instance"]
|
||||||
|
|
||||||
|
if event_type not in event_types:
|
||||||
|
return
|
||||||
|
|
||||||
|
server_info = None
|
||||||
|
|
||||||
|
if event_type == "scheduler.run_instance":
|
||||||
|
server_info = payload["request_spec"]["instance_type"]
|
||||||
|
else:
|
||||||
|
server_info = payload
|
||||||
|
|
||||||
|
server = self._makeServer(server_info)
|
||||||
|
|
||||||
|
self.nova_manager.notify(event_type="SERVER_EVENT", server=server,
|
||||||
|
event=event_type, state=state)
|
||||||
|
|
||||||
|
def warn(self, ctxt, publisher_id, event_type, payload, metadata):
|
||||||
|
LOG.debug("Notification WARN: event_type=%s, payload=%s metadata=%s"
|
||||||
|
% (event_type, payload, metadata))
|
||||||
|
|
||||||
|
def error(self, ctxt, publisher_id, event_type, payload, metadata):
|
||||||
|
LOG.debug("Notification ERROR: event_type=%s, payload=%s metadata=%s"
|
||||||
|
% (event_type, payload, metadata))
|
||||||
|
|
||||||
|
|
||||||
class NovaConductorComputeAPI(object):
|
class NovaConductorComputeAPI(object):
|
||||||
|
|
||||||
def __init__(self, topic, scheduler_manager, keystone_manager, msg):
|
def __init__(self, synergy_topic, conductor_topic, nova_manager, msg):
|
||||||
self.topic = topic
|
self.nova_manager = nova_manager
|
||||||
self.scheduler_manager = scheduler_manager
|
|
||||||
self.keystone_manager = keystone_manager
|
self.target = msg.getTarget(topic=synergy_topic,
|
||||||
self.target = msg.getTarget(topic=topic + "_synergy",
|
|
||||||
namespace="compute_task",
|
namespace="compute_task",
|
||||||
version="1.10")
|
version="1.16")
|
||||||
|
|
||||||
self.client = msg.getRPCClient(
|
self.client = msg.getRPCClient(
|
||||||
target=msg.getTarget(topic=topic,
|
target=msg.getTarget(topic=conductor_topic,
|
||||||
namespace="compute_task",
|
namespace="compute_task",
|
||||||
version="1.10"))
|
version="1.10"))
|
||||||
|
|
||||||
@ -62,66 +145,75 @@ class NovaConductorComputeAPI(object):
|
|||||||
security_groups, block_device_mapping=None,
|
security_groups, block_device_mapping=None,
|
||||||
legacy_bdm=True):
|
legacy_bdm=True):
|
||||||
for instance in instances:
|
for instance in instances:
|
||||||
|
data = {'instances': [instance],
|
||||||
|
'image': image,
|
||||||
|
'filter_properties': filter_properties,
|
||||||
|
'admin_password': admin_password,
|
||||||
|
'injected_files': injected_files,
|
||||||
|
'requested_networks': requested_networks,
|
||||||
|
'security_groups': security_groups,
|
||||||
|
'block_device_mapping': block_device_mapping,
|
||||||
|
'legacy_bdm': legacy_bdm}
|
||||||
|
|
||||||
|
req = {"context": context, "data": data,
|
||||||
|
"action": "build_instances"}
|
||||||
try:
|
try:
|
||||||
request = Request.build(context, instance, image,
|
request = Request.fromDict(req)
|
||||||
filter_properties, admin_password,
|
|
||||||
injected_files, requested_networks,
|
|
||||||
security_groups, block_device_mapping,
|
|
||||||
legacy_bdm)
|
|
||||||
|
|
||||||
self.scheduler_manager.processRequest(request)
|
self.nova_manager.notify(event_type="SERVER_CREATE",
|
||||||
|
request=request)
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
LOG.error("Exception has occured", exc_info=1)
|
LOG.info(ex)
|
||||||
LOG.error(ex)
|
|
||||||
|
|
||||||
def build_instance(self, context, instance, image, filter_properties,
|
def schedule_and_build_instances(self, context, build_requests,
|
||||||
admin_password, injected_files, requested_networks,
|
request_specs, image,
|
||||||
security_groups, block_device_mapping=None,
|
admin_password, injected_files,
|
||||||
legacy_bdm=True):
|
requested_networks, block_device_mapping):
|
||||||
kw = {'instances': [instance],
|
index = 0
|
||||||
'image': image,
|
|
||||||
'filter_properties': filter_properties,
|
|
||||||
'admin_password': admin_password,
|
|
||||||
'injected_files': injected_files,
|
|
||||||
'requested_networks': requested_networks,
|
|
||||||
'security_groups': security_groups}
|
|
||||||
|
|
||||||
|
for build_request in build_requests:
|
||||||
|
request_spec = request_specs[index]
|
||||||
|
|
||||||
|
index += 1
|
||||||
|
|
||||||
|
data = {'build_requests': [build_request],
|
||||||
|
'request_specs': [request_spec],
|
||||||
|
'image': image,
|
||||||
|
'admin_password': admin_password,
|
||||||
|
'injected_files': injected_files,
|
||||||
|
'requested_networks': requested_networks,
|
||||||
|
'block_device_mapping': block_device_mapping}
|
||||||
|
|
||||||
|
req = {"context": context, "data": data,
|
||||||
|
"action": "schedule_and_build_instances"}
|
||||||
|
|
||||||
|
request = Request.fromDict(req)
|
||||||
|
|
||||||
|
self.nova_manager.notify(event_type="SERVER_CREATE",
|
||||||
|
request=request)
|
||||||
|
|
||||||
|
def build_instance(self, context, action, data):
|
||||||
|
try:
|
||||||
|
cctxt = self.client.prepare()
|
||||||
|
cctxt.cast(context, action, **data)
|
||||||
|
except Exception as ex:
|
||||||
|
LOG.info(ex)
|
||||||
|
|
||||||
|
def migrate_server(self, context, **kwargs):
|
||||||
cctxt = self.client.prepare()
|
cctxt = self.client.prepare()
|
||||||
cctxt.cast(context, 'build_instances', **kw)
|
return cctxt.call(context, 'migrate_server', **kwargs)
|
||||||
|
|
||||||
def migrate_server(self, context, instance, scheduler_hint, live, rebuild,
|
|
||||||
flavor, block_migration, disk_over_commit,
|
|
||||||
reservations=None, clean_shutdown=True,
|
|
||||||
request_spec=None):
|
|
||||||
kw = {'instance': instance, 'scheduler_hint': scheduler_hint,
|
|
||||||
'live': live, 'rebuild': rebuild, 'flavor': flavor,
|
|
||||||
'block_migration': block_migration,
|
|
||||||
'disk_over_commit': disk_over_commit,
|
|
||||||
'reservations': reservations,
|
|
||||||
'clean_shutdown': clean_shutdown,
|
|
||||||
'request_spec': request_spec,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
def unshelve_instance(self, context, **kwargs):
|
||||||
cctxt = self.client.prepare()
|
cctxt = self.client.prepare()
|
||||||
return cctxt.call(context, 'migrate_server', **kw)
|
cctxt.cast(context, 'unshelve_instance', **kwargs)
|
||||||
|
|
||||||
def unshelve_instance(self, context, instance):
|
def rebuild_instance(self, ctxt, **kwargs):
|
||||||
cctxt = self.client.prepare(version='1.3')
|
cctxt = self.client.prepare()
|
||||||
cctxt.cast(context, 'unshelve_instance', instance=instance)
|
cctxt.cast(ctxt, 'rebuild_instance', **kwargs)
|
||||||
|
|
||||||
def rebuild_instance(self, ctxt, instance, new_pass, injected_files,
|
def resize_instance(self, ctxt, **kwargs):
|
||||||
image_ref, orig_image_ref, orig_sys_metadata, bdms,
|
cctxt = self.client.prepare()
|
||||||
recreate=False, on_shared_storage=False, host=None,
|
cctxt.cast(ctxt, 'resize_instance', **kwargs)
|
||||||
preserve_ephemeral=False, kwargs=None):
|
|
||||||
cctxt = self.client.prepare(version='1.8')
|
|
||||||
cctxt.cast(ctxt, 'rebuild_instance',
|
|
||||||
instance=instance, new_pass=new_pass,
|
|
||||||
injected_files=injected_files, image_ref=image_ref,
|
|
||||||
orig_image_ref=orig_image_ref,
|
|
||||||
orig_sys_metadata=orig_sys_metadata, bdms=bdms,
|
|
||||||
recreate=recreate, on_shared_storage=on_shared_storage,
|
|
||||||
preserve_ephemeral=preserve_ephemeral,
|
|
||||||
host=host)
|
|
||||||
|
|
||||||
|
|
||||||
class NovaManager(Manager):
|
class NovaManager(Manager):
|
||||||
@ -170,6 +262,10 @@ class NovaManager(Manager):
|
|||||||
help="the Synergy topic",
|
help="the Synergy topic",
|
||||||
default="synergy",
|
default="synergy",
|
||||||
required=False),
|
required=False),
|
||||||
|
cfg.StrOpt("notification_topic",
|
||||||
|
help="the notifiction topic",
|
||||||
|
default="notifications",
|
||||||
|
required=False),
|
||||||
cfg.StrOpt("conductor_topic",
|
cfg.StrOpt("conductor_topic",
|
||||||
help="the conductor topic",
|
help="the conductor topic",
|
||||||
default="conductor",
|
default="conductor",
|
||||||
@ -231,7 +327,6 @@ class NovaManager(Manager):
|
|||||||
raise Exception("SchedulerManager not found!")
|
raise Exception("SchedulerManager not found!")
|
||||||
|
|
||||||
self.keystone_manager = self.getManager("KeystoneManager")
|
self.keystone_manager = self.getManager("KeystoneManager")
|
||||||
self.scheduler_manager = self.getManager("SchedulerManager")
|
|
||||||
|
|
||||||
amqp_url = self.getParameter("amqp_url")
|
amqp_url = self.getParameter("amqp_url")
|
||||||
|
|
||||||
@ -257,6 +352,8 @@ class NovaManager(Manager):
|
|||||||
|
|
||||||
synergy_topic = self.getParameter("synergy_topic")
|
synergy_topic = self.getParameter("synergy_topic")
|
||||||
|
|
||||||
|
notification_topic = self.getParameter("notification_topic")
|
||||||
|
|
||||||
conductor_topic = self.getParameter("conductor_topic")
|
conductor_topic = self.getParameter("conductor_topic")
|
||||||
|
|
||||||
self.getParameter("metadata_proxy_shared_secret", fallback=True)
|
self.getParameter("metadata_proxy_shared_secret", fallback=True)
|
||||||
@ -275,9 +372,9 @@ class NovaManager(Manager):
|
|||||||
exchange=amqp_exchange)
|
exchange=amqp_exchange)
|
||||||
|
|
||||||
self.novaConductorComputeAPI = NovaConductorComputeAPI(
|
self.novaConductorComputeAPI = NovaConductorComputeAPI(
|
||||||
|
synergy_topic,
|
||||||
conductor_topic,
|
conductor_topic,
|
||||||
self.scheduler_manager,
|
self,
|
||||||
self.keystone_manager,
|
|
||||||
self.messaging)
|
self.messaging)
|
||||||
|
|
||||||
self.conductor_rpc = self.messaging.getRPCServer(
|
self.conductor_rpc = self.messaging.getRPCServer(
|
||||||
@ -286,13 +383,23 @@ class NovaManager(Manager):
|
|||||||
endpoints=[self.novaConductorComputeAPI])
|
endpoints=[self.novaConductorComputeAPI])
|
||||||
|
|
||||||
self.conductor_rpc.start()
|
self.conductor_rpc.start()
|
||||||
|
|
||||||
|
self.serverEventHandler = ServerEventHandler(self)
|
||||||
|
|
||||||
|
target = self.messaging.getTarget(topic=notification_topic,
|
||||||
|
exchange=amqp_exchange)
|
||||||
|
|
||||||
|
self.listener = self.messaging.getNotificationListener(
|
||||||
|
targets=[target], endpoints=[self.serverEventHandler])
|
||||||
|
|
||||||
|
self.listener.start()
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
LOG.error("Exception has occured", exc_info=1)
|
LOG.error("Exception has occured", exc_info=1)
|
||||||
LOG.error("NovaManager initialization failed! %s" % (ex))
|
LOG.error("NovaManager initialization failed! %s" % (ex))
|
||||||
raise ex
|
raise ex
|
||||||
|
|
||||||
def execute(self, command, *args, **kargs):
|
def execute(self, command, *args, **kargs):
|
||||||
raise Exception("command=%r not supported!" % command)
|
raise Exception("command %r not supported!" % command)
|
||||||
|
|
||||||
def task(self):
|
def task(self):
|
||||||
pass
|
pass
|
||||||
@ -496,36 +603,11 @@ class NovaManager(Manager):
|
|||||||
|
|
||||||
return server
|
return server
|
||||||
|
|
||||||
def buildServer(self, request, compute=None):
|
def buildServer(self, request):
|
||||||
if compute:
|
self.novaConductorComputeAPI.build_instance(
|
||||||
reqId = request.getId()
|
request.getContext(),
|
||||||
|
request.getAction(),
|
||||||
self.novaComputeAPI.build_and_run_instance(
|
request.getData())
|
||||||
request.getContext(),
|
|
||||||
request.getInstance(),
|
|
||||||
compute.getHost(),
|
|
||||||
request.getImage(),
|
|
||||||
request.getInstance(),
|
|
||||||
request.getFilterProperties(),
|
|
||||||
admin_password=request.getAdminPassword(),
|
|
||||||
injected_files=request.getInjectedFiles(),
|
|
||||||
requested_networks=request.getRequestedNetworks(),
|
|
||||||
security_groups=request.getSecurityGroups(),
|
|
||||||
block_device_mapping=self.getBlockDeviceMappingList(reqId),
|
|
||||||
node=compute.getNodeName(),
|
|
||||||
limits=compute.getLimits())
|
|
||||||
else:
|
|
||||||
self.novaConductorComputeAPI.build_instance(
|
|
||||||
context=request.getContext(),
|
|
||||||
instance=request.getInstance(),
|
|
||||||
image=request.getImage(),
|
|
||||||
filter_properties=request.getFilterProperties(),
|
|
||||||
admin_password=request.getAdminPassword(),
|
|
||||||
injected_files=request.getInjectedFiles(),
|
|
||||||
requested_networks=request.getRequestedNetworks(),
|
|
||||||
security_groups=request.getSecurityGroups(),
|
|
||||||
block_device_mapping=request.getBlockDeviceMapping(),
|
|
||||||
legacy_bdm=request.getLegacyBDM())
|
|
||||||
|
|
||||||
def deleteServer(self, server):
|
def deleteServer(self, server):
|
||||||
if not server:
|
if not server:
|
||||||
@ -564,33 +646,6 @@ class NovaManager(Manager):
|
|||||||
|
|
||||||
return response_data
|
return response_data
|
||||||
|
|
||||||
def setQuotaTypeServer(self, server):
|
|
||||||
if not server:
|
|
||||||
return
|
|
||||||
|
|
||||||
QUERY = "insert into nova.instance_metadata (created_at, `key`, " \
|
|
||||||
"`value`, instance_uuid) values (%s, 'quota', %s, %s)"
|
|
||||||
|
|
||||||
connection = self.db_engine.connect()
|
|
||||||
trans = connection.begin()
|
|
||||||
|
|
||||||
quota_type = "private"
|
|
||||||
|
|
||||||
if server.isEphemeral():
|
|
||||||
quota_type = "shared"
|
|
||||||
|
|
||||||
try:
|
|
||||||
connection.execute(QUERY,
|
|
||||||
[server.getCreatedAt(), quota_type,
|
|
||||||
server.getId()])
|
|
||||||
|
|
||||||
trans.commit()
|
|
||||||
except SQLAlchemyError as ex:
|
|
||||||
trans.rollback()
|
|
||||||
raise Exception(ex.message)
|
|
||||||
finally:
|
|
||||||
connection.close()
|
|
||||||
|
|
||||||
def stopServer(self, server):
|
def stopServer(self, server):
|
||||||
if not server:
|
if not server:
|
||||||
return
|
return
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from common.flavor import Flavor
|
|
||||||
from common.quota import SharedQuota
|
from common.quota import SharedQuota
|
||||||
from common.request import Request
|
from common.request import Request
|
||||||
from common.server import Server
|
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
from synergy.common.manager import Manager
|
from synergy.common.manager import Manager
|
||||||
from synergy.exception import SynergyError
|
from synergy.exception import SynergyError
|
||||||
@ -32,125 +30,6 @@ CONF = cfg.CONF
|
|||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class Notifications(object):
|
|
||||||
|
|
||||||
def __init__(self, projects, nova_manager):
|
|
||||||
super(Notifications, self).__init__()
|
|
||||||
|
|
||||||
self.projects = projects
|
|
||||||
self.nova_manager = nova_manager
|
|
||||||
|
|
||||||
def _makeServer(self, server_info):
|
|
||||||
if not server_info:
|
|
||||||
return
|
|
||||||
|
|
||||||
flavor = Flavor()
|
|
||||||
flavor.setMemory(server_info["memory_mb"])
|
|
||||||
flavor.setVCPUs(server_info["vcpus"])
|
|
||||||
flavor.setStorage(server_info["root_gb"])
|
|
||||||
|
|
||||||
if "instance_type" in server_info:
|
|
||||||
flavor.setName(server_info["instance_type"])
|
|
||||||
|
|
||||||
server = Server()
|
|
||||||
server.setFlavor(flavor)
|
|
||||||
server.setUserId(server_info["user_id"])
|
|
||||||
server.setMetadata(server_info["metadata"])
|
|
||||||
server.setDeletedAt(server_info["deleted_at"])
|
|
||||||
server.setTerminatedAt(server_info["terminated_at"])
|
|
||||||
|
|
||||||
if "host" in server_info:
|
|
||||||
server.setHost(server_info["host"])
|
|
||||||
|
|
||||||
if "uuid" in server_info:
|
|
||||||
server.setId(server_info["uuid"])
|
|
||||||
elif "instance_id" in server_info:
|
|
||||||
server.setId(server_info["instance_id"])
|
|
||||||
|
|
||||||
if "project_id" in server_info:
|
|
||||||
server.setProjectId(server_info["project_id"])
|
|
||||||
elif "tenant_id" in server_info:
|
|
||||||
server.setProjectId(server_info["tenant_id"])
|
|
||||||
|
|
||||||
if "vm_state" in server_info:
|
|
||||||
server.setState(server_info["vm_state"])
|
|
||||||
elif "state" in server_info:
|
|
||||||
server.setState(server_info["state"])
|
|
||||||
|
|
||||||
return server
|
|
||||||
|
|
||||||
def info(self, ctxt, publisher_id, event_type, payload, metadata):
|
|
||||||
LOG.debug("Notification INFO: event_type=%s payload=%s"
|
|
||||||
% (event_type, payload))
|
|
||||||
|
|
||||||
if payload is None or "state" not in payload:
|
|
||||||
return
|
|
||||||
|
|
||||||
state = payload["state"]
|
|
||||||
|
|
||||||
event_types = ["compute.instance.create.end",
|
|
||||||
"compute.instance.delete.end",
|
|
||||||
"compute.instance.update",
|
|
||||||
"scheduler.run_instance"]
|
|
||||||
|
|
||||||
if event_type not in event_types:
|
|
||||||
return
|
|
||||||
|
|
||||||
server_info = None
|
|
||||||
|
|
||||||
if event_type == "scheduler.run_instance":
|
|
||||||
server_info = payload["request_spec"]["instance_type"]
|
|
||||||
else:
|
|
||||||
server_info = payload
|
|
||||||
|
|
||||||
server = self._makeServer(server_info)
|
|
||||||
server_id = server.getId()
|
|
||||||
host = server.getHost()
|
|
||||||
|
|
||||||
if server.getProjectId() not in self.projects:
|
|
||||||
return
|
|
||||||
|
|
||||||
if event_type == "compute.instance.create.end" and \
|
|
||||||
state == "active":
|
|
||||||
LOG.info("the server %s is now active on host %s"
|
|
||||||
% (server_id, host))
|
|
||||||
else:
|
|
||||||
quota = self.projects[server.getProjectId()].getQuota()
|
|
||||||
|
|
||||||
if event_type == "compute.instance.delete.end":
|
|
||||||
LOG.info("the server %s has been deleted on host %s"
|
|
||||||
% (server_id, host))
|
|
||||||
try:
|
|
||||||
quota.release(server)
|
|
||||||
except Exception as ex:
|
|
||||||
LOG.warn("cannot release server %s "
|
|
||||||
"(reason=%s)" % (server_id, ex))
|
|
||||||
elif state == "error":
|
|
||||||
LOG.info("error occurred on server %s (host %s)"
|
|
||||||
% (server_id, host))
|
|
||||||
|
|
||||||
if not server.getTerminatedAt() and not server.getDeletedAt():
|
|
||||||
try:
|
|
||||||
self.nova_manager.deleteServer(server)
|
|
||||||
except Exception as ex:
|
|
||||||
LOG.error("cannot delete server %s: %s"
|
|
||||||
% (server_id, ex))
|
|
||||||
|
|
||||||
try:
|
|
||||||
quota.release(server)
|
|
||||||
except Exception as ex:
|
|
||||||
LOG.warn("cannot release server %s "
|
|
||||||
"(reason=%s)" % (server_id, ex))
|
|
||||||
|
|
||||||
def warn(self, ctxt, publisher_id, event_type, payload, metadata):
|
|
||||||
LOG.debug("Notification WARN: event_type=%s, payload=%s metadata=%s"
|
|
||||||
% (event_type, payload, metadata))
|
|
||||||
|
|
||||||
def error(self, ctxt, publisher_id, event_type, payload, metadata):
|
|
||||||
LOG.debug("Notification ERROR: event_type=%s, payload=%s metadata=%s"
|
|
||||||
% (event_type, payload, metadata))
|
|
||||||
|
|
||||||
|
|
||||||
class Worker(Thread):
|
class Worker(Thread):
|
||||||
|
|
||||||
def __init__(self, name, queue, project_manager, nova_manager,
|
def __init__(self, name, queue, project_manager, nova_manager,
|
||||||
@ -259,8 +138,8 @@ class Worker(Thread):
|
|||||||
try:
|
try:
|
||||||
self.nova_manager.buildServer(request)
|
self.nova_manager.buildServer(request)
|
||||||
|
|
||||||
LOG.info("building server %s (user_id=%s prj_id=%s quo"
|
LOG.info("building server %s user_id=%s prj_id=%s quo"
|
||||||
"ta=shared)" % (server_id, user_id, prj_id))
|
"ta=shared" % (server_id, user_id, prj_id))
|
||||||
|
|
||||||
found = True
|
found = True
|
||||||
except SynergyError as ex:
|
except SynergyError as ex:
|
||||||
@ -290,7 +169,6 @@ class SchedulerManager(Manager):
|
|||||||
super(SchedulerManager, self).__init__("SchedulerManager")
|
super(SchedulerManager, self).__init__("SchedulerManager")
|
||||||
|
|
||||||
self.config_opts = [
|
self.config_opts = [
|
||||||
cfg.StrOpt("notification_topic", default="notifications"),
|
|
||||||
cfg.IntOpt("backfill_depth", default=100),
|
cfg.IntOpt("backfill_depth", default=100),
|
||||||
]
|
]
|
||||||
self.workers = []
|
self.workers = []
|
||||||
@ -321,9 +199,6 @@ class SchedulerManager(Manager):
|
|||||||
self.fairshare_manager = self.getManager("FairShareManager")
|
self.fairshare_manager = self.getManager("FairShareManager")
|
||||||
self.project_manager = self.getManager("ProjectManager")
|
self.project_manager = self.getManager("ProjectManager")
|
||||||
self.backfill_depth = CONF.SchedulerManager.backfill_depth
|
self.backfill_depth = CONF.SchedulerManager.backfill_depth
|
||||||
self.notification_topic = CONF.SchedulerManager.notification_topic
|
|
||||||
self.projects = {}
|
|
||||||
self.listener = None
|
|
||||||
self.exit = False
|
self.exit = False
|
||||||
self.configured = False
|
self.configured = False
|
||||||
|
|
||||||
@ -354,25 +229,62 @@ class SchedulerManager(Manager):
|
|||||||
|
|
||||||
self.workers.append(dynamic_worker)
|
self.workers.append(dynamic_worker)
|
||||||
|
|
||||||
self.notifications = Notifications(self.projects, self.nova_manager)
|
|
||||||
|
|
||||||
target = self.nova_manager.getTarget(topic=self.notification_topic,
|
|
||||||
exchange="nova")
|
|
||||||
|
|
||||||
self.listener = self.nova_manager.getNotificationListener(
|
|
||||||
targets=[target],
|
|
||||||
endpoints=[self.notifications])
|
|
||||||
|
|
||||||
self.quota_manager.deleteExpiredServers()
|
self.quota_manager.deleteExpiredServers()
|
||||||
|
|
||||||
self.listener.start()
|
|
||||||
self.configured = True
|
self.configured = True
|
||||||
|
|
||||||
def destroy(self):
|
def destroy(self):
|
||||||
for queue_worker in self.workers:
|
for queue_worker in self.workers:
|
||||||
queue_worker.destroy()
|
queue_worker.destroy()
|
||||||
|
|
||||||
def processRequest(self, request):
|
def doOnEvent(self, event_type, *args, **kwargs):
|
||||||
|
if event_type == "SERVER_EVENT":
|
||||||
|
server = kwargs["server"]
|
||||||
|
event = kwargs["event"]
|
||||||
|
state = kwargs["state"]
|
||||||
|
|
||||||
|
self._processServerEvent(server, event, state)
|
||||||
|
elif event_type == "SERVER_CREATE":
|
||||||
|
self._processServerCreate(kwargs["request"])
|
||||||
|
|
||||||
|
def _processServerEvent(self, server, event, state):
|
||||||
|
if event == "compute.instance.create.end" and state == "active":
|
||||||
|
LOG.info("the server %s is now active on host %s"
|
||||||
|
% (server.getId(), server.getHost()))
|
||||||
|
else:
|
||||||
|
project = self.project_manager.getProject(id=server.getProjectId())
|
||||||
|
|
||||||
|
if not project:
|
||||||
|
return
|
||||||
|
|
||||||
|
quota = project.getQuota()
|
||||||
|
|
||||||
|
if event == "compute.instance.delete.end":
|
||||||
|
LOG.info("the server %s has been deleted on host %s"
|
||||||
|
% (server.getId(), server.getHost()))
|
||||||
|
try:
|
||||||
|
quota.release(server)
|
||||||
|
except Exception as ex:
|
||||||
|
LOG.warn("cannot release server %s "
|
||||||
|
"(reason=%s)" % (server.getId(), ex))
|
||||||
|
elif state == "error":
|
||||||
|
LOG.info("error occurred on server %s (host %s)"
|
||||||
|
% (server.getId(), server.getHost()))
|
||||||
|
|
||||||
|
if not server.getTerminatedAt() and not server.getDeletedAt():
|
||||||
|
try:
|
||||||
|
self.nova_manager.deleteServer(server)
|
||||||
|
except Exception as ex:
|
||||||
|
LOG.error("cannot delete server %s: %s"
|
||||||
|
% (server.getId(), ex))
|
||||||
|
|
||||||
|
try:
|
||||||
|
quota.release(server)
|
||||||
|
except Exception as ex:
|
||||||
|
LOG.warn("cannot release server %s "
|
||||||
|
"(reason=%s)" % (server.getId(), ex))
|
||||||
|
|
||||||
|
def _processServerCreate(self, request):
|
||||||
server = request.getServer()
|
server = request.getServer()
|
||||||
|
|
||||||
project = self.project_manager.getProject(id=request.getProjectId())
|
project = self.project_manager.getProject(id=request.getProjectId())
|
||||||
@ -391,8 +303,8 @@ class SchedulerManager(Manager):
|
|||||||
if 0 < num_attempts < 3:
|
if 0 < num_attempts < 3:
|
||||||
self.nova_manager.buildServer(request)
|
self.nova_manager.buildServer(request)
|
||||||
|
|
||||||
LOG.info("retrying to build the server %s (user_id"
|
LOG.info("retrying to build the server %s user_id"
|
||||||
"=%s prj_id=%s, num_attempts=%s, reason=%s)"
|
"=%s prj_id=%s, num_attempts=%s, reason=%s"
|
||||||
% (request.getId(), request.getUserId(),
|
% (request.getId(), request.getUserId(),
|
||||||
request.getProjectId(), num_attempts, reason))
|
request.getProjectId(), num_attempts, reason))
|
||||||
return
|
return
|
||||||
@ -405,10 +317,10 @@ class SchedulerManager(Manager):
|
|||||||
request.getProjectId()))
|
request.getProjectId()))
|
||||||
|
|
||||||
self.nova_manager.buildServer(request)
|
self.nova_manager.buildServer(request)
|
||||||
LOG.info("building server %s (user_id=%s prj_id=%s "
|
LOG.info("building server %s user_id=%s prj_id=%s "
|
||||||
"quota=private)" % (server.getId(),
|
"quota=private" % (server.getId(),
|
||||||
request.getUserId(),
|
request.getUserId(),
|
||||||
request.getProjectId()))
|
request.getProjectId()))
|
||||||
else:
|
else:
|
||||||
self.nova_manager.deleteServer(server)
|
self.nova_manager.deleteServer(server)
|
||||||
LOG.info("request rejected (quota exceeded): "
|
LOG.info("request rejected (quota exceeded): "
|
||||||
|
@ -13,18 +13,14 @@
|
|||||||
from mock import create_autospec
|
from mock import create_autospec
|
||||||
from mock import MagicMock
|
from mock import MagicMock
|
||||||
from sqlalchemy.engine.base import Engine
|
from sqlalchemy.engine.base import Engine
|
||||||
from synergy_scheduler_manager.common.flavor import Flavor
|
|
||||||
from synergy_scheduler_manager.common.project import Project
|
from synergy_scheduler_manager.common.project import Project
|
||||||
from synergy_scheduler_manager.common.queue import QueueDB
|
from synergy_scheduler_manager.common.queue import QueueDB
|
||||||
from synergy_scheduler_manager.common.queue import QueueItem
|
from synergy_scheduler_manager.common.queue import QueueItem
|
||||||
from synergy_scheduler_manager.common.quota import SharedQuota
|
|
||||||
from synergy_scheduler_manager.common.server import Server
|
|
||||||
from synergy_scheduler_manager.project_manager import ProjectManager
|
from synergy_scheduler_manager.project_manager import ProjectManager
|
||||||
from synergy_scheduler_manager.scheduler_manager import Notifications
|
|
||||||
from synergy_scheduler_manager.scheduler_manager import Worker
|
from synergy_scheduler_manager.scheduler_manager import Worker
|
||||||
from synergy_scheduler_manager.tests.unit import base
|
from synergy_scheduler_manager.tests.unit import base
|
||||||
|
|
||||||
|
"""
|
||||||
class TestNotifications(base.TestCase):
|
class TestNotifications(base.TestCase):
|
||||||
|
|
||||||
def test_info_quota(self):
|
def test_info_quota(self):
|
||||||
@ -120,6 +116,7 @@ class TestNotifications(base.TestCase):
|
|||||||
|
|
||||||
self.assertEqual(0, SharedQuota.getUsage('vcpus'))
|
self.assertEqual(0, SharedQuota.getUsage('vcpus'))
|
||||||
self.assertEqual(0, SharedQuota.getUsage('memory'))
|
self.assertEqual(0, SharedQuota.getUsage('memory'))
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
class TestWorker(base.TestCase):
|
class TestWorker(base.TestCase):
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
from datetime import datetime
|
||||||
from synergy_scheduler_manager.common.request import Request
|
from synergy_scheduler_manager.common.request import Request
|
||||||
from synergy_scheduler_manager.tests.unit import base
|
from synergy_scheduler_manager.tests.unit import base
|
||||||
|
|
||||||
@ -18,414 +19,278 @@ class TestRequest(base.TestCase):
|
|||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestRequest, self).setUp()
|
super(TestRequest, self).setUp()
|
||||||
|
request_specs = [{
|
||||||
|
'nova_object.version': '1.8',
|
||||||
|
'nova_object.namespace': 'nova',
|
||||||
|
'nova_object.name': u'RequestSpec',
|
||||||
|
'nova_object.data': {
|
||||||
|
'requested_destination': None,
|
||||||
|
'instance_uuid': '999',
|
||||||
|
'retry': {
|
||||||
|
'num_attempts': 1,
|
||||||
|
'hosts': []},
|
||||||
|
'num_instances': 1,
|
||||||
|
'pci_requests': {
|
||||||
|
'nova_object.version': '1.1',
|
||||||
|
'nova_object.namespace': 'nova',
|
||||||
|
'nova_object.name': 'InstancePCIRequests',
|
||||||
|
'nova_object.data': {'requests': []},
|
||||||
|
'nova_object.changes': ['requests']},
|
||||||
|
'limits': {
|
||||||
|
'nova_object.version': '1.0',
|
||||||
|
'nova_object.namespace': 'nova',
|
||||||
|
'nova_object.name': 'SchedulerLimits',
|
||||||
|
'nova_object.data': {
|
||||||
|
'vcpu': None,
|
||||||
|
'memory_mb': None,
|
||||||
|
'numa_topology': None,
|
||||||
|
'disk_gb': None},
|
||||||
|
'nova_object.changes': [
|
||||||
|
'vcpu', 'memory_mb', 'numa_topology', 'disk_gb']},
|
||||||
|
'availability_zone': 'nova',
|
||||||
|
'force_nodes': None,
|
||||||
|
'image': {
|
||||||
|
'nova_object.version': '1.8',
|
||||||
|
'nova_object.namespace': 'nova',
|
||||||
|
'nova_object.name': 'ImageMeta',
|
||||||
|
'nova_object.data': {
|
||||||
|
'status': 'active',
|
||||||
|
'properties': {
|
||||||
|
'nova_object.version': '1.16',
|
||||||
|
'nova_object.name': 'ImageMetaProps',
|
||||||
|
'nova_object.namespace': 'nova',
|
||||||
|
'nova_object.data': {}},
|
||||||
|
'name': 'cirros',
|
||||||
|
'container_format': 'bare',
|
||||||
|
'created_at': '2017-05-19T12:18:46Z',
|
||||||
|
'disk_format': 'qcow2',
|
||||||
|
'updated_at': '2017-05-19T12:18:47Z',
|
||||||
|
'id': '03d54ef8-f0ac-4ad2-92a0-95835d77d2b5',
|
||||||
|
'owner': u'01ab8de5387547d093aa8ae6b85bd8b1',
|
||||||
|
'checksum': 'f8ab98ff5e73ebab884d80c9dc9c7290',
|
||||||
|
'min_disk': 0,
|
||||||
|
'min_ram': 0,
|
||||||
|
'size': 13267968},
|
||||||
|
'nova_object.changes': [
|
||||||
|
'status', 'name', 'container_format', 'created_at',
|
||||||
|
'disk_format', 'updated_at', 'properties', 'owner',
|
||||||
|
'min_ram', 'checksum', 'min_disk', 'id', 'size']},
|
||||||
|
'instance_group': None,
|
||||||
|
'force_hosts': None,
|
||||||
|
'numa_topology': None,
|
||||||
|
'scheduler_hints': {},
|
||||||
|
'flavor': {
|
||||||
|
'nova_object.version': '1.1',
|
||||||
|
'nova_object.name': 'Flavor',
|
||||||
|
'nova_object.namespace': 'nova',
|
||||||
|
'nova_object.data': {
|
||||||
|
'memory_mb': 512,
|
||||||
|
'root_gb': 1,
|
||||||
|
'deleted_at': None,
|
||||||
|
'name': 'm1.tiny',
|
||||||
|
'deleted': False,
|
||||||
|
'created_at': '2017-05-23T09:36:21Z',
|
||||||
|
'ephemeral_gb': 0,
|
||||||
|
'updated_at': None,
|
||||||
|
'disabled': False,
|
||||||
|
'vcpus': 1,
|
||||||
|
'extra_specs': {},
|
||||||
|
'swap': 0,
|
||||||
|
'rxtx_factor': 1.0,
|
||||||
|
'is_public': True,
|
||||||
|
'flavorid': '5cdecdda',
|
||||||
|
'vcpu_weight': 0,
|
||||||
|
'id': 1}},
|
||||||
|
'project_id': u'01ab8de5387547d093aa8ae6b85bd8b1',
|
||||||
|
'id': 126,
|
||||||
|
'security_groups': {
|
||||||
|
'nova_object.version': '1.0',
|
||||||
|
'nova_object.namespace': 'nova',
|
||||||
|
'nova_object.name': 'SecurityGroupList',
|
||||||
|
'nova_object.data': {
|
||||||
|
'objects': [{
|
||||||
|
'nova_object.version': '1.2',
|
||||||
|
'nova_object.namespace': 'nova',
|
||||||
|
'nova_object.name': 'SecurityGroup',
|
||||||
|
'nova_object.data': {'uuid': 'f5b58bc9'},
|
||||||
|
'nova_object.changes': ['uuid']}]},
|
||||||
|
'nova_object.changes': ['objects']},
|
||||||
|
'ignore_hosts': None},
|
||||||
|
'nova_object.changes': ['limits', 'image', 'pci_requests']}]
|
||||||
|
|
||||||
req_dict = {
|
build_requests = [{
|
||||||
'legacy_bdm': True,
|
'nova_object.version': '1.2',
|
||||||
'requested_networks': None,
|
'nova_object.namespace': 'nova',
|
||||||
'injected_files': [],
|
'nova_object.name': 'BuildRequest',
|
||||||
'block_device_mapping': None,
|
'nova_object.data': {
|
||||||
'image': {
|
'instance_uuid': '999',
|
||||||
u'status': u'active',
|
'created_at': '2017-07-20T12:09:27Z',
|
||||||
u'created_at': u'2016-03-23T16:47:10.000000',
|
'updated_at': None,
|
||||||
u'name': u'cirros',
|
'instance': {
|
||||||
u'deleted': False,
|
'nova_object.version': '2.3',
|
||||||
u'container_format': u'bare',
|
'nova_object.name': 'Instance',
|
||||||
u'min_ram': 0,
|
'nova_object.namespace': 'nova',
|
||||||
u'disk_format': u'qcow2',
|
'nova_object.data': {
|
||||||
u'updated_at': u'2016-03-23T16:47:10.000000',
|
'vm_state': 'building',
|
||||||
u'properties': {},
|
'keypairs': {
|
||||||
u'owner': u'1a6edd87f9ec41d8aa64c8f23d719c2a',
|
'nova_object.version': '1.3',
|
||||||
u'checksum': u'ee1eca47dc88f4879d8a229cc70a07c6',
|
'nova_object.name': 'KeyPairList',
|
||||||
u'min_disk': 0,
|
'nova_object.namespace': 'nova',
|
||||||
u'is_public': True,
|
'nova_object.data': {'objects': []}},
|
||||||
u'deleted_at': None,
|
'pci_requests': {
|
||||||
u'id': u'5100f480-a40c-46cd-b8b6-ea2e5e7bf09e',
|
'nova_object.version': '1.1',
|
||||||
u'size': 13287936},
|
'nova_object.name': 'InstancePCIRequests',
|
||||||
'filter_properties': {
|
'nova_object.namespace': 'nova',
|
||||||
u'instance_type': {
|
'nova_object.data': {'requests': []}},
|
||||||
u'nova_object.version': u'1.1',
|
'availability_zone': 'nova',
|
||||||
u'nova_object.name': u'Flavor',
|
'terminated_at': None,
|
||||||
u'nova_object.namespace': u'nova',
|
'ephemeral_gb': 0,
|
||||||
u'nova_object.data': {
|
'old_flavor': None,
|
||||||
u'memory_mb': 512,
|
'updated_at': None,
|
||||||
u'root_gb': 1,
|
'numa_topology': None,
|
||||||
u'deleted_at': None,
|
'vm_mode': None,
|
||||||
u'name': u'm1.tiny',
|
'flavor': {
|
||||||
u'deleted': False,
|
'nova_object.version': '1.1',
|
||||||
u'created_at': None,
|
'nova_object.name': 'Flavor',
|
||||||
u'ephemeral_gb': 0,
|
'nova_object.namespace': 'nova',
|
||||||
u'updated_at': None,
|
'nova_object.data': {
|
||||||
u'disabled': False,
|
'memory_mb': 512,
|
||||||
u'vcpus': 1,
|
'root_gb': 1,
|
||||||
u'extra_specs': {},
|
'deleted_at': None,
|
||||||
u'swap': 0,
|
'name': 'm1.tiny',
|
||||||
u'rxtx_factor': 1.0,
|
'deleted': False,
|
||||||
u'is_public': True,
|
'created_at': '2017-05-23T09:36:21Z',
|
||||||
u'flavorid': u'1',
|
'ephemeral_gb': 0,
|
||||||
u'vcpu_weight': 0,
|
'updated_at': None,
|
||||||
u'id': 2}},
|
'disabled': False,
|
||||||
u'scheduler_hints': {}},
|
'vcpus': 1,
|
||||||
'instance': {
|
'extra_specs': {},
|
||||||
u'nova_object.version': u'2.0',
|
'swap': 0,
|
||||||
u'nova_object.name': u'Instance',
|
'rxtx_factor': 1.0,
|
||||||
u'nova_object.namespace': u'nova',
|
'is_public': True,
|
||||||
u'nova_object.data': {
|
'flavorid': '5cdecdda',
|
||||||
u'vm_state': u'building',
|
'vcpu_weight': 0,
|
||||||
u'pci_requests': {
|
'id': 1}},
|
||||||
u'nova_object.version': u'1.1',
|
'reservation_id': 'r-uavrcsgg',
|
||||||
u'nova_object.name': u'InstancePCIRequests',
|
'security_groups': {
|
||||||
u'nova_object.namespace': u'nova',
|
'nova_object.version': '1.0',
|
||||||
u'nova_object.data': {
|
'nova_object.name': 'SecurityGroupList',
|
||||||
u'instance_uuid': u'e3a7770a-8875e2ccc68b',
|
'nova_object.namespace': 'nova',
|
||||||
u'requests': []}},
|
'nova_object.data': {'objects': []}},
|
||||||
u'availability_zone': None,
|
'disable_terminate': False,
|
||||||
u'terminated_at': None,
|
'user_id': '4469ff06d1e',
|
||||||
u'ephemeral_gb': 0,
|
'uuid': '999',
|
||||||
u'instance_type_id': 2,
|
'new_flavor': None,
|
||||||
u'user_data': None,
|
'info_cache': {
|
||||||
u'numa_topology': None,
|
'nova_object.version': '1.5',
|
||||||
u'cleaned': False,
|
'nova_object.name': 'InstanceInfoCache',
|
||||||
u'vm_mode': None,
|
'nova_object.namespace': 'nova',
|
||||||
u'flavor': {
|
'nova_object.data': {
|
||||||
u'nova_object.version': u'1.1',
|
'instance_uuid': '999',
|
||||||
u'nova_object.name': u'Flavor',
|
'network_info': '[]'}},
|
||||||
u'nova_object.namespace': u'nova',
|
'hostname': 'lisa',
|
||||||
u'nova_object.data': {
|
'launched_on': None,
|
||||||
u'memory_mb': 512,
|
'display_description': 'Lisa',
|
||||||
u'root_gb': 1,
|
'key_data': None,
|
||||||
u'deleted_at': None,
|
'deleted': False,
|
||||||
u'name': u'm1.tiny',
|
'power_state': 0,
|
||||||
u'deleted': False,
|
'progress': 0,
|
||||||
u'created_at': None,
|
'project_id': '1111111',
|
||||||
u'ephemeral_gb': 0,
|
'launched_at': None,
|
||||||
u'updated_at': None,
|
'config_drive': '',
|
||||||
u'disabled': False,
|
'node': None,
|
||||||
u'vcpus': 1,
|
'ramdisk_id': '',
|
||||||
u'extra_specs': {},
|
'access_ip_v6': None,
|
||||||
u'swap': 0,
|
'access_ip_v4': None,
|
||||||
u'rxtx_factor': 1.0,
|
'kernel_id': '',
|
||||||
u'is_public': True,
|
'key_name': 'mykey',
|
||||||
u'flavorid': u'1',
|
'user_data': None,
|
||||||
u'vcpu_weight': 0,
|
'host': None,
|
||||||
u'id': 2}},
|
'ephemeral_key_uuid': None,
|
||||||
u'deleted_at': None,
|
'architecture': None,
|
||||||
u'reservation_id': u'r-s9v032d0',
|
'display_name': 'Lisa',
|
||||||
u'id': 830,
|
'system_metadata': {
|
||||||
u'security_groups': {
|
'image_min_disk': '1',
|
||||||
u'nova_object.version': u'1.0',
|
'image_min_ram': '0',
|
||||||
u'nova_object.name': u'SecurityGroupList',
|
'image_disk_format': 'qcow2',
|
||||||
u'nova_object.namespace': u'nova',
|
'image_base_image_ref': '03d54ef8',
|
||||||
u'nova_object.data': {
|
'image_container_format': 'bare'},
|
||||||
u'objects': []}},
|
'task_state': 'scheduling',
|
||||||
u'disable_terminate': False,
|
'shutdown_terminate': False,
|
||||||
u'root_device_name': None,
|
'tags': {
|
||||||
u'display_name': u'user_b1',
|
'nova_object.version': '1.1',
|
||||||
u'uuid': u'e3a7770a-dbf6-4b63-8f9a-8875e2ccc68b',
|
'nova_object.name': 'TagList',
|
||||||
u'default_swap_device': None,
|
'nova_object.namespace': 'nova',
|
||||||
u'info_cache': {
|
'nova_object.data': {u'objects': []}},
|
||||||
u'nova_object.version': u'1.5',
|
'cell_name': None,
|
||||||
u'nova_object.name': u'InstanceInfoCache',
|
'root_gb': 1,
|
||||||
u'nova_object.namespace': u'nova',
|
'locked': False,
|
||||||
u'nova_object.data': {
|
'instance_type_id': 1,
|
||||||
u'instance_uuid': u'e3a7-8875e2ccc68b',
|
'locked_by': None,
|
||||||
u'deleted': False,
|
'launch_index': 0,
|
||||||
u'created_at': u'2016-09-02T14:01:39Z',
|
'memory_mb': 512,
|
||||||
u'updated_at': None,
|
'vcpus': 1,
|
||||||
u'network_info': u'[]',
|
'image_ref': '03d54ef8',
|
||||||
u'deleted_at': None}},
|
'root_device_name': None,
|
||||||
u'hostname': u'user-b1',
|
'auto_disk_config': True,
|
||||||
u'launched_on': None,
|
'os_type': None,
|
||||||
u'display_description': u'user_b1',
|
'metadata': {'quota': 'shared'},
|
||||||
u'key_data': None,
|
'created_at': '2017-07-20T12:09:27Z'}},
|
||||||
u'deleted': False,
|
'project_id': '1111111',
|
||||||
u'power_state': 0,
|
'id': 63},
|
||||||
u'key_name': None,
|
'nova_object.changes': [u'block_device_mappings']}]
|
||||||
u'default_ephemeral_device': None,
|
|
||||||
u'progress': 0,
|
|
||||||
u'project_id': u'd20ac1ffa60841a78a865da63b2399de',
|
|
||||||
u'launched_at': None,
|
|
||||||
u'metadata': {
|
|
||||||
u'quota': u'dynamic',
|
|
||||||
u'persistent': u'False'},
|
|
||||||
u'node': None,
|
|
||||||
u'ramdisk_id': u'',
|
|
||||||
u'access_ip_v6': None,
|
|
||||||
u'access_ip_v4': None,
|
|
||||||
u'kernel_id': u'',
|
|
||||||
u'old_flavor': None,
|
|
||||||
u'updated_at': None,
|
|
||||||
u'host': None,
|
|
||||||
u'root_gb': 1,
|
|
||||||
u'user_id': u'4cb9f71a47914d0c8b78a471fd8f7015',
|
|
||||||
u'system_metadata': {
|
|
||||||
u'image_min_disk': u'1',
|
|
||||||
u'image_min_ram': u'0',
|
|
||||||
u'image_disk_format': u'qcow2',
|
|
||||||
u'image_base_image_ref': u'5100f480-a25e7bf09e',
|
|
||||||
u'image_container_format': u'bare'},
|
|
||||||
u'task_state': u'scheduling',
|
|
||||||
u'shutdown_terminate': False,
|
|
||||||
u'cell_name': None,
|
|
||||||
u'ephemeral_key_uuid': None,
|
|
||||||
u'locked': False,
|
|
||||||
u'created_at': u'2016-09-02T14:01:39Z',
|
|
||||||
u'locked_by': None,
|
|
||||||
u'launch_index': 0,
|
|
||||||
u'memory_mb': 512,
|
|
||||||
u'vcpus': 1,
|
|
||||||
u'image_ref': u'a40c-46cd-b8b6-ea2e5e7bf09e',
|
|
||||||
u'architecture': None,
|
|
||||||
u'auto_disk_config': False,
|
|
||||||
u'os_type': None,
|
|
||||||
u'config_drive': u'',
|
|
||||||
u'new_flavor': None}},
|
|
||||||
'admin_password': u'URijD456Cezi',
|
|
||||||
'context': {
|
|
||||||
u'domain': None,
|
|
||||||
u'project_domain': None,
|
|
||||||
u'auth_token': u'f9d8458ef4ae454dad75f4636304079c',
|
|
||||||
u'resource_uuid': None,
|
|
||||||
u'read_only': False,
|
|
||||||
u'user_id': u'4cb9f71a47914d0c8b78a471fd8f7015',
|
|
||||||
u'user_identity': u'fa60841a78a865da63b2399de - - -',
|
|
||||||
u'tenant': u'd20ac1ffa60841a78a865da63b2399de',
|
|
||||||
u'instance_lock_checked': False,
|
|
||||||
u'project_id': u'd20ac1ffa60841a78a865da63b2399de',
|
|
||||||
u'user_name': u'user_b1',
|
|
||||||
u'project_name': u'prj_b',
|
|
||||||
u'timestamp': u'2016-09-02T14:01:39.284558',
|
|
||||||
u'remote_address': u'10.64.31.19',
|
|
||||||
u'quota_class': None,
|
|
||||||
u'is_admin': False,
|
|
||||||
u'user': u'4cb9f71a47914d0c8b78a471fd8f7015',
|
|
||||||
u'service_catalog': [],
|
|
||||||
u'read_deleted': u'no',
|
|
||||||
u'show_deleted': False,
|
|
||||||
u'roles': [u'user'],
|
|
||||||
u'request_id': u'req-69c9e7e6-62b2fee1d6e8',
|
|
||||||
u'user_domain': None},
|
|
||||||
'security_groups': [u'default']}
|
|
||||||
|
|
||||||
self.req = Request.fromDict(req_dict)
|
data = {"build_requests": build_requests,
|
||||||
|
"request_specs": request_specs}
|
||||||
|
|
||||||
def test_get_AdminPassword(self):
|
req = {"context": {},
|
||||||
self.assertEqual(u'URijD456Cezi', self.req.getAdminPassword())
|
"data": data,
|
||||||
|
"action": "schedule_and_build_instances"}
|
||||||
|
|
||||||
def test_get_Id(self):
|
self.req = Request.fromDict(req)
|
||||||
self.assertEqual(
|
|
||||||
u'e3a7770a-dbf6-4b63-8f9a-8875e2ccc68b',
|
|
||||||
self.req.getId())
|
|
||||||
|
|
||||||
def test_get_Instance(self):
|
def test_request(self):
|
||||||
ist = {
|
self.assertIsNotNone(self.req)
|
||||||
u'nova_object.data': {
|
|
||||||
u'access_ip_v4': None,
|
|
||||||
u'access_ip_v6': None,
|
|
||||||
u'architecture': None,
|
|
||||||
u'auto_disk_config': False,
|
|
||||||
u'availability_zone': None,
|
|
||||||
u'cell_name': None,
|
|
||||||
u'cleaned': False,
|
|
||||||
u'config_drive': u'',
|
|
||||||
u'created_at': u'2016-09-02T14:01:39Z',
|
|
||||||
u'default_ephemeral_device': None,
|
|
||||||
u'default_swap_device': None,
|
|
||||||
u'deleted': False,
|
|
||||||
u'deleted_at': None,
|
|
||||||
u'disable_terminate': False,
|
|
||||||
u'display_description': u'user_b1',
|
|
||||||
u'display_name': u'user_b1',
|
|
||||||
u'ephemeral_gb': 0,
|
|
||||||
u'ephemeral_key_uuid': None,
|
|
||||||
u'flavor': {
|
|
||||||
u'nova_object.data': {
|
|
||||||
u'created_at': None,
|
|
||||||
u'deleted': False,
|
|
||||||
u'deleted_at': None,
|
|
||||||
u'disabled': False,
|
|
||||||
u'ephemeral_gb': 0,
|
|
||||||
u'extra_specs': {},
|
|
||||||
u'flavorid': u'1',
|
|
||||||
u'id': 2,
|
|
||||||
u'is_public': True,
|
|
||||||
u'memory_mb': 512,
|
|
||||||
u'name': u'm1.tiny',
|
|
||||||
u'root_gb': 1,
|
|
||||||
u'rxtx_factor': 1.0,
|
|
||||||
u'swap': 0,
|
|
||||||
u'updated_at': None,
|
|
||||||
u'vcpu_weight': 0,
|
|
||||||
u'vcpus': 1},
|
|
||||||
u'nova_object.name': u'Flavor',
|
|
||||||
u'nova_object.namespace': u'nova',
|
|
||||||
u'nova_object.version': u'1.1'},
|
|
||||||
u'host': None,
|
|
||||||
u'hostname': u'user-b1',
|
|
||||||
u'id': 830,
|
|
||||||
u'image_ref': u'a40c-46cd-b8b6-ea2e5e7bf09e',
|
|
||||||
u'info_cache': {
|
|
||||||
u'nova_object.data': {
|
|
||||||
u'created_at': u'2016-09-02T14:01:39Z',
|
|
||||||
u'deleted': False,
|
|
||||||
u'deleted_at': None,
|
|
||||||
u'instance_uuid': u'e3a7-8875e2ccc68b',
|
|
||||||
u'network_info': u'[]',
|
|
||||||
u'updated_at': None},
|
|
||||||
u'nova_object.name': u'InstanceInfoCache',
|
|
||||||
u'nova_object.namespace': u'nova',
|
|
||||||
u'nova_object.version': u'1.5'},
|
|
||||||
u'instance_type_id': 2,
|
|
||||||
u'kernel_id': u'',
|
|
||||||
u'key_data': None,
|
|
||||||
u'key_name': None,
|
|
||||||
u'launch_index': 0,
|
|
||||||
u'launched_at': None,
|
|
||||||
u'launched_on': None,
|
|
||||||
u'locked': False,
|
|
||||||
u'locked_by': None,
|
|
||||||
u'memory_mb': 512,
|
|
||||||
u'metadata': {
|
|
||||||
u'persistent': u'False',
|
|
||||||
u'quota': u'dynamic'},
|
|
||||||
u'new_flavor': None,
|
|
||||||
u'node': None,
|
|
||||||
u'numa_topology': None,
|
|
||||||
u'old_flavor': None,
|
|
||||||
u'os_type': None,
|
|
||||||
u'pci_requests': {
|
|
||||||
u'nova_object.data': {
|
|
||||||
u'instance_uuid': u'e3a7770a-8875e2ccc68b',
|
|
||||||
u'requests': []},
|
|
||||||
u'nova_object.name': u'InstancePCIRequests',
|
|
||||||
u'nova_object.namespace': u'nova',
|
|
||||||
u'nova_object.version': u'1.1'},
|
|
||||||
u'power_state': 0,
|
|
||||||
u'progress': 0,
|
|
||||||
u'project_id': u'd20ac1ffa60841a78a865da63b2399de',
|
|
||||||
u'ramdisk_id': u'',
|
|
||||||
u'reservation_id': u'r-s9v032d0',
|
|
||||||
u'root_device_name': None,
|
|
||||||
u'root_gb': 1,
|
|
||||||
u'security_groups': {
|
|
||||||
u'nova_object.data': {
|
|
||||||
u'objects': []},
|
|
||||||
u'nova_object.name': u'SecurityGroupList',
|
|
||||||
u'nova_object.namespace': u'nova',
|
|
||||||
u'nova_object.version': u'1.0'},
|
|
||||||
u'shutdown_terminate': False,
|
|
||||||
u'system_metadata': {
|
|
||||||
u'image_base_image_ref': u'5100f480-a25e7bf09e',
|
|
||||||
u'image_container_format': u'bare',
|
|
||||||
u'image_disk_format': u'qcow2',
|
|
||||||
u'image_min_disk': u'1',
|
|
||||||
u'image_min_ram': u'0'},
|
|
||||||
u'task_state': u'scheduling',
|
|
||||||
u'terminated_at': None,
|
|
||||||
u'updated_at': None,
|
|
||||||
u'user_data': None,
|
|
||||||
u'user_id': u'4cb9f71a47914d0c8b78a471fd8f7015',
|
|
||||||
u'uuid': u'e3a7770a-dbf6-4b63-8f9a-8875e2ccc68b',
|
|
||||||
u'vcpus': 1,
|
|
||||||
u'vm_mode': None,
|
|
||||||
u'vm_state': u'building'},
|
|
||||||
u'nova_object.name': u'Instance',
|
|
||||||
u'nova_object.namespace': u'nova',
|
|
||||||
u'nova_object.version': u'2.0'}
|
|
||||||
|
|
||||||
self.assertEqual(ist, self.req.getInstance())
|
def test_getId(self):
|
||||||
|
self.assertEqual('999', self.req.getId())
|
||||||
|
|
||||||
def test_get_Image(self):
|
def test_getUserId(self):
|
||||||
im = {u'checksum': u'ee1eca47dc88f4879d8a229cc70a07c6',
|
self.assertEqual('4469ff06d1e', self.req.getUserId())
|
||||||
u'container_format': u'bare',
|
|
||||||
u'created_at': u'2016-03-23T16:47:10.000000',
|
|
||||||
u'deleted': False,
|
|
||||||
u'deleted_at': None,
|
|
||||||
u'disk_format': u'qcow2',
|
|
||||||
u'id': u'5100f480-a40c-46cd-b8b6-ea2e5e7bf09e',
|
|
||||||
u'is_public': True,
|
|
||||||
u'min_disk': 0,
|
|
||||||
u'min_ram': 0,
|
|
||||||
u'name': u'cirros',
|
|
||||||
u'owner': u'1a6edd87f9ec41d8aa64c8f23d719c2a',
|
|
||||||
u'properties': {},
|
|
||||||
u'size': 13287936,
|
|
||||||
u'status': u'active',
|
|
||||||
u'updated_at': u'2016-03-23T16:47:10.000000'}
|
|
||||||
|
|
||||||
self.assertEqual(im, self.req.getImage())
|
def test_getProjectId(self):
|
||||||
|
self.assertEqual('1111111', self.req.getProjectId())
|
||||||
|
|
||||||
def test_get_Context(self):
|
def test_getAction(self):
|
||||||
cont = {u'auth_token': u'f9d8458ef4ae454dad75f4636304079c',
|
self.assertEqual('schedule_and_build_instances', self.req.getAction())
|
||||||
u'domain': None,
|
|
||||||
u'instance_lock_checked': False,
|
|
||||||
u'is_admin': False,
|
|
||||||
u'project_domain': None,
|
|
||||||
u'project_id': u'd20ac1ffa60841a78a865da63b2399de',
|
|
||||||
u'project_name': u'prj_b',
|
|
||||||
u'quota_class': None,
|
|
||||||
u'read_deleted': u'no',
|
|
||||||
u'read_only': False,
|
|
||||||
u'remote_address': u'10.64.31.19',
|
|
||||||
u'request_id': u'req-69c9e7e6-62b2fee1d6e8',
|
|
||||||
u'resource_uuid': None,
|
|
||||||
u'roles': [u'user'],
|
|
||||||
u'service_catalog': [],
|
|
||||||
u'show_deleted': False,
|
|
||||||
u'tenant': u'd20ac1ffa60841a78a865da63b2399de',
|
|
||||||
u'timestamp': u'2016-09-02T14:01:39.284558',
|
|
||||||
u'user': u'4cb9f71a47914d0c8b78a471fd8f7015',
|
|
||||||
u'user_domain': None,
|
|
||||||
u'user_id': u'4cb9f71a47914d0c8b78a471fd8f7015',
|
|
||||||
u'user_identity': u'fa60841a78a865da63b2399de - - -',
|
|
||||||
u'user_name': u'user_b1'}
|
|
||||||
|
|
||||||
self.assertEqual(cont, self.req.getContext())
|
def test_getContext(self):
|
||||||
|
self.assertEqual({}, self.req.getContext())
|
||||||
|
|
||||||
def test_get_FilterProperties(self):
|
def test_getRetry(self):
|
||||||
filt = {u'instance_type': {
|
self.assertEqual({'num_attempts': 1, 'hosts': []}, self.req.getRetry())
|
||||||
u'nova_object.data': {u'created_at': None,
|
|
||||||
u'deleted': False,
|
|
||||||
u'deleted_at': None,
|
|
||||||
u'disabled': False,
|
|
||||||
u'ephemeral_gb': 0,
|
|
||||||
u'extra_specs': {},
|
|
||||||
u'flavorid': u'1',
|
|
||||||
u'id': 2,
|
|
||||||
u'is_public': True,
|
|
||||||
u'memory_mb': 512,
|
|
||||||
u'name': u'm1.tiny',
|
|
||||||
u'root_gb': 1,
|
|
||||||
u'rxtx_factor': 1.0,
|
|
||||||
u'swap': 0,
|
|
||||||
u'updated_at': None,
|
|
||||||
u'vcpu_weight': 0,
|
|
||||||
u'vcpus': 1},
|
|
||||||
u'nova_object.name': u'Flavor',
|
|
||||||
u'nova_object.namespace': u'nova',
|
|
||||||
u'nova_object.version': u'1.1'},
|
|
||||||
u'scheduler_hints': {}}
|
|
||||||
|
|
||||||
self.assertEqual(filt, self.req.getFilterProperties())
|
def test_getServer(self):
|
||||||
|
server = self.req.getServer()
|
||||||
|
self.assertIsNotNone(server)
|
||||||
|
self.assertEqual('999', server.getId())
|
||||||
|
self.assertEqual(datetime(2017, 7, 20, 12, 9, 27),
|
||||||
|
server.getCreatedAt())
|
||||||
|
self.assertEqual('4469ff06d1e', server.getUserId())
|
||||||
|
self.assertEqual('1111111', server.getProjectId())
|
||||||
|
self.assertEqual('mykey', server.getKeyName())
|
||||||
|
self.assertEqual({'quota': 'shared'}, server.getMetadata())
|
||||||
|
self.assertFalse(server.isPermanent())
|
||||||
|
|
||||||
def test_get_InjectedFiles(self):
|
flavor = server.getFlavor()
|
||||||
self.assertEqual([], self.req.getInjectedFiles())
|
self.assertEqual('5cdecdda', flavor.getId())
|
||||||
|
self.assertEqual('m1.tiny', flavor.getName())
|
||||||
|
self.assertEqual(512, flavor.getMemory())
|
||||||
|
self.assertEqual(1, flavor.getVCPUs())
|
||||||
|
self.assertEqual(1, flavor.getStorage())
|
||||||
|
|
||||||
def test_get_RequestedNetworks(self):
|
def test_toDict(self):
|
||||||
self.assertEqual(None, self.req.getRequestedNetworks())
|
|
||||||
|
|
||||||
def test_get_SecurityGroups(self):
|
|
||||||
self.assertEqual([u'default'], self.req.getSecurityGroups())
|
|
||||||
|
|
||||||
def test_get_BlockDeviceMapping(self):
|
|
||||||
self.assertEqual(None, self.req.getBlockDeviceMapping())
|
|
||||||
|
|
||||||
def test_get_LegacyBDM(self):
|
|
||||||
self.assertEqual(True, self.req.getLegacyBDM())
|
|
||||||
|
|
||||||
def test_get_Server(self):
|
|
||||||
prjId = self.req.getServer().getProjectId()
|
|
||||||
self.assertEqual('d20ac1ffa60841a78a865da63b2399de', prjId)
|
|
||||||
|
|
||||||
def test_from_to_Dict(self):
|
|
||||||
rq_dict = self.req.toDict()
|
rq_dict = self.req.toDict()
|
||||||
self.assertEqual(True, rq_dict['legacy_bdm'])
|
self.assertIn("action", rq_dict)
|
||||||
|
self.assertIn("data", rq_dict)
|
||||||
|
self.assertIn("context", rq_dict)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user