Skip to content
Snippets Groups Projects
Select Git revision
1 result Searching

README.md

Blame
  • To learn more about this project, read the wiki.
    fixture.sh 9.87 KiB
    #!/bin/bash
    #/////////////////////////////////////////////////////////////////////////
    #//
    #// (c) University of Southampton IT Innovation Centre, 2018
    #//
    #// Copyright in this software belongs to University of Southampton
    #// IT Innovation Centre of Gamma House, Enterprise Road,
    #// Chilworth Science Park, Southampton, SO16 7NS, UK.
    #//
    #// This software may not be used, sold, licensed, transferred, copied
    #// or reproduced in whole or in part in any manner or form or in or
    #// on any media by any person other than in accordance with the terms
    #// of the Licence Agreement supplied with the software, or otherwise
    #// without the prior written consent of the copyright owners.
    #//
    #// This software is distributed WITHOUT ANY WARRANTY, without even the
    #// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
    #// PURPOSE, except where stated in the Licence Agreement supplied with
    #// the software.
    #//
    #//      Created By :            Michael Boniface
    #//      Created Date :          13/12/2018
    #//      Created for Project :   FLAME
    #//
    #/////////////////////////////////////////////////////////////////////////
    
    repo_root="/vagrant"
    target_root="/opt/clmc"
    config_file="rspec.json"
    
    usage() {
        echo "Usage: $0 create|start|stop|destroy [-f config_file] [-r repo_root] [-c container_name|all]" 1>&2
        echo "    -f defaults to '${config_file}'" 1>&2
        echo "    -r defaults to '${repo_root}'" 1>&2
        echo "    -c must be specified, use 'all' for all" 1>&2
        exit 1
    }
    
    create() {
        service_name=$1
        config_file=$2
        repo_root=$3
        if ! lxc list | grep ${service_name}; then
            # create a container with a static ip address
            echo "Creating container: ${service_name}"
            SERVICE=$(jq --arg NAME ${service_name} '.[] | select(.name==$NAME)' ${config_file})
            echo $SERVICE
            ip=$(echo $SERVICE | jq -r '.ip_address')
    
            lxc init ubuntu:16.04 ${service_name}
            echo "Creating network: ${service_name}"
            lxc network attach lxcbr0 ${service_name} eth0
            lxc config device set ${service_name} eth0 ipv4.address ${ip}
            lxc config set ${service_name} security.privileged true
    
            # copy flame clmc files into the root container
            echo "Copying files to rootfs"
            container_dir="/var/lib/lxd/containers/"${service_name}"/rootfs"
            container_repo_root=${container_dir}${target_root}
            mkdir -p ${container_repo_root}       
            cp -f ${repo_root}/reporc ${container_repo_root}   
            cp -rf ${repo_root}/scripts ${container_repo_root}     
            cp -rf ${repo_root}/src ${container_repo_root}
            chown -R 100000:100000 ${container_repo_root} 
    
            # start the container
            echo "Starting: ${service_name}"
            lxc start ${service_name}
            while :; do
                echo "Waiting for container to start: ${service_name}"
                lxc file pull ${service_name}/etc/resolv.conf - | grep -q nameserver && break
                sleep 1
            done
    
            # provision software into each container
            echo "Provisioning: ${service_name}"
            if [ ${service_name} == "clmc-service" ]; then
                cmd="${target_root}/scripts/clmc-service/install.sh"
                echo "Provisioning command ${cmd}"
                lxc exec ${service_name} --env REPO_ROOT=${target_root} --env SFEMC_FQDN="sfemc.localhost" --env SDN_CONTROLLER_IP="127.0.0.1" --env NETWORK_DEPENDENCY="network.target"-- ${cmd}
                exit_code=$?
                if [ $exit_code != 0 ]; then
                    echo "clmc-service installation failed with exit code ${exit_code}"
                    exit 1
                fi            
            elif [ ${service_name} == "test-runner" ]
            then
                cmd="${target_root}/src/test/clmctest/services/pytest/install.sh"
                lxc exec ${service_name} -- ${cmd}
                exit_code=$?
                if [ $exit_code != 0 ]; then
                    echo "test-runner installation failed with exit code ${exit_code}"
                    exit 1
                fi            
            else
                # get container parameters
                location=$(echo $SERVICE | jq -r '.location')
                sf_package_id=$(echo $SERVICE | jq -r '.sf_package_id')
                sf_id=$(echo $SERVICE | jq -r '.sf_id')
                sfc_id=$(echo $SERVICE | jq -r '.sfc_id')
                sfc_instance_id=$(echo $SERVICE | jq -r '.sfc_instance_id')
                sf_endpoint_id=$(echo $SERVICE | jq -r '.sf_endpoint_id')
                influxdb_url=$(echo $SERVICE | jq -r '.influxdb_url')
    
                # install service function specific software
                cmd="${target_root}/src/test/clmctest/services/${sf_package_id}/install.sh"
                lxc exec ${service_name} --env REPO_ROOT="${target_root}" -- ${cmd}
                exit_code=$?
                if [ $exit_code != 0 ]; then
                    echo "${sf_package_id} installation failed with exit code ${exit_code}"
                    exit 1
                fi
                # install telegraf
                cmd="${target_root}/scripts/clmc-agent/install.sh"
                lxc exec ${service_name} --env REPO_ROOT="${target_root}" -- ${cmd}
    
                # check that telegraf installed (it may not have if the reporc file was not present or Nexus server was down)
                if lxc-attach -n ${service_name} -- ls /etc/telegraf |& grep 'ls: cannot access'; then
                    echo "Telegraf agent failed to install (check reporc?)"
                    exit 1
                fi
    
                # stop telegraf before changing the configs
                lxc exec ${service_name} -- service telegraf stop
    
                # copy telegraf configuration templates
                cp -f ${repo_root}/scripts/clmc-agent/telegraf.conf ${container_dir}/etc/telegraf/
                cp -f ${repo_root}/scripts/clmc-agent/telegraf_output.conf ${container_dir}/etc/telegraf/telegraf.d/
                # copy the 'host' config into all service containers
                cp -f ${repo_root}/src/test/clmctest/services/host/telegraf*.conf ${container_dir}/etc/telegraf/telegraf.d/
                # copy the service-specific config
                cp -f ${repo_root}/src/test/clmctest/services/${sf_package_id}/telegraf*.conf ${container_dir}/etc/telegraf/telegraf.d/
                chown -R 100000:100000 ${container_dir}/etc/telegraf/
    
                # replace telegraf template with container parameters
                cmd="${target_root}/scripts/clmc-agent/configure.sh ${location} ${sfc_id} ${sfc_instance_id} ${sf_package_id} ${sf_id} ${sf_endpoint_id} ${influxdb_url}"
                lxc exec ${service_name} -- ${cmd}
    
                # start telegraf
                lxc exec ${service_name} -- service telegraf start
            fi
    
            # set forward ports
            ports=$(echo $SERVICE | jq -r '.forward_ports')
            if [ "$ports" != "null" ]; then
                for row in $(echo "${ports}" | jq -r '.[] | @base64'); do
                    _jq() {
                    echo ${row} | base64 --decode | jq -r ${1}
                    }
                    guest_port=$(_jq '.guest')
                    host_port=$(_jq '.host')
                    iptables -t nat -I PREROUTING -i enp0s3 -p TCP -d 10.0.2.15 --dport ${host_port} -j DNAT --to-destination ${ip}:${guest_port}
                done
            fi
        fi
    }
    
    start() {
        service_name=$1
        if lxc info ${service_name}; then
            echo "Starting container: ${service_name}"
            lxc start ${service_name}
        fi
    }
    
    stop() {
        service_name=$1
        if lxc info ${service_name}; then
            echo "Stopping container: ${service_name}"
            lxc stop -n ${service_name}
        fi
    }
    
    destroy() {
        service_name=$1
        config_file=$2
        if lxc list | grep ${service_name}; then
            echo "Stopping container: ${service_name}"
            lxc stop ${service_name}
            echo "Destroying container: ${service_name}"
            lxc delete ${service_name}
    
            # remove forward ports
            ports=$(echo $SERVICE | jq -r '.forward_ports')
            if [ "$ports" != "null" ]; then
                echo "destroy ports"
                for row in $(echo "${ports}" | jq -r '.[] | @base64'); do
                    _jq() {
                    echo ${row} | base64 --decode | jq -r ${1}
                    }
                    guest_port=$(_jq '.guest')
                    host_port=$(_jq '.host')
                    iptables -t nat -D PREROUTING -i enp0s3 -p TCP -d 10.0.2.15 --dport ${host_port} -j DNAT --to-destination ${ip}:${guest_port}
                done
            fi
        fi
    }
    
    # inc option index by 1 as first argument is the command and not parsed by getopts
    if [ $# -gt 1 ]; then
        OPTIND=$((OPTIND+1))
    fi
    
    # collect the optional arguments
    while getopts "hf:r:c:" opt; do
      case $opt in
        h) usage; exit ;;
        f) config_file=${OPTARG} ;;
        r) repo_root=${OPTARG} ;;
        c) container=${OPTARG} ;;
        \?) usage ;;
      esac
    done
    
    # check configuration file exists
    if [ ! -f ${config_file} ]; then
        echo "Configuration file does not exist: ${config_file}" >&2
        usage
        exit 1
    fi
    
    # check repo root directory exists
    if [ ! -d ${repo_root} ]; then
        echo "Repo root directory does not exist: ${repo_root}" >&2
        usage
        exit 1
    fi
    
    # check a service has been defined
    if [ -z ${container} ]; then
        echo "A container must be named: use 'all' for all"
        usage
        exit 1
    fi
    
    # iterate of list of services in configuration file
    command=$1
    service_names=$(jq -r '.[].name' ${config_file})
    for service_name in $service_names; do
        # if all or specific container
        if [ ${container} = all -o ${container} = ${service_name} ]; then
            case "${command}" in
                create)
                    create ${service_name} ${config_file} ${repo_root}
                    ;;
                start)
                    start ${service_name} ${config_file} ${repo_root}
                    ;;
                stop)
                    stop ${service_name} ${config_file} ${repo_root}
                    ;;
                destroy)
                    destroy ${service_name} ${config_file} ${repo_root}
                    ;;
                *)
                    usage
                    ;;
            esac
        fi
    done
    
    
    
    echo -e "\n\n------>Create iptables summary"
    iptables -t nat -L -n -v
    iptables-save > /etc/iptables/rules.v4