diff options
Diffstat (limited to 'nfvbench/chain_clients.py')
-rw-r--r-- | nfvbench/chain_clients.py | 121 |
1 files changed, 79 insertions, 42 deletions
diff --git a/nfvbench/chain_clients.py b/nfvbench/chain_clients.py index faf7c2a..71c6c97 100644 --- a/nfvbench/chain_clients.py +++ b/nfvbench/chain_clients.py @@ -185,7 +185,7 @@ class BasicStageClient(object): return None return availability_zone + ':' + host - def _lookup_servers(self, name=None, nets=None, az=None, flavor_id=None): + def _lookup_servers(self, name=None, nets=None, flavor_id=None): error_msg = 'VM with the same name, but non-matching {} found. Aborting.' networks = set([net['name'] for net in nets]) if nets else None server_list = self.comp.get_server_list() @@ -224,7 +224,10 @@ class BasicStageClient(object): files={nfvbenchvm_config_location: nfvbenchvm_config}) if server: setattr(server, 'is_reuse', False) - LOG.info('Creating instance: %s on %s', name, az) + msg = 'Creating instance: %s' % name + if az: + msg += ' on %s' % az + LOG.info(msg) else: raise StageClientException('Unable to create instance: %s.' % (name)) return server @@ -380,8 +383,8 @@ class BasicStageClient(object): compute_nodes.append(az + ':' + hostname) return compute_nodes - def get_reusable_vm(self, name, nets, az): - servers = self._lookup_servers(name=name, nets=nets, az=az, + def get_reusable_vm(self, name, nets): + servers = self._lookup_servers(name=name, nets=nets, flavor_id=self.flavor_type['flavor'].id) if servers: server = servers[0] @@ -477,17 +480,19 @@ class PVPStageClient(BasicStageClient): nets = self.config.internal_networks self.nets.extend([self._create_net(**n) for n in [nets.left, nets.right]]) - az_list = self.comp.get_enabled_az_host_list(required_count=1) - if not az_list: - raise Exception('Not enough hosts found.') + if self.comp.config.compute_nodes: + az_list = self.comp.get_enabled_az_host_list(required_count=1) + if not az_list: + raise Exception('Not enough hosts found.') + az = az_list[0] + else: + az = None - az = az_list[0] - self.compute_nodes.add(az) for chain_index in xrange(self.config.service_chain_count): name = self.config.loop_vm_name + str(chain_index) - reusable_vm = self.get_reusable_vm(name, self.nets, az) - if reusable_vm: - self.vms.append(reusable_vm) + server = self.get_reusable_vm(name, self.nets) + if server: + self.vms.append(server) else: vnic_type = 'direct' if self.config.sriov else 'normal' ports = [self._create_port(net, vnic_type) for net in self.nets] @@ -497,8 +502,19 @@ class PVPStageClient(BasicStageClient): ports[0]['mac_address'], ports[1]['mac_address']) self.created_ports.extend(ports) - self.vms.append(self._create_server(name, ports, az, config_file)) + server = self._create_server(name, ports, az, config_file) + self.vms.append(server) + + if chain_index == 0: + # First VM, save the hypervisor name. Used in future for + # maintain affinity. + self._ensure_vms_active() + server = self.comp.poll_server(server) + az = "%s:%s" % (getattr(server, 'OS-EXT-AZ:availability_zone'), + getattr(server, 'OS-EXT-SRV-ATTR:hypervisor_hostname')) + self._ensure_vms_active() + self.compute_nodes = set(self.get_loop_vm_compute_nodes()) self.set_ports() @@ -519,37 +535,36 @@ class PVVPStageClient(BasicStageClient): nets = self.config.internal_networks self.nets.extend([self._create_net(**n) for n in [nets.left, nets.right, nets.middle]]) - required_count = 2 if self.config.inter_node else 1 - az_list = self.comp.get_enabled_az_host_list(required_count=required_count) - - if not az_list: - raise Exception('Not enough hosts found.') - - az1 = az2 = az_list[0] - if self.config.inter_node: - if len(az_list) > 1: - az1 = az_list[0] - az2 = az_list[1] - else: - # fallback to intra-node - az1 = az2 = az_list[0] - self.config.inter_node = False - LOG.info('Using intra-node instead of inter-node.') - - self.compute_nodes.add(az1) - self.compute_nodes.add(az2) + if self.comp.config.compute_nodes: + required_count = 2 if self.config.inter_node else 1 + az_list = self.comp.get_enabled_az_host_list(required_count=required_count) + if not az_list: + raise Exception('Not enough hosts found.') + + az1 = az2 = az_list[0] + if self.config.inter_node: + if len(az_list) > 1: + az1 = az_list[0] + az2 = az_list[1] + else: + # fallback to intra-node + az1 = az2 = az_list[0] + self.config.inter_node = False + LOG.info('Using intra-node instead of inter-node.') + else: + az1 = az2 = None # Create loop VMs for chain_index in xrange(self.config.service_chain_count): name0 = self.config.loop_vm_name + str(chain_index) + 'a' # Attach first VM to net0 and net2 vm0_nets = self.nets[0::2] - reusable_vm0 = self.get_reusable_vm(name0, vm0_nets, az1) + reusable_vm0 = self.get_reusable_vm(name0, vm0_nets) name1 = self.config.loop_vm_name + str(chain_index) + 'b' # Attach second VM to net1 and net2 vm1_nets = self.nets[1:] - reusable_vm1 = self.get_reusable_vm(name1, vm1_nets, az2) + reusable_vm1 = self.get_reusable_vm(name1, vm1_nets) if reusable_vm0 and reusable_vm1: self.vms.extend([reusable_vm0, reusable_vm1]) @@ -583,14 +598,36 @@ class PVVPStageClient(BasicStageClient): vm1_port_net2['mac_address'], vm1_port_net1['mac_address']) - self.vms.append(self._create_server(name0, - [vm0_port_net0, vm0_port_net2], - az1, - config_file0)) - self.vms.append(self._create_server(name1, - [vm1_port_net2, vm1_port_net1], - az2, - config_file1)) + vm1 = self._create_server(name0, [vm0_port_net0, vm0_port_net2], az1, config_file0) + self.vms.append(vm1) + if chain_index == 0: + # First VM on first chain, save the hypervisor name. Used + # in future for maintain affinity. + self._ensure_vms_active() + vm1 = self.comp.poll_server(vm1) + az1 = "%s:%s" % (getattr(vm1, 'OS-EXT-AZ:availability_zone'), + getattr(vm1, 'OS-EXT-SRV-ATTR:hypervisor_hostname')) + if not self.config.inter_node: + # By default, NOVA scheduler will try first with + # different hypervisor for workload balance, but when + # inter-node is not configured, use the same AZ to run + # intra-node test case. + az2 = az1 + + vm2 = self._create_server(name1, [vm1_port_net2, vm1_port_net1], az2, config_file1) + self.vms.append(vm2) + if chain_index == 0 and self.config.inter_node: + # Second VM on first chain, save the hypervisor name. Used + # in future for maintain affinity. + self._ensure_vms_active() + vm2 = self.comp.poll_server(vm2) + az2 = "%s:%s" % (getattr(vm2, 'OS-EXT-AZ:availability_zone'), + getattr(vm2, 'OS-EXT-SRV-ATTR:hypervisor_hostname')) + if az1 == az2: + # Configure to run inter-node, but not enough node to run + self.config.inter_node = False + LOG.info('Using intra-node instead of inter-node.') self._ensure_vms_active() + self.compute_nodes = set(self.get_loop_vm_compute_nodes()) self.set_ports() |