Cherry-pick the following commits from release-0.4

* Fix errors in infrastructure
	blueprint one-style-config
	1) Update sample config - remove non-existing directory
	2) Add 0.4.1 version
	3) Rename config file to sample
	Fixes-Bug: 1270734

* Fixed issue with copy configuration files.
	Closes-Bug: #1271079

* Removed SysV EL6 standalone file, removed old setup scripts

* Fixed typo in daemon executable name

* Delete init scripts and agent config dirs
	so we will update then and not delete cache if murano-repository is unavaliable
	Closes-bug: 1274470

* Fix accessing nested-dir scripts from nested-dir agent templates.
	This works the following way: if path to agent template is,
	.g. <someHash>/template/agent/SqlServerCluster/FailoverCluster.template,
	nd it references script file '/ImportCoreFunctions.ps1', then it will
	e searched in '<someHash>/template/agent/scripts/' dir, but if it
	eferences 'Failover-Cluster.ps1', it will be searched in
	<someHash>/template/agent/scripts/SqlServerCluster/' dir.

	o the root-like agent dir '<someHash>/template/agent' corresponds to
	oot-like scripts dir '<someHash>/template/agent/scripts', and the
	ctual script file will be searched immediately in root-like scripts
	dir if it starts with '/' (absolute name), or there will be
	'rest-dirs' between root-like scripts dir and the script filename if
	the script filename is a relative one. 'rest-dirs' is the difference
	between root-like agent dir and the actual parent dir of the agent
	template which references the script dir. As you see, the
	abovementioned example is much clearer than the explanation.
	Closes-bug: #1271578

* Add forgotten deletion in metadata folder setup

* Undo init file parameter remane

* Return external network id together with routerId
	blueprint auto-assign-floating-ip

* Fix name for syslog_log_facility param

* Update reqirements for a release-0.4.1

Change-Id: I2744eaeef369220c5a8dabb027ba40622be9d242
This commit is contained in:
Ekaterina Fedorova 2014-01-20 16:14:48 +04:00
parent d1dc9e8313
commit b472670019
16 changed files with 1245 additions and 631 deletions

3
.gitignore vendored
View File

@ -14,7 +14,6 @@ dist/
#Translation build
*.mo
*.pot
#SQLite Database files
*.sqlite
*.sqlite

View File

@ -3,6 +3,10 @@ Murano Conductor README
Conductor is an Murano orchestration engine that transforms object model sent by
REST API service into a series of Heat and Murano-Agent commands
INSTALL FROM SOURCE
=====================
Please, use setup.sh script with root user privileges for install/uninstall of the software.
SEE ALSO
--------
* `Murano <http://murano.mirantis.com>`__

379
common.inc Normal file
View File

