#!/bin/bash # # POC Script to build/install/deploy/orchestrate Tacker on an OPNFV Brhamaputra Fuel cluster # Script assuming it runs on the openstack primary controller (where is opendaylight # present) and there is a fuel master on 10.20.0.2 and can be reached with default # credentials. # # author: Ferenc Cserepkei # # (c) 2016 Telefonaktiebolaget L. M. ERICSSON # # 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 # SSH_OPTIONS=(-o StrictHostKeyChecking=no -o GlobalKnownHostsFile=/dev/null -o UserKnownHostsFile=/dev/null -o LogLevel=error) MYDIR=$(dirname $(readlink -f "$0")) MYREPO="tacker-server" CLIREPO="tacker-client" DEPREPO="jsonrpclib" CLIENT=$(echo python-python-tackerclient_*_all.deb) JSONRPC=$(echo python-jsonrpclib_*_all.deb) SERVER=$(echo python-tacker_*_all.deb) # Function checks whether crudini is available, if not - installs function chkCrudini () { if [[ ! -f '/usr/bin/crudini' ]]; then wget -N http://mirrors.kernel.org/ubuntu/pool/universe/p/python-iniparse/python-iniparse_0.4-2.1build1_all.deb wget -N http://archive.ubuntu.com/ubuntu/pool/universe/c/crudini/crudini_0.3-1_amd64.deb dpkg -i python-iniparse_0.4-2.1build1_all.deb crudini_0.3-1_amd64.deb fi } # Function checks whether a python egg is available, if not, installs function chkPPkg () { PKG="$1" IPPACK=$(python - <<'____EOF' import pip from os.path import join for package in pip.get_installed_distributions(): print(package.location) print(join(package.location, *package._get_metadata("top_level.txt"))) ____EOF ) echo "$IPPACK" | grep -q "$PKG" if [ $? -ne 0 ];then pip install "$PKG" fi } # Function setting up the build/deploy environment function envSetup () { apt-get update apt-get install -y git python-pip python-all debhelper chkPPkg stdeb chkCrudini } # Function installs jsonrpclib from github function deployJsonrpclib () { if [[ -e "${MYDIR}/${JSONRPC}" ]]; then echo "$JSONRPC exists." return 1 fi cd $MYDIR rm -rf $DEPREPO git clone https://github.com/joshmarshall/jsonrpclib.git $DEPREPO cd $DEPREPO dpkg --purge python-jsonrpclib python setup.py --command-packages=stdeb.command bdist_deb cd "deb_dist" JSONRPC=$(echo python-jsonrpclib_*_all.deb) cp $JSONRPC $MYDIR dpkg -i $JSONRPC } # Function builds Tacker server from github function buildTackerServer () { if [[ -e "${MYDIR}/${SERVER}" ]]; then echo "$SERVER exists." return 1 fi cd $MYDIR rm -rf $MYREPO git clone -b 'SFC_brahmaputra' https://github.com/trozet/tacker.git $MYREPO cd $MYREPO patch -p 1 < Installed-Size: 1575 -Depends: python (>= 2.7), python (<< 2.8), python:any (>= 2.7.1-0ubuntu2), python-pbr, python-paste, python-pastedeploy, python-routes, python-anyjson, python-babel, python-eventlet, python-greenlet, python-httplib2, python-requests, python-iso8601, python-jsonrpclib, python-jinja2, python-kombu, python-netaddr, python-sqlalchemy (>= 1.0~), python-sqlalchemy (<< 1.1), python-webob, python-heatclient, python-keystoneclient, alembic, python-six, python-stevedore, python-oslo.config, python-oslo.messaging-, python-oslo.rootwrap, python-novaclient +Depends: python (>= 2.7), python (<< 2.8), python:any (>= 2.7.1-0ubuntu2), python-pbr, python-paste, python-pastedeploy, python-routes, python-anyjson, python-babel, python-eventlet, python-greenlet, python-httplib2, python-requests, python-iso8601, python-jsonrpclib, python-jinja2, python-kombu, python-netaddr, python-sqlalchemy (>= 1.0~), python-sqlalchemy (<< 1.1), python-webob, python-heatclient, python-keystoneclient, alembic, python-six, python-stevedore, python-oslo.config, python-oslo.messaging, python-oslo.rootwrap, python-novaclient Section: python Priority: optional Description: OpenStack servicevm/device manager EOFDC cd "$MYDIR" echo "Patching deb..." dpkg -b "$TMPDIR" "${MYDIR}/${SERVER}" rm -r "$TMPDIR" dpkg -i "${MYDIR}/${SERVER}" } # Function deploys Tacker-server (installs missing mandatory files: upstart, default) function deployTackerServer () { rm -rf /etc/default/tacker-server cat > /etc/default/tacker-server < /etc/init/tacker.conf <" start on runlevel [2345] stop on runlevel [!2345] respawn respawn limit 20 5 limit nofile 65535 65535 chdir /var/run pre-start script # stop job from continuing if no config file found for daemon [ ! -f /etc/default/tacker-server ] && { stop; exit 0; } [ ! -f /etc/tacker/tacker.conf ] && { stop; exit 0; } # source the config file . /etc/default/tacker-server # stop job from continuing if admin has not enabled service in # config file. [ -z "\$ENABLED" ] && { stop; exit 0; } mkdir -p /var/run/tacker mkdir -p /var/log/tacker echo "Starting tacker server" end script pre-stop script echo "Stopping tacker server" end script exec /usr/bin/python /usr/bin/tacker-server --log-file=/var/log/tacker/tacker-server.log -v -d --config-file=/etc/tacker/tacker.conf EOFSC } # Function installs python-tackerclient from github function deployTackerClient() { if [[ -e "${MYDIR}/${CLIENT}" ]]; then echo "$CLIENT exists." return 1 fi cd $MYDIR rm -rf $CLIREPO dpkg --purge python-tackerclient git clone -b 'SFC_refactor' https://github.com/trozet/python-tackerclient.git $CLIREPO cd $CLIREPO python setup.py --command-packages=stdeb.command bdist_deb cd "deb_dist" CLIENT=$(echo python-python-tackerclient_*_all.deb) cp $CLIENT $MYDIR dpkg -i "${MYDIR}/${CLIENT}" } # Function removes the cloned git repositories function remove_repo () { if [[ -d "${MYDIR}/${1}" ]]; then rm -r "$1" fi } # Funcion copies and installs built artifact on all remaining cluster nodes function populate_client() { wget -O deb http://archive.ubuntu.com/ubuntu/pool/universe/s/sshpass/sshpass_1.05-1_amd64.deb &&\ dpkg -i deb &&\ rm deb clusternodes=$(sshpass -p "r00tme" ssh ${SSH_OPTIONS[@]} root@10.20.0.2 fuel node | cut -d '|' -f 5 | grep -E -o "([0-9]{1,3}[\.]){3}[0-9]{1,3}" ) myaddr=$(ifconfig br-fw-admin | sed -n '/inet addr/s/.*addr.\([^ ]*\) .*/\1/p') for anode in $clusternodes ; do if [ "$anode" != "$myaddr" ] ; then echo "Installing $CLIENT on $anode" scp ${SSH_OPTIONS[@]} $CLIENT $anode:$CLIENT ssh ${SSH_OPTIONS[@]} $anode dpkg -i $CLIENT ssh ${SSH_OPTIONS[@]} $anode rm $CLIENT fi done } # Function orchestrate the Tacker service function orchestarte () { rm -rf /etc/puppet/modules/tacker pushd /etc/puppet/modules git clone https://github.com/trozet/puppet-tacker.git tacker rm -rf /etc/puppet/modules/tacker/.git popd ### Facts ### # Port(s) Protocol ServiceDetails Source # 8805-8872 tcp,udp Unassigned IANA bind_port='8808' auth_uri=$(crudini --get '/etc/heat/heat.conf' 'keystone_authtoken' 'auth_uri') identity_uri=$(crudini --get '/etc/heat/heat.conf' 'keystone_authtoken' 'identity_uri') mgmt_addr=$(ifconfig br-mgmt | sed -n '/inet addr/s/.*addr.\([^ ]*\) .*/\1/p') pub_addr=$(ifconfig br-ex-lnx | sed -n '/inet addr/s/.*addr.\([^ ]*\) .*/\1/p') rabbit_host=$(crudini --get '/etc/heat/heat.conf' 'oslo_messaging_rabbit' 'rabbit_hosts'| cut -d ':' -f 1) rabbit_password=$(crudini --get '/etc/heat/heat.conf' 'oslo_messaging_rabbit' 'rabbit_password') sql_host=$(hiera database_vip) database_connection="mysql://tacker:tacker@${sql_host}/tacker" admin_url="http://${mgmt_addr}:${bind_port}" public_url="http://${pub_addr}:${bind_port}" heat_api_vip=$(crudini --get '/etc/heat/heat.conf' 'heat_api' 'bind_host') allowed_hosts="[ '${sql_host}', '${HOSTNAME%%.domain.tld}', 'localhost', '127.0.0.1', '%' ]" heat_uri="http://${heat_api_vip}:8004/v1" odl_port='8282' service_tenant='services' myRegion='RegionOne' myPassword='tacker' cat > configure_tacker.pp << EOF class mysql::config {} include mysql::config class mysql::server {} include mysql::server class { 'tacker': package_ensure => 'absent', client_package_ensure => 'absent', bind_port => '${bind_port}', keystone_password => '${myPassword}', keystone_tenant => '${service_tenant}', auth_uri => '${auth_uri}', identity_uri => '${identity_uri}', database_connection => '${database_connection}', rabbit_host => '${rabbit_host}', rabbit_password => '${rabbit_password}', heat_uri => '${heat_uri}', opendaylight_host => '${mgmt_addr}', opendaylight_port => '${odl_port}', } class { 'tacker::db::mysql': password => '${myPassword}', allowed_hosts => ${allowed_hosts}, } class { 'tacker::keystone::auth': password => '${myPassword}', tenant => '${service_tenant}', admin_url => '${admin_url}', internal_url => '${admin_url}', public_url => '${public_url}', region => '${myRegion}', } EOF puppet apply configure_tacker.pp rm -f tackerc cat > tackerc <