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 #Translation build
*.mo *.mo
*.pot
#SQLite Database files #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 Conductor is an Murano orchestration engine that transforms object model sent by
REST API service into a series of Heat and Murano-Agent commands 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 SEE ALSO
-------- --------
* `Murano <http://murano.mirantis.com>`__ * `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] [DEFAULT]
# Path where log will be written # Set up logging. To use syslog just set use_syslog parameter value to 'True'
log_file = /tmp/conductor.log log_file = /tmp/murano-conductor.log
use_syslog = False
# Log verbosity syslog_log_facility = LOG_LOCAL0
debug=True
verbose=True # Log verbosity
debug = True
# Provide directory with initialization scripts verbose = True
init_scripts_dir = etc/init-scripts
# Provide directory with initialization scripts
# Provide directory with agent configs init_scripts_dir = etc/murano/init-scripts
agent_config_dir = etc/agent-config
# Provide directory with agent configs
# Directory for data cache, OS temp directory is used by default agent_config_dir = etc/murano/agent-config
#data_dir = /tmp/muranoconductor-cache
# Directory for data cache, OS temp directory is used by default
# Provide url to Murano Metadata repository data_dir = /tmp/muranoconductor-cache
# Comment this line if you registered murano-metadata in keystone catalog
murano_metadata_url = http://localhost:8084/v1 # Provide url to Murano Metadata repository
# Comment this line if you registered murano-metadata in keystone catalog
# Maximum number of environments that can be processed simultaneously murano_metadata_url = http://localhost:8084/v1
max_environments = 20
# Maximum number of environments that can be processed simultaneously
# Maximum number of VMs per environment max_environments = 20
max_hosts = 250
# Maximum number of VMs per environment
# Template IP address for generating environment subnet cidrs max_hosts = 250
env_ip_template = 10.0.0.0
# Template IP address for generating environment subnet cidrs
# Enforces default network topology. env_ip_template = 10.0.0.0
# Allowed values: nova, flat, routed
# default is routed # Enforces default network topology.
network_topology = routed # Allowed values: nova, flat, routed
# default is routed
[keystone] network_topology = routed
# URL of OpenStack KeyStone service REST API.
# Typically only hostname (or IP) needs to be changed [keystone]
auth_url = http://localhost:5000/v2.0 # URL of OpenStack KeyStone service REST API.
# Typically only hostname (or IP) needs to be changed
# Keystone SSL parameters auth_url = http://localhost:5000/v2.0
# Optional CA cert file to use in SSL connections
#ca_file = # Keystone SSL parameters
# Optional PEM-formatted certificate chain file # Optional CA cert file to use in SSL connections
#cert_file = #ca_file =
# Optional PEM-formatted file that contains the private key # Optional PEM-formatted certificate chain file
#key_file = #cert_file =
# If set then the server's certificate will not be verified # Optional PEM-formatted file that contains the private key
insecure = False #key_file =
# If set then the server's certificate will not be verified
[heat] insecure = False
# Heat SSL parameters
# Optional CA cert file to use in SSL connections [heat]
#ca_file = # Heat SSL parameters
# Optional PEM-formatted certificate chain file # Optional CA cert file to use in SSL connections
#cert_file = #ca_file =
# Optional PEM-formatted file that contains the private key # Optional PEM-formatted certificate chain file
#key_file = #cert_file =
# If set then the server's certificate will not be verified # Optional PEM-formatted file that contains the private key
insecure = False #key_file =
# Valid endpoint types: publicURL (default), internalURL, adminURL # If set then the server's certificate will not be verified
endpoint_type = publicURL insecure = False
# Valid endpoint types: publicURL (default), internalURL, adminURL
[neutron] endpoint_type = publicURL
# Optional CA cert file to use in SSL connections
#ca_cert = [neutron]
# Allow self signed server certificate # Optional CA cert file to use in SSL connections
insecure = False #ca_cert =
# Valid endpoint types: publicURL (default), internalURL, adminURL # Allow self signed server certificate
endpoint_type = publicURL insecure = False
# Valid endpoint types: publicURL (default), internalURL, adminURL
[rabbitmq] endpoint_type = publicURL
# Connection parameters to RabbitMQ service
[rabbitmq]
# Hostname or IP address where RabbitMQ is located. # Connection parameters to RabbitMQ service
# !!! Change localhost to your real IP or hostname as this address must be reachable from VMs !!!
host = localhost # Hostname or IP address where RabbitMQ is located.
# !!! Change localhost to your real IP or hostname as this address must be reachable from VMs !!!
# RabbitMQ port (5672 is a default) host = localhost
port = 5672
# RabbitMQ port (5672 is a default)
# Use SSL for RabbitMQ connections (True or False) port = 5672
ssl = False
# Use SSL for RabbitMQ connections (True or False)
# Path to SSL CA certificate or empty to allow self signed server certificate ssl = False
#ca_certs =
# Path to SSL CA certificate or empty to allow self signed server certificate
# RabbitMQ credentials. Fresh RabbitMQ installation has "guest" account with "guest" password. #ca_certs =
# It is recommended to create dedicated user account for Murano using RabbitMQ web console or command line utility
login = guest # RabbitMQ credentials. Fresh RabbitMQ installation has "guest" account with "guest" password.
password = guest # It is recommended to create dedicated user account for Murano using RabbitMQ web console or command line utility
login = guest
# RabbitMQ virtual host (vhost). Fresh RabbitMQ installation has "/" vhost preconfigured. password = guest
# It is recommended to create dedicated vhost for Murano using RabbitMQ web console or command line utility
virtual_host = / # 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). \ routers = self.neutron.list_routers(tenant_id=self.tenant_id). \
get("routers") get("routers")
if not len(routers): if not len(routers):
routerId = "NOT_FOUND" routerId = externalNetId = "NOT_FOUND"
else: else:
routerId = routers[0]["id"] routerId = routers[0]["id"]
externalNetId = routers[0]['external_gateway_info']['network_id']
if len(routers) > 1: if len(routers) > 1:
for router in routers: for router in routers:
if "murano" in router["name"].lower(): if "murano" in router["name"].lower():
routerId = router["id"] routerId = router["id"]
externalNetId = \
router['external_gateway_info']['network_id']
break break
for callback in self.router_requests: for callback in self.router_requests:
callback(routerId) callback(routerId, externalNetId)
self.router_requests = [] self.router_requests = []
return True return True

View File

@ -62,13 +62,49 @@ class VmAgentExecutor(CommandBase):
else: else:
return self._build_v2_execution_plan(template, path) 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): def _build_v1_execution_plan(self, template, path):
scripts_folder = os.path.join( agent_dir_root, rest_dirs = self._split_agent_path(path)
os.path.dirname(path), 'scripts') scripts_folder = os.path.join(agent_dir_root, 'scripts')
script_files = template.get('Scripts', []) script_files = template.get('Scripts', [])
scripts = [] scripts = []
for script in script_files: 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)) log.debug('Loading script "{0}"'.format(script_path))
with open(script_path) as script_file: with open(script_path) as script_file:
script_data = script_file.read() 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): def prepare(data_dir):
if not os.path.exists(data_dir): if not os.path.exists(data_dir):
os.makedirs(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, init_scripts_dst = os.path.join(data_dir,
os.path.basename(CONF.init_scripts_dir)) os.path.basename(CONF.init_scripts_dir))
if not os.path.exists(init_scripts_dst): if os.path.exists(init_scripts_dst):
shutil.copytree(CONF.init_scripts_dir, 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, agent_config_dst = os.path.join(data_dir,
os.path.basename(CONF.agent_config_dir)) os.path.basename(CONF.agent_config_dir))
if not os.path.exists(agent_config_dst): if os.path.exists(agent_config_dst):
shutil.copytree(CONF.agent_config_dir, 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) 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): def get_default_router(engine, context, body, result=None):
command_dispatcher = context['/commandDispatcher'] command_dispatcher = context['/commandDispatcher']
def callback(result_value): def callback(routerId, externalNetId):
if result is not None: if result is not None:
context[result] = {"routerId": result_value} context[result] = {"routerId": routerId,
"floatingId": externalNetId}
success_handler = body.find('success') success_handler = body.find('success')
if success_handler is not None: if success_handler is not None:

View File

@ -11,8 +11,7 @@ netaddr>=0.7.6
oslo.config>=1.2.0 oslo.config>=1.2.0
deep deep
# Please, revert to murano-common>=x.x.x before release murano-common==0.4.1
http://tarballs.openstack.org/murano-common/murano-common-master.tar.gz#egg=muranocommon-0.4
PyYAML>=3.1.0 PyYAML>=3.1.0
http://tarballs.openstack.org/murano-metadataclient/murano-metadataclient-master.tar.gz#egg=metadataclient-0.4 murano-metadataclient==0.4.1
python-neutronclient>=2.3.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] [metadata]
name = murano-conductor name = murano-conductor
summary = The Conductor is orchestration engine server summary = The Conductor is orchestration engine server
version = 0.3 version = 0.4.1
description-file = description-file =
README.rst README.rst
license = Apache License, Version 2.0 license = Apache License, Version 2.0
author = Mirantis, Inc. author = Mirantis, Inc.
author-email = murano-all@lists.openstack.org author-email = murano-all@lists.openstack.org
home-page = htts://launchpad.net/murano home-page = https://launchpad.net/murano
classifier = classifier =
Development Status :: 5 - Production/Stable Development Status :: 5 - Production/Stable
Environment :: OpenStack Environment :: OpenStack

470
setup.sh Normal file → Executable file
View File

@ -1,5 +1,5 @@
#!/bin/sh #!/bin/bash
# Copyright (c) 2013 Mirantis, Inc. # Copyright (c) 2014 Mirantis, Inc.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may # 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 # 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 # License for the specific language governing permissions and limitations
# under the License. # under the License.
# #
# Ubuntu script. RUN_DIR=$(cd $(dirname "$0") && pwd)
INC_FILE="$RUN_DIR/common.inc"
LOGLVL=1 if [ -f "$INC_FILE" ]; then
SERVICE_CONTENT_DIRECTORY=`cd $(dirname "$0") && pwd` source "$INC_FILE"
PREREQ_PKGS="upstart wget git make python-pip python-dev python-mysqldb libxml2-dev libxslt-dev libffi-dev" else
SERVICE_SRV_NAME="murano-conductor" echo "Can't load \"$INC_FILE\" or file not found, exiting!"
GIT_CLONE_DIR=`echo $SERVICE_CONTENT_DIRECTORY | sed -e "s/$SERVICE_SRV_NAME//"` exit 1
#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
fi fi
echo "description \"$SERVICE_SRV_NAME service\" #
author \"Igor Yozhikov <iyozhikov@mirantis.com>\" DAEMON_NAME="murano-conductor"
start on runlevel [2345] DAEMON_USER="murano"
stop on runlevel [!2345] DAEMON_GROUP="murano"
respawn DAEMON_CFG_DIR="/etc/murano"
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" DAEMON_CACHE_DIR="/var/cache/murano"
log "Reloading initctl" DAEMON_LOG_DIR="/var/log/murano"
initctl reload-configuration 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 function inject_init()
purgeinit()
{ {
rm -f /etc/init.d/$SERVICE_SRV_NAME retval=0
rm -f /etc/init/$SERVICE_SRV_NAME.conf _dist=$(lowercase $DISTRO_BASED_ON)
log "Reloading initctl" eval src_init_sctipt="$DAEMON_NAME-$_dist"
initctl reload-configuration _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
} }
function purge_init()
# uninstall
uninst()
{ {
# Uninstall trough pip retval=0
# looking up for python package installed _dist=$(lowercase $DISTRO_BASED_ON)
PYPKG=$SERVICE_SRV_NAME _initscript="openstack-$DAEMON_NAME"
pip freeze | grep $PYPKG service $_initscript stop
if [ $? -eq 0 ]; then if [ $? -ne 0 ]; then
log "Removing package \"$PYPKG\" with pip" retval=1
pip uninstall $PYPKG --yes fi
else case $_dist in
log "Python package \"$PYPKG\" not found" "debian")
fi 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
} }
function run_pip_uninstall()
# postinstall
postinst()
{ {
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 line args'
COMMAND="$1" COMMAND="$1"
case $COMMAND in case $COMMAND in
inject-init ) install)
get_service_exec_path rm -rf $LOGFILE
log "Injecting \"$SERVICE_SRV_NAME\" to init..." log "Installing \"$DAEMON_NAME\" to system..."
injectinit install_daemon
postinst ;;
;;
install ) uninstall )
inst log "Uninstalling \"$DAEMON_NAME\" from system..."
get_service_exec_path uninstall_daemon
injectinit ;;
postinst
;;
installfromgit ) * )
inst "yes" echo -e "Usage: $(basename "$0") [command] \nCommands:\n\tinstall - Install \"$DAEMON_NAME\" software\n\tuninstall - Uninstall \"$DAEMON_NAME\" software"
get_service_exec_path exit 1
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
;;
esac esac