@ -0,0 +1,379 @@
#!/bin/bash
#
# Common functions file
#
DEBUGLVL=2
RUN_DIR=${RUN_DIR:-$(cd $(dirname "$0") && pwd)}
LOGFILE="$RUN_DIR/install.log"
PIPAPPS="pip python-pip pip-python"
PIPCMD=""
PIPARGS=""
TRBL_FILE=""
if [ "$DEBUGLVL" -eq 4 ]; then
set -x
fi
function log {
if [ "$DEBUGLVL" -gt 0 ]; then
chars=$(echo "@$" | wc -c)
case $DEBUGLVL in
1)
echo -e "LOG:>$@"
;;
2)
echo -e "$(date +"%m-%d-%Y %H:%M") LOG:>$@" | tee --append $LOGFILE
;;
3)
echo -e "$(date +"%m-%d-%Y %H:%M") LOG:>$@" >> $LOGFILE
;;
4)
echo -e "$(date +"%m-%d-%Y %H:%M") LOG:>$@" | tee --append $LOGFILE
;;
esac
fi
}
function lowercase(){
echo "$1" | sed "y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/"
}
function get_os(){
KERNEL=$(uname -r)
MACH=$(uname -m)
OS=$(uname)
if [ "${OS}" = "Linux" ] ; then
if [ -f /etc/redhat-release ] ; then
DISTRO_BASED_ON='RedHat'
PACKAGER='yum'
PKG_MGR='rpm'
DIST=$(cat /etc/redhat-release |sed s/\ release.*//)
PSUEDONAME=$(cat /etc/redhat-release | sed s/.*\(// | sed s/\)//)
REV=$(cat /etc/redhat-release | sed s/.*release\ // | sed s/\ .*//)
elif [ -f /etc/SuSE-release ] ; then
DISTRO_BASED_ON='SuSe'
PACKAGER='zypper'
PKG_MGR='rpm'
PSUEDONAME=$(cat /etc/SuSE-release | tr "\n" ' '| sed s/VERSION.*//)
REV=$(cat /etc/SuSE-release | tr "\n" ' ' | sed s/.*=\ //)
elif [ -f /etc/debian_version ] ; then
DISTRO_BASED_ON='Debian'
PACKAGER='apt-get'
PKG_MGR='dpkg'
DIST=$(cat /etc/lsb-release | grep '^DISTRIB_ID' | awk -F= '{ print $2 }')
PSUEDONAME=$(cat /etc/lsb-release | grep '^DISTRIB_CODENAME' | awk -F= '{ print $2 }')
REV=$(cat /etc/lsb-release | grep '^DISTRIB_RELEASE' | awk -F= '{ print $2 }')
fi
if [ -f /etc/UnitedLinux-release ] ; then
DIST="${DIST}[$(cat /etc/UnitedLinux-release | tr "\n" ' ' | sed s/VERSION.*//)]"
fi
OS=$(lowercase $OS)
DISTRO_BASED_ON=$(lowercase $DISTRO_BASED_ON)
readonly OS
readonly DIST
readonly DISTRO_BASED_ON
readonly PSUEDONAME
readonly REV
readonly KERNEL
readonly MACH
#readonly PACKAGER
else
OS=unknown
readonly OS
log "Unsupported OS:\"$OS\", sorry, exiting!"
exit 1
fi
}
function find_or_install()
{
_searching_for=$1
_pkg_mrg_cmd=''
_pkgr_cmd=''
retval=0
case $(lowercase $DISTRO_BASED_ON) in
"debian")
_pkg_mrg_cmd="$PKG_MGR -s $_searching_for"
_pkgr_cmd="$PACKAGER install $_searching_for --yes"
;;
*)
_pkg_mrg_cmd="$PKG_MGR -q $_searching_for"
_pkgr_cmd="$PACKAGER install $_searching_for -y"
;;
esac
$_pkg_mrg_cmd > /dev/null 2>&1
if [ $? -eq 0 ]; then
log "Package \"$_searching_for\" already installed"
retval=2
else
log "Installing \"$_searching_for\"..."
$_pkgr_cmd > /dev/null 2>&1
if [ $? -ne 0 ];then
log "...installation fails, exiting!"
retval=1
else
log "...success"
retval=0
fi
fi
return $retval
}
function is_py_package_installed()
{
retval=0
py_pkg=$1
found_pkg=$($PIPCMD freeze | grep -E "^$py_pkg")
if [ $? -ne 0 ]; then
retval=1
fi
echo $found_pkg
return $retval
}
function genpass()
{
echo $(date | md5sum |head -c${5:-13})
}
function shslash()
{
echo $1 | sed 's/\//\\\//g'
}
function split()
{
# Prefix local names with the function name to try to avoid conflicts
# local split_wordlist
split_wordlist="$1"
shift
read "$@" <<EOF-split-end-of-arguments
${split_wordlist}
EOF-split-end-of-arguments
}
# Returns true if v1 >= v2, false if v1 < v2
function version_ge()
{
# Prefix local names with the function name to try to avoid conflicts
# local version_ge_1 version_ge_2 version_ge_a version_ge_b
# local version_ge_save_ifs
version_ge_v1="$1"
version_ge_v2="$2"
version_ge_save_ifs="$IFS"
while test -n "${version_ge_v1}${version_ge_v2}"; do
IFS="."
split "$version_ge_v1" version_ge_a version_ge_v1
split "$version_ge_v2" version_ge_b version_ge_v2
IFS="$version_ge_save_ifs"
#echo " compare $version_ge_a $version_ge_b"
test "0$version_ge_a" -gt "0$version_ge_b" && return 0 # v1>v2: true
test "0$version_ge_a" -lt "0$version_ge_b" && return 1 # v1<v2:false
done
# version strings are both empty & no differences found - must be equal.
return 0 # v1==v2: true
}
function find_pip()
{
_pipargs=""
pip_min_ver="1.4"
for cmd in $PIPAPPS
do
_cmd=$(which $cmd 2>/dev/null)
if [ $? -eq 0 ];then
break
fi
done
if [ -z "$_cmd" ];then
echo "Can't find \"pip\" in system, please install it first, exiting!"
exit 1
else
_pip_ver=$($_cmd --version | grep -oE "[0-9]\.[0-9]" | head -n1)
if [ -n "$_pip_ver" ]; then
version_ge $_pip_ver $pip_min_ver
if [ $? -ne 0 ]; then
log "Upgrading pip ..."
$_cmd install --upgrade pip==$pip_min_ver
if [ $? -ne 0 ]; then
log "...pip upgrade fails, exiting!"
exit 1
else
log "...success"
sleep 2
for cmd in $PIPAPPS
do
_cmd=$(which $cmd 2>/dev/null)
if [ $? -eq 0 ];then
break
fi
done
fi
fi
_pip_ver=$($_cmd --version | grep -oE "[0-9]\.[0-9]" | head -n1)
version_ge $_pip_ver "1.5"
if [ $? -eq 0 ]; then
log "For future use, sorry, use pip v$pip_min_ver, exiting!"
exit 1
##_pipargs="--allow-unverified --allow-external"
#_pipargs="--allow-all-external"
#mk_dir "/root/.pip"
#_pipcfg="/root/.pip/pip.conf"
#if [ ! -f "$_pipcfg" ]; then
# touch $_pipcfg
#fi
#iniset 'install' 'allow-all-external' 'true' "$_pipcfg"
#iniset 'install' 'allow-all-unverified' 'true' "$_pipcfg"
#log "Setuptools upgrade required..."
#$cmd install setuptools --no-use-wheel --upgrade >> $LOGFILE 2>&1
#if [ $? -ne 0 ]; then
# log "...upgrade fails, exiting"
# exit 1
#else
# log "...success"
#fi
fi
log "Found pip version - $_pip_ver"
fi
PIPARGS=$_pipargs
PIPCMD=$_cmd
fi
}
function add_daemon_credentials()
{
retval=0
daemonuser=${1:-murano}
daemongroup=${2:-murano}
daemonhomedir=${3:-/home/$daemonuser}
getent group $daemongroup > /dev/null
if [ $? -ne 0 ]; then
log "Creating group \"$daemongroup\"..."
groupadd -r $daemongroup
if [ $? -eq 0 ]; then
log "...success"
else
log "Can't create \"$daemongroup\", exiting!"
retval=1
exit 1
fi
else
log "Group \"$daemongroup\" exists"
fi
getent passwd $daemonuser > /dev/null
if [ $? -ne 0 ]; then
log "Creating user \"$daemonuser\"..."
useradd -r -g $daemongroup -G $daemongroup -d $daemonhomedir -s $(which nologin) -c "Murano Daemons" $daemonuser
if [ $? -eq 0 ]; then
log "...success"
else
log "Can't create \"$daemonuser\", exiting!"
retval=1
exit 1
fi
else
log "User \"$daemonuser\" exists"
fi
return $retval
}
function remove_daemon_credentials()
{
retval=0
daemonuser=${1:-murano}
daemongroup=${2:-murano}
daemonhomedir=${3:-/home/$daemonuser}
getent passwd $daemonuser > /dev/null
if [ $? -eq 0 ]; then
log "Deleting user \"$daemonuser\"..."
userdel -f $daemonuser
if [ $? -eq 0 ]; then
if [ -d "$daemonhomedir" ]; then
rm -rf $daemonhomedir
fi
log "...success"
else
log "Can't delete \"$daemonuser\", exiting!"
retval=1
exit 1
fi
fi
getent group $daemongroup > /dev/null
if [ $? -eq 0 ]; then
log "Deleting group \"$daemongroup\"..."
groupdel $daemongroup
if [ $? -eq 0 ]; then
log "...success"
else
log "Can't delete \"$daemongroup\", exiting!"
retval=1
exit 1
fi
fi
return $retval
}
function iniset()
{
local section=$1
local option=$2
local value=$3
local file=$4
local line
if [ -z "$section" ] ; then
# No section name specified
sed -i -e "s/^\($option[ \t]*=[ \t]*\).*$/\1$value/" "$file"
else
# Check if section already exists
if ! grep -q "^\[$section\]" "$file" ; then
# Add section at the end
echo -e "\n[$section]" >>"$file"
fi
# Check if parameter in the section exists
line=$(sed -ne "/^\[$section\]/,/^\[.*\]/ { /^$option[ \t]*=/ p; }" "$file")
if [ -z "$line" ] ; then
# Add parameter if it is not exists
sed -i -e "/^\[$section\]/ a\\
$option = $value
" "$file"
else
# Replace existing parameter
sed -i -e "/^\[$section\]/,/^\[.*\]/ s|^\($option[ \t]*=[ \t]*\).*$|\1$value|" "$file"
fi
fi
}
function mk_dir()
{
retval=0
path_to_check=$1
if [ -d "$path_to_check" ]; then
log "Path \"$path_to_check\" already exists."
elif [ -f "$path_to_check" ]; then
log "Path \"path_to_check\" is an existing file, exiting!"
exit 1
else
mkdir -p "$path_to_check"
if [ $? -ne 0 ]; then
log "Can't create \"$path_to_check\", exiting!"
retval=1
exit 1
fi
fi
if [ $# -eq 3 ]; then
owner_user=$2
owner_group=$3
chown -R $owner_user:$owner_group $path_to_check
if [ $? -ne 0 ]; then
log "Can't set ownership to \"$owner_user:$owner_group\" for \"$path_to_check\", exiting!"
retval=1
exit 1
fi
fi
return $retval
}
function get_service_exec_path()
{
retval=0
if [ -z "$SERVICE_EXEC_PATH" ]; then
SERVICE_EXEC_PATH=$(which $DAEMON_NAME)
if [ $? -ne 0 ]; then
log "Can't find \"$DAEMON_NAME\", please install the \"$SERVICE_SRV_NAME\" by running \"$(basename "$0") install\" or set variable SERVICE_EXEC_PATH=/path/to/daemon before running setup script, exiting!"
retval=1
fi
else
if [ ! -x "$SERVICE_EXEC_PATH" ]; then
log "\"$SERVICE_EXEC_PATH\" in not executable, please install the \"$DAEMON_NAME\" or set variable SERVICE_EXEC_PATH=/path/to/daemon before running setup script, exiting!"
retval=1
fi
fi
return $retval
}

4
etc/init.d/README.rst Normal file
View File

@ -0,0 +1,4 @@
SysV init scripts
=====================
murano-conductor-redhat - for RedHat based Linux distibution
murano-conductor-debian - for Debian based Linux distibution

View File

@ -0,0 +1,104 @@
#!/bin/sh
# Copyright (c) 2014 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
# Author: Igor Yozhikov <iyozhikov@mirantis.com>
#
### BEGIN INIT INFO
# Provides: murano-conductor
# Required-Start: $network $local_fs $remote_fs $syslog
# Required-Stop: $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: OpenStack Murano Conductor Service
# Description: This startup script launches murano-conductor service daemon.
### END INIT INFO
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin
DESC="murano-conductor"
NAME=murano-conductor
DAEMON=$(which muranoconductor)
PIDFILE=/var/run/murano/$NAME.pid
SCRIPTNAME=/etc/init.d/openstack-$NAME
SYSTEM_USER=murano
CONFIG_FILE=/etc/murano/murano-conductor.conf
# Exit if the package is not installed
[ -x $DAEMON ] || exit 5
# source function library
. /lib/lsb/init-functions
do_start()
{
if [ ! -d "/var/run/murano" ]; then
mkdir -p /var/run/murano
chown -R $SYSTEM_USER /var/run/murano
fi
start-stop-daemon --start --background --quiet --chuid $SYSTEM_USER:$SYSTEM_USER --make-pidfile --pidfile $PIDFILE --startas $DAEMON --test -- --config-file=$CONFIG_FILE > /dev/null || return 1
start-stop-daemon --start --background --quiet --chuid $SYSTEM_USER:$SYSTEM_USER --make-pidfile --pidfile $PIDFILE --startas $DAEMON -- --config-file=$CONFIG_FILE || return 2
}
do_stop()
{
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE
RETVAL="$?"
rm -f $PIDFILE
return "$RETVAL"
}
case "$1" in
start)
log_daemon_msg "Starting $DESC" "$NAME"
do_start
case "$?" in
0|1) log_end_msg 0 ;;
2) log_end_msg 1 ;;
esac
;;
stop)
log_daemon_msg "Stopping $DESC" "$NAME"
do_stop
case "$?" in
0|1) log_end_msg 0 ;;
2) log_end_msg 1 ;;
esac
;;
status)
status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
;;
restart|force-reload)
log_daemon_msg "Restarting $DESC" "$NAME"
do_stop
case "$?" in
0|1)
do_start
case "$?" in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;; # Old process is still running
*) log_end_msg 1 ;; # Failed to start
esac
;;
*)
# Failed to stop
log_end_msg 1
;;
esac
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
exit 3
;;
esac

