def _test_init_instance_reverts_crashed_migrations(self, old_vm_state=None): power_on = True if (not old_vm_state or old_vm_state == vm_states.ACTIVE) else False sys_meta = {"old_vm_state": old_vm_state} instance = { "uuid": "foo", "vm_state": vm_states.ERROR, "task_state": task_states.RESIZE_MIGRATING, "power_state": power_state.SHUTDOWN, "system_metadata": sys_meta, } fixed = dict(instance, task_state=None) self.mox.StubOutWithMock(compute_utils, "get_nw_info_for_instance") self.mox.StubOutWithMock(utils, "instance_sys_meta") self.mox.StubOutWithMock(self.compute.driver, "plug_vifs") self.mox.StubOutWithMock(self.compute.driver, "finish_revert_migration") self.mox.StubOutWithMock(self.compute, "_get_instance_volume_block_device_info") self.mox.StubOutWithMock(self.compute.driver, "get_info") self.mox.StubOutWithMock(self.compute, "_instance_update") compute_utils.get_nw_info_for_instance(instance).AndReturn(network_model.NetworkInfo()) self.compute.driver.plug_vifs(instance, []) utils.instance_sys_meta(instance).AndReturn(sys_meta) self.compute._get_instance_volume_block_device_info(self.context, instance).AndReturn([]) self.compute.driver.finish_revert_migration(instance, [], [], power_on) self.compute._instance_update(self.context, instance["uuid"], task_state=None).AndReturn(fixed) self.compute.driver.get_info(fixed).AndReturn({"state": power_state.SHUTDOWN}) self.mox.ReplayAll() self.compute._init_instance(self.context, instance)
def _prepare_instance(self, context, instance): instance["name"] = instance["display_name"] instance["status"] = self._status_map.get( instance["vm_state"], instance["vm_state"]) image_id = instance["image_ref"] if image_id is None or len(image_id) == 0: image_id = instance["system_metadata"]["image_base_image_ref"] if image_id is None or len(image_id) == 0: image_id = instance["system_metadata"]["image_image_id"] image = image_api.API().get_item_by_id(context, image_id) if image is not None: instance["image"] = image['name'] instance["cached_nwinfo"] = \ compute_utils.get_nw_info_for_instance(instance) attached_disks = db.block_device_mapping_get_all_by_instance( nova_context.get_admin_context(), instance['uuid']) for disk in attached_disks: if disk["volume_id"] is not None: disk["volume"] = disk_api.API().get_item_by_id( context, disk["volume_id"]) instance["attached_disks"] = attached_disks return instance
def add_floating_ip(uid, pool_name, context): """ Adds an ip to an VM instance. uid -- id of the VM. pool_name -- name of the pool context -- The os context. """ vm_instance = vm.get_vm(uid, context) cached_nwinfo = utils.get_nw_info_for_instance(vm_instance) if not cached_nwinfo: raise AttributeError('No nw_info cache associated with instance') fixed_ips = cached_nwinfo.fixed_ips() if not fixed_ips: raise AttributeError('No fixed ips associated to instance') float_address = NETWORK_API.allocate_floating_ip(context, pool_name) try: address = fixed_ips[0]['address'] NETWORK_API.associate_floating_ip(context, vm_instance, float_address, address) except exception.FloatingIpAssociated: msg = 'floating ip is already associated' raise AttributeError(msg) except exception.NoFloatingIpInterface: msg = 'l3driver call to add floating ip failed' raise AttributeError(msg) return float_address
def get_vif_for_provider_ip(self, context, **kwargs): """Return the VIF for a VM.""" provider_ip = kwargs['provider_ip'] LOG.debug("provider ip = % s" % provider_ip) # retrieve the instance id from the provider ip # from the nova metadata filters = { 'filter': [{'name': 'tag:provider_ip', 'value': provider_ip}] } instances = objects.InstanceList.get_by_filters( context, filters=filters) # should return only one and check it if len(instances) == 1: instance = instances[0] vif_id = instance.metadata['ip_%s' % provider_ip] hyper_net_info = compute_utils.get_nw_info_for_instance(instance) hyper_vif = None for vif in hyper_net_info: if vif.get('id') == vif_id: hyper_vif = vif break neutron = neutronapi.get_client(context, admin=True) check_host_exist(neutron, instance.uuid) neutron.update_port(hyper_vif, {'port': {'binding:host_id': instance.uuid}}) return {'instance_id': instance.uuid, 'hyper_vif': hyper_vif} else: return None
def _add_floating_ip(self, req, id, body): """Associate floating_ip to an instance.""" context = req.environ['nova.context'] authorize(context) address = body['addFloatingIp']['address'] instance = common.get_instance(self.compute_api, context, id, want_objects=True) cached_nwinfo = compute_utils.get_nw_info_for_instance(instance) if not cached_nwinfo: msg = _('No nw_info cache associated with instance') raise webob.exc.HTTPBadRequest(explanation=msg) fixed_ips = cached_nwinfo.fixed_ips() if not fixed_ips: msg = _('No fixed ips associated to instance') raise webob.exc.HTTPBadRequest(explanation=msg) fixed_address = None if 'fixed_address' in body['addFloatingIp']: fixed_address = body['addFloatingIp']['fixed_address'] for fixed in fixed_ips: if fixed['address'] == fixed_address: break else: msg = _('Specified fixed address not assigned to instance') raise webob.exc.HTTPBadRequest(explanation=msg) if not fixed_address: fixed_address = fixed_ips[0]['address'] if len(fixed_ips) > 1: LOG.warning(_LW('multiple fixed_ips exist, using the first: ' '%s'), fixed_address) try: self.network_api.associate_floating_ip(context, instance, floating_address=address, fixed_address=fixed_address) except exception.FloatingIpAssociated: msg = _('floating ip is already associated') raise webob.exc.HTTPBadRequest(explanation=msg) except exception.NoFloatingIpInterface: msg = _('l3driver call to add floating ip failed') raise webob.exc.HTTPBadRequest(explanation=msg) except exception.FloatingIpNotFoundForAddress: msg = _('floating ip not found') raise webob.exc.HTTPNotFound(explanation=msg) except exception.Forbidden as e: raise webob.exc.HTTPForbidden(explanation=e.format_message()) except Exception as e: msg = _('Unable to associate floating ip %(address)s to ' 'fixed ip %(fixed_address)s for instance %(id)s. ' 'Error: %(error)s') % ( {'address': address, 'fixed_address': fixed_address, 'id': id, 'error': e}) LOG.exception(msg) raise webob.exc.HTTPBadRequest(explanation=msg) return webob.Response(status_int=202)
def get_vifs_for_instance(self, context, **kwargs): """Return the list of VIF for an instance.""" instance_id = kwargs['instance_id'] LOG.debug('get_vifs_for_instance %s' % instance_id) instance = objects.Instance.get_by_uuid( nova_context.get_admin_context(), instance_id) hyper_net_info = compute_utils.get_nw_info_for_instance(instance) neutron = neutronapi.get_client(context, admin=True) check_host_exist(neutron, instance_id) tenant_ids = [] LOG.debug('hyper_net_info: %s' % hyper_net_info) for vif in hyper_net_info: tenant_ids.append(vif['network']['meta']['tenant_id']) neutron.update_port(vif['id'], {'port': {'binding:host_id': instance_id}}) # get all the tenant router LOG.debug('tenant_ids: %s' % tenant_ids) for tenant_id in tenant_ids: routers = neutron.list_routers({'tenant_id': tenant_id})['routers'] LOG.debug('routers: %s' % routers) for router in routers: neutron.update_router(router['id'], {'router': {'admin_state_up': 'False'}}) neutron.update_router(router['id'], {'router': {'admin_state_up': 'True'}}) return hyper_net_info
def get_vifs_for_instance(self, context, **kwargs): """Return the list of VIF for an instance.""" instance_id = kwargs['instance_id'] LOG.debug("get_vifs_for_instance %s" % instance_id) instance = objects.Instance.get_by_uuid( nova_context.get_admin_context(), instance_id) net_info = compute_utils.get_nw_info_for_instance(instance) # TODO: retrieve the provider_net_info (IP/MAC) return {'net_info': net_info, 'provider_net_info': [None, None, None]}
def _get_instances_with_network(self, context, network, zone_id): affected_instances = [] network_id = network['id'] instances = self.get_items(context, zone_id) for instance in instances: cached_nwinfo = compute_utils.get_nw_info_for_instance(instance) if cached_nwinfo: for network_info in cached_nwinfo: if network_id == network_info['network']['id']: affected_instances.append(instance) return affected_instances
def _add_floating_ip(self, req, id, body): """Associate floating_ip to an instance.""" context = req.environ['nova.context'] authorize(context) try: address = body['addFloatingIp']['address'] except TypeError: msg = _("Missing parameter dict") raise webob.exc.HTTPBadRequest(explanation=msg) except KeyError: msg = _("Address not specified") raise webob.exc.HTTPBadRequest(explanation=msg) instance = self.compute_api.get(context, id) cached_nwinfo = compute_utils.get_nw_info_for_instance(instance) if not cached_nwinfo: msg = _('No nw_info cache associated with instance') raise webob.exc.HTTPBadRequest(explanation=msg) fixed_ips = cached_nwinfo.fixed_ips() if not fixed_ips: msg = _('No fixed ips associated to instance') raise webob.exc.HTTPBadRequest(explanation=msg) # TODO(tr3buchet): this will associate the floating IP with the # first fixed_ip an instance has. This should be # changed to support specifying a particular fixed_ip if # multiple exist. if len(fixed_ips) > 1: msg = _('multiple fixed_ips exist, using the first: %s') LOG.warning(msg, fixed_ips[0]['address']) try: self.network_api.associate_floating_ip(context, instance, floating_address=address, fixed_address=fixed_ips[0]['address']) except exception.FloatingIpAssociated: msg = _('floating ip is already associated') raise webob.exc.HTTPBadRequest(explanation=msg) except exception.NoFloatingIpInterface: msg = _('l3driver call to add floating ip failed') raise webob.exc.HTTPBadRequest(explanation=msg) except (exception.FloatingIpNotFoundForAddress, exception.NotAuthorized): msg = _('floating ip not found') raise webob.exc.HTTPNotFound(explanation=msg) except Exception: msg = _('Error. Unable to associate floating ip') LOG.exception(msg) raise webob.exc.HTTPBadRequest(explanation=msg) return webob.Response(status_int=202)
def _get_existing_networks(self, context, server_id): """Returns networks a server is already connected to.""" instance = self.get_instance(context, server_id) nw_info = compute_utils.get_nw_info_for_instance(instance) networks = [] for vif in nw_info: networks.append(vif["network"]["id"]) if not networks: return set() return set(networks)
def _test_init_instance_reverts_crashed_migrations(self, old_vm_state=None): power_on = True if (not old_vm_state or old_vm_state == vm_states.ACTIVE) else False sys_meta = { 'old_vm_state': old_vm_state } instance = { 'uuid': 'foo', 'vm_state': vm_states.ERROR, 'task_state': task_states.RESIZE_MIGRATING, 'power_state': power_state.SHUTDOWN, 'system_metadata': sys_meta } fixed = dict(instance, task_state=None) self.mox.StubOutWithMock(compute_utils, 'get_nw_info_for_instance') self.mox.StubOutWithMock(utils, 'instance_sys_meta') self.mox.StubOutWithMock(self.compute.driver, 'plug_vifs') self.mox.StubOutWithMock(self.compute.driver, 'finish_revert_migration') self.mox.StubOutWithMock(self.compute, '_get_instance_volume_block_device_info') self.mox.StubOutWithMock(self.compute.driver, 'get_info') self.mox.StubOutWithMock(self.compute, '_instance_update') compute_utils.get_nw_info_for_instance(instance).AndReturn( network_model.NetworkInfo()) self.compute.driver.plug_vifs(instance, []) utils.instance_sys_meta(instance).AndReturn(sys_meta) self.compute._get_instance_volume_block_device_info( self.context, instance).AndReturn([]) self.compute.driver.finish_revert_migration(instance, [], [], power_on) self.compute._instance_update(self.context, instance['uuid'], task_state=None).AndReturn(fixed) self.compute.driver.get_info(fixed).AndReturn( {'state': power_state.SHUTDOWN}) self.mox.ReplayAll() self.compute._init_instance(self.context, instance)
def get_networks_for_instance(context, instance): """Returns a prepared nw_info list for passing into the view builders We end up with a data structure like:: {'public': {'ips': [{'addr': '10.0.0.1', 'version': 4}, {'addr': '2001::1', 'version': 6}], 'floating_ips': [{'addr': '172.16.0.1', 'version': 4}, {'addr': '172.16.2.1', 'version': 4}]}, ...} """ nw_info = compute_utils.get_nw_info_for_instance(instance) return get_networks_for_instance_from_nw_info(nw_info)
def _get_network_info(self, context, server_id, entity_maker): """Returns a list of VIFs, transformed through entity_maker.""" instance = self._get_instance(context, server_id) nw_info = compute_utils.get_nw_info_for_instance(instance) vifs = [] for vif in nw_info: addr = [dict(network_id=vif["network"]["id"], network_label=vif["network"]["label"], address=ip["address"]) for ip in vif.fixed_ips()] v = dict(address=vif["address"], id=vif["id"], ip_addresses=addr) vifs.append(entity_maker(context, v)) return {'virtual_interfaces': vifs}
def _gather_port_ids(self, context, instance, port_ids=None): """Return an instance's complete list of port_ids.""" ifaces = compute_utils.get_nw_info_for_instance(instance) # This code path is only done when refreshing the network_cache if port_ids is None: port_ids = [iface['id'] for iface in ifaces] else: # an interface was added/removed from instance. # Include existing interfaces so they are not removed from the db. port_ids = [iface['id'] for iface in ifaces] + port_ids return port_ids
def __init__(self, instance, **kwargs): super(InstancePayload, self).__init__(**kwargs) # Note(gibi): ugly but needed to avoid cyclic import from nova.compute import utils network_info = utils.get_nw_info_for_instance(instance) ips = IpPayload.from_network_info(network_info) flavor = flavor_payload.FlavorPayload(flavor=instance.flavor) super(InstancePayload, self).__init__( ip_addresses=ips, flavor=flavor, **kwargs) self.populate_schema(instance=instance)
def add_flaoting_ip_to_vm(uid, attributes, context): """ Adds an ip to an VM instance. uid -- id of the VM. attributes -- the call attributes (dict) context -- The os context. """ vm_instance = vm.get_vm(uid, context) cached_nwinfo = compute_utils.get_nw_info_for_instance(vm_instance) if not cached_nwinfo: raise AttributeError('No nw_info cache associated with instance') fixed_ips = cached_nwinfo.fixed_ips() if not fixed_ips: raise AttributeError('No fixed ips associated to instance') if 'org.openstack.network.floating.pool' not in attributes: pool = None else: pool = attributes['org.openstack.network.floating.pool'] float_address = NETWORK_API.allocate_floating_ip(context, pool) if len(fixed_ips) > 1: LOG.warn('multiple fixed_ips exist, using the first') try: address = fixed_ips[0]['address'] NETWORK_API.associate_floating_ip(context, vm_instance, floating_address=float_address, fixed_address=address) except exception.FloatingIpAssociated: msg = 'floating ip is already associated' raise AttributeError(msg) except exception.NoFloatingIpInterface: msg = 'l3driver call to add floating ip failed' raise AttributeError(msg) except Exception as error: msg = 'Error. Unable to associate floating ip' + str(error) raise AttributeError(msg) return float_address
def _build_network_info_model(self, context, instance, networks=None, port_ids=None): LOG.debug('Enter _build_network_info_model with instance %s and ' 'networks %s' % (instance['project_id'], networks)) # Get all the nova networks associated with the neutron network passed # in. If no neutron network was passed in, this will return all nova # networks. net_infos = [] if networks is None and port_ids is None: # We need to check to see if the cache thinks we're none as well network_info = compute_utils.get_nw_info_for_instance(instance) # If the network info is an empty list...it may be valid. However, # it is improbable. We should go query against the master list, # which is neutron. if network_info is None or len(network_info) == 0: net_infos = self._update_instance_nw_cache(instance, context) # We didn't get the network infos - this could mean that the cache data # on the instance is proper. So let's call neutron's parent API and # get network details. if net_infos == []: net_infos = super(PowerVMAPI, self)._build_network_info_model(context, instance, networks, port_ids) LOG.debug('Found net_infos %s' % net_infos) # Get the neutron networks related to our instance if the invoker did # not pass them in. if not networks: networks = self._get_available_networks(context, instance['project_id']) msg = (ras.vif_get_msg ('info', 'NO_NET_FOUND') % {'host': instance['host']}) ras.function_tracepoint(LOG, __name__, ras.TRACE_INFO, msg) # Pare down the nova networks list to only include those that map to # the neutron network we're interested in. This will also add in the # vlan id to the nova network object. return self._match_network_models(networks, net_infos, context)
def get_networks_for_instance(context, instance): """Returns a prepared nw_info list for passing into the view builders We end up with a data structure like:: {'public': {'ips': [{'address': '10.0.0.1', 'version': 4, 'mac_address': 'aa:aa:aa:aa:aa:aa'}, {'address': '2001::1', 'version': 6, 'mac_address': 'aa:aa:aa:aa:aa:aa'}], 'floating_ips': [{'address': '172.16.0.1', 'version': 4, 'mac_address': 'aa:aa:aa:aa:aa:aa'}, {'address': '172.16.2.1', 'version': 4, 'mac_address': 'aa:aa:aa:aa:aa:aa'}]}, ...} """ nw_info = compute_utils.get_nw_info_for_instance(instance) return get_networks_for_instance_from_nw_info(nw_info)
def _gather_port_ids_and_networks(self, context, instance, networks=None, port_ids=None): """Return an instance's complete list of port_ids and networks.""" if (networks is None and port_ids is not None) or (port_ids is None and networks is not None): message = ( "This method needs to be called with either " "networks=None and port_ids=None or port_ids and " " networks as not none." ) raise exception.NovaException(message=message) ifaces = compute_utils.get_nw_info_for_instance(instance) # This code path is only done when refreshing the network_cache if port_ids is None: port_ids = [iface["id"] for iface in ifaces] net_ids = [iface["network"]["id"] for iface in ifaces] if networks is None: networks = self._get_available_networks(context, instance["project_id"], net_ids) # an interface was added/removed from instance. else: # Since networks does not contain the existing networks on the # instance we use their values from the cache and add it. networks = networks + [ { "id": iface["network"]["id"], "name": iface["network"]["label"], "tenant_id": iface["network"]["meta"]["tenant_id"], } for iface in ifaces ] # Include existing interfaces so they are not removed from the db. port_ids = [iface["id"] for iface in ifaces] + port_ids iface_slot_map = {} for iface in ifaces: iface_slot_map[iface["id"]] = iface["meta"].get("pci_slotnum", None) return networks, port_ids, iface_slot_map
def _vpn_dict(self, context, project_id, instance): elevated = context.elevated() rv = {"project_id": project_id} if not instance: rv["state"] = "pending" return rv rv["instance_id"] = instance["uuid"] rv["created_at"] = timeutils.isotime(instance["created_at"]) nw_info = compute_utils.get_nw_info_for_instance(instance) if not nw_info: return rv vif = nw_info[0] ips = [ip for ip in vif.fixed_ips() if ip["version"] == 4] if ips: rv["internal_ip"] = ips[0]["address"] # NOTE(vish): Currently network_api.get does an owner check on # project_id. This is probably no longer necessary # but rather than risk changes in the db layer, # we are working around it here by changing the # project_id in the context. This can be removed # if we remove the project_id check in the db. elevated.project_id = project_id network = self.network_api.get(elevated, vif["network"]["id"]) if network: vpn_ip = network["vpn_public_address"] vpn_port = network["vpn_public_port"] rv["public_ip"] = vpn_ip rv["public_port"] = vpn_port if vpn_ip and vpn_port: if utils.vpn_ping(vpn_ip, vpn_port): rv["state"] = "running" else: rv["state"] = "down" else: rv["state"] = "invalid" return rv
def _vpn_dict(self, context, project_id, instance): elevated = context.elevated() rv = {'project_id': project_id} if not instance: rv['state'] = 'pending' return rv rv['instance_id'] = instance['uuid'] rv['created_at'] = timeutils.isotime(instance['created_at']) nw_info = compute_utils.get_nw_info_for_instance(instance) if not nw_info: return rv vif = nw_info[0] ips = [ip for ip in vif.fixed_ips() if ip['version'] == 4] if ips: rv['internal_ip'] = ips[0]['address'] # NOTE(vish): Currently network_api.get does an owner check on # project_id. This is probably no longer necessary # but rather than risk changes in the db layer, # we are working around it here by changing the # project_id in the context. This can be removed # if we remove the project_id check in the db. elevated.project_id = project_id network = self.network_api.get(elevated, vif['network']['id']) if network: vpn_ip = network['vpn_public_address'] vpn_port = network['vpn_public_port'] rv['public_ip'] = vpn_ip rv['public_port'] = vpn_port if vpn_ip and vpn_port: if utils.vpn_ping(vpn_ip, vpn_port): rv['state'] = 'running' else: rv['state'] = 'down' else: rv['state'] = 'invalid' return rv
def test_instance_object_none_info_cache(self): inst = fake_instance.fake_instance_obj('fake-context', expected_attrs=['info_cache']) self.assertIsNone(inst.info_cache) result = compute_utils.get_nw_info_for_instance(inst) self.assertEqual(jsonutils.dumps([]), result.json())
def run(self): bdms = objects.BlockDeviceMappingList.get_by_instance_uuid( self.context, self.instance['uuid']) is_boot_from_image = False #save the volume volume_dict_for_boot_index = {} volume_dict_for_image_id ={} volume_dict_for_mountpoint ={} block_device_mapping = None volume_ids = [] system_volume_image_id = None #step1 get the source instance info instance = common.get_instance(self.compute_api, self.context, self.instance.uuid, want_objects=True) for bdm in bdms: if bdm.image_id is not None and bdm.boot_index == 0 and bdm.destination_type =='local': is_boot_from_image =True system_volume_image_id = bdm.image_id if bdm.volume_id is not None: if bdm.boot_index == 0: volume = self.volume_api.get(self.context, bdm.volume_id) volume_image_metadata = volume.get('volume_metadata') system_volume_image_id = volume_image_metadata['image_id'] volume_dict_for_boot_index[bdm.volume_id]=bdm.boot_index volume_ids.append(bdm.volume_id) volume_dict_for_mountpoint[bdm.volume_id] =bdm.device_name #step2 stop the instance self._stop_instance(instance) #step3 create image of vm and volume boot_image_uuid = None if is_boot_from_image: if self.migrate_system_volume is False: boot_image_uuid = system_volume_image_id else: tmp_image_name = "%s@%s" % (uuid.uuid1(), self.instance.uuid) instance = common.get_instance(self.compute_api, self.context, self.instance.uuid, want_objects=True) image_meta = self.compute_api.snapshot(self.context, instance, name=tmp_image_name, extra_properties=None) query_image_status_count=1800 filters = {'name':tmp_image_name} imagelist = self.image_api.get_all(self.context,filters=filters) image = imagelist[0] while image['status'] != 'active': time.sleep(1) imagelist = self.image_api.get_all(self.context,filters=filters) image = imagelist[0] #image_uuid = image['id'] #image = self.image_api.get(self.context,image_uuid ) if image['status'] =='error': msg = _("migrate vm failed.") raise exc.HTTPBadRequest(explanation=msg) query_image_status_count = query_image_status_count-1 if query_image_status_count == 0 and image['status'] != 'active': msg = _("migrate vm failed.") raise exc.HTTPBadRequest(explanation=msg) boot_image_uuid =image['id'] #data_volume upload to glance #import pdb #pdb.set_trace() volume_dict_for_image_id= self._upload_volume_to_image(volume_ids, volume_dict_for_boot_index) else : instance.task_state = task_states.IMAGE_SNAPSHOT instance.save() if self.migrate_system_volume is False: boot_image_uuid = system_volume_image_id volume_dict_for_image_id = self._upload_volume_to_image(volume_ids, volume_dict_for_boot_index) try: #step4 create the target volume source_target_vol_mapping = self._create_target_volume(volume_dict_for_image_id) #step5 check the volume status self._check_volume_status(source_target_vol_mapping) except exc.HTTPBadRequest as e: #exception occurred,reset the instance task_state LOG.error('error occur when create target volume') instance.task_state = None instance.save() raise e #reset the instance task_state instance.task_state = None instance.save() #step6 prepare the params of create vm block_device_mapping=self._create_bdm(source_target_vol_mapping, volume_dict_for_boot_index, volume_dict_for_mountpoint) access_ip_v4 = instance.access_ip_v4 if access_ip_v4 is not None: self._validate_access_ipv4(access_ip_v4) access_ip_v6 = instance.access_ip_v6 if access_ip_v6 is not None: self._validate_access_ipv6(access_ip_v6) #networks = common.get_networks_for_instance(context, instance) min_count = 1 max_count = 1 name=instance.display_name key_name = None metadata = instance.metadata injected_files = [] security_group=instance.security_groups user_data=instance.user_data flavor_id = instance.system_metadata['instance_type_flavorid'] scheduler_hints = {} #check_server_group_quota = \ # self.ext_mgr.is_loaded('os-server-group-quotas') check_server_group_quota=True requested_networks = [] nw_info = compute_utils.get_nw_info_for_instance(instance) for vif in nw_info: net_uuid = vif['network']['id'] net_ip = vif['network']['subnets'][0]['ips'][0]['address'] requested_networks.append({'fixed_ip':net_ip, 'uuid':net_uuid}) requested_networks = self._get_requested_networks(requested_networks) #update the instance metadata the metadata use for vcloud delete vm self.compute_api.update_instance_metadata(self.context,instance,{'quick_delete_once': 'True'},delete=False) #TODO detach port delete #step7 delete the vm self.compute_api.delete(self.context,instance) #import pdb #pdb.set_trace() #step8 create vm while True: time.sleep(3) try: _get_inst_type = flavors.get_flavor_by_flavor_id inst_type = _get_inst_type(flavor_id, ctxt=self.context, read_deleted="no") (instances, resv_id) = self.compute_api.create(self.context, inst_type, boot_image_uuid, display_name=name, display_description=name, key_name=key_name, metadata=metadata, access_ip_v4=access_ip_v4, access_ip_v6=access_ip_v6, injected_files=injected_files, admin_password=None, min_count=min_count, max_count=max_count, requested_networks=requested_networks, security_group=security_group, user_data=user_data, availability_zone=self.availability_zone, config_drive=None, block_device_mapping=block_device_mapping, auto_disk_config=None, scheduler_hints=scheduler_hints, legacy_bdm=True, check_server_group_quota=check_server_group_quota) except (exception.PortInUse, exception.NoUniqueMatch) as error: readable = traceback.format_exc() LOG.exception('migrate exception10:%s', readable) continue raise exc.HTTPConflict(explanation=error.format_message()) except exception.FixedIpAlreadyInUse as error: readable = traceback.format_exc() LOG.exception('migrate exception11:%s', readable) continue raise exc.HTTPBadRequest(explanation=error.format_message()) break if instances is not None and len(instances) == 1: instance_new = instances[0] query_new_vm_status_count=1200 while instance_new.vm_state != 'active': time.sleep(2) instance_new = common.get_instance(self.compute_api, self.context, instance_new.uuid, want_objects=True) if instance_new.vm_state == 'error' : LOG.error("bulid instance failed") msg = _("migrate vm failed.") raise exc.HTTPBadRequest(explanation=msg) query_new_vm_status_count =query_new_vm_status_count-1 if query_new_vm_status_count ==0 and instance_new.vm_state != 'active': msg = _("migrate vm failed.") raise exc.HTTPBadRequest(explanation=msg) #step 9 delete the image LOG.debug('begin clear the image and volume') self._delete_tmp_image(boot_image_uuid, volume_dict_for_image_id) #step 10 delete the volume self._delete_volume_after_migrate(volume_ids)
def _add_floating_ip(self, req, id, body): """Associate floating_ip to an instance.""" context = req.environ['nova.context'] authorize(context) try: address = body['addFloatingIp']['address'] except TypeError: msg = _("Missing parameter dict") raise webob.exc.HTTPBadRequest(explanation=msg) except KeyError: msg = _("Address not specified") raise webob.exc.HTTPBadRequest(explanation=msg) instance = common.get_instance(self.compute_api, context, id) cached_nwinfo = compute_utils.get_nw_info_for_instance(instance) if not cached_nwinfo: msg = _('No nw_info cache associated with instance') raise webob.exc.HTTPBadRequest(explanation=msg) fixed_ips = cached_nwinfo.fixed_ips() if not fixed_ips: msg = _('No fixed ips associated to instance') raise webob.exc.HTTPBadRequest(explanation=msg) fixed_address = None if self.ext_mgr.is_loaded('os-extended-floating-ips'): if 'fixed_address' in body['addFloatingIp']: fixed_address = body['addFloatingIp']['fixed_address'] for fixed in fixed_ips: if fixed['address'] == fixed_address: break else: msg = _('Specified fixed address not assigned to instance') raise webob.exc.HTTPBadRequest(explanation=msg) if not fixed_address: fixed_address = fixed_ips[0]['address'] if len(fixed_ips) > 1: msg = _('multiple fixed_ips exist, using the first: %s') LOG.warning(msg, fixed_address) try: self.network_api.associate_floating_ip(context, instance, floating_address=address, fixed_address=fixed_address) except exception.FloatingIpAssociated: msg = _('floating ip is already associated') raise webob.exc.HTTPBadRequest(explanation=msg) except exception.NoFloatingIpInterface: msg = _('l3driver call to add floating ip failed') raise webob.exc.HTTPBadRequest(explanation=msg) except exception.FloatingIpNotFoundForAddress: msg = _('floating ip not found') raise webob.exc.HTTPNotFound(explanation=msg) except exception.Forbidden as e: raise webob.exc.HTTPForbidden(explanation=e.format_message()) except Exception: msg = _('Error. Unable to associate floating ip') LOG.exception(msg) raise webob.exc.HTTPBadRequest(explanation=msg) return webob.Response(status_int=202)
def run(self): LOG.error('begin time of migrate is %s' %(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))) bdms = objects.BlockDeviceMappingList.get_by_instance_uuid( self.context, self.instance['uuid']) is_boot_from_image = False volume_dict_for_image_id ={} #add system_volume system_volume=None data_volume_info_dict={} block_device_mapping = None volume_ids = [] system_volume_image_id = None #step1 get the source instance info instance = common.get_instance(self.compute_api, self.context, self.instance.uuid, want_objects=True) #get the interface-port info search_opts = {'device_id': instance['uuid']} try: data = self.network_api.list_ports(self.context, **search_opts) except exception.NotFound as e: raise exc.HTTPNotFound(explanation=e.format_message()) except NotImplementedError: msg = _("Network driver does not support this function.") raise webob.exc.HTTPNotImplemented(explanation=msg) ports = data.get('ports', []) access_ip_v4 = instance.access_ip_v4 access_ip_v6 = instance.access_ip_v6 min_count = 1 max_count = 1 name=instance.display_name key_name = None metadata = instance.metadata injected_files = [] security_group=instance.security_groups user_data=instance.user_data flavor_id = instance.system_metadata['instance_type_flavorid'] scheduler_hints = {} #check_server_group_quota = \ # self.ext_mgr.is_loaded('os-server-group-quotas') check_server_group_quota=True requested_networks = [] nw_info = compute_utils.get_nw_info_for_instance(instance) for vif in nw_info: net_uuid = vif['network']['id'] net_ip = vif['network']['subnets'][0]['ips'][0]['address'] requested_networks.append({'fixed_ip':net_ip, 'uuid':net_uuid}) requested_networks = self._get_requested_networks(requested_networks) for port in ports: LOG.debug('begin detach the port %s of instance %s' %(port['id'],instance.uuid)) self.compute_api.detach_interface(self.context,instance, port_id=port['id']) time.sleep(2) LOG.debug('end detach the port %s of instance %s' %(port['id'],instance.uuid)) for bdm in bdms: if bdm.image_id is not None and bdm.boot_index == 0 and bdm.destination_type =='local': is_boot_from_image =True system_volume_image_id = bdm.image_id if bdm.volume_id is not None: if bdm.boot_index == 0: volume = self.volume_api.get(self.context, bdm.volume_id) system_volume = volume volume_image_metadata = volume.get('volume_metadata') system_volume_image_id = volume_image_metadata['image_id'] else: volume_info={'boot_index':bdm.boot_index,'mount_point':bdm.device_name} data_volume_info_dict[bdm.volume_id]=volume_info #step2 stop the instance LOG.error('begin time of stop instance is %s' %(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))) self._stop_instance(instance) LOG.error('end time of stop instance is %s' %(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))) #get the image of target vm boot_image_uuid = None if is_boot_from_image: if self.migrate_system_volume is False: boot_image_uuid = system_volume_image_id else: tmp_image_name = "%s@%s" % (uuid.uuid1(), self.instance.uuid) instance = common.get_instance(self.compute_api, self.context, self.instance.uuid, want_objects=True) image_meta = self.compute_api.snapshot(self.context, instance, name=tmp_image_name, extra_properties=None) query_image_status_count=1800 filters = {'name':tmp_image_name} imagelist = self.image_api.get_all(self.context,filters=filters) image = imagelist[0] while image['status'] != 'active': time.sleep(1) imagelist = self.image_api.get_all(self.context,filters=filters) image = imagelist[0] #image_uuid = image['id'] #image = self.image_api.get(self.context,image_uuid ) if image['status'] =='error': msg = _("migrate vm failed.") raise exc.HTTPBadRequest(explanation=msg) query_image_status_count = query_image_status_count-1 if query_image_status_count == 0 and image['status'] != 'active': msg = _("migrate vm failed.") raise exc.HTTPBadRequest(explanation=msg) boot_image_uuid =image['id'] else: if self.migrate_system_volume is False: boot_image_uuid = system_volume_image_id else : response = self.volume_api.upload_to_image(self.context, system_volume['id'], True, system_volume['id'], 'bare', 'qcow2') image_id_of_volume = response[1]['os-volume_upload_image']['image_id'] image = self.image_api.get(self.context,image_id_of_volume) query_image_status_count=1800 LOG.info('query the image %s status of the voluem %s' %(image_id_of_volume,system_volume['id'])) while image['status'] != 'active': time.sleep(2) image = self.image_api.get(self.context,image_id_of_volume) if image['status'] == 'error': msg = _("migrate vm failed.") raise exc.HTTPBadRequest(explanation=msg) query_cascaded_image_status_count = query_image_status_count-1 if query_cascaded_image_status_count == 0 and image['status'] != 'active': msg = _("migrate vm failed.") raise exc.HTTPBadRequest(explanation=msg) boot_image_uuid = image_id_of_volume _get_inst_type = flavors.get_flavor_by_flavor_id inst_type = _get_inst_type(flavor_id, ctxt=self.context, read_deleted="no") instances=self._create_instance(inst_type,boot_image_uuid, display_name=name, display_description=name,key_name=key_name,metadata=metadata, access_ip_v4=access_ip_v4,access_ip_v6=access_ip_v6,injected_files=injected_files, admin_password=None, min_count=min_count,max_count=max_count, requested_networks=requested_networks, security_group=security_group, user_data=user_data,availability_zone=self.availability_zone, config_drive=None, block_device_mapping=block_device_mapping, auto_disk_config=None, scheduler_hints=scheduler_hints, legacy_bdm=True,check_server_group_quota=check_server_group_quota) volume_dict_for_image_id = self._upload_data_volume_to_image(data_volume_info_dict) source_target_vol_mapping = self._create_target_volume(volume_dict_for_image_id) #update the instance metadata the metadata use for vcloud delete vm self.compute_api.update_instance_metadata(self.context,instance,{'quick_delete_once': 'True'},delete=False) #step7 delete the vm LOG.error('begin time of delete instance is %s' %(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))) self.compute_api.delete(self.context,instance) LOG.error('end time of delete instance is %s' %(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))) #mount volume and reboot instance_new =None if instances is not None and len(instances) == 1: instance_new = instances[0] query_new_vm_status_count=1200 while instance_new.vm_state != 'active': time.sleep(2) instance_new = common.get_instance(self.compute_api, self.context, instance_new.uuid, want_objects=True) if instance_new.vm_state == 'error' : LOG.error("bulid instance failed") msg = _("migrate vm failed.") raise exc.HTTPBadRequest(explanation=msg) query_new_vm_status_count =query_new_vm_status_count-1 if query_new_vm_status_count ==0 and instance_new.vm_state != 'active': msg = _("migrate vm failed.") raise exc.HTTPBadRequest(explanation=msg) self._mount_data_volume(instance_new, source_target_vol_mapping, data_volume_info_dict) self.compute_api.reboot(self.context, instance_new, 'SOFT') #step 9 delete the image LOG.debug('begin clear the image and volume') self._delete_tmp_image(boot_image_uuid, volume_dict_for_image_id) #step 10 delete the volume self._delete_volume_after_migrate(data_volume_info_dict) time.sleep(2) instance_new = common.get_instance(self.compute_api, self.context, instance_new.uuid, want_objects=True) while instance_new.vm_state != 'active': time.sleep(2) instance_new = common.get_instance(self.compute_api, self.context, instance_new.uuid, want_objects=True) if instance_new.vm_state == 'error' : LOG.error("bulid instance failed") msg = _("migrate vm failed.") raise exc.HTTPBadRequest(explanation=msg) query_new_vm_status_count =query_new_vm_status_count-1 if query_new_vm_status_count ==0 and instance_new.vm_state != 'active': msg = _("migrate vm failed.") raise exc.HTTPBadRequest(explanation=msg) LOG.error('end time of migrate is %s' %(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
def _add_floating_ip(self, req, id, body): """Associate floating_ip to an instance.""" context = req.environ["nova.context"] authorize(context) try: address = body["addFloatingIp"]["address"] except TypeError: msg = _("Missing parameter dict") raise webob.exc.HTTPBadRequest(explanation=msg) except KeyError: msg = _("Address not specified") raise webob.exc.HTTPBadRequest(explanation=msg) instance = common.get_instance(self.compute_api, context, id) cached_nwinfo = compute_utils.get_nw_info_for_instance(instance) if not cached_nwinfo: msg = _("No nw_info cache associated with instance") raise webob.exc.HTTPBadRequest(explanation=msg) fixed_ips = cached_nwinfo.fixed_ips() if not fixed_ips: msg = _("No fixed ips associated to instance") raise webob.exc.HTTPBadRequest(explanation=msg) fixed_address = None if self.ext_mgr.is_loaded("os-extended-floating-ips"): if "fixed_address" in body["addFloatingIp"]: fixed_address = body["addFloatingIp"]["fixed_address"] for fixed in fixed_ips: if fixed["address"] == fixed_address: break else: msg = _("Specified fixed address not assigned to instance") raise webob.exc.HTTPBadRequest(explanation=msg) if not fixed_address: fixed_address = fixed_ips[0]["address"] if len(fixed_ips) > 1: LOG.warn(_LW("multiple fixed_ips exist, using the first: " "%s"), fixed_address) try: self.network_api.associate_floating_ip( context, instance, floating_address=address, fixed_address=fixed_address ) except exception.FloatingIpAssociated: msg = _("floating ip is already associated") raise webob.exc.HTTPBadRequest(explanation=msg) except exception.NoFloatingIpInterface: msg = _("l3driver call to add floating ip failed") raise webob.exc.HTTPBadRequest(explanation=msg) except exception.FloatingIpNotFoundForAddress: msg = _("floating ip not found") raise webob.exc.HTTPNotFound(explanation=msg) except exception.Forbidden as e: raise webob.exc.HTTPForbidden(explanation=e.format_message()) except Exception as e: msg = _( "Unable to associate floating ip %(address)s to " "fixed ip %(fixed_address)s for instance %(id)s. " "Error: %(error)s" ) % ({"address": address, "fixed_address": fixed_address, "id": id, "error": e}) LOG.exception(msg) raise webob.exc.HTTPBadRequest(explanation=msg) return webob.Response(status_int=202)
def _add_floating_ip(self, req, id, body): """Associate floating_ip to an instance.""" context = req.environ["nova.context"] context.can(fi_policies.BASE_POLICY_NAME) address = body["addFloatingIp"]["address"] instance = common.get_instance(self.compute_api, context, id, expected_attrs=["flavor"]) cached_nwinfo = compute_utils.get_nw_info_for_instance(instance) if not cached_nwinfo: LOG.warning( _LW("Info cache is %r during associate with no nw_info cache"), instance.info_cache, instance=instance ) msg = _("No nw_info cache associated with instance") raise webob.exc.HTTPBadRequest(explanation=msg) fixed_ips = cached_nwinfo.fixed_ips() if not fixed_ips: msg = _("No fixed IPs associated to instance") raise webob.exc.HTTPBadRequest(explanation=msg) fixed_address = None if "fixed_address" in body["addFloatingIp"]: fixed_address = body["addFloatingIp"]["fixed_address"] for fixed in fixed_ips: if fixed["address"] == fixed_address: break else: msg = _("Specified fixed address not assigned to instance") raise webob.exc.HTTPBadRequest(explanation=msg) if not fixed_address: try: fixed_address = next(ip["address"] for ip in fixed_ips if netutils.is_valid_ipv4(ip["address"])) except StopIteration: msg = _( "Unable to associate floating IP %(address)s " "to any fixed IPs for instance %(id)s. " "Instance has no fixed IPv4 addresses to " "associate." ) % ({"address": address, "id": id}) raise webob.exc.HTTPBadRequest(explanation=msg) if len(fixed_ips) > 1: LOG.warning(_LW("multiple fixed_ips exist, using the first " "IPv4 fixed_ip: %s"), fixed_address) try: self.network_api.associate_floating_ip( context, instance, floating_address=address, fixed_address=fixed_address ) except exception.FloatingIpAssociated: msg = _("floating IP is already associated") raise webob.exc.HTTPBadRequest(explanation=msg) except exception.NoFloatingIpInterface: msg = _("l3driver call to add floating IP failed") raise webob.exc.HTTPBadRequest(explanation=msg) except exception.InstanceUnknownCell as e: raise webob.exc.HTTPNotFound(explanation=e.format_message()) except exception.FloatingIpNotFoundForAddress: msg = _("floating IP not found") raise webob.exc.HTTPNotFound(explanation=msg) except exception.Forbidden as e: raise webob.exc.HTTPForbidden(explanation=e.format_message()) except Exception as e: msg = _( "Unable to associate floating IP %(address)s to " "fixed IP %(fixed_address)s for instance %(id)s. " "Error: %(error)s" ) % ({"address": address, "fixed_address": fixed_address, "id": id, "error": e}) LOG.exception(msg) raise webob.exc.HTTPBadRequest(explanation=msg) return webob.Response(status_int=202)
def instance_rules(self, instance, network_info): ctxt = context.get_admin_context() ipv4_rules = [] ipv6_rules = [] # Initialize with basic rules self._do_basic_rules(ipv4_rules, ipv6_rules, network_info) # Set up rules to allow traffic to/from DHCP server self._do_dhcp_rules(ipv4_rules, network_info) #Allow project network traffic if CONF.allow_same_net_traffic: self._do_project_network_rules(ipv4_rules, ipv6_rules, network_info) # We wrap these in CONF.use_ipv6 because they might cause # a DB lookup. The other ones are just list operations, so # they're not worth the clutter. if CONF.use_ipv6: # Allow RA responses self._do_ra_rules(ipv6_rules, network_info) security_groups = self._virtapi.security_group_get_by_instance( ctxt, instance) # then, security group chains and rules for security_group in security_groups: rules = self._virtapi.security_group_rule_get_by_security_group( ctxt, security_group) for rule in rules: LOG.debug(_('Adding security group rule: %r'), rule, instance=instance) if not rule['cidr']: version = 4 else: version = netutils.get_ip_version(rule['cidr']) if version == 4: fw_rules = ipv4_rules else: fw_rules = ipv6_rules protocol = rule['protocol'] if protocol: protocol = rule['protocol'].lower() if version == 6 and protocol == 'icmp': protocol = 'icmpv6' args = ['-j ACCEPT'] if protocol: args += ['-p', protocol] if protocol in ['udp', 'tcp']: args += self._build_tcp_udp_rule(rule, version) elif protocol == 'icmp': args += self._build_icmp_rule(rule, version) if rule['cidr']: LOG.debug('Using cidr %r', rule['cidr'], instance=instance) args += ['-s', rule['cidr']] fw_rules += [' '.join(args)] else: if rule['grantee_group']: for instance in rule['grantee_group']['instances']: nw_info = compute_utils.get_nw_info_for_instance( instance) ips = [ip['address'] for ip in nw_info.fixed_ips() if ip['version'] == version] LOG.debug('ips: %r', ips, instance=instance) for ip in ips: subrule = args + ['-s %s' % ip] fw_rules += [' '.join(subrule)] LOG.debug('Using fw_rules: %r', fw_rules, instance=instance) ipv4_rules += ['-j $sg-fallback'] ipv6_rules += ['-j $sg-fallback'] return ipv4_rules, ipv6_rules
def instance_rules(self, instance, network_info): # make sure this is legacy nw_info network_info = self._handle_network_info_model(network_info) ctxt = context.get_admin_context() ipv4_rules = [] ipv6_rules = [] # Initialize with basic rules self._do_basic_rules(ipv4_rules, ipv6_rules, network_info) # Set up rules to allow traffic to/from DHCP server self._do_dhcp_rules(ipv4_rules, network_info) #Allow project network traffic if CONF.allow_same_net_traffic: self._do_project_network_rules(ipv4_rules, ipv6_rules, network_info) # We wrap these in CONF.use_ipv6 because they might cause # a DB lookup. The other ones are just list operations, so # they're not worth the clutter. if CONF.use_ipv6: # Allow RA responses self._do_ra_rules(ipv6_rules, network_info) security_groups = self._virtapi.security_group_get_by_instance( ctxt, instance) # then, security group chains and rules for security_group in security_groups: rules = self._virtapi.security_group_rule_get_by_security_group( ctxt, security_group) for rule in rules: LOG.debug(_('Adding security group rule: %r'), rule, instance=instance) if not rule['cidr']: version = 4 else: version = netutils.get_ip_version(rule['cidr']) if version == 4: fw_rules = ipv4_rules else: fw_rules = ipv6_rules protocol = rule['protocol'] if protocol: protocol = rule['protocol'].lower() if version == 6 and protocol == 'icmp': protocol = 'icmpv6' args = ['-j ACCEPT'] if protocol: args += ['-p', protocol] if protocol in ['udp', 'tcp']: args += self._build_tcp_udp_rule(rule, version) elif protocol == 'icmp': args += self._build_icmp_rule(rule, version) if rule['cidr']: LOG.debug('Using cidr %r', rule['cidr'], instance=instance) args += ['-s', rule['cidr']] fw_rules += [' '.join(args)] else: if rule['grantee_group']: for instance in rule['grantee_group']['instances']: nw_info = compute_utils.get_nw_info_for_instance( instance) ips = [ ip['address'] for ip in nw_info.fixed_ips() if ip['version'] == version ] LOG.debug('ips: %r', ips, instance=instance) for ip in ips: subrule = args + ['-s %s' % ip] fw_rules += [' '.join(subrule)] LOG.debug('Using fw_rules: %r', fw_rules, instance=instance) ipv4_rules += ['-j $sg-fallback'] ipv6_rules += ['-j $sg-fallback'] return ipv4_rules, ipv6_rules
def _add_floating_ip(self, req, id, body): """Associate floating_ip to an instance.""" context = req.environ['nova.context'] authorize(context) address = body['addFloatingIp']['address'] instance = common.get_instance(self.compute_api, context, id, expected_attrs=['flavor']) cached_nwinfo = compute_utils.get_nw_info_for_instance(instance) if not cached_nwinfo: LOG.warning( _LW('Info cache is %r during associate') % instance.info_cache, instance=instance) msg = _('No nw_info cache associated with instance') raise webob.exc.HTTPBadRequest(explanation=msg) fixed_ips = cached_nwinfo.fixed_ips() if not fixed_ips: msg = _('No fixed IPs associated to instance') raise webob.exc.HTTPBadRequest(explanation=msg) fixed_address = None if 'fixed_address' in body['addFloatingIp']: fixed_address = body['addFloatingIp']['fixed_address'] for fixed in fixed_ips: if fixed['address'] == fixed_address: break else: msg = _('Specified fixed address not assigned to instance') raise webob.exc.HTTPBadRequest(explanation=msg) if not fixed_address: try: fixed_address = next(ip['address'] for ip in fixed_ips if netaddr.valid_ipv4(ip['address'])) except StopIteration: msg = _('Unable to associate floating IP %(address)s ' 'to any fixed IPs for instance %(id)s. ' 'Instance has no fixed IPv4 addresses to ' 'associate.') % ( {'address': address, 'id': id}) raise webob.exc.HTTPBadRequest(explanation=msg) if len(fixed_ips) > 1: LOG.warning(_LW('multiple fixed_ips exist, using the first ' 'IPv4 fixed_ip: %s'), fixed_address) try: self.network_api.associate_floating_ip(context, instance, floating_address=address, fixed_address=fixed_address) except exception.FloatingIpAssociated: msg = _('floating IP is already associated') raise webob.exc.HTTPBadRequest(explanation=msg) except exception.NoFloatingIpInterface: msg = _('l3driver call to add floating IP failed') raise webob.exc.HTTPBadRequest(explanation=msg) except exception.InstanceUnknownCell as e: raise webob.exc.HTTPNotFound(explanation=e.format_message()) except exception.FloatingIpNotFoundForAddress: msg = _('floating IP not found') raise webob.exc.HTTPNotFound(explanation=msg) except exception.Forbidden as e: raise webob.exc.HTTPForbidden(explanation=e.format_message()) except Exception as e: msg = _('Unable to associate floating IP %(address)s to ' 'fixed IP %(fixed_address)s for instance %(id)s. ' 'Error: %(error)s') % ( {'address': address, 'fixed_address': fixed_address, 'id': id, 'error': e}) LOG.exception(msg) raise webob.exc.HTTPBadRequest(explanation=msg) return webob.Response(status_int=202)
def run(self): #imageName=str(uuid.uuid4()) #create image #image_meta = self.compute_api.snapshot(self.context, self.instance, name=imageId, extra_properties=None) bdms = objects.BlockDeviceMappingList.get_by_instance_uuid( self.context, self.instance['uuid']) volume_ids = [bdm.volume_id for bdm in bdms if bdm.volume_id] image_uuid = None if volume_ids is None or volume_ids == []: tmp_image_name = "%s@%s" % (uuid.uuid1(), self.instance.uuid) image_meta = self.compute_api.snapshot(self.context, self.instance, name=tmp_image_name, extra_properties=None) image_uuid = image_meta['id'] try: filters = {'name':tmp_image_name} imagelist = self.image_api.get_all(self.context,filters=filters) image = imagelist[0] while image['status'] != 'active': time.sleep(1) imagelist = self.image_api.get_all(self.context,filters=filters) image = imagelist[0] image_uuid = image['id'] image = self.image_api.get(self.context,image_uuid ) except (exception.NotFound, exception.InvalidImageRef): explanation = _("Image not found.") raise webob.exc.HTTPNotFound(explanation=explanation) else : for volume_id in volume_ids: volume = self.volume_api.get(self.context, volume_id) #import pdb #pdb.set_trace() response = self.volume_api.upload_to_image(self.context, volume_id, True, volume_id, 'bare', 'qcow2') image_uuid = response[1]['os-volume_upload_image']['image_id'] #image_uuid = image_meta['id'] try: image = self.image_api.get(self.context, image_uuid) cascading_image_name = image['id'] filters = {'name':cascading_image_name} cascading_image = self.image_api.get_all(self.context,filters=filters) cascading_image_id = cascading_image[0]['id'] cascading_image = self.image_api.get(self.context,cascading_image_id ) while cascading_image['status'] != 'active': time.sleep(1) cascading_image = self.image_api.get(self.context,cascading_image_id ) except (exception.NotFound, exception.InvalidImageRef): explanation = _("Image not found.") raise webob.exc.HTTPNotFound(explanation=explanation) access_ip_v4 = self.instance.access_ip_v4 if access_ip_v4 is not None: self._validate_access_ipv4(access_ip_v4) access_ip_v6 = self.instance.access_ip_v6 if access_ip_v6 is not None: self._validate_access_ipv6(access_ip_v6) #networks = common.get_networks_for_instance(context, instance) min_count = 1 max_count = 1 name=self.instance.display_name key_name = None metadata = self.instance.metadata injected_files = [] security_group=self.instance.security_groups user_data=self.instance.user_data flavor_id = self.instance.system_metadata['instance_type_flavorid'] scheduler_hints = {} legacy_bdm = True #check_server_group_quota = \ # self.ext_mgr.is_loaded('os-server-group-quotas') check_server_group_quota=True requested_networks = [] nw_info = compute_utils.get_nw_info_for_instance(self.instance) for vif in nw_info: net_uuid = vif['network']['id'] net_ip = vif['network']['subnets'][0]['ips'][0]['address'] requested_networks.append({'fixed_ip':net_ip, 'uuid':net_uuid}) requested_networks = self._get_requested_networks(requested_networks) #detach port delete self.compute_api.delete(self.context,self.instance) while True: time.sleep(3) try: _get_inst_type = flavors.get_flavor_by_flavor_id inst_type = _get_inst_type(flavor_id, ctxt=self.context, read_deleted="no") (instances, resv_id) = self.compute_api.create(self.context, inst_type, image_uuid, display_name=name, display_description=name, key_name=key_name, metadata=metadata, access_ip_v4=access_ip_v4, access_ip_v6=access_ip_v6, injected_files=injected_files, admin_password=None, min_count=min_count, max_count=max_count, requested_networks=requested_networks, security_group=security_group, user_data=user_data, availability_zone=self.availability_zone, config_drive=None, block_device_mapping=None, auto_disk_config=None, scheduler_hints=scheduler_hints, legacy_bdm=legacy_bdm, check_server_group_quota=check_server_group_quota) except (exception.QuotaError, exception.PortLimitExceeded) as error: raise exc.HTTPForbidden( 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 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 UnicodeDecodeError as error: msg = "UnicodeError: %s" % unicode(error) raise exc.HTTPBadRequest(explanation=msg) except (exception.ImageNotActive, exception.FlavorDiskTooSmall, exception.FlavorMemoryTooSmall, exception.NetworkNotFound, exception.PortNotFound, exception.FixedIpAlreadyInUse, exception.SecurityGroupNotFound, exception.InstanceUserDataTooLarge, exception.InstanceUserDataMalformed) as error: raise exc.HTTPBadRequest(explanation=error.format_message()) except (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.NoUniqueMatch) as error: continue raise exc.HTTPConflict(explanation=error.format_message()) except exception.Invalid as error: raise exc.HTTPBadRequest(explanation=error.format_message()) break
def test_instance_dict_none_info_cache(self): inst = fake_instance.fake_db_instance(info_cache=None) self.assertIsNone(inst['info_cache']) result = compute_utils.get_nw_info_for_instance(inst) self.assertEqual(jsonutils.dumps([]), result.json())
def _add_floating_ip(self, req, id, body): """Associate floating_ip to an instance.""" context = req.environ['nova.context'] authorize(context) address = body['addFloatingIp']['address'] instance = common.get_instance(self.compute_api, context, id) cached_nwinfo = compute_utils.get_nw_info_for_instance(instance) if not cached_nwinfo: LOG.warning(_LW('Info cache is %r during associate') % instance.info_cache, instance=instance) msg = _('No nw_info cache associated with instance') raise webob.exc.HTTPBadRequest(explanation=msg) fixed_ips = cached_nwinfo.fixed_ips() if not fixed_ips: msg = _('No fixed ips associated to instance') raise webob.exc.HTTPBadRequest(explanation=msg) fixed_address = None if 'fixed_address' in body['addFloatingIp']: fixed_address = body['addFloatingIp']['fixed_address'] for fixed in fixed_ips: if fixed['address'] == fixed_address: break else: msg = _('Specified fixed address not assigned to instance') raise webob.exc.HTTPBadRequest(explanation=msg) if not fixed_address: try: fixed_address = (ip['address'] for ip in fixed_ips if netaddr.valid_ipv4(ip['address'])).next() except StopIteration: msg = _('Unable to associate floating ip %(address)s ' 'to any fixed IPs for instance %(id)s. ' 'Instance has no fixed IPv4 addresses to ' 'associate.') % ({ 'address': address, 'id': id }) raise webob.exc.HTTPBadRequest(explanation=msg) if len(fixed_ips) > 1: LOG.warning( _LW('multiple fixed_ips exist, using the first ' 'IPv4 fixed_ip: %s'), fixed_address) try: self.network_api.associate_floating_ip(context, instance, floating_address=address, fixed_address=fixed_address) except exception.FloatingIpAssociated: msg = _('floating ip is already associated') raise webob.exc.HTTPBadRequest(explanation=msg) except exception.NoFloatingIpInterface: msg = _('l3driver call to add floating ip failed') raise webob.exc.HTTPBadRequest(explanation=msg) except exception.FloatingIpNotFoundForAddress: msg = _('floating ip not found') raise webob.exc.HTTPNotFound(explanation=msg) except exception.Forbidden as e: raise webob.exc.HTTPForbidden(explanation=e.format_message()) except Exception as e: msg = _('Unable to associate floating ip %(address)s to ' 'fixed ip %(fixed_address)s for instance %(id)s. ' 'Error: %(error)s') % ({ 'address': address, 'fixed_address': fixed_address, 'id': id, 'error': e }) LOG.exception(msg) raise webob.exc.HTTPBadRequest(explanation=msg) return webob.Response(status_int=202)
def instance_rules(self, instance, network_info): ctxt = context.get_admin_context() if isinstance(instance, dict): # NOTE(danms): allow old-world instance objects from # unconverted callers; all we need is instance.uuid below instance = objects.Instance._from_db_object( ctxt, objects.Instance(), instance, []) ipv4_rules = [] ipv6_rules = [] # Initialize with basic rules self._do_basic_rules(ipv4_rules, ipv6_rules, network_info) # Set up rules to allow traffic to/from DHCP server self._do_dhcp_rules(ipv4_rules, network_info) #Allow project network traffic if CONF.allow_same_net_traffic: self._do_project_network_rules(ipv4_rules, ipv6_rules, network_info) # We wrap these in CONF.use_ipv6 because they might cause # a DB lookup. The other ones are just list operations, so # they're not worth the clutter. if CONF.use_ipv6: # Allow RA responses self._do_ra_rules(ipv6_rules, network_info) security_groups = security_group_obj.SecurityGroupList.get_by_instance( ctxt, instance) # then, security group chains and rules for security_group in security_groups: rules_cls = security_group_rule_obj.SecurityGroupRuleList rules = rules_cls.get_by_security_group(ctxt, security_group) for rule in rules: LOG.debug('Adding security group rule: %r', rule, instance=instance) if not rule['cidr']: version = 4 else: version = netutils.get_ip_version(rule['cidr']) if version == 4: fw_rules = ipv4_rules else: fw_rules = ipv6_rules protocol = rule['protocol'] if protocol: protocol = rule['protocol'].lower() if version == 6 and protocol == 'icmp': protocol = 'icmpv6' args = ['-j ACCEPT'] if protocol: args += ['-p', protocol] if protocol in ['udp', 'tcp']: args += self._build_tcp_udp_rule(rule, version) elif protocol == 'icmp': args += self._build_icmp_rule(rule, version) if rule['cidr']: LOG.debug('Using cidr %r', rule['cidr'], instance=instance) args += ['-s', str(rule['cidr'])] fw_rules += [' '.join(args)] else: if rule['grantee_group']: insts = (objects.InstanceList.get_by_security_group( ctxt, rule['grantee_group'])) for instance in insts: if instance['info_cache']['deleted']: LOG.debug('ignoring deleted cache') continue nw_info = compute_utils.get_nw_info_for_instance( instance) ips = [ ip['address'] for ip in nw_info.fixed_ips() if ip['version'] == version ] LOG.debug('ips: %r', ips, instance=instance) for ip in ips: subrule = args + ['-s %s' % ip] fw_rules += [' '.join(subrule)] LOG.debug('Using fw_rules: %r', fw_rules, instance=instance) ipv4_rules += ['-j $sg-fallback'] ipv6_rules += ['-j $sg-fallback'] return ipv4_rules, ipv6_rules
def instance_rules(self, instance, network_info): ctxt = context.get_admin_context() if isinstance(instance, dict): # NOTE(danms): allow old-world instance objects from # unconverted callers; all we need is instance.uuid below instance = objects.Instance._from_db_object( ctxt, objects.Instance(), instance, []) ipv4_rules = [] ipv6_rules = [] # Initialize with basic rules self._do_basic_rules(ipv4_rules, ipv6_rules, network_info) # Set up rules to allow traffic to/from DHCP server self._do_dhcp_rules(ipv4_rules, network_info) #Allow project network traffic if CONF.allow_same_net_traffic: self._do_project_network_rules(ipv4_rules, ipv6_rules, network_info) # We wrap these in CONF.use_ipv6 because they might cause # a DB lookup. The other ones are just list operations, so # they're not worth the clutter. if CONF.use_ipv6: # Allow RA responses self._do_ra_rules(ipv6_rules, network_info) security_groups = security_group_obj.SecurityGroupList.get_by_instance( ctxt, instance) # then, security group chains and rules for security_group in security_groups: rules_cls = security_group_rule_obj.SecurityGroupRuleList rules = rules_cls.get_by_security_group(ctxt, security_group) for rule in rules: if not rule['cidr']: version = 4 else: version = netutils.get_ip_version(rule['cidr']) if version == 4: fw_rules = ipv4_rules else: fw_rules = ipv6_rules protocol = rule['protocol'] if protocol: protocol = rule['protocol'].lower() if version == 6 and protocol == 'icmp': protocol = 'icmpv6' args = ['-j ACCEPT'] if protocol: args += ['-p', protocol] if protocol in ['udp', 'tcp']: args += self._build_tcp_udp_rule(rule, version) elif protocol == 'icmp': args += self._build_icmp_rule(rule, version) if rule['cidr']: args += ['-s', str(rule['cidr'])] fw_rules += [' '.join(args)] else: if rule['grantee_group']: insts = ( objects.InstanceList.get_by_security_group( ctxt, rule['grantee_group'])) for instance in insts: if instance['info_cache']['deleted']: LOG.debug('ignoring deleted cache') continue nw_info = compute_utils.get_nw_info_for_instance( instance) ips = [ip['address'] for ip in nw_info.fixed_ips() if ip['version'] == version] LOG.debug('ips: %r', ips, instance=instance) for ip in ips: subrule = args + ['-s %s' % ip] fw_rules += [' '.join(subrule)] ipv4_rules += ['-j $sg-fallback'] ipv6_rules += ['-j $sg-fallback'] LOG.debug('Security Groups %s translated to ipv4: %r, ipv6: %r', security_groups, ipv4_rules, ipv6_rules, instance=instance) return ipv4_rules, ipv6_rules