Add features to support VTS

Change-Id: I425ffb5095646271c8bf408ee3df480f4b277747
This commit is contained in:
Yichen Wang 2016-06-20 10:41:18 -07:00
parent ccca3bfabc
commit 6cfbc4d5e8
5 changed files with 121 additions and 49 deletions

View File

@ -147,13 +147,13 @@ class Compute(object):
# and check that it gets into the ACTIVE state
def create_server(self, vmname, image, flavor, key_name,
nic, sec_group, avail_zone=None, user_data=None,
config_drive=None,
retry_count=10):
config_drive=None, files=None, retry_count=10):
if sec_group:
security_groups = [sec_group.name]
else:
security_groups = None
# Also attach the created security group for the test
instance = self.novaclient.servers.create(name=vmname,
image=image,
@ -163,6 +163,7 @@ class Compute(object):
availability_zone=avail_zone,
userdata=user_data,
config_drive=config_drive,
files=files,
security_groups=security_groups)
if not instance:
return None

View File

@ -17,7 +17,7 @@ import re
from log import LOG
import monitor
from netaddr import IPAddress
import netaddr
import sshutils
@ -55,7 +55,8 @@ class Instance(object):
self.gmond_port = int(config.gmond_svr_port)
else:
self.gmond_port = 0
self.config_drive = None
self.config_drive = config.config_drive
self.no_floatingip = config.no_floatingip
# Setup the ssh connectivity
# this function is only used for native hosts
@ -70,6 +71,42 @@ class Instance(object):
connect_retry_count=self.config.ssh_retry_count)
return True
def get_network_interface(self, port_info):
ip_address = port_info['fixed_ips'][0]['ip_address']
subnet_id = port_info['fixed_ips'][0]['subnet_id']
subnet_info = self.net.neutron_client.show_subnet(subnet_id)['subnet']
cidr = netaddr.IPNetwork(subnet_info['cidr'])
network_dict = {
'ip_address': ip_address,
'netmask': str(cidr.netmask),
'network': str(cidr.network),
'broadcast': str(cidr.broadcast),
'gateway': subnet_info['gateway_ip'],
'dns': ''
}
if subnet_info['dns_nameservers']:
dns_servers = ','.join(subnet_info['dns_nameservers'])
network_dict['dns'] = 'dns-nameservers %s\n' % dns_servers
retStr = (
'# The loopback network interface\n'
'auto lo\n'
'iface lo inet loopback\n'
'\n'
'# The primary network interface\n'
'auto eth0\n'
'iface eth0 inet static\n'
' address %(ip_address)s\n'
' netmask %(netmask)s\n'
' network %(network)s\n'
' broadcast %(broadcast)s\n'
' gateway %(gateway)s\n'
' %(dns)s'
) % network_dict
return retStr
# Create a new VM instance, associate a floating IP for ssh access
# and extract internal network IP
# Retruns True if success, False otherwise
@ -90,7 +127,7 @@ class Instance(object):
else:
user_data = None
if self.config.vnic_type:
if self.config.vnic_type or self.config.no_dhcp:
# create the VM by passing a port ID instead of a net ID
self.port = self.net.create_port(int_net['id'],
[sec_group.id],
@ -103,6 +140,11 @@ class Instance(object):
# create the VM by passing a net ID
nics = [{'net-id': int_net['id']}]
files = None
if self.config.no_dhcp:
network_interface = self.get_network_interface(self.port)
files = {'/etc/network/interfaces': network_interface}
self.instance = self.comp.create_server(self.name,
image,
flavor_type,
@ -112,6 +154,7 @@ class Instance(object):
az,
user_data,
self.config_drive,
files,
self.config.generic_retry_count)
if user_data:
user_data.close()
@ -130,7 +173,7 @@ class Instance(object):
else:
# Set the internal ip to the correct ip for v4 and v6
for ip_address in self.instance.networks[internal_network_name]:
ip = IPAddress(ip_address)
ip = netaddr.IPAddress(ip_address)
if self.config.ipv6_mode:
if ip.version == 6:
self.internal_ip = ip_address
@ -140,14 +183,17 @@ class Instance(object):
if ip.version == 4:
self.internal_ip = ip_address
ipv4_fixed_address = ip_address
fip = self.net.create_floating_ip()
if not fip:
self.display('Floating ip creation failed')
return False
self.ssh_access.host = fip['floatingip']['floating_ip_address']
self.ssh_ip_id = fip['floatingip']['id']
self.display('Associating floating IP %s', self.ssh_access.host)
self.instance.add_floating_ip(self.ssh_access.host, ipv4_fixed_address)
if self.no_floatingip:
self.ssh_access.host = self.internal_ip
else:
fip = self.net.create_floating_ip()
if not fip:
self.display('Floating ip creation failed.')
return False
self.ssh_access.host = fip['floatingip']['floating_ip_address']
self.ssh_ip_id = fip['floatingip']['id']
self.display('Associating floating IP %s', self.ssh_access.host)
self.instance.add_floating_ip(self.ssh_access.host, ipv4_fixed_address)
# extract the IP for the data network
self.display('Internal network IP: %s', self.internal_ip)

View File

@ -75,35 +75,34 @@ class Network(object):
self.ext_net = network
break
if not self.ext_net:
LOG.error("No external network found.")
return
if self.ext_net:
LOG.info("Using external network: " + self.ext_net['name'])
# Find or create the router to the external network
ext_net_id = self.ext_net['id']
routers = neutron_client.list_routers()['routers']
for router in routers:
external_gw_info = router['external_gateway_info']
if external_gw_info:
if external_gw_info['network_id'] == ext_net_id:
self.ext_router = router
LOG.info('Found external router: %s' % (self.ext_router['name']))
break
LOG.info("Using external network: " + self.ext_net['name'])
# Find or create the router to the external network
ext_net_id = self.ext_net['id']
routers = neutron_client.list_routers()['routers']
for router in routers:
external_gw_info = router['external_gateway_info']
if external_gw_info:
if external_gw_info['network_id'] == ext_net_id:
self.ext_router = router
LOG.info('Found external router: %s' % (self.ext_router['name']))
break
# create a new external router if none found and a name was given
self.ext_router_name = config.router_name
if (not self.ext_router) and self.ext_router_name:
self.ext_router = self.create_router(self.ext_router_name,
self.ext_net['id'])
LOG.info('Created ext router %s.' % (self.ext_router_name))
self.ext_router_created = True
# create a new external router if none found and a name was given
self.ext_router_name = config.router_name
if (not self.ext_router) and self.ext_router_name:
self.ext_router = self.create_router(self.ext_router_name,
self.ext_net['id'])
LOG.info('Created ext router %s.' % (self.ext_router_name))
self.ext_router_created = True
else:
LOG.warning("No external network found.")
if config.ipv6_mode:
self.ipv6_enabled = True
# Create the networks and subnets depending on v4 or v6
enable_dhcp = not config.no_dhcp
if config.ipv6_mode:
for (net, subnet, cidr, subnet_v6, cidr_v6) in zip(config.internal_network_name,
config.internal_subnet_name,
@ -112,7 +111,8 @@ class Network(object):
config.internal_cidr_v6):
int_net = self.create_net(net, subnet, cidr,
config.dns_nameservers,
subnet_v6, cidr_v6, config.ipv6_mode)
subnet_v6, cidr_v6, config.ipv6_mode,
enable_dhcp=enable_dhcp)
self.vm_int_net.append(int_net)
if config.same_network_only:
break
@ -121,14 +121,16 @@ class Network(object):
config.internal_subnet_name,
config.internal_cidr):
int_net = self.create_net(net, subnet, cidr,
config.dns_nameservers)
config.dns_nameservers,
enable_dhcp=enable_dhcp)
self.vm_int_net.append(int_net)
if config.same_network_only:
break
# Add both internal networks to router interface to enable
# network to network connectivity
self.__add_router_interface()
if self.ext_net:
self.__add_router_interface()
self.l2agent_type = self._get_l2agent_type()
self.internal_iface_dict = self._get_internal_iface_dict()
@ -138,7 +140,8 @@ class Network(object):
# return that network.
# dns_nameservers: a list of name servers e.g. ['8.8.8.8']
def create_net(self, network_name, subnet_name, cidr, dns_nameservers,
subnet_name_ipv6=None, cidr_ipv6=None, ipv6_mode=None):
subnet_name_ipv6=None, cidr_ipv6=None, ipv6_mode=None,
enable_dhcp=True):
for network in self.networks:
if network['name'] == network_name:
@ -162,6 +165,9 @@ class Network(object):
'dns_nameservers': dns_nameservers
}
}
if not enable_dhcp:
body['subnet']['enable_dhcp'] = False
subnet = self.neutron_client.create_subnet(body)['subnet']
# add subnet id to the network dict since it has just been added
network['subnets'] = [subnet['id']]
@ -178,6 +184,8 @@ class Network(object):
'ipv6_address_mode': ipv6_mode
}
}
if not enable_dhcp:
body['subnet']['enable_dhcp'] = False
subnet = self.neutron_client.create_subnet(body)['subnet']
# add the subnet id to the network dict
network['subnets'].append(subnet['id'])
@ -253,6 +261,9 @@ class Network(object):
# May fail with neutronclient.common.exceptions.Conflict
# if there are floating IP in use - just ignore
LOG.warning('Router interface may have floating IP in use: not deleted')
except TypeError:
# Externel router is not existed, so let's just continue
pass
# Lookup network given network name
def lookup_network(self, network_name):
@ -304,7 +315,7 @@ class Network(object):
body['port']['binding:vnic_type'] = vnic_type
port = self.neutron_client.create_port(body)
if self.config.debug:
LOG.info('Created port ' + port['port']['id'])
LOG.debug('Created port ' + port['port']['id'])
return port['port']
def delete_port(self, port):