View File

@ -0,0 +1,102 @@
#!/bin/sh
# Copyright (c) 2014 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
# Author: Igor Yozhikov <iyozhikov@mirantis.com>
#
### BEGIN INIT INFO
# Provides: murano-conductor
# Required-Start: $network $local_fs $remote_fs $syslog
# Required-Stop: $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: OpenStack Murano Conductor Service
# Description: This startup script launches murano-conductor service daemon.
### END INIT INFO
# chkconfig: 3 90 10
# description: This startup script launches murano-conductor service daemon.
# config: /etc/murano/murano-conductor.conf, /etc/murano/murano-conductor-paste.ini
#
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin
DESC="murano-conductor"
NAME=murano-conductor
DAEMON=$(which muranoconductor)
PIDFILE=/var/run/murano/$NAME.pid
SCRIPTNAME=/etc/init.d/openstack-$NAME
SYSTEM_USER=murano
CONFIG_FILE=/etc/murano/murano-conductor.conf
LOCKFILE=/var/lock/subsys/$NAME
# Exit if the package is not installed
[ -x $DAEMON ] || exit 5
# source function library
. /etc/init.d/functions
RETVAL=0
start() {
if [ ! -d "/var/run/murano" ]; then
mkdir -p /var/run/murano
chown -R $SYSTEM_USER /var/run/murano
fi
echo -n "Starting $NAME: "
daemon --user $SYSTEM_USER "$DAEMON --config-file=$CONFIG_FILE &>/dev/null & echo \$! > $PIDFILE"
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && touch $LOCKFILE
return $RETVAL
}
stop() {
echo -n "Stopping $NAME: "
#killproc $DAEMON -TERM
killproc -p $PIDFILE $DAEMON
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && rm -f $LOCKFILE
return $RETVAL
}
restart() {
stop
start
}
rh_status() {
# run checks to determine if the service is running or use generic status
status $DAEMON
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
status)
rh_status
;;
*)
echo $"Usage: $0 {start|stop|status|restart}"
exit 2
esac
exit $?

View File

@ -1,96 +1,98 @@
[DEFAULT]
# Path where log will be written
log_file = /tmp/conductor.log
# Log verbosity
debug=True
verbose=True
# Provide directory with initialization scripts
init_scripts_dir = etc/init-scripts
# Provide directory with agent configs
agent_config_dir = etc/agent-config
# Directory for data cache, OS temp directory is used by default
#data_dir = /tmp/muranoconductor-cache
# Provide url to Murano Metadata repository
# Comment this line if you registered murano-metadata in keystone catalog
murano_metadata_url = http://localhost:8084/v1
# Maximum number of environments that can be processed simultaneously
max_environments = 20
# Maximum number of VMs per environment
max_hosts = 250
# Template IP address for generating environment subnet cidrs
env_ip_template = 10.0.0.0
# Enforces default network topology.
# Allowed values: nova, flat, routed
# default is routed
network_topology = routed
[keystone]
# URL of OpenStack KeyStone service REST API.
# Typically only hostname (or IP) needs to be changed
auth_url = http://localhost:5000/v2.0
# Keystone SSL parameters
# Optional CA cert file to use in SSL connections
#ca_file =
# Optional PEM-formatted certificate chain file
#cert_file =
# Optional PEM-formatted file that contains the private key
#key_file =
# If set then the server's certificate will not be verified
insecure = False
[heat]
# Heat SSL parameters
# Optional CA cert file to use in SSL connections
#ca_file =
# Optional PEM-formatted certificate chain file
#cert_file =
# Optional PEM-formatted file that contains the private key
#key_file =
# If set then the server's certificate will not be verified
insecure = False
# Valid endpoint types: publicURL (default), internalURL, adminURL
endpoint_type = publicURL
[neutron]
# Optional CA cert file to use in SSL connections
#ca_cert =
# Allow self signed server certificate
insecure = False
# Valid endpoint types: publicURL (default), internalURL, adminURL
endpoint_type = publicURL
[rabbitmq]
# Connection parameters to RabbitMQ service
# Hostname or IP address where RabbitMQ is located.
# !!! Change localhost to your real IP or hostname as this address must be reachable from VMs !!!
host = localhost
# RabbitMQ port (5672 is a default)
port = 5672
# Use SSL for RabbitMQ connections (True or False)
ssl = False
# Path to SSL CA certificate or empty to allow self signed server certificate
#ca_certs =
# RabbitMQ credentials. Fresh RabbitMQ installation has "guest" account with "guest" password.
# It is recommended to create dedicated user account for Murano using RabbitMQ web console or command line utility
login = guest
password = guest
# RabbitMQ virtual host (vhost). Fresh RabbitMQ installation has "/" vhost preconfigured.
# It is recommended to create dedicated vhost for Murano using RabbitMQ web console or command line utility
virtual_host = /
[DEFAULT]
# Set up logging. To use syslog just set use_syslog parameter value to 'True'
log_file = /tmp/murano-conductor.log
use_syslog = False
syslog_log_facility = LOG_LOCAL0
# Log verbosity
debug = True
verbose = True
# Provide directory with initialization scripts
init_scripts_dir = etc/murano/init-scripts
# Provide directory with agent configs
agent_config_dir = etc/murano/agent-config
# Directory for data cache, OS temp directory is used by default
data_dir = /tmp/muranoconductor-cache
# Provide url to Murano Metadata repository
# Comment this line if you registered murano-metadata in keystone catalog
murano_metadata_url = http://localhost:8084/v1
# Maximum number of environments that can be processed simultaneously
max_environments = 20
# Maximum number of VMs per environment
max_hosts = 250
# Template IP address for generating environment subnet cidrs
env_ip_template = 10.0.0.0
# Enforces default network topology.
# Allowed values: nova, flat, routed
# default is routed
network_topology = routed
[keystone]
# URL of OpenStack KeyStone service REST API.
# Typically only hostname (or IP) needs to be changed
auth_url = http://localhost:5000/v2.0
# Keystone SSL parameters
# Optional CA cert file to use in SSL connections
#ca_file =
# Optional PEM-formatted certificate chain file
#cert_file =
# Optional PEM-formatted file that contains the private key
#key_file =
# If set then the server's certificate will not be verified
insecure = False
[heat]
# Heat SSL parameters
# Optional CA cert file to use in SSL connections
#ca_file =
# Optional PEM-formatted certificate chain file
#cert_file =
# Optional PEM-formatted file that contains the private key
#key_file =
# If set then the server's certificate will not be verified
insecure = False
# Valid endpoint types: publicURL (default), internalURL, adminURL
endpoint_type = publicURL
[neutron]
# Optional CA cert file to use in SSL connections
#ca_cert =
# Allow self signed server certificate
insecure = False
# Valid endpoint types: publicURL (default), internalURL, adminURL
endpoint_type = publicURL
[rabbitmq]
# Connection parameters to RabbitMQ service
# Hostname or IP address where RabbitMQ is located.
# !!! Change localhost to your real IP or hostname as this address must be reachable from VMs !!!
host = localhost
# RabbitMQ port (5672 is a default)
port = 5672
# Use SSL for RabbitMQ connections (True or False)
ssl = False
# Path to SSL CA certificate or empty to allow self signed server certificate
#ca_certs =
# RabbitMQ credentials. Fresh RabbitMQ installation has "guest" account with "guest" password.
# It is recommended to create dedicated user account for Murano using RabbitMQ web console or command line utility
login = guest
password = guest
# RabbitMQ virtual host (vhost). Fresh RabbitMQ installation has "/" vhost preconfigured.
# It is recommended to create dedicated vhost for Murano using RabbitMQ web console or command line utility
virtual_host = /

