Adding the ability to use pre-created ports in Network scenarios

It's possible to launch an instance with virtual interfaces
either by specifying the network the interface should be attached
to or the port.
There are cases (e.g. SR-IOV) where it's only possible to launch
an instance with a pre-created port.
Enabling the creation of  a port with known vnic_types (Currently
'normal','direct' and 'macvtap') and launching an instance with this port
attached.

Nova support Neutron SR-IOV ports https://wiki.openstack.org/wiki/Nova-neutron-sriov

Change-Id: Id5cbd50d285ac0c7e8099c30151ace9d99f02020
This commit is contained in:
Itzik Brown 2014-12-08 12:58:20 +02:00
parent acd4ffe7c5
commit 2ca01cd20b
5 changed files with 80 additions and 5 deletions

@ -779,6 +779,10 @@
# value)
#dns_servers = 8.8.8.8,8.8.4.4
# vnic_type to use when Launching instances with pre-configured ports.
# Supported ports are: ['normal','direct','macvtap'] (string value)
#port_vnic_type = <None>
[network-feature-enabled]

@ -455,7 +455,13 @@ NetworkGroup = [
cfg.ListOpt('dns_servers',
default=["8.8.8.8", "8.8.4.4"],
help="List of dns servers which should be used"
" for subnet creation")
" for subnet creation"),
cfg.StrOpt('port_vnic_type',
choices=[None, 'normal', 'direct', 'macvtap'],
help="vnic_type to use when Launching instances"
" with pre-configured ports."
" Supported ports are:"
" ['normal','direct','macvtap']"),
]
network_feature_group = cfg.OptGroup(name='network-feature-enabled',

@ -639,14 +639,15 @@ class NetworkScenarioTest(ScenarioTest):
self.addCleanup(self.delete_wrapper, subnet.delete)
return subnet
def _create_port(self, network, client=None, namestart='port-quotatest'):
def _create_port(self, network_id, client=None, namestart='port-quotatest',
**kwargs):
if not client:
client = self.network_client
name = data_utils.rand_name(namestart)
result = client.create_port(
name=name,
network_id=network.id,
tenant_id=network.tenant_id)
network_id=network_id,
**kwargs)
self.assertIsNotNone(result, 'Unable to allocate port')
port = net_resources.DeletablePort(client=client,
**result['port'])
@ -1047,6 +1048,66 @@ class NetworkScenarioTest(ScenarioTest):
subnet.add_to_router(router.id)
return network, subnet, router
def create_server(self, name=None, image=None, flavor=None,
wait_on_boot=True, wait_on_delete=True,
create_kwargs=None):
vnic_type = CONF.network.port_vnic_type
# If vnic_type is configured create port for
# every network
if vnic_type:
ports = []
networks = []
create_port_body = {'binding:vnic_type': vnic_type,
'namestart': 'port-smoke'}
if create_kwargs:
net_client = create_kwargs.get("network_client",
self.network_client)
# Convert security group names to security group ids
# to pass to create_port
if create_kwargs.get('security_groups'):
security_groups = net_client.list_security_groups().get(
'security_groups')
sec_dict = dict([(s['name'], s['id'])
for s in security_groups])
sec_groups_names = [s['name'] for s in create_kwargs[
'security_groups']]
security_groups_ids = [sec_dict[s]
for s in sec_groups_names]
if security_groups_ids:
create_port_body[
'security_groups'] = security_groups_ids
networks = create_kwargs.get('networks')
else:
net_client = self.network_client
# If there are no networks passed to us we look up
# for the tenant's private networks and create a port
# if there is only one private network. The same behaviour
# as we would expect when passing the call to the clients
# with no networks
if not networks:
networks = net_client.list_networks(filters={
'router:external': False})
self.assertEqual(1, len(networks),
"There is more than one"
" network for the tenant")
for net in networks:
net_id = net['uuid']
port = self._create_port(network_id=net_id,
client=net_client,
**create_port_body)
ports.append({'port': port.id})
if ports:
create_kwargs['networks'] = ports
return super(NetworkScenarioTest, self).create_server(
name=name, image=image, flavor=flavor,
wait_on_boot=wait_on_boot, wait_on_delete=wait_on_delete,
create_kwargs=create_kwargs)
# power/provision states as of icehouse
class BaremetalPowerStates(object):

@ -381,6 +381,9 @@ class TestNetworkBasicOps(manager.NetworkScenarioTest):
@testtools.skipUnless(CONF.compute_feature_enabled.interface_attach,
'NIC hotplug not available')
@testtools.skipIf(CONF.network.port_vnic_type in ['direct', 'macvtap'],
'NIC hotplug not supported for '
'vnic_type direct or macvtap')
@test.attr(type='smoke')
@test.services('compute', 'network')
def test_hotplug_nic(self):

@ -238,7 +238,8 @@ class TestSecurityGroupsBasicOps(manager.NetworkScenarioTest):
],
'key_name': tenant.keypair['name'],
'security_groups': security_groups_names,
'tenant_id': tenant.creds.tenant_id
'tenant_id': tenant.creds.tenant_id,
'network_client': tenant.manager.network_client
}
server = self.create_server(name=name, create_kwargs=create_kwargs)
self.assertEqual(