View File

@ -30,11 +30,6 @@ class PerfInstance(Instance):
self.tp_tool = config.tp_tool(self)
else:
self.tp_tool = None
# Override the config drive option to save in instance
if config.config_drive:
self.config_drive = True
else:
self.config_drive = None
# No args is reserved for native host server
def create(self, image=None, flavor_type=None,

View File

@ -270,8 +270,8 @@ class VmtpTest(object):
self.config.internal_network_name = int_net_name
else:
# Make sure we have an external network and an external router
self.assert_true(self.net.ext_net)
self.assert_true(self.net.ext_router)
# self.assert_true(self.net.ext_net)
# self.assert_true(self.net.ext_router)
self.assert_true(self.net.vm_int_net)
# Get hosts for the availability zone to use
@ -826,6 +826,22 @@ def parse_opts_from_cli():
help='binding vnic type for test VMs',
metavar='<direct|macvtap|normal>')
parser.add_argument('--no-dhcp', dest='no_dhcp',
default=False,
action='store_true',
help='Assign IP address to guest instance')
parser.add_argument('--no-floatingip', dest='no_floatingip',
default=False,
action='store_true',
help='Do not assign floating IP to guest instance')
parser.add_argument('--use-config-drive', dest='config_drive',
default=False,
action='store_true',
help='Use config drive to configure guest instance. Enable this option '
'when metadata service is not available')
parser.add_argument('-d', '--debug', dest='debug',
default=False,
action='store_true',
@ -979,6 +995,9 @@ def merge_opts_to_configs(opts):
if opts.os_dataplane_network:
config.os_dataplane_network = opts.os_dataplane_network
config.config_drive = opts.config_drive
config.no_floatingip = opts.no_floatingip
config.no_dhcp = opts.no_dhcp
config.delete_image_after_run = opts.delete_image_after_run
#####################################################