View File

@ -107,17 +107,21 @@ class NeutronExecutor(CommandBase):
routers = self.neutron.list_routers(tenant_id=self.tenant_id). \
get("routers")
if not len(routers):
routerId = "NOT_FOUND"
routerId = externalNetId = "NOT_FOUND"
else:
routerId = routers[0]["id"]
externalNetId = routers[0]['external_gateway_info']['network_id']
if len(routers) > 1:
for router in routers:
if "murano" in router["name"].lower():
routerId = router["id"]
externalNetId = \
router['external_gateway_info']['network_id']
break
for callback in self.router_requests:
callback(routerId)
callback(routerId, externalNetId)
self.router_requests = []
return True

View File

@ -62,13 +62,49 @@ class VmAgentExecutor(CommandBase):
else:
return self._build_v2_execution_plan(template, path)
def _split_path(self, _path, parts=None):
if parts is None:
parts = []
head, tail = os.path.split(_path)
if tail:
parts.append(tail)
elif os.path.isabs(head): # head is '/' and tail is '' - stop
parts.append(head)
head = None
if head:
return self._split_path(head, parts)
else:
parts.reverse()
return parts
@staticmethod
def _join(*args):
return os.path.join(*args) if args else ''
def _split_agent_path(self, path, agent_root_dir_depth=3):
agent_subdir = os.path.dirname(os.path.normpath(path))
dir_parts = self._split_path(agent_subdir)
return (self._join(*dir_parts[:agent_root_dir_depth]),
self._join(*dir_parts[agent_root_dir_depth:]))
def _ensure_relpath(self, path):
parts = self._split_path(os.path.normpath(path))
if parts and os.path.isabs(parts[0]):
return self._join(*parts[1:]), True
else:
return path, False
def _build_v1_execution_plan(self, template, path):
scripts_folder = os.path.join(
os.path.dirname(path), 'scripts')
agent_dir_root, rest_dirs = self._split_agent_path(path)
scripts_folder = os.path.join(agent_dir_root, 'scripts')
script_files = template.get('Scripts', [])
scripts = []
for script in script_files:
script_path = os.path.join(scripts_folder, script)
script, was_abspath = self._ensure_relpath(script)
if was_abspath:
script_path = os.path.join(scripts_folder, script)
else:
script_path = os.path.join(scripts_folder, rest_dirs, script)
log.debug('Loading script "{0}"'.format(script_path))
with open(script_path) as script_file:
script_data = script_file.read()

View File

@ -0,0 +1,249 @@
# Translations template for murano-conductor.
# Copyright (C) 2014 ORGANIZATION
# This file is distributed under the same license as the murano-conductor
# project.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: murano-conductor 0.4\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2014-01-20 14:55+0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 1.3\n"
#: muranoconductor/config.py:151
msgid "Invalid syslog facility"
msgstr ""
#: muranoconductor/config.py:225
#, python-format
msgid "Loading %(app_name)s from %(conf_file)s"
msgstr ""
#: muranoconductor/config.py:236
#, python-format
msgid ""
"Unable to load %(app_name)s from configuration file %(conf_file)s.\n"
"Got: %(e)r"
msgstr ""
#: muranoconductor/openstack/common/eventlet_backdoor.py:141
#, python-format
msgid "Eventlet backdoor listening on %(port)s for process %(pid)d"
msgstr ""
#: muranoconductor/openstack/common/exception.py:103
msgid "Uncaught exception"
msgstr ""
#: muranoconductor/openstack/common/excutils.py:62
#, python-format
msgid "Original exception being dropped: %s"
msgstr ""
#: muranoconductor/openstack/common/excutils.py:90
#, python-format
msgid "Unexpected exception occurred %d time(s)... retrying."
msgstr ""
#: muranoconductor/openstack/common/fileutils.py:64
#, python-format
msgid "Reloading cached file %s"
msgstr ""
#: muranoconductor/openstack/common/lockutils.py:100
#, python-format
msgid "Could not release the acquired lock `%s`"
msgstr ""
#: muranoconductor/openstack/common/lockutils.py:166
#, python-format
msgid "Got semaphore \"%(lock)s\""
msgstr ""
#: muranoconductor/openstack/common/lockutils.py:175
#, python-format
msgid "Attempting to grab file lock \"%(lock)s\""
msgstr ""
#: muranoconductor/openstack/common/lockutils.py:185
#, python-format
msgid "Created lock path: %s"
msgstr ""
#: muranoconductor/openstack/common/lockutils.py:203
#, python-format
msgid "Got file lock \"%(lock)s\" at %(path)s"
msgstr ""
#: muranoconductor/openstack/common/lockutils.py:207
#, python-format
msgid "Released file lock \"%(lock)s\" at %(path)s"
msgstr ""
#: muranoconductor/openstack/common/lockutils.py:244
#, python-format
msgid "Got semaphore / lock \"%(function)s\""
msgstr ""
#: muranoconductor/openstack/common/lockutils.py:248
#, python-format
msgid "Semaphore / lock released \"%(function)s\""
msgstr ""
#: muranoconductor/openstack/common/log.py:244
#, python-format
msgid "Deprecated: %s"
msgstr ""
#: muranoconductor/openstack/common/log.py:336
#, python-format
msgid "Error loading logging config %(log_config)s: %(err_msg)s"
msgstr ""
#: muranoconductor/openstack/common/log.py:386
#, python-format
msgid "syslog facility must be one of: %s"
msgstr ""
#: muranoconductor/openstack/common/log.py:556
#, python-format
msgid "Fatal call to deprecated config: %(msg)s"
msgstr ""
#: muranoconductor/openstack/common/loopingcall.py:84
#, python-format
msgid "task run outlasted interval by %s sec"
msgstr ""
#: muranoconductor/openstack/common/loopingcall.py:91
msgid "in fixed duration looping call"
msgstr ""
#: muranoconductor/openstack/common/loopingcall.py:131
#, python-format
msgid "Dynamic looping call sleeping for %.02f seconds"
msgstr ""
#: muranoconductor/openstack/common/loopingcall.py:138
msgid "in dynamic looping call"
msgstr ""
#: muranoconductor/openstack/common/service.py:103
#: muranoconductor/openstack/common/service.py:271
msgid "Full set of CONF:"
msgstr ""
#: muranoconductor/openstack/common/service.py:112
#: muranoconductor/openstack/common/service.py:214
#, python-format
msgid "Caught %s, exiting"
msgstr ""
#: muranoconductor/openstack/common/service.py:123
msgid "Exception during rpc cleanup."
msgstr ""
#: muranoconductor/openstack/common/service.py:159
msgid "Parent process has died unexpectedly, exiting"
msgstr ""
#: muranoconductor/openstack/common/service.py:196
msgid "Forking too fast, sleeping"
msgstr ""
#: muranoconductor/openstack/common/service.py:219
msgid "Unhandled exception"
msgstr ""
#: muranoconductor/openstack/common/service.py:226
#, python-format
msgid "Started child %d"
msgstr ""
#: muranoconductor/openstack/common/service.py:236
#, python-format
msgid "Starting %d workers"
msgstr ""
#: muranoconductor/openstack/common/service.py:253
#, python-format
msgid "Child %(pid)d killed by signal %(sig)d"
msgstr ""
#: muranoconductor/openstack/common/service.py:257
#, python-format
msgid "Child %(pid)s exited with status %(code)d"
msgstr ""
#: muranoconductor/openstack/common/service.py:261
#, python-format
msgid "pid %d not in child list"
msgstr ""
#: muranoconductor/openstack/common/service.py:289
#, python-format
msgid "Caught %s, stopping children"
msgstr ""
#: muranoconductor/openstack/common/service.py:300
#, python-format
msgid "Waiting on %d children to exit"
msgstr ""
#: muranoconductor/openstack/common/sslutils.py:52
#, python-format
msgid "Unable to find cert_file : %s"
msgstr ""
#: muranoconductor/openstack/common/sslutils.py:55
#, python-format
msgid "Unable to find ca_file : %s"
msgstr ""
#: muranoconductor/openstack/common/sslutils.py:58
#, python-format
msgid "Unable to find key_file : %s"
msgstr ""
#: muranoconductor/openstack/common/sslutils.py:61
msgid ""
"When running server in SSL mode, you must specify both a cert_file and "
"key_file option value in your configuration file"
msgstr ""
#: muranoconductor/openstack/common/sslutils.py:100
#, python-format
msgid "Invalid SSL version : %s"
msgstr ""
#: muranoconductor/openstack/common/notifier/api.py:129
#, python-format
msgid "%s not in valid priorities"
msgstr ""
#: muranoconductor/openstack/common/notifier/api.py:145
#, python-format
msgid ""
"Problem '%(e)s' attempting to send to notification system. "
"Payload=%(payload)s"
msgstr ""
#: muranoconductor/openstack/common/notifier/api.py:164
#, python-format
msgid "Failed to load notifier %s. These notifications will not be sent."
msgstr ""
#: muranoconductor/openstack/common/notifier/rpc_notifier.py:45
#: muranoconductor/openstack/common/notifier/rpc_notifier2.py:51
#, python-format
msgid "Could not send notification to %(topic)s. Payload=%(message)s"
msgstr ""

