def test_resize_quota_exceeds_fails(self): self.mox.StubOutWithMock(flavors, 'get_flavor_by_flavor_id') self.mox.StubOutWithMock(self.compute_api, '_upsize_quota_delta') self.mox.StubOutWithMock(self.compute_api, '_reserve_quota_delta') # Should never reach these. self.mox.StubOutWithMock(self.compute_api, 'update') self.mox.StubOutWithMock(quota.QUOTAS, 'commit') self.mox.StubOutWithMock(self.compute_api, '_record_action_start') self.mox.StubOutWithMock(self.compute_api.compute_task_api, 'migrate_server') fake_inst = obj_base.obj_to_primitive(self._create_instance_obj()) current_flavor = flavors.extract_flavor(fake_inst) fake_flavor = dict(id=200, flavorid='flavor-id', name='foo', disabled=False) flavors.get_flavor_by_flavor_id( 'flavor-id', read_deleted='no').AndReturn(fake_flavor) deltas = dict(resource=0) self.compute_api._upsize_quota_delta( self.context, fake_flavor, current_flavor).AndReturn(deltas) usage = dict(in_use=0, reserved=0) over_quota_args = dict(quotas={'resource': 0}, usages={'resource': usage}, overs=['resource']) self.compute_api._reserve_quota_delta(self.context, deltas, project_id=fake_inst['project_id']).AndRaise( exception.OverQuota(**over_quota_args)) self.mox.ReplayAll() self.assertRaises(exception.TooManyInstances, self.compute_api.resize, self.context, fake_inst, flavor_id='flavor-id')
def test_resize_quota_exceeds_fails(self): self.mox.StubOutWithMock(flavors, 'get_flavor_by_flavor_id') self.mox.StubOutWithMock(self.compute_api, '_upsize_quota_delta') self.mox.StubOutWithMock(self.compute_api, '_reserve_quota_delta') # Should never reach these. self.mox.StubOutWithMock(self.compute_api, 'update') self.mox.StubOutWithMock(quota.QUOTAS, 'commit') self.mox.StubOutWithMock(self.compute_api, '_record_action_start') self.mox.StubOutWithMock(self.compute_api.compute_task_api, 'migrate_server') fake_inst = obj_base.obj_to_primitive(self._create_instance_obj()) current_flavor = flavors.extract_flavor(fake_inst) fake_flavor = dict(id=200, flavorid='flavor-id', name='foo', disabled=False) flavors.get_flavor_by_flavor_id( 'flavor-id', read_deleted='no').AndReturn(fake_flavor) deltas = dict(resource=0) self.compute_api._upsize_quota_delta( self.context, fake_flavor, current_flavor).AndReturn(deltas) usage = dict(in_use=0, reserved=0) over_quota_args = dict(quotas={'resource': 0}, usages={'resource': usage}, overs=['resource']) self.compute_api._reserve_quota_delta(self.context, deltas, project_id=fake_inst['project_id']).AndRaise( exception.OverQuota(**over_quota_args)) self.mox.ReplayAll() self.assertRaises(exception.TooManyInstances, self.compute_api.resize, self.context, fake_inst, flavor_id='flavor-id')
def test_resize_disabled_flavor_fails(self): self.mox.StubOutWithMock(flavors, 'get_flavor_by_flavor_id') # Should never reach these. self.mox.StubOutWithMock(self.compute_api, '_reserve_quota_delta') self.mox.StubOutWithMock(self.compute_api, 'update') self.mox.StubOutWithMock(quota.QUOTAS, 'commit') self.mox.StubOutWithMock(self.compute_api, '_record_action_start') self.mox.StubOutWithMock(self.compute_api.compute_task_api, 'migrate_server') fake_inst = obj_base.obj_to_primitive(self._create_instance_obj()) fake_flavor = dict(id=200, flavorid='flavor-id', name='foo', disabled=True) flavors.get_flavor_by_flavor_id( 'flavor-id', read_deleted='no').AndReturn(fake_flavor) self.mox.ReplayAll() self.assertRaises(exception.FlavorNotFound, self.compute_api.resize, self.context, fake_inst, flavor_id='flavor-id')
def instance_create(context, inst): inst_type = flavors.get_flavor_by_flavor_id(3) image_uuid = "76fa36fc-c930-4bf3-8c8a-ea2a2420deb6" def_image_ref = "http://localhost/images/%s" % image_uuid self.instance_cache_num += 1 instance = fake_instance.fake_db_instance( **{ "id": self.instance_cache_num, "display_name": inst["display_name"] or "test", "uuid": fakes.FAKE_UUID, "instance_type": inst_type, "access_ip_v4": "1.2.3.4", "access_ip_v6": "fead::1234", "image_ref": inst.get("image_ref", def_image_ref), "user_id": "fake", "project_id": "fake", "reservation_id": inst["reservation_id"], "created_at": datetime.datetime(2010, 10, 10, 12, 0, 0), "updated_at": datetime.datetime(2010, 11, 11, 11, 0, 0), "progress": 0, "fixed_ips": [], "task_state": "", "vm_state": "", "root_device_name": inst.get("root_device_name", "vda"), } ) return instance
def resize_vm(uid, flavor_id, context): """ Resizes a VM up or down Update: libvirt now supports resize see: http://wiki.openstack.org/HypervisorSupportMatrix uid -- id of the instance flavor_id -- image reference. context -- the os context """ instance = get_vm(uid, context) kwargs = {} try: flavor = flavors.get_flavor_by_flavor_id(flavor_id) COMPUTE_API.resize(context, instance, flavor_id=flavor['flavorid'], **kwargs) ready = False i = 0 # XXX are 15 secs enough to resize? while not ready and i < 15: i += 1 state = get_vm(uid, context)['vm_state'] if state == 'resized': ready = True import time time.sleep(1) instance = get_vm(uid, context) COMPUTE_API.confirm_resize(context, instance) except Exception as e: raise AttributeError(str(e))
def resize_vm(uid, flavor_id, context): """ Resizes a VM up or down Update: libvirt now supports resize see: http://wiki.openstack.org/HypervisorSupportMatrix uid -- id of the instance flavor_id -- image reference. context -- the os context """ instance = get_vm(uid, context) kwargs = {} try: flavor = flavors.get_flavor_by_flavor_id(flavor_id) COMPUTE_API.resize(context, instance, flavor_id=flavor['flavorid'], **kwargs) ready = False i = 0 # XXX are 15 secs enough to resize? while not ready and i < 15: i += 1 state = get_vm(uid, context)['vm_state'] if state == 'resized': ready = True import time time.sleep(1) instance = get_vm(uid, context) COMPUTE_API.confirm_resize(context, instance) except Exception as e: raise AttributeError(str(e))
def instance_create(context, inst): inst_type = flavors.get_flavor_by_flavor_id(3) image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6' def_image_ref = 'http://localhost/images/%s' % image_uuid self.instance_cache_num += 1 instance = fake_instance.fake_db_instance(**{ 'id': self.instance_cache_num, 'display_name': inst['display_name'] or 'test', 'uuid': FAKE_UUID, 'instance_type': inst_type, 'access_ip_v4': '1.2.3.4', 'access_ip_v6': 'fead::1234', 'image_ref': inst.get('image_ref', def_image_ref), 'user_id': 'fake', 'project_id': 'fake', 'availability_zone': 'nova', 'reservation_id': inst['reservation_id'], "created_at": datetime.datetime(2010, 10, 10, 12, 0, 0), "updated_at": datetime.datetime(2010, 11, 11, 11, 0, 0), "progress": 0, "fixed_ips": [], "task_state": "", "vm_state": "", "root_device_name": inst.get('root_device_name', 'vda'), }) return instance
def instance_create(context, inst): inst_type = flavors.get_flavor_by_flavor_id(3) image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6' def_image_ref = 'http://localhost/images/%s' % image_uuid self.instance_cache_num += 1 instance = fake_instance.fake_db_instance(**{ 'id': self.instance_cache_num, 'display_name': inst['display_name'] or 'test', 'uuid': inst['uuid'], 'instance_type': inst_type, 'access_ip_v4': '1.2.3.4', 'access_ip_v6': 'fead::1234', 'image_ref': inst.get('image_ref', def_image_ref), 'user_id': 'fake', 'project_id': 'fake', 'reservation_id': inst['reservation_id'], "created_at": datetime.datetime(2010, 10, 10, 12, 0, 0), "updated_at": datetime.datetime(2010, 11, 11, 11, 0, 0), "progress": 0, "fixed_ips": [], "task_state": "", "vm_state": "", "security_groups": inst['security_groups'], }) self.instance_cache_by_id[instance['id']] = instance self.instance_cache_by_uuid[instance['uuid']] = instance return instance
def instance_create(context, inst): inst_type = flavors.get_flavor_by_flavor_id(3) image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6' def_image_ref = 'http://localhost/v3/os-images/%s' % image_uuid self.instance_cache_num += 1 instance = { 'id': self.instance_cache_num, 'display_name': inst['display_name'] or 'test', 'uuid': MANUAL_INSTANCE_UUID, 'instance_type': dict(inst_type), 'access_ip_v4': '1.2.3.4', 'access_ip_v6': 'fead::1234', 'image_ref': inst.get('image_ref', def_image_ref), 'user_id': 'fake', 'project_id': 'fake', 'reservation_id': inst['reservation_id'], "created_at": datetime.datetime(2010, 10, 10, 12, 0, 0), "updated_at": datetime.datetime(2010, 11, 11, 11, 0, 0), "user_data": None, "progress": 0, "fixed_ips": [], "task_state": "", "vm_state": "", } self.instance_cache_by_id[instance['id']] = instance self.instance_cache_by_uuid[instance['uuid']] = instance return instance
def test_will_get_instance_by_flavor_id(self): default_instance_type = objects.Flavor.get_by_name( context.get_admin_context(), 'm1.small') flavorid = default_instance_type.flavorid fetched = flavors.get_flavor_by_flavor_id(flavorid) self.assertIsInstance(fetched, objects.Flavor) self.assertEqual(default_instance_type.flavorid, fetched.flavorid)
def _fake_compute_api_create(cls, context, instance_type, image_href, **kwargs): self._block_device_mapping_seen = kwargs.get("block_device_mapping") self._legacy_bdm_seen = kwargs.get("legacy_bdm") inst_type = flavors.get_flavor_by_flavor_id(2) resv_id = None return ( [ { "id": 1, "display_name": "test_server", "uuid": FAKE_UUID, "instance_type": inst_type, "access_ip_v4": "1.2.3.4", "access_ip_v6": "fead::1234", "image_ref": IMAGE_UUID, "user_id": "fake", "project_id": "fake", "created_at": datetime.datetime(2010, 10, 10, 12, 0, 0), "updated_at": datetime.datetime(2010, 11, 11, 11, 0, 0), "progress": 0, "fixed_ips": [], } ], resv_id, )
def instance_create(context, inst): inst_type = flavors.get_flavor_by_flavor_id(3) image_uuid = "76fa36fc-c930-4bf3-8c8a-ea2a2420deb6" def_image_ref = "http://localhost/v3/os-images/%s" % image_uuid self.instance_cache_num += 1 instance = { "id": self.instance_cache_num, "display_name": inst["display_name"] or "test", "uuid": MANUAL_INSTANCE_UUID, "instance_type": dict(inst_type), "access_ip_v4": "1.2.3.4", "access_ip_v6": "fead::1234", "image_ref": inst.get("image_ref", def_image_ref), "user_id": "fake", "project_id": "fake", "reservation_id": inst["reservation_id"], "created_at": datetime.datetime(2010, 10, 10, 12, 0, 0), "updated_at": datetime.datetime(2010, 11, 11, 11, 0, 0), "user_data": None, "progress": 0, "fixed_ips": [], "task_state": "", "vm_state": "", } self.instance_cache_by_id[instance["id"]] = instance self.instance_cache_by_uuid[instance["uuid"]] = instance return instance
def instance_create(context, inst): inst_type = flavors.get_flavor_by_flavor_id(3) image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6' def_image_ref = 'http://localhost/images/{0!s}'.format(image_uuid) self.instance_cache_num += 1 instance = fake_instance.fake_db_instance(**{ 'id': self.instance_cache_num, 'display_name': inst['display_name'] or 'test', 'uuid': inst['uuid'], 'instance_type': inst_type, 'access_ip_v4': '1.2.3.4', 'access_ip_v6': 'fead::1234', 'image_ref': inst.get('image_ref', def_image_ref), 'user_id': 'fake', 'project_id': 'fake', 'reservation_id': inst['reservation_id'], "created_at": datetime.datetime(2010, 10, 10, 12, 0, 0), "updated_at": datetime.datetime(2010, 11, 11, 11, 0, 0), "progress": 0, "fixed_ips": [], "task_state": "", "vm_state": "", "security_groups": inst['security_groups'], }) self.instance_cache_by_id[instance['id']] = instance self.instance_cache_by_uuid[instance['uuid']] = instance return instance
def instance_create(context, inst): inst_type = flavors.get_flavor_by_flavor_id(3) image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6' def_image_ref = 'http://localhost/images/%s' % image_uuid self.instance_cache_num += 1 instance = fake_instance.fake_db_instance( **{ 'id': self.instance_cache_num, 'display_name': inst['display_name'] or 'test', 'uuid': FAKE_UUID, 'instance_type': dict(inst_type), 'access_ip_v4': '1.2.3.4', 'access_ip_v6': 'fead::1234', 'image_ref': inst.get('image_ref', def_image_ref), 'user_id': 'fake', 'project_id': 'fake', 'availability_zone': 'nova', 'reservation_id': inst['reservation_id'], "created_at": datetime.datetime(2010, 10, 10, 12, 0, 0), "updated_at": datetime.datetime(2010, 11, 11, 11, 0, 0), "progress": 0, "fixed_ips": [], "task_state": "", "vm_state": "", "root_device_name": inst.get('root_device_name', 'vda'), }) return instance
def instance_create(context, inst): inst_type = flavors.get_flavor_by_flavor_id(3) image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6' def_image_ref = 'http://localhost/v3/os-images/%s' % image_uuid self.instance_cache_num += 1 instance = { 'id': self.instance_cache_num, 'display_name': inst['display_name'] or 'test', 'uuid': MANUAL_INSTANCE_UUID, 'instance_type': dict(inst_type), 'access_ip_v4': '1.2.3.4', 'access_ip_v6': 'fead::1234', 'image_ref': inst.get('image_ref', def_image_ref), 'user_id': 'fake', 'project_id': 'fake', 'reservation_id': inst['reservation_id'], "created_at": datetime.datetime(2010, 10, 10, 12, 0, 0), "updated_at": datetime.datetime(2010, 11, 11, 11, 0, 0), "user_data": None, "progress": 0, "fixed_ips": [], "task_state": "", "vm_state": "", } self.instance_cache_by_id[instance['id']] = instance self.instance_cache_by_uuid[instance['uuid']] = instance return instance
def instance_create(context, inst): inst_type = flavors.get_flavor_by_flavor_id(3) image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6' def_image_ref = 'http://localhost/images/%s' % image_uuid self.instance_cache_num += 1 instance = fake_instance.fake_db_instance(**{ 'id': self.instance_cache_num, 'display_name': inst['display_name'] or 'test', 'uuid': FAKE_UUID, 'instance_type': inst_type, 'access_ip_v4': '1.2.3.4', 'access_ip_v6': 'fead::1234', 'image_ref': inst.get('image_ref', def_image_ref), 'user_id': 'fake', 'project_id': 'fake', 'reservation_id': inst['reservation_id'], "created_at": datetime.datetime(2010, 10, 10, 12, 0, 0), "updated_at": datetime.datetime(2010, 11, 11, 11, 0, 0), "config_drive": None, "progress": 0, "fixed_ips": [], "task_state": "", "vm_state": "", "root_device_name": inst.get('root_device_name', 'vda'), "security_groups": inst['security_groups'], "extra": {"pci_requests": None, "numa_topology": None}, }) self.instance_cache_by_id[instance['id']] = instance self.instance_cache_by_uuid[instance['uuid']] = instance return instance
def show(self, req, id): """Return data about the given flavor id.""" try: flavor = flavors.get_flavor_by_flavor_id(id) req.cache_db_flavor(flavor) except exception.FlavorNotFound as e: raise webob.exc.HTTPNotFound(explanation=e.format_message()) return self._view_builder.show(req, flavor)
def show(self, req, id): """Return data about the given flavor id.""" try: flavor = flavors.get_flavor_by_flavor_id(id) req.cache_db_flavor(flavor) except exception.NotFound: raise webob.exc.HTTPNotFound() return self._view_builder.show(req, flavor)
def show(self, req, id): """Return data about the given flavor id.""" try: flavor = flavors.get_flavor_by_flavor_id(id) req.cache_db_flavor(flavor) except exception.FlavorNotFound as e: raise webob.exc.HTTPNotFound(explanation=e.format_message()) return self._view_builder.show(req, flavor)
def show(self, req, id): """Return data about the given flavor id.""" try: flavor = flavors.get_flavor_by_flavor_id(id) req.cache_db_flavor(flavor) except exception.NotFound: raise webob.exc.HTTPNotFound() return self._view_builder.show(req, flavor)
def show(self, req, id): """Return data about the given flavor id.""" try: context = req.environ['nova.context'] flavor = flavors.get_flavor_by_flavor_id(id, ctxt=context, read_deleted='no') req.cache_db_flavor(flavor) except exception.NotFound: raise webob.exc.HTTPNotFound() return self._view_builder.show(req, flavor)
def _delete(self, req, id): context = req.environ["nova.context"] authorize(context) try: flavor = flavors.get_flavor_by_flavor_id(id, ctxt=context, read_deleted="no") except exception.FlavorNotFound as e: raise webob.exc.HTTPNotFound(explanation=e.format_message()) flavors.destroy(flavor["name"])
def _delete(self, req, id): context = req.environ['nova.context'] authorize(context) try: flavor = flavors.get_flavor_by_flavor_id( id, ctxt=context, read_deleted="no") except exception.FlavorNotFound as e: raise webob.exc.HTTPNotFound(explanation=e.format_message()) flavors.destroy(flavor['name'])
def test_read_deleted_false_converting_flavorid(self): """Ensure deleted flavors are not returned when not needed (for example when creating a server and attempting to translate from flavorid to instance_type_id. """ flavors.create("instance_type1", 256, 1, 120, 100, "test1") flavors.destroy("instance_type1") flavors.create("instance_type1_redo", 256, 1, 120, 100, "test1") instance_type = flavors.get_flavor_by_flavor_id("test1", read_deleted="no") self.assertEqual("instance_type1_redo", instance_type.name)
def test_resize_invalid_flavor_fails(self): self.mox.StubOutWithMock(flavors, 'get_flavor_by_flavor_id') # Should never reach these. self.mox.StubOutWithMock(self.compute_api, '_reserve_quota_delta') self.mox.StubOutWithMock(self.compute_api, 'update') self.mox.StubOutWithMock(quota.QUOTAS, 'commit') self.mox.StubOutWithMock(self.compute_api, '_record_action_start') self.mox.StubOutWithMock(self.compute_api.compute_task_api, 'migrate_server') fake_inst = obj_base.obj_to_primitive(self._create_instance_obj()) exc = exception.FlavorNotFound(flavor_id='flavor-id') flavors.get_flavor_by_flavor_id('flavor-id', read_deleted='no').AndRaise(exc) self.mox.ReplayAll() self.assertRaises(exception.FlavorNotFound, self.compute_api.resize, self.context, fake_inst, flavor_id='flavor-id')
def show(self, req, id): """Return data about the given flavor id.""" context = req.environ['nova.context'] try: flavor = flavors.get_flavor_by_flavor_id(id, ctxt=context) req.cache_db_flavor(flavor) except exception.FlavorNotFound as e: raise webob.exc.HTTPNotFound(explanation=e.format_message()) include_description = api_version_request.is_supported( req, flavors_view.FLAVOR_DESCRIPTION_MICROVERSION) return self._view_builder.show(req, flavor, include_description)
def test_read_deleted_false_converting_flavorid(self): """Ensure deleted flavors are not returned when not needed (for example when creating a server and attempting to translate from flavorid to instance_type_id. """ flavors.create("instance_type1", 256, 1, 120, 100, "test1") flavors.destroy("instance_type1") flavors.create("instance_type1_redo", 256, 1, 120, 100, "test1") instance_type = flavors.get_flavor_by_flavor_id("test1", read_deleted="no") self.assertEqual("instance_type1_redo", instance_type.name)
def _delete(self, req, id): context = req.environ['nova.context'] authorize(context) try: flavor = flavors.get_flavor_by_flavor_id( id, ctxt=context, read_deleted="no") except exception.FlavorNotFound as e: raise webob.exc.HTTPNotFound(explanation=e.format_message()) flavors.destroy(flavor['name']) return webob.Response(status_int=202)
def test_resize_same_flavor_fails(self): self.mox.StubOutWithMock(flavors, 'get_flavor_by_flavor_id') # Should never reach these. self.mox.StubOutWithMock(self.compute_api, '_reserve_quota_delta') self.mox.StubOutWithMock(self.compute_api, 'update') self.mox.StubOutWithMock(quota.QUOTAS, 'commit') self.mox.StubOutWithMock(self.compute_api, '_record_action_start') self.mox.StubOutWithMock(self.compute_api.compute_task_api, 'migrate_server') fake_inst = obj_base.obj_to_primitive(self._create_instance_obj()) fake_flavor = flavors.extract_flavor(fake_inst) flavors.get_flavor_by_flavor_id( fake_flavor['flavorid'], read_deleted='no').AndReturn(fake_flavor) self.mox.ReplayAll() # Pass in flavor_id.. same as current flavor. self.assertRaises(exception.CannotResizeToSameFlavor, self.compute_api.resize, self.context, fake_inst, flavor_id=fake_flavor['flavorid'])
def test_resize_same_flavor_fails(self): self.mox.StubOutWithMock(flavors, 'get_flavor_by_flavor_id') # Should never reach these. self.mox.StubOutWithMock(self.compute_api, '_reserve_quota_delta') self.mox.StubOutWithMock(self.compute_api, 'update') self.mox.StubOutWithMock(quota.QUOTAS, 'commit') self.mox.StubOutWithMock(self.compute_api, '_record_action_start') self.mox.StubOutWithMock(self.compute_api.compute_task_api, 'migrate_server') fake_inst = obj_base.obj_to_primitive(self._create_instance_obj()) fake_flavor = flavors.extract_flavor(fake_inst) flavors.get_flavor_by_flavor_id( fake_flavor['flavorid'], read_deleted='no').AndReturn(fake_flavor) self.mox.ReplayAll() # Pass in flavor_id.. same as current flavor. self.assertRaises(exception.CannotResizeToSameFlavor, self.compute_api.resize, self.context, fake_inst, flavor_id=fake_flavor['flavorid'])
def test_can_read_deleted_types_using_flavor_id(self): # Ensure deleted flavors can be read when querying flavor_id. inst_type_name = "test" inst_type_flavor_id = "test1" inst_type = flavors.create(inst_type_name, 256, 1, 120, 100, inst_type_flavor_id) self.assertEqual(inst_type_name, inst_type["name"]) # NOTE(jk0): The deleted flavor will show up here because the context # in get_flavor_by_flavor_id() is set to use read_deleted by # default. flavors.destroy(inst_type["name"]) deleted_inst_type = flavors.get_flavor_by_flavor_id(inst_type_flavor_id) self.assertEqual(inst_type_name, deleted_inst_type["name"])
def test_can_read_deleted_types_using_flavor_id(self): # Ensure deleted flavors can be read when querying flavor_id. inst_type_name = "test" inst_type_flavor_id = "test1" inst_type = flavors.create(inst_type_name, 256, 1, 120, 100, inst_type_flavor_id) self.assertEqual(inst_type_name, inst_type.name) # NOTE(jk0): The deleted flavor will show up here because the context # in get_flavor_by_flavor_id() is set to use read_deleted by # default. flavors.destroy(inst_type.name) deleted_inst_type = flavors.get_flavor_by_flavor_id( inst_type_flavor_id) self.assertEqual(inst_type_name, deleted_inst_type.name)
def index(self, req, flavor_id): context = req.environ['nova.context'] authorize(context) try: flavor = flavors.get_flavor_by_flavor_id(flavor_id, ctxt=context) except exception.FlavorNotFound as e: raise webob.exc.HTTPNotFound(explanation=e.format_message()) # public flavor to all projects if flavor['is_public']: explanation = _("Access list not available for public flavors.") raise webob.exc.HTTPNotFound(explanation=explanation) # private flavor to listed projects only return _marshall_flavor_access(flavor_id)
def index(self, req, flavor_id): context = req.environ['nova.context'] authorize(context) try: flavor = flavors.get_flavor_by_flavor_id(flavor_id, ctxt=context) except exception.FlavorNotFound as e: raise webob.exc.HTTPNotFound(explanation=e.format_message()) # public flavor to all projects if flavor['is_public']: explanation = _("Access list not available for public flavors.") raise webob.exc.HTTPNotFound(explanation=explanation) # private flavor to listed projects only return _marshall_flavor_access(flavor_id)
def _delete(self, req, id): context = req.environ['nova.context'] authorize(context) try: flavor = flavors.get_flavor_by_flavor_id( id, ctxt=context, read_deleted="no") except exception.FlavorNotFound as e: raise webob.exc.HTTPNotFound(explanation=e.format_message()) flavors.destroy(flavor['name']) # NOTE(oomichi): Return 202 for backwards compatibility but should be # 204 as this operation complete the deletion of aggregate resource and # return no response body. return webob.Response(status_int=202)
def resize(self, context, instance, flavor_id=None, *args, **kwargs): """Resize (ie, migrate) a running instance. If flavor_id is None, the process is considered a migration, keeping the original flavor_id. If flavor_id is not None, the instance should be migrated to a new host and resized to the new flavor_id. """ super(ComputeCellsAPI, self).resize(context, instance, flavor_id=flavor_id, *args, **kwargs) # NOTE(johannes): If we get to this point, then we know the # specified flavor_id is valid and exists. We'll need to load # it again, but that should be safe. old_instance_type = flavors.extract_flavor(instance) if not flavor_id: new_instance_type = old_instance_type else: new_instance_type = flavors.get_flavor_by_flavor_id( flavor_id, read_deleted="no") # NOTE(johannes): Later, when the resize is confirmed or reverted, # the superclass implementations of those methods will need access # to a local migration record for quota reasons. We don't need # source and/or destination information, just the old and new # flavors. Status is set to 'finished' since nothing else # will update the status along the way. self.db.migration_create( context.elevated(), { 'instance_uuid': instance['uuid'], 'old_instance_type_id': old_instance_type['id'], 'new_instance_type_id': new_instance_type['id'], 'status': 'finished' }) # FIXME(comstud): pass new instance_type object down to a method # that'll unfold it self._cast_to_cells(context, instance, 'resize', flavor_id=flavor_id, *args, **kwargs)
def _delete(self, req, id): context = req.environ['nova.context'] authorize(context) # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks. nova_context.require_admin_context(context) try: flavor = flavors.get_flavor_by_flavor_id( id, ctxt=context, read_deleted="no") except exception.FlavorNotFound as e: raise webob.exc.HTTPNotFound(explanation=e.format_message()) flavors.destroy(flavor['name']) return webob.Response(status_int=202)
def show(self, req, id): """Return data about the given flavor id.""" context = req.environ['nova.context'] try: flavor = flavors.get_flavor_by_flavor_id(id, ctxt=context) except exception.FlavorNotFound as e: raise webob.exc.HTTPNotFound(explanation=e.format_message()) include_extra_specs = False if api_version_request.is_supported( req, flavors_view.FLAVOR_EXTRA_SPECS_MICROVERSION): include_extra_specs = context.can( fes_policies.POLICY_ROOT % 'index', fatal=False) include_description = api_version_request.is_supported( req, flavors_view.FLAVOR_DESCRIPTION_MICROVERSION) return self._view_builder.show( req, flavor, include_description=include_description, include_extra_specs=include_extra_specs)
def show(self, req, id): """Return data about the given flavor id.""" context = req.environ['nova.context'] try: flavor = flavors.get_flavor_by_flavor_id(id, ctxt=context) except exception.FlavorNotFound as e: raise webob.exc.HTTPNotFound(explanation=e.format_message()) include_extra_specs = False if api_version_request.is_supported( req, flavors_view.FLAVOR_EXTRA_SPECS_MICROVERSION): include_extra_specs = context.can( fes_policies.POLICY_ROOT % 'index', fatal=False) include_description = api_version_request.is_supported( req, flavors_view.FLAVOR_DESCRIPTION_MICROVERSION) return self._view_builder.show( req, flavor, include_description=include_description, include_extra_specs=include_extra_specs)
def _delete(self, req, id): context = req.environ['nova.context'] authorize(context) # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks. nova_context.require_admin_context(context) try: flavor = flavors.get_flavor_by_flavor_id(id, ctxt=context, read_deleted="no") except exception.FlavorNotFound as e: raise webob.exc.HTTPNotFound(explanation=e.format_message()) flavors.destroy(flavor['name']) return webob.Response(status_int=202)
def fake_compute_api_create(cls, context, instance_type, image_href, **kwargs): global _block_device_mapping_seen _block_device_mapping_seen = kwargs.get('block_device_mapping') inst_type = flavors.get_flavor_by_flavor_id(2) resv_id = None return ([{'id': 1, 'display_name': 'test_server', 'uuid': FAKE_UUID, 'instance_type': dict(inst_type), 'access_ip_v4': '1.2.3.4', 'access_ip_v6': 'fead::1234', 'image_ref': IMAGE_UUID, 'user_id': 'fake', 'project_id': 'fake', 'created_at': datetime.datetime(2010, 10, 10, 12, 0, 0), 'updated_at': datetime.datetime(2010, 11, 11, 11, 0, 0), 'progress': 0, 'fixed_ips': [] }], resv_id)
def fake_compute_api_create(cls, context, instance_type, image_href, **kwargs): global _block_device_mapping_seen _block_device_mapping_seen = kwargs.get('block_device_mapping') inst_type = flavors.get_flavor_by_flavor_id(2) resv_id = None return ([{ 'id': 1, 'display_name': 'test_server', 'uuid': FAKE_UUID, 'instance_type': dict(inst_type), 'access_ip_v4': '1.2.3.4', 'access_ip_v6': 'fead::1234', 'image_ref': IMAGE_UUID, 'user_id': 'fake', 'project_id': 'fake', 'created_at': datetime.datetime(2010, 10, 10, 12, 0, 0), 'updated_at': datetime.datetime(2010, 11, 11, 11, 0, 0), 'progress': 0, 'fixed_ips': [] }], resv_id)
def resize(self, context, instance, flavor_id=None, *args, **kwargs): """Resize (ie, migrate) a running instance. If flavor_id is None, the process is considered a migration, keeping the original flavor_id. If flavor_id is not None, the instance should be migrated to a new host and resized to the new flavor_id. """ super(ComputeCellsAPI, self).resize(context, instance, flavor_id=flavor_id, *args, **kwargs) # NOTE(johannes): If we get to this point, then we know the # specified flavor_id is valid and exists. We'll need to load # it again, but that should be safe. old_instance_type = flavors.extract_flavor(instance) if not flavor_id: new_instance_type = old_instance_type else: new_instance_type = flavors.get_flavor_by_flavor_id( flavor_id, read_deleted="no") # NOTE(johannes): Later, when the resize is confirmed or reverted, # the superclass implementations of those methods will need access # to a local migration record for quota reasons. We don't need # source and/or destination information, just the old and new # flavors. Status is set to 'finished' since nothing else # will update the status along the way. self.db.migration_create(context.elevated(), {'instance_uuid': instance['uuid'], 'old_instance_type_id': old_instance_type['id'], 'new_instance_type_id': new_instance_type['id'], 'status': 'finished'}) # FIXME(comstud): pass new instance_type object down to a method # that'll unfold it self._cast_to_cells(context, instance, 'resize', flavor_id=flavor_id, *args, **kwargs)
def test_will_get_instance_by_flavor_id(self): default_instance_type = flavors.get_default_flavor() flavorid = default_instance_type['flavorid'] fetched = flavors.get_flavor_by_flavor_id(flavorid) self.assertEqual(default_instance_type, fetched)
def create(self, req, body): """Creates a new server for a given user.""" context = req.environ['nova.context'] server_dict = body['server'] password = self._get_server_admin_password(server_dict) name = common.normalize_name(server_dict['name']) if api_version_request.is_supported(req, min_version='2.19'): if 'description' in server_dict: # This is allowed to be None description = server_dict['description'] else: # No default description description = None else: description = name # Arguments to be passed to instance create function create_kwargs = {} # Query extensions which want to manipulate the keyword # arguments. # NOTE(cyeoh): This is the hook that extensions use # to replace the extension specific code below. # When the extensions are ported this will also result # in some convenience function from this class being # moved to the extension if list(self.create_extension_manager): self.create_extension_manager.map(self._create_extension_point, server_dict, create_kwargs, body) availability_zone = create_kwargs.pop("availability_zone", None) helpers.translate_attributes(helpers.CREATE, server_dict, create_kwargs) target = { 'project_id': context.project_id, 'user_id': context.user_id, 'availability_zone': availability_zone} context.can(server_policies.SERVERS % 'create', target) # TODO(Shao He, Feng) move this policy check to os-availability-zone # extension after refactor it. parse_az = self.compute_api.parse_availability_zone try: availability_zone, host, node = parse_az(context, availability_zone) except exception.InvalidInput as err: raise exc.HTTPBadRequest(explanation=six.text_type(err)) if host or node: context.can(server_policies.SERVERS % 'create:forced_host', {}) block_device_mapping = create_kwargs.get("block_device_mapping") # TODO(Shao He, Feng) move this policy check to os-block-device-mapping # extension after refactor it. if block_device_mapping: context.can(server_policies.SERVERS % 'create:attach_volume', target) image_uuid = self._image_from_req_data(server_dict, create_kwargs) # NOTE(cyeoh): Although an extension can set # return_reservation_id in order to request that a reservation # id be returned to the client instead of the newly created # instance information we do not want to pass this parameter # to the compute create call which always returns both. We use # this flag after the instance create call to determine what # to return to the client return_reservation_id = create_kwargs.pop('return_reservation_id', False) requested_networks = None if ('os-networks' in self.extension_info.get_extensions() or utils.is_neutron()): requested_networks = server_dict.get('networks') if requested_networks is not None: requested_networks = self._get_requested_networks( requested_networks) if requested_networks and len(requested_networks): context.can(server_policies.SERVERS % 'create:attach_network', target) try: flavor_id = self._flavor_id_from_req_data(body) except ValueError: msg = _("Invalid flavorRef provided.") raise exc.HTTPBadRequest(explanation=msg) try: inst_type = flavors.get_flavor_by_flavor_id( flavor_id, ctxt=context, read_deleted="no") (instances, resv_id) = self.compute_api.create(context, inst_type, image_uuid, display_name=name, display_description=description, availability_zone=availability_zone, forced_host=host, forced_node=node, metadata=server_dict.get('metadata', {}), admin_password=password, requested_networks=requested_networks, check_server_group_quota=True, **create_kwargs) except (exception.QuotaError, exception.PortLimitExceeded) as error: raise exc.HTTPForbidden( explanation=error.format_message()) except exception.ImageNotFound: msg = _("Can not find requested image") raise exc.HTTPBadRequest(explanation=msg) except exception.FlavorNotFound: msg = _("Invalid flavorRef provided.") raise exc.HTTPBadRequest(explanation=msg) except exception.KeypairNotFound: msg = _("Invalid key_name provided.") raise exc.HTTPBadRequest(explanation=msg) except exception.ConfigDriveInvalidValue: msg = _("Invalid config_drive provided.") raise exc.HTTPBadRequest(explanation=msg) except exception.ExternalNetworkAttachForbidden as error: raise exc.HTTPForbidden(explanation=error.format_message()) except messaging.RemoteError as err: msg = "%(err_type)s: %(err_msg)s" % {'err_type': err.exc_type, 'err_msg': err.value} raise exc.HTTPBadRequest(explanation=msg) except UnicodeDecodeError as error: msg = "UnicodeError: %s" % error raise exc.HTTPBadRequest(explanation=msg) except (exception.ImageNotActive, exception.ImageBadRequest, exception.FixedIpNotFoundForAddress, exception.FlavorDiskTooSmall, exception.FlavorMemoryTooSmall, exception.InvalidMetadata, exception.InvalidRequest, exception.InvalidVolume, exception.MultiplePortsNotApplicable, exception.InvalidFixedIpAndMaxCountRequest, exception.InstanceUserDataMalformed, exception.InstanceUserDataTooLarge, exception.PortNotFound, exception.FixedIpAlreadyInUse, exception.SecurityGroupNotFound, exception.PortRequiresFixedIP, exception.NetworkRequiresSubnet, exception.NetworkNotFound, exception.NetworkDuplicated, exception.InvalidBDM, exception.InvalidBDMSnapshot, exception.InvalidBDMVolume, exception.InvalidBDMImage, exception.InvalidBDMBootSequence, exception.InvalidBDMLocalsLimit, exception.InvalidBDMVolumeNotBootable, exception.InvalidBDMEphemeralSize, exception.InvalidBDMFormat, exception.InvalidBDMSwapSize, exception.AutoDiskConfigDisabledByImage, exception.ImageNUMATopologyIncomplete, exception.ImageNUMATopologyForbidden, exception.ImageNUMATopologyAsymmetric, exception.ImageNUMATopologyCPUOutOfRange, exception.ImageNUMATopologyCPUDuplicates, exception.ImageNUMATopologyCPUsUnassigned, exception.ImageNUMATopologyMemoryOutOfRange, exception.InstanceGroupNotFound, exception.PciRequestAliasNotDefined, exception.UnableToAutoAllocateNetwork) as error: raise exc.HTTPBadRequest(explanation=error.format_message()) except (exception.PortInUse, exception.InstanceExists, exception.NetworkAmbiguous, exception.NoUniqueMatch) as error: raise exc.HTTPConflict(explanation=error.format_message()) # If the caller wanted a reservation_id, return it if return_reservation_id: # NOTE(cyeoh): In v3 reservation_id was wrapped in # servers_reservation but this is reverted for V2 API # compatibility. In the long term with the tasks API we # will probably just drop the concept of reservation_id return wsgi.ResponseObject({'reservation_id': resv_id}) req.cache_db_instances(instances) server = self._view_builder.create(req, instances[0]) if CONF.enable_instance_password: server['server']['adminPass'] = password robj = wsgi.ResponseObject(server) return self._add_location(robj)
def create(self, req, body): """Creates a new server for a given user.""" context = req.environ['nova.context'] server_dict = body['server'] password = self._get_server_admin_password(server_dict) name = server_dict['name'] # Arguments to be passed to instance create function create_kwargs = {} # Query extensions which want to manipulate the keyword # arguments. # NOTE(cyeoh): This is the hook that extensions use # to replace the extension specific code below. # When the extensions are ported this will also result # in some convenience function from this class being # moved to the extension if list(self.create_extension_manager): self.create_extension_manager.map(self._create_extension_point, server_dict, create_kwargs, body) image_uuid = self._image_from_req_data(server_dict, create_kwargs) # NOTE(cyeoh): Although an extension can set # return_reservation_id in order to request that a reservation # id be returned to the client instead of the newly created # instance information we do not want to pass this parameter # to the compute create call which always returns both. We use # this flag after the instance create call to determine what # to return to the client return_reservation_id = create_kwargs.pop('return_reservation_id', False) requested_networks = None # TODO(cyeoh): bp v3-api-core-as-extensions # Replace with an extension point when the os-networks # extension is ported. Currently reworked # to take into account is_neutron # if (self.ext_mgr.is_loaded('os-networks') # or utils.is_neutron()): # requested_networks = server_dict.get('networks') if utils.is_neutron(): requested_networks = server_dict.get('networks') if requested_networks is not None: requested_networks = self._get_requested_networks( requested_networks) try: flavor_id = self._flavor_id_from_req_data(body) except ValueError as error: msg = _("Invalid flavorRef provided.") raise exc.HTTPBadRequest(explanation=msg) try: inst_type = flavors.get_flavor_by_flavor_id( flavor_id, ctxt=context, read_deleted="no") (instances, resv_id) = self.compute_api.create(context, inst_type, image_uuid, display_name=name, display_description=name, metadata=server_dict.get('metadata', {}), admin_password=password, requested_networks=requested_networks, check_server_group_quota=True, **create_kwargs) except (exception.QuotaError, exception.PortLimitExceeded) as error: raise exc.HTTPForbidden( explanation=error.format_message(), headers={'Retry-After': 0}) except exception.ImageNotFound as error: msg = _("Can not find requested image") raise exc.HTTPBadRequest(explanation=msg) except exception.FlavorNotFound as error: msg = _("Invalid flavorRef provided.") raise exc.HTTPBadRequest(explanation=msg) except exception.KeypairNotFound as error: msg = _("Invalid key_name provided.") raise exc.HTTPBadRequest(explanation=msg) except exception.ConfigDriveInvalidValue: msg = _("Invalid config_drive provided.") raise exc.HTTPBadRequest(explanation=msg) except exception.ExternalNetworkAttachForbidden as error: raise exc.HTTPForbidden(explanation=error.format_message()) except messaging.RemoteError as err: msg = "%(err_type)s: %(err_msg)s" % {'err_type': err.exc_type, 'err_msg': err.value} raise exc.HTTPBadRequest(explanation=msg) except UnicodeDecodeError as error: msg = "UnicodeError: %s" % error raise exc.HTTPBadRequest(explanation=msg) except (exception.ImageNotActive, exception.FlavorDiskTooSmall, exception.FlavorMemoryTooSmall, exception.InvalidMetadata, exception.InvalidRequest, exception.InvalidVolume, exception.MultiplePortsNotApplicable, exception.InvalidFixedIpAndMaxCountRequest, exception.InstanceUserDataMalformed, exception.InstanceUserDataTooLarge, exception.PortNotFound, exception.FixedIpAlreadyInUse, exception.SecurityGroupNotFound, exception.PortRequiresFixedIP, exception.NetworkRequiresSubnet, exception.NetworkNotFound, exception.InvalidBDMVolumeNotBootable, exception.InvalidBDMSnapshot, exception.InvalidBDMVolume, exception.InvalidBDMImage, exception.InvalidBDMBootSequence, exception.InvalidBDMLocalsLimit, exception.InvalidBDMVolumeNotBootable, exception.AutoDiskConfigDisabledByImage) as error: raise exc.HTTPBadRequest(explanation=error.format_message()) except (exception.PortInUse, exception.InstanceExists, exception.NetworkAmbiguous, exception.NoUniqueMatch) as error: raise exc.HTTPConflict(explanation=error.format_message()) # If the caller wanted a reservation_id, return it if return_reservation_id: # NOTE(cyeoh): In v3 reservation_id was wrapped in # servers_reservation but this is reverted for V2 API # compatibility. In the long term with the tasks API we # will probably just drop the concept of reservation_id return wsgi.ResponseObject({'reservation_id': resv_id}) req.cache_db_instances(instances) server = self._view_builder.create(req, instances[0]) if CONF.enable_instance_password: server['server']['adminPass'] = password robj = wsgi.ResponseObject(server) return self._add_location(robj)
def create_vm(entity, context): """ Create a VM for an given OCCI entity. entity -- the OCCI resource entity. context -- the os context. """ # TODO: needs major overhaul! if 'occi.compute.hostname' in entity.attributes: name = entity.attributes['occi.compute.hostname'] else: name = None key_name = key_data = None password = utils.generate_password() access_ip_v4 = None access_ip_v6 = None user_data = None metadata = {} injected_files = [] min_count = max_count = 1 requested_networks = None sg_names = [] availability_zone = None config_drive = None block_device_mapping = None kernel_id = ramdisk_id = None auto_disk_config = None scheduler_hints = None resource_template = None os_template = None for mixin in entity.mixins: if isinstance(mixin, os_mixins.ResourceTemplate): resource_template = mixin elif isinstance(mixin, os_mixins.OsTemplate): os_template = mixin elif mixin == os_addon.OS_KEY_PAIR_EXT: attr = 'org.openstack.credentials.publickey.name' key_name = entity.attributes[attr] attr = 'org.openstack.credentials.publickey.data' key_data = entity.attributes[attr] elif mixin == os_addon.OS_USER_DATA_EXT: attr = 'org.openstack.compute.user_data' user_data = entity.attributes[attr] # Look for security group. If the group is non-existant, the # call to create will fail. if os_addon.SEC_GROUP in mixin.related: secgroup = COMPUTE_API.security_group_api.get(context, name=mixin.term) sg_names.append(secgroup["name"]) if not os_template: raise AttributeError('Please provide a valid OS Template.') if resource_template: inst_type = flavors.get_flavor_by_flavor_id(resource_template.res_id) else: inst_type = None # make the call try: (instances, _reservation_id) = COMPUTE_API.create( context=context, instance_type=inst_type, image_href=os_template.os_id, kernel_id=kernel_id, ramdisk_id=ramdisk_id, min_count=min_count, max_count=max_count, display_name=name, display_description=name, key_name=key_name, key_data=key_data, security_group=sg_names, availability_zone=availability_zone, user_data=user_data, metadata=metadata, injected_files=injected_files, admin_password=password, block_device_mapping=block_device_mapping, access_ip_v4=access_ip_v4, access_ip_v6=access_ip_v6, requested_networks=requested_networks, config_drive=config_drive, auto_disk_config=auto_disk_config, scheduler_hints=scheduler_hints) except Exception as e: raise AttributeError(e.message) # return first instance return instances[0]
def create(self, req, body): """Creates a new server for a given user.""" if not self.is_valid_body(body, 'server'): raise exc.HTTPBadRequest(_("The request body is invalid")) context = req.environ['nova.context'] server_dict = body['server'] password = self._get_server_admin_password(server_dict) if 'name' not in server_dict: msg = _("Server name is not defined") raise exc.HTTPBadRequest(explanation=msg) name = server_dict['name'] self._validate_server_name(name) name = name.strip() # Arguments to be passed to instance create function create_kwargs = {} # Query extensions which want to manipulate the keyword # arguments. # NOTE(cyeoh): This is the hook that extensions use # to replace the extension specific code below. # When the extensions are ported this will also result # in some convenience function from this class being # moved to the extension if list(self.create_extension_manager): self.create_extension_manager.map(self._create_extension_point, server_dict, create_kwargs) image_uuid = self._image_from_req_data(server_dict, create_kwargs) # NOTE(cyeoh): Although an extension can set # return_reservation_id in order to request that a reservation # id be returned to the client instead of the newly created # instance information we do not want to pass this parameter # to the compute create call which always returns both. We use # this flag after the instance create call to determine what # to return to the client return_reservation_id = create_kwargs.pop('return_reservation_id', False) requested_networks = None # TODO(cyeoh): bp v3-api-core-as-extensions # Replace with an extension point when the os-networks # extension is ported. Currently reworked # to take into account is_neutron #if (self.ext_mgr.is_loaded('os-networks') # or utils.is_neutron()): # requested_networks = server_dict.get('networks') if utils.is_neutron(): requested_networks = server_dict.get('networks') if requested_networks is not None: requested_networks = self._get_requested_networks( requested_networks) try: flavor_id = self._flavor_id_from_req_data(body) except ValueError as error: msg = _("Invalid flavor_ref provided.") raise exc.HTTPBadRequest(explanation=msg) try: inst_type = flavors.get_flavor_by_flavor_id(flavor_id, ctxt=context, read_deleted="no") (instances, resv_id) = self.compute_api.create( context, inst_type, image_uuid, display_name=name, display_description=name, metadata=server_dict.get('metadata', {}), admin_password=password, requested_networks=requested_networks, **create_kwargs) except (exception.QuotaError, exception.PortLimitExceeded) as error: raise exc.HTTPRequestEntityTooLarge( explanation=error.format_message(), headers={'Retry-After': 0}) except exception.InvalidMetadataSize as error: raise exc.HTTPRequestEntityTooLarge( explanation=error.format_message()) except exception.ImageNotFound as error: msg = _("Can not find requested image") raise exc.HTTPBadRequest(explanation=msg) except exception.FlavorNotFound as error: msg = _("Invalid flavor_ref provided.") raise exc.HTTPBadRequest(explanation=msg) except exception.KeypairNotFound as error: msg = _("Invalid key_name provided.") raise exc.HTTPBadRequest(explanation=msg) except exception.ConfigDriveInvalidValue: msg = _("Invalid config_drive provided.") raise exc.HTTPBadRequest(explanation=msg) except messaging.RemoteError as err: msg = "%(err_type)s: %(err_msg)s" % { 'err_type': err.exc_type, 'err_msg': err.value } raise exc.HTTPBadRequest(explanation=msg) except UnicodeDecodeError as error: msg = "UnicodeError: %s" % unicode(error) raise exc.HTTPBadRequest(explanation=msg) except (exception.ImageNotActive, exception.FlavorDiskTooSmall, exception.FlavorMemoryTooSmall, exception.InvalidMetadata, exception.InvalidRequest, exception.MultiplePortsNotApplicable, exception.InstanceUserDataMalformed, exception.PortNotFound, exception.SecurityGroupNotFound, exception.NetworkNotFound) as error: raise exc.HTTPBadRequest(explanation=error.format_message()) except (exception.PortInUse, exception.NoUniqueMatch) as error: raise exc.HTTPConflict(explanation=error.format_message()) # If the caller wanted a reservation_id, return it if return_reservation_id: return wsgi.ResponseObject( {'servers_reservation': { 'reservation_id': resv_id }}) req.cache_db_instances(instances) server = self._view_builder.create(req, instances[0]) if CONF.enable_instance_password: server['server']['admin_password'] = password robj = wsgi.ResponseObject(server) return self._add_location(robj)
def create(self, req, body): """Creates a new server for a given user.""" if not self.is_valid_body(body, 'server'): raise exc.HTTPBadRequest(_("The request body is invalid")) context = req.environ['nova.context'] server_dict = body['server'] password = self._get_server_admin_password(server_dict) if 'name' not in server_dict: msg = _("Server name is not defined") raise exc.HTTPBadRequest(explanation=msg) name = server_dict['name'] self._validate_server_name(name) name = name.strip() # Arguments to be passed to instance create function create_kwargs = {} # Query extensions which want to manipulate the keyword # arguments. # NOTE(cyeoh): This is the hook that extensions use # to replace the extension specific code below. # When the extensions are ported this will also result # in some convenience function from this class being # moved to the extension if list(self.create_extension_manager): self.create_extension_manager.map(self._create_extension_point, server_dict, create_kwargs) image_uuid = self._image_from_req_data(server_dict, create_kwargs) # NOTE(cyeoh): Although an extension can set # return_reservation_id in order to request that a reservation # id be returned to the client instead of the newly created # instance information we do not want to pass this parameter # to the compute create call which always returns both. We use # this flag after the instance create call to determine what # to return to the client return_reservation_id = create_kwargs.pop('return_reservation_id', False) requested_networks = None # TODO(cyeoh): bp v3-api-core-as-extensions # Replace with an extension point when the os-networks # extension is ported. Currently reworked # to take into account is_neutron #if (self.ext_mgr.is_loaded('os-networks') # or utils.is_neutron()): # requested_networks = server_dict.get('networks') if utils.is_neutron(): requested_networks = server_dict.get('networks') if requested_networks is not None: requested_networks = self._get_requested_networks( requested_networks) try: flavor_id = self._flavor_id_from_req_data(body) except ValueError as error: msg = _("Invalid flavor_ref provided.") raise exc.HTTPBadRequest(explanation=msg) try: inst_type = flavors.get_flavor_by_flavor_id( flavor_id, ctxt=context, read_deleted="no") (instances, resv_id) = self.compute_api.create(context, inst_type, image_uuid, display_name=name, display_description=name, metadata=server_dict.get('metadata', {}), admin_password=password, requested_networks=requested_networks, **create_kwargs) except (exception.QuotaError, exception.PortLimitExceeded) as error: raise exc.HTTPRequestEntityTooLarge( explanation=error.format_message(), headers={'Retry-After': 0}) except exception.InvalidMetadataSize as error: raise exc.HTTPRequestEntityTooLarge( explanation=error.format_message()) except exception.ImageNotFound as error: msg = _("Can not find requested image") raise exc.HTTPBadRequest(explanation=msg) except exception.FlavorNotFound as error: msg = _("Invalid flavor_ref provided.") raise exc.HTTPBadRequest(explanation=msg) except exception.KeypairNotFound as error: msg = _("Invalid key_name provided.") raise exc.HTTPBadRequest(explanation=msg) except exception.ConfigDriveInvalidValue: msg = _("Invalid config_drive provided.") raise exc.HTTPBadRequest(explanation=msg) except messaging.RemoteError as err: msg = "%(err_type)s: %(err_msg)s" % {'err_type': err.exc_type, 'err_msg': err.value} raise exc.HTTPBadRequest(explanation=msg) except UnicodeDecodeError as error: msg = "UnicodeError: %s" % unicode(error) raise exc.HTTPBadRequest(explanation=msg) except (exception.ImageNotActive, exception.FlavorDiskTooSmall, exception.FlavorMemoryTooSmall, exception.InvalidMetadata, exception.InvalidRequest, exception.MultiplePortsNotApplicable, exception.InstanceUserDataMalformed, exception.PortNotFound, exception.SecurityGroupNotFound, exception.NetworkNotFound) as error: raise exc.HTTPBadRequest(explanation=error.format_message()) except (exception.PortInUse, exception.NoUniqueMatch) as error: raise exc.HTTPConflict(explanation=error.format_message()) # If the caller wanted a reservation_id, return it if return_reservation_id: return wsgi.ResponseObject( {'servers_reservation': {'reservation_id': resv_id}}) req.cache_db_instances(instances) server = self._view_builder.create(req, instances[0]) if CONF.enable_instance_password: server['server']['admin_password'] = password robj = wsgi.ResponseObject(server) return self._add_location(robj)
def _test_resize(self, flavor_id_passed=True, same_host=False, allow_same_host=False, allow_mig_same_host=False, project_id=None, extra_kwargs=None): if extra_kwargs is None: extra_kwargs = {} self.flags(allow_resize_to_same_host=allow_same_host, allow_migrate_to_same_host=allow_mig_same_host) params = {} if project_id is not None: # To test instance w/ different project id than context (admin) params['project_id'] = project_id fake_inst = obj_base.obj_to_primitive( self._create_instance_obj(params=params)) self.mox.StubOutWithMock(flavors, 'get_flavor_by_flavor_id') self.mox.StubOutWithMock(self.compute_api, '_upsize_quota_delta') self.mox.StubOutWithMock(self.compute_api, '_reserve_quota_delta') self.mox.StubOutWithMock(self.compute_api, 'update') self.mox.StubOutWithMock(quota.QUOTAS, 'commit') self.mox.StubOutWithMock(self.compute_api, '_record_action_start') self.mox.StubOutWithMock(self.compute_api.compute_task_api, 'migrate_server') current_flavor = flavors.extract_flavor(fake_inst) if flavor_id_passed: new_flavor = dict(id=200, flavorid='new-flavor-id', name='new_flavor', disabled=False) flavors.get_flavor_by_flavor_id( 'new-flavor-id', read_deleted='no').AndReturn(new_flavor) else: new_flavor = current_flavor resvs = ['resvs'] self.compute_api._upsize_quota_delta( self.context, new_flavor, current_flavor).AndReturn('deltas') self.compute_api._reserve_quota_delta( self.context, 'deltas', project_id=fake_inst['project_id']).AndReturn(resvs) self.compute_api.update(self.context, fake_inst, task_state=task_states.RESIZE_PREP, expected_task_state=None, progress=0, **extra_kwargs).AndReturn(fake_inst) if allow_same_host: filter_properties = {'ignore_hosts': []} else: filter_properties = {'ignore_hosts': [fake_inst['host']]} if not flavor_id_passed and not allow_mig_same_host: filter_properties['ignore_hosts'].append(fake_inst['host']) if self.is_cells: quota.QUOTAS.commit(self.context, resvs, project_id=fake_inst['project_id']) resvs = [] self.compute_api._record_action_start(self.context, fake_inst, 'resize') scheduler_hint = {'filter_properties': filter_properties} self.compute_api.compute_task_api.migrate_server( self.context, fake_inst, scheduler_hint=scheduler_hint, live=False, rebuild=False, flavor=new_flavor, block_migration=None, disk_over_commit=None, reservations=resvs) if self.is_cells: self.mox.StubOutWithMock(self.context, 'elevated') self.mox.StubOutWithMock(self.compute_api.db, 'migration_create') self.mox.StubOutWithMock(self.compute_api, '_cast_to_cells') if flavor_id_passed: flavors.get_flavor_by_flavor_id( 'new-flavor-id', read_deleted='no').AndReturn(new_flavor) self.context.elevated().AndReturn(self.context) self.compute_api.db.migration_create( self.context, dict(instance_uuid=fake_inst['uuid'], old_instance_type_id=current_flavor['id'], new_instance_type_id=new_flavor['id'], status='finished')) self.compute_api._cast_to_cells(self.context, fake_inst, 'resize', flavor_id=new_flavor['flavorid'], **extra_kwargs) self.mox.ReplayAll() if flavor_id_passed: self.compute_api.resize(self.context, fake_inst, flavor_id='new-flavor-id', **extra_kwargs) else: self.compute_api.resize(self.context, fake_inst, **extra_kwargs)
def test_will_get_instance_by_flavor_id(self): default_instance_type = flavors.get_default_flavor() flavorid = default_instance_type.flavorid fetched = flavors.get_flavor_by_flavor_id(flavorid) self.assertIsInstance(fetched, objects.Flavor) self.assertEqual(default_instance_type.flavorid, fetched.flavorid)
def test_will_get_instance_by_flavor_id(self): default_instance_type = flavors.get_default_flavor() flavorid = default_instance_type['flavorid'] fetched = flavors.get_flavor_by_flavor_id(flavorid) self.assertEqual(default_instance_type, fetched)
def stub_instance(id=1, user_id=None, project_id=None, host=None, node=None, vm_state=None, task_state=None, reservation_id="", uuid=FAKE_UUID, image_ref="10", flavor_id="1", name=None, key_name='', access_ipv4=None, access_ipv6=None, progress=0, auto_disk_config=False, display_name=None, display_description=None, include_fake_metadata=True, config_drive=None, power_state=None, nw_cache=None, metadata=None, security_groups=None, root_device_name=None, limit=None, marker=None, launched_at=timeutils.utcnow(), terminated_at=timeutils.utcnow(), availability_zone='', locked_by=None, cleaned=False, memory_mb=0, vcpus=0, root_gb=0, ephemeral_gb=0, instance_type=None, launch_index=0, kernel_id="", ramdisk_id="", user_data=None, system_metadata=None, services=None): if user_id is None: user_id = 'fake_user' if project_id is None: project_id = 'fake_project' if metadata: metadata = [{'key': k, 'value': v} for k, v in metadata.items()] elif include_fake_metadata: metadata = [models.InstanceMetadata(key='seq', value=str(id))] else: metadata = [] inst_type = flavors.get_flavor_by_flavor_id(int(flavor_id)) sys_meta = flavors.save_flavor_info({}, inst_type) sys_meta.update(system_metadata or {}) if host is not None: host = str(host) if key_name: key_data = 'FAKE' else: key_data = '' if security_groups is None: security_groups = [{ "id": 1, "name": "test", "description": "Foo:", "project_id": "project", "user_id": "user", "created_at": None, "updated_at": None, "deleted_at": None, "deleted": False }] # ReservationID isn't sent back, hack it in there. server_name = name or "server%s" % id if reservation_id != "": server_name = "reservation_%s" % (reservation_id, ) info_cache = create_info_cache(nw_cache) if instance_type is None: instance_type = flavors.get_default_flavor() flavorinfo = jsonutils.dumps({ 'cur': instance_type.obj_to_primitive(), 'old': None, 'new': None, }) instance = { "id": int(id), "created_at": datetime.datetime(2010, 10, 10, 12, 0, 0), "updated_at": datetime.datetime(2010, 11, 11, 11, 0, 0), "deleted_at": datetime.datetime(2010, 12, 12, 10, 0, 0), "deleted": None, "user_id": user_id, "project_id": project_id, "image_ref": image_ref, "kernel_id": kernel_id, "ramdisk_id": ramdisk_id, "launch_index": launch_index, "key_name": key_name, "key_data": key_data, "config_drive": config_drive, "vm_state": vm_state or vm_states.ACTIVE, "task_state": task_state, "power_state": power_state, "memory_mb": memory_mb, "vcpus": vcpus, "min_vcpus": vcpus, "max_vcpus": vcpus, "root_gb": root_gb, "ephemeral_gb": ephemeral_gb, "ephemeral_key_uuid": None, "hostname": display_name or server_name, "host": host, "node": node, "instance_type_id": 1, "instance_type": inst_type, "user_data": user_data, "reservation_id": reservation_id, "mac_address": "", "launched_at": launched_at, "terminated_at": terminated_at, "availability_zone": availability_zone, "display_name": display_name or server_name, "display_description": display_description, "locked": locked_by is not None, "locked_by": locked_by, "metadata": metadata, "access_ip_v4": access_ipv4, "access_ip_v6": access_ipv6, "uuid": uuid, "progress": progress, "auto_disk_config": auto_disk_config, "name": "instance-%s" % id, "shutdown_terminate": True, "disable_terminate": False, "security_groups": security_groups, "root_device_name": root_device_name, "system_metadata": utils.dict_to_metadata(sys_meta), "pci_devices": [], "vm_mode": "", "default_swap_device": "", "default_ephemeral_device": "", "launched_on": "", "cell_name": "", "architecture": "", "os_type": "", "extra": { "numa_topology": None, "pci_requests": None, "flavor": flavorinfo, }, "cleaned": cleaned, "services": services } instance.update(info_cache) instance['info_cache']['instance_uuid'] = instance['uuid'] return instance
def create(self, req, body): """Creates a new server for a given user.""" context = req.environ['nova.context'] server_dict = body['server'] password = self._get_server_admin_password(server_dict) name = server_dict['name'] # Arguments to be passed to instance create function create_kwargs = {} # Query extensions which want to manipulate the keyword # arguments. # NOTE(cyeoh): This is the hook that extensions use # to replace the extension specific code below. # When the extensions are ported this will also result # in some convenience function from this class being # moved to the extension if list(self.create_extension_manager): self.create_extension_manager.map(self._create_extension_point, server_dict, create_kwargs, body) image_uuid = self._image_from_req_data(server_dict, create_kwargs) # NOTE(cyeoh): Although an extension can set # return_reservation_id in order to request that a reservation # id be returned to the client instead of the newly created # instance information we do not want to pass this parameter # to the compute create call which always returns both. We use # this flag after the instance create call to determine what # to return to the client return_reservation_id = create_kwargs.pop('return_reservation_id', False) requested_networks = None if ('os-networks' in self.extension_info.get_extensions() or utils.is_neutron()): requested_networks = server_dict.get('networks') if requested_networks is not None: requested_networks = self._get_requested_networks( requested_networks) try: flavor_id = self._flavor_id_from_req_data(body) except ValueError as error: msg = _("Invalid flavorRef provided.") raise exc.HTTPBadRequest(explanation=msg) try: inst_type = flavors.get_flavor_by_flavor_id(flavor_id, ctxt=context, read_deleted="no") (instances, resv_id) = self.compute_api.create( context, inst_type, image_uuid, display_name=name, display_description=name, metadata=server_dict.get('metadata', {}), admin_password=password, requested_networks=requested_networks, check_server_group_quota=True, **create_kwargs) except (exception.QuotaError, exception.PortLimitExceeded) as error: raise exc.HTTPForbidden(explanation=error.format_message(), headers={'Retry-After': 0}) except exception.ImageNotFound: msg = _("Can not find requested image") raise exc.HTTPBadRequest(explanation=msg) except exception.FlavorNotFound: msg = _("Invalid flavorRef provided.") raise exc.HTTPBadRequest(explanation=msg) except exception.KeypairNotFound: msg = _("Invalid key_name provided.") raise exc.HTTPBadRequest(explanation=msg) except exception.ConfigDriveInvalidValue: msg = _("Invalid config_drive provided.") raise exc.HTTPBadRequest(explanation=msg) except exception.ExternalNetworkAttachForbidden as error: raise exc.HTTPForbidden(explanation=error.format_message()) except messaging.RemoteError as err: msg = "%(err_type)s: %(err_msg)s" % { 'err_type': err.exc_type, 'err_msg': err.value } raise exc.HTTPBadRequest(explanation=msg) except UnicodeDecodeError as error: msg = "UnicodeError: %s" % error raise exc.HTTPBadRequest(explanation=msg) except (exception.ImageNotActive, exception.FlavorDiskTooSmall, exception.FlavorMemoryTooSmall, exception.InvalidMetadata, exception.InvalidRequest, exception.InvalidVolume, exception.MultiplePortsNotApplicable, exception.InvalidFixedIpAndMaxCountRequest, exception.InstanceUserDataMalformed, exception.InstanceUserDataTooLarge, exception.PortNotFound, exception.FixedIpAlreadyInUse, exception.SecurityGroupNotFound, exception.PortRequiresFixedIP, exception.NetworkRequiresSubnet, exception.NetworkNotFound, exception.InvalidBDMVolumeNotBootable, exception.InvalidBDMSnapshot, exception.InvalidBDMVolume, exception.InvalidBDMImage, exception.InvalidBDMBootSequence, exception.InvalidBDMLocalsLimit, exception.InvalidBDMVolumeNotBootable, exception.AutoDiskConfigDisabledByImage, exception.ImageNUMATopologyIncomplete, exception.ImageNUMATopologyForbidden, exception.ImageNUMATopologyAsymmetric, exception.ImageNUMATopologyCPUOutOfRange, exception.ImageNUMATopologyCPUDuplicates, exception.ImageNUMATopologyCPUsUnassigned, exception.ImageNUMATopologyMemoryOutOfRange) as error: raise exc.HTTPBadRequest(explanation=error.format_message()) except (exception.PortInUse, exception.InstanceExists, exception.NetworkAmbiguous, exception.NoUniqueMatch) as error: raise exc.HTTPConflict(explanation=error.format_message()) # If the caller wanted a reservation_id, return it if return_reservation_id: # NOTE(cyeoh): In v3 reservation_id was wrapped in # servers_reservation but this is reverted for V2 API # compatibility. In the long term with the tasks API we # will probably just drop the concept of reservation_id return wsgi.ResponseObject({'reservation_id': resv_id}) req.cache_db_instances(instances) server = self._view_builder.create(req, instances[0]) if CONF.enable_instance_password: server['server']['adminPass'] = password robj = wsgi.ResponseObject(server) return self._add_location(robj)
def stub_instance(id, user_id=None, project_id=None, host=None, node=None, vm_state=None, task_state=None, reservation_id="", uuid=FAKE_UUID, image_ref="10", flavor_id="1", name=None, key_name='', access_ipv4=None, access_ipv6=None, progress=0, auto_disk_config=False, display_name=None, include_fake_metadata=True, config_drive=None, power_state=None, nw_cache=None, metadata=None, security_groups=None, root_device_name=None, limit=None, marker=None, launched_at=timeutils.utcnow(), terminated_at=timeutils.utcnow(), availability_zone='', locked_by=None, cleaned=False, memory_mb=0, vcpus=0, root_gb=0, ephemeral_gb=0): if user_id is None: user_id = 'fake_user' if project_id is None: project_id = 'fake_project' if metadata: metadata = [{'key': k, 'value': v} for k, v in metadata.items()] elif include_fake_metadata: metadata = [models.InstanceMetadata(key='seq', value=str(id))] else: metadata = [] inst_type = flavors.get_flavor_by_flavor_id(int(flavor_id)) sys_meta = flavors.save_flavor_info({}, inst_type) if host is not None: host = str(host) if key_name: key_data = 'FAKE' else: key_data = '' if security_groups is None: security_groups = [{"id": 1, "name": "test", "description": "Foo:", "project_id": "project", "user_id": "user", "created_at": None, "updated_at": None, "deleted_at": None, "deleted": False}] # ReservationID isn't sent back, hack it in there. server_name = name or "server%s" % id if reservation_id != "": server_name = "reservation_%s" % (reservation_id, ) info_cache = create_info_cache(nw_cache) instance = { "id": int(id), "created_at": datetime.datetime(2010, 10, 10, 12, 0, 0), "updated_at": datetime.datetime(2010, 11, 11, 11, 0, 0), "deleted_at": datetime.datetime(2010, 12, 12, 10, 0, 0), "deleted": None, "user_id": user_id, "project_id": project_id, "image_ref": image_ref, "kernel_id": "", "ramdisk_id": "", "launch_index": 0, "key_name": key_name, "key_data": key_data, "config_drive": config_drive, "vm_state": vm_state or vm_states.BUILDING, "task_state": task_state, "power_state": power_state, "memory_mb": memory_mb, "vcpus": vcpus, "root_gb": root_gb, "ephemeral_gb": ephemeral_gb, "ephemeral_key_uuid": None, "hostname": display_name or server_name, "host": host, "node": node, "instance_type_id": 1, "instance_type": inst_type, "user_data": "", "reservation_id": reservation_id, "mac_address": "", "scheduled_at": timeutils.utcnow(), "launched_at": launched_at, "terminated_at": terminated_at, "availability_zone": availability_zone, "display_name": display_name or server_name, "display_description": "", "locked": locked_by is not None, "locked_by": locked_by, "metadata": metadata, "access_ip_v4": access_ipv4, "access_ip_v6": access_ipv6, "uuid": uuid, "progress": progress, "auto_disk_config": auto_disk_config, "name": "instance-%s" % id, "shutdown_terminate": True, "disable_terminate": False, "security_groups": security_groups, "root_device_name": root_device_name, "system_metadata": utils.dict_to_metadata(sys_meta), "pci_devices": [], "vm_mode": "", "default_swap_device": "", "default_ephemeral_device": "", "launched_on": "", "cell_name": "", "architecture": "", "os_type": "", "cleaned": cleaned} instance.update(info_cache) instance['info_cache']['instance_uuid'] = instance['uuid'] return instance
def create_vm(entity, context): """ Create a VM for an given OCCI entity. entity -- the OCCI resource entity. context -- the os context. """ # TODO: needs major overhaul! if 'occi.compute.hostname' in entity.attributes: name = entity.attributes['occi.compute.hostname'] else: name = None key_name = key_data = None password = utils.generate_password() access_ip_v4 = None access_ip_v6 = None user_data = None metadata = {} injected_files = [] min_count = max_count = 1 requested_networks = None sg_names = [] availability_zone = None config_drive = None block_device_mapping = None kernel_id = ramdisk_id = None auto_disk_config = None scheduler_hints = None resource_template = None os_template = None for mixin in entity.mixins: if isinstance(mixin, os_mixins.ResourceTemplate): resource_template = mixin elif isinstance(mixin, os_mixins.OsTemplate): os_template = mixin elif mixin == os_addon.OS_KEY_PAIR_EXT: attr = 'org.openstack.credentials.publickey.name' key_name = entity.attributes[attr] attr = 'org.openstack.credentials.publickey.data' key_data = entity.attributes[attr] elif mixin == os_addon.OS_USER_DATA_EXT: attr = 'org.openstack.compute.user_data' user_data = entity.attributes[attr] # Look for security group. If the group is non-existant, the # call to create will fail. if os_addon.SEC_GROUP in mixin.related: secgroup = COMPUTE_API.security_group_api.get(context, name=mixin.term) sg_names.append(secgroup["name"]) if not os_template: raise AttributeError('Please provide a valid OS Template.') # Parse storage links for link in entity.links: if 'occi.storagelink.state' not in link.attributes: continue block_device_mapping = [ { "volume_size": "", "volume_id": link.target.attributes['occi.core.id'], "delete_on_termination": "0", "device_name": link.attributes['occi.storagelink.mountpoint']}] if resource_template: inst_type = flavors.get_flavor_by_flavor_id(resource_template.res_id) else: inst_type = None # make the call try: (instances, _reservation_id) = COMPUTE_API.create( context=context, instance_type=inst_type, image_href=os_template.os_id, kernel_id=kernel_id, ramdisk_id=ramdisk_id, min_count=min_count, max_count=max_count, display_name=name, display_description=name, key_name=key_name, key_data=key_data, security_group=sg_names, availability_zone=availability_zone, user_data=user_data, metadata=metadata, injected_files=injected_files, admin_password=password, block_device_mapping=block_device_mapping, access_ip_v4=access_ip_v4, access_ip_v6=access_ip_v6, requested_networks=requested_networks, config_drive=config_drive, auto_disk_config=auto_disk_config, scheduler_hints=scheduler_hints) except Exception as e: raise AttributeError(e.message) # return first instance return instances[0]