#!/bin/python # # Copyright (c) 2017 All rights reserved # This program and the accompanying materials # are made available under the terms of the Apache License, Version 2.0 # which accompanies this distribution, and is available at # # http://www.apache.org/licenses/LICENSE-2.0 # # import os from utils.utils_log import LOG, for_all_methods, log_enter_exit from utils.service import Service from utils.processutils import execute from utils import utils_yaml from utils.shutil import shutil from utils.node_manager import NodeManager MAX_NODES = 5 @for_all_methods(log_enter_exit) class TestEnvironment(Service): NODE_NAME = 'baremetal' TEMPLATES = '../templates' BRIGES = ['admin', 'private', 'public', 'storage'] def run(self, sys_args, config): self.env = str(sys_args.env_number).replace('"', '') self.BUILD_DIR = '../build/apex-%s' % self.env self.cleanup() if sys_args.cleanup: return if not sys_args.cloner_info or not sys_args.snapshot_disks\ or not sys_args.vjump_hosts: LOG.error('--cloner-info, --snapshot-disks and --vjump-hosts ' ' have to be given if not only --cleanup.') exit(1) node_info = utils_yaml.read_dict_from_yaml(sys_args.cloner_info + '/node.yaml') nodes = node_info['servers'] number_of_nodes = len(nodes) disk_home = self.BUILD_DIR + '/disks/' shutil.mkdir_if_not_exsist(disk_home) # Create Snapshots for i in range(number_of_nodes): disk_name = '%s%s.qcow2' % (self.NODE_NAME, i) self.create_snapshot('%s/%s' % (sys_args.snapshot_disks, disk_name), '%s/%s' % (disk_home, disk_name)) # Create Bridges if not existing for net in self.BRIGES: bridge_name = '%s-%s' % (net, self.env) if not self.check_if_br_exists(bridge_name): LOG.info('Creating bridge %s' % bridge_name) execute('ovs-vsctl add-br %s' % bridge_name, as_root=True) # Create virtual Nodes dom_template = self.TEMPLATES + '/nodes/baremetalX.xml' dom_config = self.BUILD_DIR + '/nodes/baremetalX.xml' shutil.mkdir_if_not_exsist(self.BUILD_DIR + '/nodes/') LOG.info('Creating virtual Nodes') for name, node in nodes.iteritems(): orig_node_name = node['vNode-name'] node_name = orig_node_name + '-' + self.env LOG.info('Create node %s' % node_name) type = node['type'] if type == 'compute': cpu = 4 mem = 4 elif type == 'controller': cpu = 8 mem = 10 else: raise Exception('Unknown node type! %s' % type) shutil.copy('to', dom_template, dom_config) shutil.replace_string_in_file(dom_config, 'NaMe', node_name) disk_full_path = os.path.abspath('%s/%s.qcow2' % (disk_home, orig_node_name)) shutil.replace_string_in_file(dom_config, 'DiSk', disk_full_path) shutil.replace_string_in_file(dom_config, 'vCpU', str(cpu)) shutil.replace_string_in_file(dom_config, 'MeMoRy', str(mem)) shutil.replace_string_in_file(dom_config, 'InDeX', self.env) execute('virsh define ' + dom_config) execute('virsh start ' + node_name) cores_per_environment = 8 cores = '%s-%s' % (int(self.env) * 8, int(self.env) * 8 + cores_per_environment - 1) LOG.info('Pining vCPU of node %s to cores %s' % (node_name, cores)) for i in range(cpu): execute('virsh vcpupin %(node)s %(nodes_cpu)s %(host_cpu)s' % {'node': node_name, 'nodes_cpu': i, 'host_cpu': cores}) # Upload cloner_info to jenkins slave node_name = 'jenkins%s' % self.env jenkins_node_config = utils_yaml.read_dict_from_yaml( sys_args.vjump_hosts)['servers'] if node_name not in jenkins_node_config: raise Exception('Jenkins host %s not provided in %s' % (node_name, sys_args.vjump_hosts)) jenkins_slave = NodeManager(jenkins_node_config).get_node(node_name) if 'CLONER_INFO' in os.environ: cloner_info_path = os.environ['CLONER_INFO'] else: cloner_info_path = '/home/jenkins/' jenkins_slave.copy('to', sys_args.cloner_info, cloner_info_path) def check_if_br_exists(self, bridge): _, (_, rc) = execute('ovs-vsctl br-exists %s' % bridge, check_exit_code=[0, 2], as_root=True) return True if rc == 0 else False def create_snapshot(self, orig, path): LOG.info('Creating snapshot of %s in %s' % (orig, path)) execute('qemu-img create -f qcow2 -b %s %s' % (orig, path), as_root=True) def cleanup(self): for i in range(MAX_NODES): rv, (_, rc) = execute('virsh destroy %(name)s%(i)s-%(env)s' % {'i': i, 'env': self.env, 'name': self.NODE_NAME}, check_exit_code=[0, 1]) if rc == 0: LOG.info(rv) rv, (_, rc) = execute('virsh undefine %(name)s%(i)s-%(env)s' % {'i': i, 'env': self.env, 'name': self.NODE_NAME}, check_exit_code=[0, 1]) if rc == 0: LOG.info(rv) execute('rm -rf ' + self.BUILD_DIR) def create_cli_parser(self, parser): parser.add_argument('--env-number', help="Number of the environment", required=True) parser.add_argument('--cloner-info', help="Path to the cloner-info", required=False) parser.add_argument('--snapshot-disks', help="Path to the snapshots", required=False) parser.add_argument('--vjump-hosts', help=("Path to the information of" " the virtual jumphosts"), required=False) parser.add_argument('--cleanup', help="Only Cleanup", required=False, action='store_true') return parser def main(): main = TestEnvironment() main.start() if __name__ == '__main__': main()