View File

@ -135,14 +135,27 @@ def release(folder):
def prepare(data_dir):
if not os.path.exists(data_dir):
os.makedirs(data_dir)
log.info("Creating directory '{0}' to store "
"conductor data".format(data_dir))
init_scripts_dst = os.path.join(data_dir,
os.path.basename(CONF.init_scripts_dir))
if not os.path.exists(init_scripts_dst):
shutil.copytree(CONF.init_scripts_dir, init_scripts_dst)
if os.path.exists(init_scripts_dst):
log.info("Found existing init scripts directory at"
" '{0}'. Deleting it.'".format(init_scripts_dst))
shutil.rmtree(init_scripts_dst)
log.info("Copying init scripts directory from '{0}' "
"to '{1}'".format(CONF.init_scripts_dir, init_scripts_dst))
shutil.copytree(CONF.init_scripts_dir, init_scripts_dst)
agent_config_dst = os.path.join(data_dir,
os.path.basename(CONF.agent_config_dir))
if not os.path.exists(agent_config_dst):
shutil.copytree(CONF.agent_config_dir, agent_config_dst)
if os.path.exists(agent_config_dst):
log.info("Found existing agent config directory at"
" '{0}'. Deleting it.'".format(agent_config_dst))
shutil.rmtree(agent_config_dst)
log.info("Copying agent config directory from '{0}' "
"to '{1}'".format(CONF.agent_config_dir, agent_config_dst))
shutil.copytree(CONF.agent_config_dir, agent_config_dst)
os.chdir(data_dir)

View File

