Enhancements networking support of storage testing

1. Support to run storage testing off provider network;
2. Support to run sotrage testing with IPv6 subnets;
3. Remove the NOVA client version restriction;
4. Update to use ubuntu 18.04 as KloudBuster base image;
5. Use config_drive to pass configs;

Change-Id: Ie0753b0c6616edb13c5426c26a9e04983d330d0d
This commit is contained in:
Yichen Wang 2019-04-29 18:34:17 -07:00
parent 3466504541
commit 1da3c08594
10 changed files with 56 additions and 42 deletions

9
kb_build.sh Normal file → Executable file
View File

@ -40,8 +40,13 @@ function build_vm {
# Add the kloudbuster elements directory to the DIB elements path
export ELEMENTS_PATH=./elements
# Install Ubuntu 16.04
export DIB_RELEASE=xenial
# canned user/password for direct login
export DIB_DEV_USER_USERNAME=kloudbuster
export DIB_DEV_USER_PASSWORD=kloudbuster
export DIB_DEV_USER_PWDLESS_SUDO=Y
# Install Ubuntu 18.04
export DIB_RELEASE=bionic
time disk-image-create -o $kb_image_name block-device-mbr ubuntu kloudbuster
rm -rf venv $kb_image_name.d

View File

@ -43,16 +43,21 @@ mkdir -p /data/www
chmod -R 777 /data
# redis server should listen on all interfaces
sed -i "s/127.0.0.1/0.0.0.0/g" /etc/redis/redis.conf
sed -i "s/^bind 127.0.0.1 ::1/bind 0.0.0.0 ::0/g" /etc/redis/redis.conf
# if started nginx should be allowed to open more file descriptors
sed -i 's/start-stop-daemon\ --start/ulimit\ \-n\ 102400\n\t\0/g' /etc/init.d/nginx
# Auto start the KloudBuster Agent, with user-data
sed -i "s/^exit\s0/cd \/kb_test\n\0/g" /etc/rc.local
sed -i "s/^exit\s0/if wget http\:\/\/169.254.169.254\/latest\/user-data; then \:; fi\n\0/g" /etc/rc.local
sed -i 's/^exit\s0/echo `hostname -I` `hostname` >>\/etc\/hosts\n\0/g' /etc/rc.local
sed -i "s/^exit\s0/python kb_vm_agent.py \&\n\0/g" /etc/rc.local
echo '#!/bin/bash' > /etc/rc.local
echo 'echo -e "127.0.0.1\\t`hostname`" >> /etc/hosts' >> /etc/rc.local
echo 'echo `hostname -I` `hostname` >> /etc/hosts' >> /etc/rc.local
echo 'mkdir -p /mnt/config' >> /etc/rc.local
echo 'mount /dev/disk/by-label/config-2 /mnt/config' >> /etc/rc.local
echo 'cp /mnt/config/openstack/latest/user_data /kb_test/' >> /etc/rc.local
echo 'cd /kb_test' >> /etc/rc.local
echo 'python kb_vm_agent.py &' >> /etc/rc.local
chmod +x /etc/rc.local
# =================
# KloudBuster Proxy
@ -108,13 +113,7 @@ rm -rf /tmp/wrk2
rm -rf /tmp/fio
# Uninstall unneeded packages
apt-get -y --purge remove libyaml-dev
apt-get -y --purge remove libssl-dev
apt-get -y --purge remove zlib1g-dev
apt-get -y --purge remove libaio-dev
apt-get -y --purge remove python-pip
apt-get -y --purge remove python-dev
apt-get -y --purge remove build-essential
apt-get -y --purge remove cmake
apt-get -y --purge remove libyaml-dev libssl-dev zlib1g-dev libaio-dev python-pip python-dev build-essential cmake
apt-get -y --purge autoremove
apt-get -y install python
apt-get -y autoclean

View File

@ -42,7 +42,7 @@ def exec_command(cmd, cwd=None):
p = subprocess.Popen(cmd, cwd=cwd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(stdout, stderr) = p.communicate()
if p.returncode:
syslog.syslog("Command failed: " + cmd)
syslog.syslog("Command failed: " + ' '.join(cmd))
if stderr:
syslog.syslog(stderr)
return p.returncode
@ -173,7 +173,7 @@ class KBA_Client(object):
host = user_data['redis_server']
port = user_data['redis_server_port']
self.user_data = user_data
self.redis_obj = redis.StrictRedis(host=host, port=port)
self.redis_obj = redis.Redis(host=host, port=port)
self.pubsub = self.redis_obj.pubsub(ignore_subscribe_messages=True)
self.hello_thread = None
self.stop_hello = threading.Event()
@ -199,7 +199,7 @@ class KBA_Client(object):
def report(self, cmd, client_type, data):
message = {'cmd': cmd, 'sender-id': self.vm_name,
'client-type': client_type, 'data': data}
self.redis_obj.publish(self.report_chan_name, message)
self.redis_obj.publish(self.report_chan_name, str(message))
def send_hello(self):
# Sending "hello" message to master node every 2 seconds
@ -595,7 +595,7 @@ class KBA_Proxy(object):
if __name__ == "__main__":
try:
with open('user-data', 'r') as f:
with open('user_data', 'r') as f:
user_data = dict(eval(f.read()))
except Exception as e:
# KloudBuster starts without user-data

View File

@ -51,7 +51,7 @@ class BaseCompute(object):
# security group, keypair with a provided public key
def create_server(self, image_name, flavor_type, keyname,
nic, sec_group, avail_zone=None, user_data=None,
config_drive=None, retry_count=100):
config_drive=True, retry_count=100):
"""
Create a VM instance given following parameters
1. VM Name
@ -141,11 +141,11 @@ class SecGroup(object):
self.novaclient = novaclient
self.neutronclient = neutronclient
def create_secgroup_with_rules(self, group_name):
def create_secgroup_with_rules(self, group_name, is_ipv6=False):
body = {
'security_group': {
'name': group_name,
'description': 'Test sec group'
'description': 'KloudBuster security group'
}
}
group = self.neutronclient.create_security_group(body)['security_group']
@ -158,6 +158,9 @@ class SecGroup(object):
}
}
if is_ipv6:
body['security_group_rule']['ethertype'] = 'IPv6'
# Allow ping traffic
body['security_group_rule']['protocol'] = 'icmp'
body['security_group_rule']['port_range_min'] = None

View File

@ -155,7 +155,8 @@ class BaseNetwork(object):
secgroup_instance = base_compute.SecGroup(self.nova_client, self.neutron_client)
self.secgroup_list.append(secgroup_instance)
secgroup_name = network_prefix + "-SG" + str(secgroup_count)
secgroup_instance.create_secgroup_with_rules(secgroup_name)
secgroup_instance.create_secgroup_with_rules(
secgroup_name, is_ipv6=self.network['is_ipv6'])
self.res_logger.log('sec_groups', secgroup_instance.secgroup['name'],
secgroup_instance.secgroup['id'])
@ -261,11 +262,14 @@ class BaseNetwork(object):
# add subnet id to the network dict since it has just been added
self.network['subnets'] = [subnet['id']]
self.network['subnet_ip'] = cidr
self.network['is_ipv6'] = False
def add_provider_network(self, name):
self.network = find_provider_network(self.neutron_client, name)
if len(self.network['subnets']) > 0:
self.network['subnet_ip'] = self.get_cidr_from_subnet_id(self.network['subnets'][0])
subnet = self.neutron_client.show_subnet(self.network['subnets'][0])['subnet']
self.network['subnet_ip'] = subnet['cidr']
self.network['is_ipv6'] = True if subnet['ipv6_address_mode'] else False
def get_cidr_from_subnet_id(self, subnetID):
sub = self.neutron_client.show_subnet(subnetID)
@ -306,7 +310,7 @@ class Router(object):
of network interfaces to router
"""
def __init__(self, user, is_dumb=False):
def __init__(self, user, provider_network=None):
self.neutron_client = user.neutron_client
self.nova_client = user.nova_client
self.router = None
@ -319,7 +323,7 @@ class Router(object):
self.shared_port_id = None
# Store the interface ip of shared network attached to router
self.shared_interface_ip = None
self.is_dumb = is_dumb
self.provider_network = provider_network
def create_network_resources(self, config_scale):
"""
@ -328,10 +332,11 @@ class Router(object):
network
"""
if self.is_dumb:
if self.provider_network:
# This is dummy router, use provider network directly
network_instance = BaseNetwork(self)
self.network_list.append(network_instance)
network_instance.add_provider_network(config_scale['multicast_provider_network_name'])
network_instance.add_provider_network(self.provider_network)
network_instance.create_compute_resources(network_instance.network['name'],
config_scale)
return
@ -371,12 +376,12 @@ class Router(object):
# Now delete the compute resources and the network resources
flag = flag & network.delete_compute_resources()
if network.network:
if self.is_dumb:
if self.provider_network:
continue
flag = flag & self.remove_router_interface(network)
flag = flag & network.delete_network()
# Also delete the shared port and remove it from router interface
if self.shared_network and not self.is_dumb:
if self.shared_network and not self.provider_network:
flag = flag & self.remove_router_interface(self.shared_network, use_port=True)
self.shared_network = None
@ -414,10 +419,10 @@ class Router(object):
Also delete the networks attached to this router
"""
# Delete the network resources first and than delete the router itself
if not self.router and not self.is_dumb:
if not self.router and not self.provider_network:
return True
network_flag = self.delete_network_resources()
if self.is_dumb:
if self.provider_network:
return network_flag
router_flag = False
for _ in range(10):

View File

@ -61,8 +61,8 @@ vm_creation_concurrency: 5
# example to debug)
public_key_file:
# Name of Provider network used for multicast tests.
multicast_provider_network_name: '' # Leave blank to use first available (default) network.
# Name of Provider network used for multicast tests or storage tests.
provider_network_name:
# TSDB connectors are optional and can be used to retrieve CPU usage information and attach them
# to the results.

View File

@ -111,8 +111,8 @@ class KBRunner(object):
def send_cmd(self, cmd, client_type, data):
message = {'cmd': cmd, 'sender-id': 'kb-master',
'client-type': client_type, 'data': data}
LOG.kbdebug(message)
self.redis_obj.publish(self.orches_chan_name, message)
LOG.kbdebug(str(message))
self.redis_obj.publish(self.orches_chan_name, str(message))
def polling_vms(self, timeout, polling_interval=None):
'''

View File

@ -251,7 +251,9 @@ class Kloud(object):
instance.fixed_ip = instance.instance.networks.values()[0][0]
u_fip = instance.config['use_floatingip']
if instance.vm_name == "KB-PROXY" and not u_fip and not self.multicast_mode:
if self.scale_cfg['provider_network']:
instance.fip = None
elif instance.vm_name == "KB-PROXY" and not u_fip and not self.multicast_mode:
neutron_client = instance.network.router.user.neutron_client
external_network = base_network.find_external_network(neutron_client)
instance.fip = base_network.create_floating_ip(neutron_client, external_network)

View File

@ -143,11 +143,12 @@ class User(object):
self.key_pair.add_public_key(self.key_name, config_scale.public_key_file)
# Find the external network that routers need to attach to
if self.tenant.kloud.multicast_mode:
router_instance = base_network.Router(self, is_dumb=True)
if self.tenant.kloud.multicast_mode or (
self.tenant.kloud.storage_mode and config_scale.provider_network):
router_instance = base_network.Router(
self, provider_network=config_scale.provider_network_name)
self.router_list.append(router_instance)
router_instance.create_network_resources(config_scale)
else:
external_network = base_network.find_external_network(self.neutron_client)
# Create the required number of routers and append them to router list

View File

@ -11,8 +11,7 @@ python-cinderclient>=2.0.1
python-glanceclient>=2.6.0
python-openstackclient>=3.11.0
python-neutronclient>=6.2.0
# starting from 10.0.0, floating ip apis are removed from novaclient
python-novaclient>=9.0.0,<10.0.0
python-novaclient>=9.0.0
python-keystoneclient>=3.10.0
attrdict>=2.0.0
hdrhistogram>=0.5.2