Cherry-pick all changes from release-0.1 branch
Change-Id: Ibd8bfcf199b07700226629fd5c0679669ea29578
This commit is contained in:
parent
6717dddffa
commit
b8bc196805
@ -1,3 +1,4 @@
|
||||
include tools/pip-requires
|
||||
include run_tests.sh
|
||||
include ChangeLog
|
||||
include README.rst
|
||||
@ -11,4 +12,4 @@ include openstack-common.conf
|
||||
include muranoapi/db/migrate_repo/README
|
||||
include muranoapi/db/migrate_repo/migrate.cfg
|
||||
include muranoapi/db/migrate_repo/versions/*.sql
|
||||
global-exclude *.pyc
|
||||
global-exclude *.pyc
|
||||
|
@ -14,14 +14,11 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import gettext
|
||||
import os
|
||||
import sys
|
||||
|
||||
# If ../muranoapi/__init__.py exists, add ../ to Python search path, so that
|
||||
# it will override what happens to be installed in /usr/(local/)lib/python...
|
||||
from muranoapi.common.service import TaskResultHandlerService
|
||||
|
||||
possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
|
||||
os.pardir,
|
||||
os.pardir))
|
||||
@ -29,11 +26,11 @@ if os.path.exists(os.path.join(possible_topdir, 'muranoapi', '__init__.py')):
|
||||
sys.path.insert(0, possible_topdir)
|
||||
|
||||
from muranoapi.common import config
|
||||
from muranoapi.common.service import TaskResultHandlerService
|
||||
from muranoapi.openstack.common import log
|
||||
from muranoapi.openstack.common import wsgi
|
||||
from muranoapi.openstack.common import service
|
||||
|
||||
gettext.install('muranoapi', './muranoapi/locale', unicode=1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
|
@ -7,6 +7,8 @@ paste.app_factory = muranoapi.api.v1.router:API.factory
|
||||
[filter:context]
|
||||
paste.filter_factory = muranoapi.api.middleware.context:ContextMiddleware.factory
|
||||
|
||||
#For more information see Auth-Token Middleware with Username and Password
|
||||
#http://docs.openstack.org/developer/keystone/configuringservices.html
|
||||
[filter:authtoken]
|
||||
paste.filter_factory = keystoneclient.middleware.auth_token:filter_factory
|
||||
auth_host = localhost
|
||||
|
@ -11,22 +11,36 @@ bind_host = 0.0.0.0
|
||||
# Port the bind the server to
|
||||
bind_port = 8082
|
||||
|
||||
# Log to this file. Make sure the user running skeleton-api has
|
||||
# permissions to write to this file!
|
||||
# Log to this file. Make sure the user has permissions to write to this file!
|
||||
log_file = /tmp/murano-api.log
|
||||
|
||||
#A valid SQLAlchemy connection string for the metadata database
|
||||
sql_connection = sqlite:///murano.sqlite
|
||||
|
||||
#A boolean that determines if the database will be automatically created
|
||||
db_auto_create = True
|
||||
|
||||
[reports]
|
||||
#Change this params only when you know what you are doing
|
||||
results_exchange = task-results
|
||||
results_queue = task-results
|
||||
reports_exchange = task-reports
|
||||
reports_queue = task-reports
|
||||
|
||||
[rabbitmq]
|
||||
# Connection parameters to RabbitMQ service
|
||||
|
||||
# Hostname or IP address where RabbitMQ is located.
|
||||
host = localhost
|
||||
|
||||
# RabbitMQ port (5672 is a default)
|
||||
port = 5672
|
||||
virtual_host = murano
|
||||
login = murano
|
||||
password = murano
|
||||
|
||||
# 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 = /
|
@ -11,3 +11,6 @@
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import gettext
|
||||
gettext.install('muranoapi', './muranoapi/locale', unicode=1)
|
||||
|
@ -16,6 +16,7 @@ from muranoapi import utils
|
||||
from muranoapi.db.services.systemservices import SystemServices
|
||||
from muranoapi.openstack.common import wsgi
|
||||
from muranoapi.openstack.common import log as logging
|
||||
from webob.exc import HTTPNotFound
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -52,8 +53,11 @@ class Controller(object):
|
||||
session_id = request.context.session
|
||||
delete = SystemServices.delete_service
|
||||
|
||||
delete(active_directory_id, 'activeDirectories', session_id,
|
||||
environment_id)
|
||||
try:
|
||||
delete(active_directory_id, 'activeDirectories', session_id,
|
||||
environment_id)
|
||||
except ValueError:
|
||||
raise HTTPNotFound()
|
||||
|
||||
|
||||
def create_resource():
|
||||
|
@ -16,6 +16,7 @@ from muranoapi import utils
|
||||
from muranoapi.db.services.systemservices import SystemServices
|
||||
from muranoapi.openstack.common import wsgi
|
||||
from muranoapi.openstack.common import log as logging
|
||||
from webob.exc import HTTPNotFound
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -51,7 +52,10 @@ class Controller(object):
|
||||
session_id = request.context.session
|
||||
delete = SystemServices.delete_service
|
||||
|
||||
delete(app_farm_id, 'aspNetAppFarms', session_id, environment_id)
|
||||
try:
|
||||
delete(app_farm_id, 'aspNetAppFarms', session_id, environment_id)
|
||||
except ValueError:
|
||||
raise HTTPNotFound()
|
||||
|
||||
|
||||
def create_resource():
|
||||
|
@ -16,6 +16,7 @@ from muranoapi import utils
|
||||
from muranoapi.db.services.systemservices import SystemServices
|
||||
from muranoapi.openstack.common import wsgi
|
||||
from muranoapi.openstack.common import log as logging
|
||||
from webob.exc import HTTPNotFound
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -51,7 +52,10 @@ class Controller(object):
|
||||
session_id = request.context.session
|
||||
delete = SystemServices.delete_service
|
||||
|
||||
delete(app_id, 'aspNetApps', session_id, environment_id)
|
||||
try:
|
||||
delete(app_id, 'aspNetApps', session_id, environment_id)
|
||||
except ValueError:
|
||||
raise HTTPNotFound()
|
||||
|
||||
|
||||
def create_resource():
|
||||
|
@ -42,39 +42,49 @@ class Controller(object):
|
||||
|
||||
return session.to_dict()
|
||||
|
||||
def show(self, request, session_id):
|
||||
def show(self, request, environment_id, session_id):
|
||||
log.debug(_('Session:Show <SessionId: {0}>'.format(session_id)))
|
||||
|
||||
unit = get_session()
|
||||
session = unit.query(Session).get(session_id)
|
||||
|
||||
if session.environment_id != environment_id:
|
||||
log.error('Session <SessionId {0}> is not tied with Environment '
|
||||
'<EnvId {1}>'.format(session_id, environment_id))
|
||||
raise exc.HTTPNotFound()
|
||||
|
||||
user_id = request.context.user
|
||||
if session.user_id != user_id:
|
||||
log.info('User <UserId {0}> is not authorized to access '
|
||||
'session <SessionId {1}>.'.format(user_id, session_id))
|
||||
log.error('User <UserId {0}> is not authorized to access '
|
||||
'session <SessionId {1}>.'.format(user_id, session_id))
|
||||
raise exc.HTTPUnauthorized()
|
||||
|
||||
if not SessionServices.validate(session):
|
||||
log.info('Session <SessionId {0}> is invalid'.format(session_id))
|
||||
log.error('Session <SessionId {0}> is invalid'.format(session_id))
|
||||
raise exc.HTTPForbidden()
|
||||
|
||||
return session.to_dict()
|
||||
|
||||
def delete(self, request, session_id):
|
||||
def delete(self, request, environment_id, session_id):
|
||||
log.debug(_('Session:Delete <SessionId: {0}>'.format(session_id)))
|
||||
|
||||
unit = get_session()
|
||||
session = unit.query(Session).get(session_id)
|
||||
|
||||
if session.environment_id != environment_id:
|
||||
log.error('Session <SessionId {0}> is not tied with Environment '
|
||||
'<EnvId {1}>'.format(session_id, environment_id))
|
||||
raise exc.HTTPNotFound()
|
||||
|
||||
user_id = request.context.user
|
||||
if session.user_id != user_id:
|
||||
log.info('User <UserId {0}> is not authorized to access '
|
||||
'session <SessionId {1}>.'.format(user_id, session_id))
|
||||
log.error('User <UserId {0}> is not authorized to access '
|
||||
'session <SessionId {1}>.'.format(user_id, session_id))
|
||||
raise exc.HTTPUnauthorized()
|
||||
|
||||
if session.state == SessionState.deploying:
|
||||
log.info('Session <SessionId: {0}> is in deploying state and '
|
||||
'could not be deleted'.format(session_id))
|
||||
log.error('Session <SessionId: {0}> is in deploying state and '
|
||||
'could not be deleted'.format(session_id))
|
||||
raise exc.HTTPForbidden()
|
||||
|
||||
with unit.begin():
|
||||
|
@ -16,6 +16,7 @@ from muranoapi import utils
|
||||
from muranoapi.db.services.systemservices import SystemServices
|
||||
from muranoapi.openstack.common import wsgi
|
||||
from muranoapi.openstack.common import log as logging
|
||||
from webob.exc import HTTPNotFound
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -51,8 +52,11 @@ class Controller(object):
|
||||
session_id = request.context.session
|
||||
delete = SystemServices.delete_service
|
||||
|
||||
delete(web_server_farm_id, 'webServerFarms', session_id,
|
||||
environment_id)
|
||||
try:
|
||||
delete(web_server_farm_id, 'webServerFarms', session_id,
|
||||
environment_id)
|
||||
except ValueError:
|
||||
raise HTTPNotFound()
|
||||
|
||||
|
||||
def create_resource():
|
||||
|
@ -16,6 +16,7 @@ from muranoapi import utils
|
||||
from muranoapi.db.services.systemservices import SystemServices
|
||||
from muranoapi.openstack.common import wsgi
|
||||
from muranoapi.openstack.common import log as logging
|
||||
from webob.exc import HTTPNotFound
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -51,7 +52,10 @@ class Controller(object):
|
||||
session_id = request.context.session
|
||||
delete = SystemServices.delete_service
|
||||
|
||||
delete(web_server_id, 'webServers', session_id, environment_id)
|
||||
try:
|
||||
delete(web_server_id, 'webServers', session_id, environment_id)
|
||||
except ValueError:
|
||||
raise HTTPNotFound()
|
||||
|
||||
|
||||
def create_resource():
|
||||
|
@ -58,12 +58,27 @@ rabbit_opts = [
|
||||
cfg.StrOpt('virtual_host', default='/'),
|
||||
]
|
||||
|
||||
db_opts = [
|
||||
cfg.IntOpt('sql_idle_timeout', default=3600,
|
||||
help=_('Period in seconds after which SQLAlchemy should '
|
||||
'reestablish its connection to the database.')),
|
||||
cfg.IntOpt('sql_max_retries', default=60,
|
||||
help=_('The number of times to retry a connection to the SQL'
|
||||
'server.')),
|
||||
cfg.IntOpt('sql_retry_interval', default=1,
|
||||
help=_('The amount of time to wait (in seconds) before '
|
||||
'attempting to retry the SQL connection.')),
|
||||
cfg.BoolOpt('db_auto_create', default=False,
|
||||
help=_('A boolean that determines if the database will be '
|
||||
'automatically created.')),
|
||||
]
|
||||
|
||||
CONF = cfg.CONF
|
||||
CONF.register_opts(paste_deploy_opts, group='paste_deploy')
|
||||
CONF.register_cli_opts(bind_opts)
|
||||
# CONF.register_opts(bind_opts)
|
||||
CONF.register_opts(reports_opts, group='reports')
|
||||
CONF.register_opts(rabbit_opts, group='rabbitmq')
|
||||
CONF.register_opts(db_opts)
|
||||
|
||||
|
||||
CONF.import_opt('verbose', 'muranoapi.openstack.common.log')
|
||||
|
@ -12,35 +12,37 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import socket
|
||||
|
||||
from amqplib.client_0_8 import AMQPConnectionException
|
||||
import anyjson
|
||||
from eventlet import patcher
|
||||
import eventlet
|
||||
from muranoapi.common.utils import retry, handle
|
||||
from muranoapi.db.models import Status, Session, Environment
|
||||
from muranoapi.db.session import get_session
|
||||
|
||||
amqp = patcher.import_patched('amqplib.client_0_8')
|
||||
|
||||
from muranoapi.openstack.common import service
|
||||
from muranoapi.openstack.common import log as logging
|
||||
from muranoapi.common import config
|
||||
|
||||
amqp = eventlet.patcher.import_patched('amqplib.client_0_8')
|
||||
conf = config.CONF.reports
|
||||
rabbitmq = config.CONF.rabbitmq
|
||||
log = logging.getLogger(__name__)
|
||||
channel = None
|
||||
|
||||
|
||||
class TaskResultHandlerService(service.Service):
|
||||
def __init__(self, threads=1000):
|
||||
super(TaskResultHandlerService, self).__init__(threads)
|
||||
class TaskResultHandlerService():
|
||||
thread = None
|
||||
|
||||
def start(self):
|
||||
super(TaskResultHandlerService, self).start()
|
||||
self.tg.add_thread(self._handle_results)
|
||||
self.thread = eventlet.spawn(self.connect)
|
||||
|
||||
def stop(self):
|
||||
super(TaskResultHandlerService, self).stop()
|
||||
pass
|
||||
|
||||
def _handle_results(self):
|
||||
def wait(self):
|
||||
self.thread.wait()
|
||||
|
||||
@retry((socket.error, AMQPConnectionException), tries=-1)
|
||||
def connect(self):
|
||||
connection = amqp.Connection('{0}:{1}'.
|
||||
format(rabbitmq.host, rabbitmq.port),
|
||||
virtual_host=rabbitmq.virtual_host,
|
||||
@ -67,36 +69,15 @@ class TaskResultHandlerService(service.Service):
|
||||
ch.wait()
|
||||
|
||||
|
||||
def handle_report(msg):
|
||||
log.debug(_('Got report message from orchestration engine:\n{0}'.
|
||||
format(msg.body)))
|
||||
|
||||
params = anyjson.deserialize(msg.body)
|
||||
params['entity_id'] = params['id']
|
||||
del params['id']
|
||||
|
||||
status = Status()
|
||||
status.update(params)
|
||||
|
||||
session = get_session()
|
||||
#connect with session
|
||||
conf_session = session.query(Session).filter_by(
|
||||
**{'environment_id': status.environment_id,
|
||||
'state': 'deploying'}).first()
|
||||
status.session_id = conf_session.id
|
||||
|
||||
with session.begin():
|
||||
session.add(status)
|
||||
|
||||
|
||||
@handle
|
||||
def handle_result(msg):
|
||||
log.debug(_('Got result message from '
|
||||
'orchestration engine:\n{0}'.format(msg.body)))
|
||||
|
||||
environment_result = anyjson.deserialize(msg.body)
|
||||
if 'deleted' in environment_result:
|
||||
log.debug(_('Result for environment {0} is dropped. '
|
||||
'Environment is deleted'.format(environment_result['id'])))
|
||||
log.debug(_('Result for environment {0} is dropped. Environment '
|
||||
'is deleted'.format(environment_result['id'])))
|
||||
|
||||
msg.channel.basic_ack(msg.delivery_tag)
|
||||
return
|
||||
@ -119,3 +100,26 @@ def handle_result(msg):
|
||||
conf_session.save(session)
|
||||
|
||||
msg.channel.basic_ack(msg.delivery_tag)
|
||||
|
||||
|
||||
@handle
|
||||
def handle_report(msg):
|
||||
log.debug(_('Got report message from orchestration '
|
||||
'engine:\n{0}'.format(msg.body)))
|
||||
|
||||
params = anyjson.deserialize(msg.body)
|
||||
params['entity_id'] = params['id']
|
||||
del params['id']
|
||||
|
||||
status = Status()
|
||||
status.update(params)
|
||||
|
||||
session = get_session()
|
||||
#connect with session
|
||||
conf_session = session.query(Session).filter_by(
|
||||
**{'environment_id': status.environment_id,
|
||||
'state': 'deploying'}).first()
|
||||
status.session_id = conf_session.id
|
||||
|
||||
with session.begin():
|
||||
session.add(status)
|
||||
|
77
muranoapi/common/utils.py
Normal file
77
muranoapi/common/utils.py
Normal file
@ -0,0 +1,77 @@
|
||||
# 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.
|
||||
|
||||
import eventlet
|
||||
from functools import wraps
|
||||
from muranoapi.openstack.common import log as logging
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def retry(ExceptionToCheck, tries=4, delay=3, backoff=2):
|
||||
"""Retry calling the decorated function using an exponential backoff.
|
||||
|
||||
http://www.saltycrane.com/blog/2009/11/trying-out-retry-decorator-python/
|
||||
original from: http://wiki.python.org/moin/PythonDecoratorLibrary#Retry
|
||||
|
||||
:param ExceptionToCheck: the exception to check. may be a tuple of
|
||||
exceptions to check
|
||||
:type ExceptionToCheck: Exception or tuple
|
||||
:param tries: number of times to try (not retry) before giving up
|
||||
:type tries: int
|
||||
:param delay: initial delay between retries in seconds
|
||||
:type delay: int
|
||||
:param backoff: backoff multiplier e.g. value of 2 will double the delay
|
||||
each retry
|
||||
:type backoff: int
|
||||
"""
|
||||
|
||||
def deco_retry(f):
|
||||
@wraps(f)
|
||||
def f_retry(*args, **kwargs):
|
||||
mtries, mdelay = tries, delay
|
||||
forever = mtries == -1
|
||||
while forever or mtries > 1:
|
||||
try:
|
||||
return f(*args, **kwargs)
|
||||
except ExceptionToCheck as e:
|
||||
|
||||
log.exception(e)
|
||||
log.info("Retrying in {0} seconds...".format(mdelay))
|
||||
|
||||
eventlet.sleep(mdelay)
|
||||
|
||||
if not forever:
|
||||
mtries -= 1
|
||||
|
||||
if mdelay < 60:
|
||||
mdelay *= backoff
|
||||
return f(*args, **kwargs)
|
||||
|
||||
return f_retry
|
||||
|
||||
return deco_retry
|
||||
|
||||
|
||||
def handle(f):
|
||||
"""Handles exception in wrapped function and writes to log."""
|
||||
|
||||
@wraps(f)
|
||||
def f_handle(*args, **kwargs):
|
||||
try:
|
||||
return f(*args, **kwargs)
|
||||
except Exception as e:
|
||||
log.exception(e)
|
||||
|
||||
return f_handle
|
@ -206,7 +206,7 @@ class SystemServices(object):
|
||||
if not 'services' in env_description:
|
||||
env_description['services'] = {}
|
||||
|
||||
if not 'webServers' in env_description['services']:
|
||||
if not 'aspNetApps' in env_description['services']:
|
||||
env_description['services']['aspNetApps'] = []
|
||||
|
||||
env_description['services']['aspNetApps'].append(aspApp)
|
||||
@ -240,7 +240,7 @@ class SystemServices(object):
|
||||
if not 'services' in env_description:
|
||||
env_description['services'] = {}
|
||||
|
||||
if not 'webServerFarmss' in env_description['services']:
|
||||
if not 'webServerFarms' in env_description['services']:
|
||||
env_description['services']['webServerFarms'] = []
|
||||
|
||||
env_description['services']['webServerFarms'].append(web_server_farm)
|
||||
@ -274,7 +274,7 @@ class SystemServices(object):
|
||||
if not 'services' in env_description:
|
||||
env_description['services'] = {}
|
||||
|
||||
if not 'webServers' in env_description['services']:
|
||||
if not 'aspNetAppFarms' in env_description['services']:
|
||||
env_description['services']['aspNetAppFarms'] = []
|
||||
|
||||
env_description['services']['aspNetAppFarms'].append(aspApp_farm)
|
||||
@ -289,12 +289,15 @@ class SystemServices(object):
|
||||
environment_id, session_id)
|
||||
|
||||
if not 'services' in env_description:
|
||||
raise ValueError('This environment does not have services')
|
||||
raise NameError('This environment does not have services')
|
||||
|
||||
services = []
|
||||
if service_type in env_description['services']:
|
||||
services = env_description['services'][service_type]
|
||||
|
||||
if service_id not in [srv['id'] for srv in services]:
|
||||
raise ValueError('Specified service does not exist')
|
||||
|
||||
services = [srv for srv in services if srv['id'] != service_id]
|
||||
env_description['services'][service_type] = services
|
||||
|
||||
|
@ -20,88 +20,169 @@
|
||||
"""Session management functions."""
|
||||
|
||||
import os
|
||||
import time
|
||||
import sqlalchemy
|
||||
import logging
|
||||
|
||||
from migrate.versioning import api as versioning_api
|
||||
from migrate import exceptions as versioning_exceptions
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.engine.url import make_url
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from sqlalchemy.pool import NullPool
|
||||
from sqlalchemy.exc import DisconnectionError
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
|
||||
from muranoapi.common.config import CONF as conf
|
||||
|
||||
from muranoapi.db import migrate_repo
|
||||
from muranoapi.openstack.common import log as mlogging
|
||||
|
||||
|
||||
MAKER = None
|
||||
ENGINE = None
|
||||
_ENGINE = None
|
||||
_MAKER = None
|
||||
_MAX_RETRIES = None
|
||||
_RETRY_INTERVAL = None
|
||||
_IDLE_TIMEOUT = None
|
||||
_CONNECTION = None
|
||||
|
||||
sa_logger = None
|
||||
log = mlogging.getLogger(__name__)
|
||||
|
||||
|
||||
class MySQLPingListener(object):
|
||||
def _ping_listener(dbapi_conn, connection_rec, connection_proxy):
|
||||
|
||||
"""
|
||||
Ensures that MySQL connections checked out of the
|
||||
pool are alive.
|
||||
|
||||
Borrowed from:
|
||||
http://groups.google.com/group/sqlalchemy/msg/a4ce563d802c929f
|
||||
|
||||
Error codes caught:
|
||||
* 2006 MySQL server has gone away
|
||||
* 2013 Lost connection to MySQL server during query
|
||||
* 2014 Commands out of sync; you can't run this command now
|
||||
* 2045 Can't open shared memory; no answer from server (%lu)
|
||||
* 2055 Lost connection to MySQL server at '%s', system error: %d
|
||||
|
||||
from http://dev.mysql.com/doc/refman/5.6/ru_RU/error-messages-client.html
|
||||
"""
|
||||
|
||||
def checkout(self, dbapi_con, con_record, con_proxy):
|
||||
try:
|
||||
dbapi_con.cursor().execute('select 1')
|
||||
except dbapi_con.OperationalError, ex:
|
||||
if ex.args[0] in (2006, 2013, 2014, 2045, 2055):
|
||||
logging.warn('Got mysql server has gone away: %s', ex)
|
||||
raise DisconnectionError("Database server went away")
|
||||
else:
|
||||
raise
|
||||
try:
|
||||
dbapi_conn.cursor().execute('select 1')
|
||||
except dbapi_conn.OperationalError as ex:
|
||||
if ex.args[0] in (2006, 2013, 2014, 2045, 2055):
|
||||
msg = 'Got mysql server has gone away: %s' % ex
|
||||
log.warn(msg)
|
||||
raise DisconnectionError(msg)
|
||||
else:
|
||||
raise
|
||||
|
||||
|
||||
def setup_db_env():
|
||||
"""
|
||||
Setup configuration for database
|
||||
"""
|
||||
global sa_logger, _IDLE_TIMEOUT, _MAX_RETRIES, _RETRY_INTERVAL, _CONNECTION
|
||||
|
||||
_IDLE_TIMEOUT = conf.sql_idle_timeout
|
||||
_MAX_RETRIES = conf.sql_max_retries
|
||||
_RETRY_INTERVAL = conf.sql_retry_interval
|
||||
_CONNECTION = conf.sql_connection
|
||||
sa_logger = logging.getLogger('sqlalchemy.engine')
|
||||
if conf.debug:
|
||||
sa_logger.setLevel(logging.DEBUG)
|
||||
|
||||
|
||||
def get_session(autocommit=True, expire_on_commit=False):
|
||||
"""Return a SQLAlchemy session."""
|
||||
global MAKER
|
||||
|
||||
if MAKER is None:
|
||||
MAKER = sessionmaker(autocommit=autocommit,
|
||||
expire_on_commit=expire_on_commit)
|
||||
engine = get_engine()
|
||||
MAKER.configure(bind=engine)
|
||||
session = MAKER()
|
||||
"""Helper method to grab session"""
|
||||
global _MAKER
|
||||
if not _MAKER:
|
||||
get_engine()
|
||||
_get_maker(autocommit, expire_on_commit)
|
||||
assert _MAKER
|
||||
session = _MAKER()
|
||||
return session
|
||||
|
||||
|
||||
def get_engine():
|
||||
"""Return a SQLAlchemy engine."""
|
||||
global ENGINE
|
||||
"""May assign _ENGINE if not already assigned"""
|
||||
global _ENGINE, sa_logger, _CONNECTION, _IDLE_TIMEOUT, _MAX_RETRIES,\
|
||||
_RETRY_INTERVAL
|
||||
|
||||
connection_url = make_url(conf.sql_connection)
|
||||
if ENGINE is None or not ENGINE.url == connection_url:
|
||||
engine_args = {'pool_recycle': 3600,
|
||||
'echo': False,
|
||||
'convert_unicode': True
|
||||
}
|
||||
if 'sqlite' in connection_url.drivername:
|
||||
engine_args['poolclass'] = NullPool
|
||||
if 'mysql' in connection_url.drivername:
|
||||
engine_args['listeners'] = [MySQLPingListener()]
|
||||
ENGINE = create_engine(conf.sql_connection, **engine_args)
|
||||
if not _ENGINE:
|
||||
setup_db_env()
|
||||
|
||||
sync()
|
||||
return ENGINE
|
||||
connection_dict = sqlalchemy.engine.url.make_url(_CONNECTION)
|
||||
|
||||
engine_args = {
|
||||
'pool_recycle': _IDLE_TIMEOUT,
|
||||
'echo': False,
|
||||
'convert_unicode': True}
|
||||
|
||||
try:
|
||||
_ENGINE = sqlalchemy.create_engine(_CONNECTION, **engine_args)
|
||||
|
||||
if 'mysql' in connection_dict.drivername:
|
||||
sqlalchemy.event.listen(_ENGINE, 'checkout', _ping_listener)
|
||||
|
||||
_ENGINE.connect = _wrap_db_error(_ENGINE.connect)
|
||||
_ENGINE.connect()
|
||||
except Exception as err:
|
||||
msg = _("Error configuring registry database with supplied "
|
||||
"sql_connection. Got error: %s") % err
|
||||
log.error(msg)
|
||||
raise
|
||||
|
||||
if conf.db_auto_create:
|
||||
log.info(_('auto-creating DB'))
|
||||
_auto_create_db()
|
||||
else:
|
||||
log.info(_('not auto-creating DB'))
|
||||
|
||||
return _ENGINE
|
||||
|
||||
|
||||
def sync():
|
||||
def _get_maker(autocommit=True, expire_on_commit=False):
|
||||
"""Return a SQLAlchemy sessionmaker."""
|
||||
"""May assign __MAKER if not already assigned"""
|
||||
global _MAKER, _ENGINE
|
||||
assert _ENGINE
|
||||
if not _MAKER:
|
||||
_MAKER = sessionmaker(bind=_ENGINE, autocommit=autocommit,
|
||||
expire_on_commit=expire_on_commit)
|
||||
return _MAKER
|
||||
|
||||
|
||||
def _is_db_connection_error(args):
|
||||
"""Return True if error in connecting to db."""
|
||||
# NOTE(adam_g): This is currently MySQL specific and needs to be extended
|
||||
# to support Postgres and others.
|
||||
conn_err_codes = ('2002', '2003', '2006')
|
||||
for err_code in conn_err_codes:
|
||||
if args.find(err_code) != -1:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def _wrap_db_error(f):
|
||||
"""Retry DB connection. Copied from nova and modified."""
|
||||
def _wrap(*args, **kwargs):
|
||||
try:
|
||||
return f(*args, **kwargs)
|
||||
except sqlalchemy.exc.OperationalError as e:
|
||||
if not _is_db_connection_error(e.args[0]):
|
||||
raise
|
||||
|
||||
remaining_attempts = _MAX_RETRIES
|
||||
while True:
|
||||
log.warning(_('SQL connection failed. %d attempts left.'),
|
||||
remaining_attempts)
|
||||
remaining_attempts -= 1
|
||||
time.sleep(_RETRY_INTERVAL)
|
||||
try:
|
||||
return f(*args, **kwargs)
|
||||
except sqlalchemy.exc.OperationalError as e:
|
||||
if (remaining_attempts == 0 or
|
||||
not _is_db_connection_error(e.args[0])):
|
||||
raise
|
||||
except sqlalchemy.exc.DBAPIError:
|
||||
raise
|
||||
except sqlalchemy.exc.DBAPIError:
|
||||
raise
|
||||
_wrap.func_name = f.func_name
|
||||
return _wrap
|
||||
|
||||
|
||||
def _auto_create_db():
|
||||
repo_path = os.path.abspath(os.path.dirname(migrate_repo.__file__))
|
||||
try:
|
||||
versioning_api.upgrade(conf.sql_connection, repo_path)
|
||||
|
@ -1,6 +1,6 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright (c) 2012 Openstack, LLC.
|
||||
# Copyright (c) 2012 OpenStack Foundation.
|
||||
# Administrator of the National Aeronautics and Space Administration.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
|
@ -1,6 +1,6 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2011 OpenStack LLC.
|
||||
# Copyright 2011 OpenStack Foundation.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
|
@ -1,6 +1,6 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2011 OpenStack LLC.
|
||||
# Copyright 2011 OpenStack Foundation.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
|
@ -38,14 +38,10 @@ import functools
|
||||
import inspect
|
||||
import itertools
|
||||
import json
|
||||
import logging
|
||||
import xmlrpclib
|
||||
|
||||
from muranoapi.openstack.common.gettextutils import _
|
||||
from muranoapi.openstack.common import timeutils
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def to_primitive(value, convert_instances=False, convert_datetime=True,
|
||||
level=0, max_depth=3):
|
||||
@ -85,8 +81,6 @@ def to_primitive(value, convert_instances=False, convert_datetime=True,
|
||||
return 'mock'
|
||||
|
||||
if level > max_depth:
|
||||
LOG.error(_('Max serialization depth exceeded on object: %d %s'),
|
||||
level, value)
|
||||
return '?'
|
||||
|
||||
# The try block may not be necessary after the class check above,
|
||||
|
@ -1,6 +1,6 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2011 OpenStack LLC.
|
||||
# Copyright 2011 OpenStack Foundation.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
|
@ -1,6 +1,6 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2011 OpenStack LLC.
|
||||
# Copyright 2011 OpenStack Foundation.
|
||||
# Copyright 2010 United States Government as represented by the
|
||||
# Administrator of the National Aeronautics and Space Administration.
|
||||
# All Rights Reserved.
|
||||
@ -328,7 +328,7 @@ def setup(product_name):
|
||||
if CONF.log_config:
|
||||
logging.config.fileConfig(CONF.log_config)
|
||||
else:
|
||||
_setup_logging_from_conf(product_name)
|
||||
_setup_logging_from_conf()
|
||||
sys.excepthook = _create_logging_excepthook(product_name)
|
||||
|
||||
|
||||
@ -362,8 +362,8 @@ def _find_facility_from_conf():
|
||||
return facility
|
||||
|
||||
|
||||
def _setup_logging_from_conf(product_name):
|
||||
log_root = getLogger(product_name).logger
|
||||
def _setup_logging_from_conf():
|
||||
log_root = getLogger(None).logger
|
||||
for handler in log_root.handlers:
|
||||
log_root.removeHandler(handler)
|
||||
|
||||
@ -401,7 +401,8 @@ def _setup_logging_from_conf(product_name):
|
||||
if CONF.log_format:
|
||||
handler.setFormatter(logging.Formatter(fmt=CONF.log_format,
|
||||
datefmt=datefmt))
|
||||
handler.setFormatter(LegacyFormatter(datefmt=datefmt))
|
||||
else:
|
||||
handler.setFormatter(LegacyFormatter(datefmt=datefmt))
|
||||
|
||||
if CONF.debug:
|
||||
log_root.setLevel(logging.DEBUG)
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2011 OpenStack LLC.
|
||||
# Copyright 2011 OpenStack Foundation.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2011 OpenStack LLC.
|
||||
# Copyright 2011 OpenStack Foundation.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2011 OpenStack LLC.
|
||||
# Copyright 2011 OpenStack Foundation.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2011 OpenStack LLC.
|
||||
# Copyright 2011 OpenStack Foundation.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2011 OpenStack LLC.
|
||||
# Copyright 2011 OpenStack Foundation.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2011 OpenStack LLC.
|
||||
# Copyright 2011 OpenStack Foundation.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2011 OpenStack LLC.
|
||||
# Copyright 2011 OpenStack Foundation.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
|
@ -1,6 +1,6 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2011 OpenStack LLC.
|
||||
# Copyright 2011 OpenStack Foundation.
|
||||
# Copyright 2012-2013 Hewlett-Packard Development Company, L.P.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
@ -149,7 +149,7 @@ def write_git_changelog():
|
||||
git_dir = _get_git_directory()
|
||||
if not os.getenv('SKIP_WRITE_GIT_CHANGELOG'):
|
||||
if git_dir:
|
||||
git_log_cmd = 'git --git-dir=%s log --stat' % git_dir
|
||||
git_log_cmd = 'git --git-dir=%s log' % git_dir
|
||||
changelog = _run_shell_command(git_log_cmd)
|
||||
mailmap = _parse_git_mailmap(git_dir)
|
||||
with open(new_changelog, "w") as changelog_file:
|
||||
@ -171,6 +171,14 @@ def generate_authors():
|
||||
" log --format='%aN <%aE>' | sort -u | "
|
||||
"egrep -v '" + jenkins_email + "'")
|
||||
changelog = _run_shell_command(git_log_cmd)
|
||||
signed_cmd = ("git log --git-dir=" + git_dir +
|
||||
" | grep -i Co-authored-by: | sort -u")
|
||||
signed_entries = _run_shell_command(signed_cmd)
|
||||
if signed_entries:
|
||||
new_entries = "\n".join(
|
||||
[signed.split(":", 1)[1].strip()
|
||||
for signed in signed_entries.split("\n") if signed])
|
||||
changelog = "\n".join((changelog, new_entries))
|
||||
mailmap = _parse_git_mailmap(git_dir)
|
||||
with open(new_authors, 'w') as new_authors_fh:
|
||||
new_authors_fh.write(canonicalize_emails(changelog, mailmap))
|
||||
|
@ -1,6 +1,6 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2011 OpenStack LLC.
|
||||
# Copyright 2011 OpenStack Foundation.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
@ -25,18 +25,22 @@ import datetime
|
||||
import iso8601
|
||||
|
||||
|
||||
TIME_FORMAT = "%Y-%m-%dT%H:%M:%S"
|
||||
PERFECT_TIME_FORMAT = "%Y-%m-%dT%H:%M:%S.%f"
|
||||
# ISO 8601 extended time format with microseconds
|
||||
_ISO8601_TIME_FORMAT_SUBSECOND = '%Y-%m-%dT%H:%M:%S.%f'
|
||||
_ISO8601_TIME_FORMAT = '%Y-%m-%dT%H:%M:%S'
|
||||
PERFECT_TIME_FORMAT = _ISO8601_TIME_FORMAT_SUBSECOND
|
||||
|
||||
|
||||
def isotime(at=None):
|
||||
def isotime(at=None, subsecond=False):
|
||||
"""Stringify time in ISO 8601 format"""
|
||||
if not at:
|
||||
at = utcnow()
|
||||
str = at.strftime(TIME_FORMAT)
|
||||
st = at.strftime(_ISO8601_TIME_FORMAT
|
||||
if not subsecond
|
||||
else _ISO8601_TIME_FORMAT_SUBSECOND)
|
||||
tz = at.tzinfo.tzname(None) if at.tzinfo else 'UTC'
|
||||
str += ('Z' if tz == 'UTC' else tz)
|
||||
return str
|
||||
st += ('Z' if tz == 'UTC' else tz)
|
||||
return st
|
||||
|
||||
|
||||
def parse_isotime(timestr):
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
# Copyright 2012 OpenStack LLC
|
||||
# Copyright 2012 OpenStack Foundation
|
||||
# Copyright 2012-2013 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
|
@ -1,6 +1,6 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2011 OpenStack LLC.
|
||||
# Copyright 2011 OpenStack Foundation.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
|
@ -14,17 +14,15 @@
|
||||
# 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"
|
||||
PREREQ_PKGS="upstart wget git make python-pip python-devel mysql-connector-python libxml2-devel libxslt-devel"
|
||||
SERVICE_SRV_NAME="murano-api"
|
||||
GIT_CLONE_DIR=`echo $SERVICE_CONTENT_DIRECTORY | sed -e "s/$SERVICE_SRV_NAME//"`
|
||||
ETC_CFG_DIR="/etc/$SERVICE_SRV_NAME"
|
||||
SERVICE_CONFIG_FILE_PATH="$ETC_CFG_DIR/murano-api.conf"
|
||||
|
||||
if [ -z "$SERVICE_EXEC_PATH" ];then
|
||||
SERVICE_EXEC_PATH="/usr/bin/murano-api"
|
||||
fi
|
||||
# Functions
|
||||
# Loger function
|
||||
log()
|
||||
@ -94,15 +92,32 @@ CLONE_FROM_GIT=$1
|
||||
|
||||
# Setupping...
|
||||
log "Running setup.py"
|
||||
MRN_CND_SPY=$GIT_CLONE_DIR/$SERVICE_SRV_NAME/setup.py
|
||||
log $MRN_CND_SPY
|
||||
#MRN_CND_SPY=$GIT_CLONE_DIR/$SERVICE_SRV_NAME/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:_____________________________________________________________"
|
||||
cd $GIT_CLONE_DIR/$SERVICE_SRV_NAME && $MRN_CND_SPY install
|
||||
if [ $? -ne 0 ]; then
|
||||
log "Install of \"$MRN_CND_SPY\" FAILS, exiting!!!"
|
||||
exit
|
||||
#cd $GIT_CLONE_DIR/$SERVICE_SRV_NAME && $MRN_CND_SPY install
|
||||
#if [ $? -ne 0 ]; then
|
||||
# log "\"$MRN_CND_SPY\" python setup FAILS, exiting!"
|
||||
# exit 1
|
||||
#fi
|
||||
## Setup through pip
|
||||
# Creating tarball
|
||||
#cd $GIT_CLONE_DIR/$SERVICE_SRV_NAME && $MRN_CND_SPY sdist
|
||||
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 $GIT_CLONE_DIR/$SERVICE_SRV_NAME/dist/*.tar.gz`)
|
||||
#pip install $GIT_CLONE_DIR/$SERVICE_SRV_NAME/dist/$TRBL_FILE
|
||||
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!"
|
||||
@ -118,22 +133,44 @@ CLONE_FROM_GIT=$1
|
||||
fi
|
||||
# making smaple configs
|
||||
log "Making sample configuration files at \"$ETC_CFG_DIR\""
|
||||
for file in `ls $GIT_CLONE_DIR/$SERVICE_SRV_NAME/etc`
|
||||
#for file in `ls $GIT_CLONE_DIR/$SERVICE_SRV_NAME/etc`
|
||||
for file in `ls $SERVICE_CONTENT_DIRECTORY/etc`
|
||||
do
|
||||
cp -f "$GIT_CLONE_DIR/$SERVICE_SRV_NAME/etc/$file" "$ETC_CFG_DIR/$file.sample"
|
||||
#cp -f "$GIT_CLONE_DIR/$SERVICE_SRV_NAME/etc/$file" "$ETC_CFG_DIR/$file.sample"
|
||||
cp -f "$SERVICE_CONTENT_DIRECTORY/etc/$file" "$ETC_CFG_DIR/$file.sample"
|
||||
done
|
||||
}
|
||||
|
||||
# searching for service executable in path
|
||||
get_service_exec_path()
|
||||
{
|
||||
if [ -z "$SERVICE_EXEC_PATH" ]; then
|
||||
SERVICE_EXEC_PATH=`which $SERVICE_SRV_NAME`
|
||||
if [ $? -ne 0 ]; then
|
||||
log "Can't find \"$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 \"$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
|
||||
echo "description \"$SERVICE_SRV_NAME service\"
|
||||
author \"Igor Yozhikov <iyozhikov@mirantis.com>\"
|
||||
start on runlevel [2345]
|
||||
stop on runlevel [!2345]
|
||||
respawn
|
||||
env PYTHONPATH=\$PYTHONPATH:$GIT_CLONE_DIR/$SERVICE_SRV_NAME
|
||||
export PYTHONPATH
|
||||
exec $SERVICE_EXEC_PATH --config-file=$SERVICE_CONFIG_FILE_PATH" > "/etc/init/$SERVICE_SRV_NAME.conf"
|
||||
log "Reloading initctl"
|
||||
initctl reload-configuration
|
||||
@ -151,8 +188,16 @@ purgeinit()
|
||||
# uninstall
|
||||
uninst()
|
||||
{
|
||||
rm -f $SERVICE_EXEC_PATH
|
||||
rm -rf $SERVICE_CONTENT_DIRECTORY
|
||||
# Uninstall trough pip
|
||||
# looking up for python package installed
|
||||
PYPKG=`echo $SERVICE_SRV_NAME | tr -d '-'`
|
||||
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
|
||||
}
|
||||
|
||||
# postinstall
|
||||
@ -164,12 +209,7 @@ postinst()
|
||||
COMMAND="$1"
|
||||
case $COMMAND in
|
||||
inject-init )
|
||||
# searching for daemon PATH
|
||||
if [ ! -x $SERVICE_EXEC_PATH ]; then
|
||||
log "Can't find \"$SERVICE_SRV_NAME\" in at \"$SERVICE_EXEC_PATH\", please install the \"$SERVICE_SRV_NAME\" or set variable SERVICE_EXEC_PATH=/path/to/daemon before running setup script, exiting!!!"
|
||||
exit
|
||||
fi
|
||||
ln -s /lib/init/upstart-job /etc/init.d/$SERVICE_SRV_NAME
|
||||
get_service_exec_path
|
||||
log "Injecting \"$SERVICE_SRV_NAME\" to init..."
|
||||
injectinit
|
||||
postinst
|
||||
@ -177,12 +217,14 @@ case $COMMAND in
|
||||
|
||||
install )
|
||||
inst
|
||||
get_service_exec_path
|
||||
injectinit
|
||||
postinst
|
||||
;;
|
||||
|
||||
installfromgit )
|
||||
inst "yes"
|
||||
get_service_exec_path
|
||||
injectinit
|
||||
postinst
|
||||
;;
|
||||
@ -201,7 +243,7 @@ case $COMMAND in
|
||||
;;
|
||||
|
||||
* )
|
||||
echo "Usage: $(basename "$0") install | installfromgit | uninstall | inject-init | purge-init"
|
||||
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
|
||||
|
91
setup.sh
91
setup.sh
@ -17,16 +17,12 @@
|
||||
|
||||
LOGLVL=1
|
||||
SERVICE_CONTENT_DIRECTORY=`cd $(dirname "$0") && pwd`
|
||||
PREREQ_PKGS="wget git python-pip python-dev python-mysqldb"
|
||||
PREREQ_PKGS="wget make git python-pip python-dev python-mysqldb libxml2-dev libxslt-dev"
|
||||
SERVICE_SRV_NAME="murano-api"
|
||||
GIT_CLONE_DIR=`echo $SERVICE_CONTENT_DIRECTORY | sed -e "s/$SERVICE_SRV_NAME//"`
|
||||
ETC_CFG_DIR="/etc/$SERVICE_SRV_NAME"
|
||||
SERVICE_CONFIG_FILE_PATH="$ETC_CFG_DIR/murano-api.conf"
|
||||
|
||||
|
||||
if [ -z "$SERVICE_EXEC_PATH" ];then
|
||||
SERVICE_EXEC_PATH="/usr/local/bin/murano-api"
|
||||
fi
|
||||
# Functions
|
||||
# Loger function
|
||||
log()
|
||||
@ -67,7 +63,6 @@ gitclone()
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# install
|
||||
inst()
|
||||
{
|
||||
@ -97,15 +92,32 @@ CLONE_FROM_GIT=$1
|
||||
|
||||
# Setupping...
|
||||
log "Running setup.py"
|
||||
MRN_CND_SPY=$GIT_CLONE_DIR/$SERVICE_SRV_NAME/setup.py
|
||||
log $MRN_CND_SPY
|
||||
if [ -e $MRN_CND_SPY ];then
|
||||
#MRN_CND_SPY=$GIT_CLONE_DIR/$SERVICE_SRV_NAME/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:_____________________________________________________________"
|
||||
cd $GIT_CLONE_DIR/$SERVICE_SRV_NAME && $MRN_CND_SPY install
|
||||
#cd $GIT_CLONE_DIR/$SERVICE_SRV_NAME && $MRN_CND_SPY install
|
||||
#if [ $? -ne 0 ]; then
|
||||
# log "\"$MRN_CND_SPY\" python setup FAILS, exiting!"
|
||||
# exit 1
|
||||
#fi
|
||||
## Setup through pip
|
||||
# Creating tarball
|
||||
#cd $GIT_CLONE_DIR/$SERVICE_SRV_NAME && $MRN_CND_SPY sdist
|
||||
cd $SERVICE_CONTENT_DIRECTORY && $MRN_CND_SPY sdist
|
||||
if [ $? -ne 0 ];then
|
||||
log "Install of \"$MRN_CND_SPY\" FAILS, exiting!!!"
|
||||
exit
|
||||
log "\"$MRN_CND_SPY\" tarball creation FAILS, exiting!!!"
|
||||
exit 1
|
||||
fi
|
||||
# Running tarball install
|
||||
#TRBL_FILE=$(basename `ls $GIT_CLONE_DIR/$SERVICE_SRV_NAME/dist/*.tar.gz`)
|
||||
#pip install $GIT_CLONE_DIR/$SERVICE_SRV_NAME/dist/$TRBL_FILE
|
||||
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!"
|
||||
@ -116,38 +128,57 @@ CLONE_FROM_GIT=$1
|
||||
mkdir -p $ETC_CFG_DIR
|
||||
if [ $? -ne 0 ];then
|
||||
log "Can't create $ETC_CFG_DIR, exiting!!!"
|
||||
exit
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
# making sample configs
|
||||
log "Making sample configuration files at \"$ETC_CFG_DIR\""
|
||||
for file in `ls $GIT_CLONE_DIR/$SERVICE_SRV_NAME/etc`
|
||||
#for file in `ls $GIT_CLONE_DIR/$SERVICE_SRV_NAME/etc`
|
||||
for file in `ls $SERVICE_CONTENT_DIRECTORY/etc`
|
||||
do
|
||||
cp -f "$GIT_CLONE_DIR/$SERVICE_SRV_NAME/etc/$file" "$ETC_CFG_DIR/$file.sample"
|
||||
#cp -f "$GIT_CLONE_DIR/$SERVICE_SRV_NAME/etc/$file" "$ETC_CFG_DIR/$file.sample"
|
||||
cp -f "$SERVICE_CONTENT_DIRECTORY/etc/$file" "$ETC_CFG_DIR/$file.sample"
|
||||
done
|
||||
}
|
||||
|
||||
# searching for service executable in path
|
||||
get_service_exec_path()
|
||||
{
|
||||
if [ -z "$SERVICE_EXEC_PATH" ]; then
|
||||
SERVICE_EXEC_PATH=`which $SERVICE_SRV_NAME`
|
||||
if [ $? -ne 0 ]; then
|
||||
log "Can't find \"$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 \"$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
|
||||
echo "description \"$SERVICE_SRV_NAME service\"
|
||||
author \"Igor Yozhikov <iyozhikov@mirantis.com>\"
|
||||
start on runlevel [2345]
|
||||
stop on runlevel [!2345]
|
||||
respawn
|
||||
env PYTHONPATH=\$PYTHONPATH:$GIT_CLONE_DIR/$SERVICE_SRV_NAME
|
||||
export PYTHONPATH
|
||||
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
|
||||
update-rc.d $SERVICE_SRV_NAME defaults
|
||||
}
|
||||
|
||||
# purge init
|
||||
purgeinit()
|
||||
{
|
||||
update-rc.d -f $SERVICE_SRV_NAME remove
|
||||
rm -f /etc/init.d/$SERVICE_SRV_NAME
|
||||
rm -f /etc/init/$SERVICE_SRV_NAME.conf
|
||||
log "Reloading initctl"
|
||||
@ -157,8 +188,16 @@ purgeinit()
|
||||
# uninstall
|
||||
uninst()
|
||||
{
|
||||
rm -f $SERVICE_EXEC_PATH
|
||||
rm -rf $SERVICE_CONTENT_DIRECTORY
|
||||
# Uninstall trough pip
|
||||
# looking up for python package installed
|
||||
PYPKG=`echo $SERVICE_SRV_NAME | tr -d '-'`
|
||||
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
|
||||
}
|
||||
|
||||
# postinstall
|
||||
@ -170,11 +209,7 @@ postinst()
|
||||
COMMAND="$1"
|
||||
case $COMMAND in
|
||||
inject-init )
|
||||
# searching for daemon PATH
|
||||
if [ ! -x $SERVICE_EXEC_PATH ]; then
|
||||
log "Can't find \"$SERVICE_SRV_NAME\" in at \"$SERVICE_EXEC_PATH\", please install the \"$SERVICE_SRV_NAME\" or set variable SERVICE_EXEC_PATH=/path/to/daemon before running setup script, exiting!!!"
|
||||
exit
|
||||
fi
|
||||
get_service_exec_path
|
||||
log "Injecting \"$SERVICE_SRV_NAME\" to init..."
|
||||
injectinit
|
||||
postinst
|
||||
@ -182,12 +217,14 @@ case $COMMAND in
|
||||
|
||||
install )
|
||||
inst
|
||||
get_service_exec_path
|
||||
injectinit
|
||||
postinst
|
||||
;;
|
||||
|
||||
installfromgit )
|
||||
inst "yes"
|
||||
get_service_exec_path
|
||||
injectinit
|
||||
postinst
|
||||
;;
|
||||
@ -206,7 +243,7 @@ case $COMMAND in
|
||||
;;
|
||||
|
||||
* )
|
||||
echo "Usage: $(basename "$0") install | installfromgit | uninstall | inject-init | purge-init"
|
||||
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
|
||||
|
@ -1,6 +1,6 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2013 OpenStack, LLC
|
||||
# Copyright 2013 OpenStack Foundation
|
||||
# Copyright 2013 IBM Corp.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
@ -185,7 +185,8 @@ class Fedora(Distro):
|
||||
self.run_command(['sudo', 'yum', 'install', '-y', pkg], **kwargs)
|
||||
|
||||
def apply_patch(self, originalfile, patchfile):
|
||||
self.run_command(['patch', originalfile, patchfile])
|
||||
self.run_command(['patch', '-N', originalfile, patchfile],
|
||||
check_exit_code=False)
|
||||
|
||||
def install_virtualenv(self):
|
||||
if self.check_cmd('virtualenv'):
|
||||
|
Loading…
x
Reference in New Issue
Block a user