@ -48,9 +48,10 @@ def get_subnet(engine, context, body, routerId=None, existingNetwork=None,
def get_default_router(engine, context, body, result=None):
command_dispatcher = context['/commandDispatcher']
def callback(result_value):
def callback(routerId, externalNetId):
if result is not None:
context[result] = {"routerId": result_value}
context[result] = {"routerId": routerId,
"floatingId": externalNetId}
success_handler = body.find('success')
if success_handler is not None:

View File

@ -11,8 +11,7 @@ netaddr>=0.7.6
oslo.config>=1.2.0
deep
# Please, revert to murano-common>=x.x.x before release
http://tarballs.openstack.org/murano-common/murano-common-master.tar.gz#egg=muranocommon-0.4
murano-common==0.4.1
PyYAML>=3.1.0
http://tarballs.openstack.org/murano-metadataclient/murano-metadataclient-master.tar.gz#egg=metadataclient-0.4
python-neutronclient>=2.3.1
murano-metadataclient==0.4.1
python-neutronclient>=2.3.0,<3

View File

@ -1,280 +0,0 @@
#!/bin/sh
# Copyright (c) 2013 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
# CentOS script
LOGLVL=1
SERVICE_CONTENT_DIRECTORY=`cd $(dirname "$0") && pwd`
PREREQ_PKGS="upstart wget git make python-pip python-devel mysql-connector-python libffi-devel"
PIPAPPS="pip python-pip pip-python"
PIPCMD=""
SERVICE_SRV_NAME="murano-conductor"
GIT_CLONE_DIR=`echo $SERVICE_CONTENT_DIRECTORY | sed -e "s/$SERVICE_SRV_NAME//"`
#ETC_CFG_DIR="/etc/$SERVICE_SRV_NAME"
ETC_CFG_DIR="/etc/murano"
LOG_DIR="/var/log/murano/"
SERVICE_CONFIG_FILE_PATH="$ETC_CFG_DIR/conductor.conf"
# Functions
# Loger function
log()
{
MSG=$1
if [ $LOGLVL -gt 0 ]; then
echo "LOG:> $MSG"
fi
}
# Check or install package
in_sys_pkg()
{
PKG=$1
rpm -q $PKG > /dev/null 2>&1
if [ $? -eq 0 ]; then
log "Package \"$PKG\" already installed"
else
log "Installing \"$PKG\"..."
yum install $PKG --assumeyes > /dev/null 2>&1
if [ $? -ne 0 ];then
log "installation fails, exiting!!!"
exit
fi
fi
}
# find pip
find_pip()
{
for cmd in $PIPAPPS
do
_cmd=$(which $cmd 2>/dev/null)
if [ $? -eq 0 ];then
break
fi
done
if [ -z $_cmd ];then
echo "Can't find \"pip\" in system, please install it first, exiting!"
exit 1
else
PIPCMD=$_cmd
fi
}
# git clone
gitclone()
{
FROM=$1
CLONEROOT=$2
log "Cloning from \"$FROM\" repo to \"$CLONEROOT\""
cd $CLONEROOT && git clone $FROM > /dev/null 2>&1
if [ $? -ne 0 ];then
log "cloning from \"$FROM\" fails, exiting!!!"
exit
fi
}
# install
inst()
{
CLONE_FROM_GIT=$1
# Checking packages
for PKG in $PREREQ_PKGS
do
in_sys_pkg $PKG
done
# Find python pip
find_pip
# If clone from git set
if [ ! -z $CLONE_FROM_GIT ]; then
# Preparing clone root directory
if [ ! -d $GIT_CLONE_DIR ];then
log "Creating $GIT_CLONE_DIR direcory..."
mkdir -p $GIT_CLONE_DIR
if [ $? -ne 0 ];then
log "Can't create $GIT_CLONE_DIR, exiting!!!"
exit
fi
fi
# Cloning from GIT
GIT_WEBPATH_PRFX="https://github.com/stackforge/"
gitclone "$GIT_WEBPATH_PRFX$SERVICE_SRV_NAME.git" $GIT_CLONE_DIR
# End clone from git section
fi
# Setupping...
log "Running setup.py"
MRN_CND_SPY=$GIT_CLONE_DIR/$SERVICE_SRV_NAME/setup.py
if [ -e $MRN_CND_SPY ];then
chmod +x $MRN_CND_SPY
log "$MRN_CND_SPY output:_____________________________________________________________"
## Setup through pip
# Creating tarball
rm -rf $SERVICE_CONTENT_DIRECTORY/*.egg-info
cd $SERVICE_CONTENT_DIRECTORY && python $MRN_CND_SPY egg_info
if [ $? -ne 0 ];then
log "\"$MRN_CND_SPY\" egg info creation FAILS, exiting!!!"
exit 1
fi
rm -rf $SERVICE_CONTENT_DIRECTORY/dist/*
cd $SERVICE_CONTENT_DIRECTORY && $MRN_CND_SPY sdist
if [ $? -ne 0 ];then
log "\"$MRN_CND_SPY\" tarball creation FAILS, exiting!!!"
exit 1
fi
# Running tarball install
TRBL_FILE=$(basename `ls $SERVICE_CONTENT_DIRECTORY/dist/*.tar.gz`)
$PIPCMD install $SERVICE_CONTENT_DIRECTORY/dist/$TRBL_FILE
if [ $? -ne 0 ];then
log "$PIPCMD install \"$TRBL_FILE\" FAILS, exiting!!!"
exit 1
fi
else
log "$MRN_CND_SPY not found!"
fi
# Creating etc directory for config files
if [ ! -d $ETC_CFG_DIR ];then
log "Creating $ETC_CFG_DIR direcory..."
mkdir -p $ETC_CFG_DIR
if [ $? -ne 0 ];then
log "Can't create $ETC_CFG_DIR, exiting!!!"
exit
fi
fi
# Creating log directory for the murano
if [ ! -d $LOG_DIR ];then
log "Creating $LOG_DIR direcory..."
mkdir -p $LOG_DIR
if [ $? -ne 0 ];then
log "Can't create $LOG_DIR, exiting!!!"
exit 1
fi
chmod -R a+rw $LOG_DIR
fi
# making sample configs
log "Making sample configuration files at \"$ETC_CFG_DIR\""
for file in $(ls $SERVICE_CONTENT_DIRECTORY/etc)
do
if [ -d "$SERVICE_CONTENT_DIRECTORY/etc/$file" ];then
cp -f -R "$SERVICE_CONTENT_DIRECTORY/etc/$file" "$ETC_CFG_DIR/"
else
cp -f "$SERVICE_CONTENT_DIRECTORY/etc/$file" "$ETC_CFG_DIR/$file.sample"
fi
done
# making templates data
#log "Making templates directory"
#cp -f -R "$SERVICE_CONTENT_DIRECTORY/data" "$ETC_CFG_DIR/"
}
# searching for service executable in path
get_service_exec_path()
{
if [ -z "$SERVICE_EXEC_PATH" ]; then
SERVICE_EXEC_PATH=$(which muranoconductor)
if [ $? -ne 0 ]; then
log "Can't find \"conductor ($SERVICE_SRV_NAME)\", please install the \"$SERVICE_SRV_NAME\" by running \"$(basename "$0") install\" or set variable SERVICE_EXEC_PATH=/path/to/daemon before running setup script, exiting!"
exit 1
fi
else
if [ ! -x "$SERVICE_EXEC_PATH" ]; then
log "\"$SERVICE_EXEC_PATH\" in not executable, please install the \"conductor ($SERVICE_SRV_NAME)\" or set variable SERVICE_EXEC_PATH=/path/to/daemon before running setup script, exiting!"
exit 1
fi
fi
}
# inject init
injectinit()
{
echo "description \"$SERVICE_SRV_NAME service\"
author \"Igor Yozhikov <iyozhikov@mirantis.com>\"
start on runlevel [2345]
stop on runlevel [!2345]
respawn
exec $SERVICE_EXEC_PATH --config-file=$SERVICE_CONFIG_FILE_PATH" > "/etc/init/$SERVICE_SRV_NAME.conf"
log "Reloading initctl"
initctl reload-configuration
}
# purge init
purgeinit()
{
rm -f /etc/init/$SERVICE_SRV_NAME.conf
log "Reloading initctl"
initctl reload-configuration
}
# uninstall
uninst()
{
# Uninstall trough pip
find_pip
# looking up for python package installed
PYPKG=$SERVICE_SRV_NAME
_pkg=$($PIPCMD freeze | grep $PYPKG)
if [ $? -eq 0 ]; then
log "Removing package \"$PYPKG\" with pip"
$PIPCMD uninstall $_pkg --yes
else
log "Python package \"$PYPKG\" not found"
fi
}
# postinstall
postinst()
{
log "Please, make proper configuration,located at \"$ETC_CFG_DIR\", before starting the \"$SERVICE_SRV_NAME\" daemon!"
}
# Command line args'
COMMAND="$1"
case $COMMAND in
inject-init )
get_service_exec_path
log "Injecting \"$SERVICE_SRV_NAME\" to init..."
injectinit
postinst
;;
install )
inst
get_service_exec_path
injectinit
postinst
;;
installfromgit )
inst "yes"
get_service_exec_path
injectinit
postinst
;;
purge-init )
log "Purging \"$SERVICE_SRV_NAME\" from init..."
stop $SERVICE_SRV_NAME
purgeinit
;;
uninstall )
log "Uninstalling \"$SERVICE_SRV_NAME\" from system..."
stop $SERVICE_SRV_NAME
purgeinit
uninst
;;
* )
echo -e "Usage: $(basename "$0") command \nCommands:\n\tinstall - Install $SERVICE_SRV_NAME software\n\tuninstall - Uninstall $SERVICE_SRV_NAME software\n\tinject-init - Add $SERVICE_SRV_NAME to the system start-up\n\tpurge-init - Remove $SERVICE_SRV_NAME from the system start-up"
exit 1
;;
esac

View File

@ -1,13 +1,13 @@
[metadata]
name = murano-conductor
summary = The Conductor is orchestration engine server
version = 0.3
version = 0.4.1
description-file =
README.rst
license = Apache License, Version 2.0
author = Mirantis, Inc.
author-email = murano-all@lists.openstack.org
home-page = htts://launchpad.net/murano
home-page = https://launchpad.net/murano
classifier =
Development Status :: 5 - Production/Stable
Environment :: OpenStack

470
setup.sh Normal file → Executable file
View File

@ -1,5 +1,5 @@
#!/bin/sh
# Copyright (c) 2013 Mirantis, Inc.
#!/bin/bash
# Copyright (c) 2014 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
@ -13,252 +13,250 @@
# License for the specific language governing permissions and limitations
# under the License.
#
# Ubuntu script.
LOGLVL=1
SERVICE_CONTENT_DIRECTORY=`cd $(dirname "$0") && pwd`
PREREQ_PKGS="upstart wget git make python-pip python-dev python-mysqldb libxml2-dev libxslt-dev libffi-dev"
SERVICE_SRV_NAME="murano-conductor"
GIT_CLONE_DIR=`echo $SERVICE_CONTENT_DIRECTORY | sed -e "s/$SERVICE_SRV_NAME//"`
#ETC_CFG_DIR="/etc/$SERVICE_SRV_NAME"
ETC_CFG_DIR="/etc/murano"
LOG_DIR="/var/log/murano/"
SERVICE_CONFIG_FILE_PATH="$ETC_CFG_DIR/conductor.conf"
# Functions
# Loger function
log()
{
MSG=$1
if [ $LOGLVL -gt 0 ]; then
echo "LOG:> $MSG"
fi
}
# Check or install package
in_sys_pkg()
{
PKG=$1
dpkg -s $PKG > /dev/null 2>&1
if [ $? -eq 0 ]; then
log "Package \"$PKG\" already installed"
else
log "Installing \"$PKG\"..."
apt-get install $PKG --yes > /dev/null 2>&1
if [ $? -ne 0 ];then
log "installation fails, exiting!!!"
exit
fi
fi
}
# git clone
gitclone()
{
FROM=$1
CLONEROOT=$2
log "Cloning from \"$FROM\" repo to \"$CLONEROOT\""
cd $CLONEROOT && git clone $FROM > /dev/null 2>&1
if [ $? -ne 0 ];then
log "cloning from \"$FROM\" fails, exiting!!!"
exit
fi
}
# install
inst()
{
CLONE_FROM_GIT=$1
# Checking packages
for PKG in $PREREQ_PKGS
do
in_sys_pkg $PKG
done
# If clone from git set
if [ ! -z $CLONE_FROM_GIT ]; then
# Preparing clone root directory
if [ ! -d $GIT_CLONE_DIR ];then
log "Creating $GIT_CLONE_DIR direcory..."
mkdir -p $GIT_CLONE_DIR
if [ $? -ne 0 ];then
log "Can't create $GIT_CLONE_DIR, exiting!!!"
exit
fi
fi
# Cloning from GIT
GIT_WEBPATH_PRFX="https://github.com/stackforge/"
gitclone "$GIT_WEBPATH_PRFX$SERVICE_SRV_NAME.git" $GIT_CLONE_DIR
# End clone from git section
fi
# Setupping...
log "Running setup.py"
MRN_CND_SPY=$SERVICE_CONTENT_DIRECTORY/setup.py
if [ -e $MRN_CND_SPY ];then
chmod +x $MRN_CND_SPY
log "$MRN_CND_SPY output:_____________________________________________________________"
## Setup through pip
# Creating tarball
rm -rf $SERVICE_CONTENT_DIRECTORY/*.egg-info
cd $SERVICE_CONTENT_DIRECTORY && python $MRN_CND_SPY egg_info
if [ $? -ne 0 ];then
log "\"$MRN_CND_SPY\" egg info creation FAILS, exiting!!!"
exit 1
fi
rm -rf $SERVICE_CONTENT_DIRECTORY/dist/*
cd $SERVICE_CONTENT_DIRECTORY && $MRN_CND_SPY sdist
if [ $? -ne 0 ];then
log "\"$MRN_CND_SPY\" tarball creation FAILS, exiting!!!"
exit 1
fi
# Running tarball install
TRBL_FILE=$(basename `ls $SERVICE_CONTENT_DIRECTORY/dist/*.tar.gz`)
pip install $SERVICE_CONTENT_DIRECTORY/dist/$TRBL_FILE
if [ $? -ne 0 ];then
log "pip install \"$TRBL_FILE\" FAILS, exiting!!!"
exit 1
fi
else
log "$MRN_CND_SPY not found!"
fi
# Creating etc directory for config files
if [ ! -d $ETC_CFG_DIR ];then
log "Creating $ETC_CFG_DIR direcory..."
mkdir -p $ETC_CFG_DIR
if [ $? -ne 0 ];then
log "Can't create $ETC_CFG_DIR, exiting!!!"
exit 1
fi
fi
# Creating log directory for the murano
if [ ! -d $LOG_DIR ];then
log "Creating $LOG_DIR direcory..."
mkdir -p $LOG_DIR
if [ $? -ne 0 ];then
log "Can't create $LOG_DIR, exiting!!!"
exit 1
fi
chmod -R a+rw $LOG_DIR
fi
# making sample configs
log "Making sample configuration files at \"$ETC_CFG_DIR\""
for file in $(ls $SERVICE_CONTENT_DIRECTORY/etc)
do
if [ -d "$SERVICE_CONTENT_DIRECTORY/etc/$file" ];then
cp -f -R "$SERVICE_CONTENT_DIRECTORY/etc/$file" "$ETC_CFG_DIR/"
else
cp -f "$SERVICE_CONTENT_DIRECTORY/etc/$file" "$ETC_CFG_DIR/$file.sample"
fi
done
# making templates data
#log "Making templates directory"
#cp -f -R "$SERVICE_CONTENT_DIRECTORY/data" "$ETC_CFG_DIR/"
}
# searching for service executable in path
get_service_exec_path()
{
if [ -z "$SERVICE_EXEC_PATH" ]; then
SERVICE_EXEC_PATH=$(which muranoconductor)
if [ $? -ne 0 ]; then
log "Can't find \"conductor ($SERVICE_SRV_NAME)\", please install the \"$SERVICE_SRV_NAME\" by running \"$(basename "$0") install\" or set variable SERVICE_EXEC_PATH=/path/to/daemon before running setup script, exiting!"
exit 1
fi
else
if [ ! -x "$SERVICE_EXEC_PATH" ]; then
log "\"$SERVICE_EXEC_PATH\" in not executable, please install the \"conductor ($SERVICE_SRV_NAME)\" or set variable SERVICE_EXEC_PATH=/path/to/daemon before running setup script, exiting!"
exit 1
fi
fi
}
# inject init
injectinit()
{
ln -s /lib/init/upstart-job /etc/init.d/$SERVICE_SRV_NAME
if [ $? -ne 0 ]; then
log "Can't create symlink, please run \"$(basename "$0") purge-init\" before \"$(basename "$0") inject-init\", exiting"
exit 1
RUN_DIR=$(cd $(dirname "$0") && pwd)
INC_FILE="$RUN_DIR/common.inc"
if [ -f "$INC_FILE" ]; then
source "$INC_FILE"
else
echo "Can't load \"$INC_FILE\" or file not found, exiting!"
exit 1
fi
echo "description \"$SERVICE_SRV_NAME service\"
author \"Igor Yozhikov <iyozhikov@mirantis.com>\"
start on runlevel [2345]
stop on runlevel [!2345]
respawn
exec start-stop-daemon --start --chuid root --user root --name $SERVICE_SRV_NAME --exec $SERVICE_EXEC_PATH -- --config-file=$SERVICE_CONFIG_FILE_PATH" > "/etc/init/$SERVICE_SRV_NAME.conf"
log "Reloading initctl"
initctl reload-configuration
#
DAEMON_NAME="murano-conductor"
DAEMON_USER="murano"
DAEMON_GROUP="murano"
DAEMON_CFG_DIR="/etc/murano"
DAEMON_CACHE_DIR="/var/cache/murano"
DAEMON_LOG_DIR="/var/log/murano"
LOGFILE="/tmp/${DAEMON_NAME}_install.log"
DAEMON_DB_CONSTR="sqlite:///$DAEMON_CFG_DIR/$DAEMON_NAME.sqlite"
common_pkgs="wget git make gcc python-pip python-setuptools dos2unix"
# Distro-specific package namings
debian_pkgs="python-dev python-mysqldb libxml2-dev libxslt1-dev libffi-dev libssl-dev"
redhat_pkgs="python-devel MySQL-python libxml2-devel libxslt-devel libffi-devel openssl-devel"
#
get_os
eval req_pkgs="\$$(lowercase $DISTRO_BASED_ON)_pkgs"
REQ_PKGS="$common_pkgs $req_pkgs"
function install_prerequisites()
{
retval=0
_dist=$(lowercase $DISTRO_BASED_ON)
if [ $_dist = "redhat" ]; then
yum repolist | grep -qoE "epel"
if [ $? -ne 0 ]; then
log "Enabling EPEL6..."
rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm >> $LOGFILE 2>&1
if [ $? -ne 0 ]; then
log "... can't enable EPEL6, exiting!"
retval=1
return $retval
fi
fi
yum --quiet makecache
fi
for pack in $REQ_PKGS
do
find_or_install "$pack"
if [ $? -eq 1 ]; then
retval=1
break
else
retval=0
fi
done
return $retval
}
function make_tarball()
{
retval=0
log "Preparing tarball package..."
setuppy="$RUN_DIR/setup.py"
if [ -e "$setuppy" ]; then
chmod +x $setuppy
rm -rf $RUN_DIR/*.egg-info
cd $RUN_DIR && python $setuppy egg_info > /dev/null 2>&1
if [ $? -ne 0 ];then
log "...\"$setuppy\" egg info creation fails, exiting!!!"
retval=1
exit 1
fi
rm -rf $RUN_DIR/dist/*
log "...\"setup.py sdist\" output will be recorded in \"$LOGFILE\""
cd $RUN_DIR && $setuppy sdist >> $LOGFILE 2>&1
if [ $? -ne 0 ];then
log "...\"$setuppy\" tarball creation fails, exiting!!!"
retval=1
exit 1
fi
#TRBL_FILE=$(basename $(ls $RUN_DIR/dist/*.tar.gz | head -n 1))
TRBL_FILE=$(ls $RUN_DIR/dist/*.tar.gz | head -n 1)
if [ ! -e "$TRBL_FILE" ]; then
log "...tarball not found, exiting!"
retval=1
else
log "...success, tarball created as \"$TRBL_FILE\""
retval=0
fi
else
log "...\"$setuppy\" not found, exiting!"
retval=1
fi
return $retval
}
function run_pip_install()
{
find_pip
retval=0
tarball_file=${1:-$TRBL_FILE}
log "Running \"$PIPCMD install $PIPARGS $tarball_file\" output will be recorded in \"$LOGFILE\""
$PIPCMD install $PIPARGS $tarball_file >> $LOGFILE 2>&1
if [ $? -ne 0 ]; then
log "...pip install fails, exiting!"
retval=1
exit 1
fi
return $retval
}
# purge init
purgeinit()
function inject_init()
{
rm -f /etc/init.d/$SERVICE_SRV_NAME
rm -f /etc/init/$SERVICE_SRV_NAME.conf
log "Reloading initctl"
initctl reload-configuration
retval=0
_dist=$(lowercase $DISTRO_BASED_ON)
eval src_init_sctipt="$DAEMON_NAME-$_dist"
_initscript="openstack-$DAEMON_NAME"
cp -f "$RUN_DIR/etc/init.d/$src_init_sctipt" "/etc/init.d/$_initscript" || retval=$?
chmod +x "/etc/init.d/$_initscript" || retval=$?
iniset '' 'SYSTEM_USER' "$DAEMON_USER" "/etc/init.d/$_initscript"
iniset '' 'DAEMON' "$(shslash $SERVICE_EXEC_PATH)" "/etc/init.d/$_initscript"
case $_dist in
"debian")
update-rc.d $_initscript defaults || retval=$?
update-rc.d $_initscript enable || retval=$?
;;
*)
chkconfig --add $_initscript || retval=$?
chkconfig $_initscript on || retval=$?
;;
esac
return $retval
}
# uninstall
uninst()
function purge_init()
{
# Uninstall trough pip
# looking up for python package installed
PYPKG=$SERVICE_SRV_NAME
pip freeze | grep $PYPKG
if [ $? -eq 0 ]; then
log "Removing package \"$PYPKG\" with pip"
pip uninstall $PYPKG --yes
else
log "Python package \"$PYPKG\" not found"
fi
retval=0
_dist=$(lowercase $DISTRO_BASED_ON)
_initscript="openstack-$DAEMON_NAME"
service $_initscript stop
if [ $? -ne 0 ]; then
retval=1
fi
case $_dist in
"debian")
update-rc.d $_initscript disable
update-rc.d -f $_initscript remove || retval=$?
;;
*)
chkconfig $_initscript off || retval=$?
chkconfig --del $_initscript || retval=$?
;;
esac
rm -f "/etc/init.d/$_initscript" || retval=$?
return $retval
}
# postinstall
postinst()
function run_pip_uninstall()
{
log "Please, make proper configuration,located at \"$ETC_CFG_DIR\", before starting the \"$SERVICE_SRV_NAME\" daemon!"
find_pip
retval=0
pack_to_del=$(is_py_package_installed "$DAEMON_NAME")
if [ $? -eq 0 ]; then
log "Running \"$PIPCMD uninstall $PIPARGS $DAEMON_NAME\" output will be recorded in \"$LOGFILE\""
$PIPCMD uninstall $pack_to_del --yes >> $LOGFILE 2>&1
if [ $? -ne 0 ]; then
log "...can't uninstall $DAEMON_NAME with $PIPCMD"
retval=1
else
log "...success"
fi
else
log "Python package for \"$DAEMON_NAME\" not found"
fi
return $retval
}
function install_daemon()
{
install_prerequisites || exit 1
make_tarball || exit $?
run_pip_install || exit $?
add_daemon_credentials "$DAEMON_USER" "$DAEMON_GROUP" || exit $?
log "Creating required directories..."
mk_dir "$DAEMON_CFG_DIR" "$DAEMON_USER" "$DAEMON_GROUP" || exit 1
mk_dir "$DAEMON_CACHE_DIR" "$DAEMON_USER" "$DAEMON_GROUP" || exit 1
mk_dir "$DAEMON_LOG_DIR" "$DAEMON_USER" "$DAEMON_GROUP" || exit 1
log "Making sample configuration files at \"$DAEMON_CFG_DIR\""
_src_conf_dir="$RUN_DIR/etc/murano"
_prefix="murano-"
for file in $(ls $_src_conf_dir)
do
if [ -d "$_src_conf_dir/$file" ]; then
#Dir copy
cp -f -r "$_src_conf_dir/$file" "$DAEMON_CFG_DIR/$file"
else
#cp -f "$_src_conf_dir/$file" "$DAEMON_CFG_DIR/${_prefix}${file}.sample"
cp -f "$_src_conf_dir/$file" "$DAEMON_CFG_DIR/$file"
config_file=$_prefix$(echo $file | sed -e 's/.sample$//')
#removing Cr Lf
dos2unix "$DAEMON_CFG_DIR/$file"
if [ ! -e "$DAEMON_CFG_DIR/$config_file" ]; then
cp -f "$_src_conf_dir/$file" "$DAEMON_CFG_DIR/$config_file"
dos2unix "$DAEMON_CFG_DIR/$config_file"
else
log "\"$DAEMON_CFG_DIR/$config_file\" exists, skipping copy."
fi
fi
done
log "Setting log file and sqlite db placement..."
iniset 'DEFAULT' 'log_file' "$(shslash $DAEMON_LOG_DIR/$DAEMON_NAME.log)" "$DAEMON_CFG_DIR/$DAEMON_NAME.conf"
iniset 'DEFAULT' 'verbose' 'True' "$DAEMON_CFG_DIR/$DAEMON_NAME.conf"
iniset 'DEFAULT' 'debug' 'True' "$DAEMON_CFG_DIR/$DAEMON_NAME.conf"
iniset 'DEFAULT' 'init_scripts_dir' "$(shslash $DAEMON_CFG_DIR/init-scripts)" "$DAEMON_CFG_DIR/$DAEMON_NAME.conf"
iniset 'DEFAULT' 'agent_config_dir' "$(shslash $DAEMON_CFG_DIR/agent-config)" "$DAEMON_CFG_DIR/$DAEMON_NAME.conf"
iniset 'DEFAULT' 'data_dir' "$(shslash $DAEMON_CACHE_DIR/muranoconductor-data)" "$DAEMON_CFG_DIR/$DAEMON_NAME.conf"
log "Searching daemon in \$PATH..."
OLD_DAEMON_NAME=$DAEMON_NAME
#murano-conductor->muranoconductor
DAEMON_NAME=$(echo $DAEMON_NAME | tr -d '-')
get_service_exec_path || exit $?
DAEMON_NAME=$OLD_DAEMON_NAME
log "...found at \"$SERVICE_EXEC_PATH\""
log "Installing SysV init script."
inject_init || exit $?
log "Everything done, please, verify \"$DAEMON_CFG_DIR/$DAEMON_NAME.conf\", service created as \"openstack-${DAEMON_NAME}\"."
}
function uninstall_daemon()
{
log "Removing SysV init script..."
purge_init || exit $?
remove_daemon_credentials "$DAEMON_USER" "$DAEMON_GROUP" || exit $?
run_pip_uninstall || exit $?
log "Software uninstalled, daemon configuration files and logs located at \"$DAEMON_CFG_DIR\" and \"$DAEMON_LOG_DIR\"."
}
# Command line args'
COMMAND="$1"
case $COMMAND in
inject-init )
get_service_exec_path
log "Injecting \"$SERVICE_SRV_NAME\" to init..."
injectinit
postinst
;;
install)
rm -rf $LOGFILE
log "Installing \"$DAEMON_NAME\" to system..."
install_daemon
;;
install )
inst
get_service_exec_path
injectinit
postinst
;;
uninstall )
log "Uninstalling \"$DAEMON_NAME\" from system..."
uninstall_daemon
;;
installfromgit )
inst "yes"
get_service_exec_path
injectinit
postinst
;;
purge-init )
log "Purging \"$SERVICE_SRV_NAME\" from init..."
stop $SERVICE_SRV_NAME
purgeinit
;;
uninstall )
log "Uninstalling \"$SERVICE_SRV_NAME\" from system..."
stop $SERVICE_SRV_NAME
purgeinit
uninst
;;
* )
echo "Usage: $(basename "$0") command \nCommands:\n\tinstall - Install $SERVICE_SRV_NAME software\n\tuninstall - Uninstall $SERVICE_SRV_NAME software\n\tinject-init - Add $SERVICE_SRV_NAME to the system start-up\n\tpurge-init - Remove $SERVICE_SRV_NAME from the system start-up"
exit 1
;;
* )
echo -e "Usage: $(basename "$0") [command] \nCommands:\n\tinstall - Install \"$DAEMON_NAME\" software\n\tuninstall - Uninstall \"$DAEMON_NAME\" software"
exit 1
;;
esac