Cherry-pick the following commits from release-0.4
* Fix errors in infrastructure blueprinr 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 * Catch AttributeError in case of incorrect session_id Closes-Bug: 1269749 * Fixed issue with copy configuration files. Closes-Bug: #1271079 * Add translation support Use openstack.common.gettextutils for translation Closes-Bug: #1267514 * Fix name for syslog_log_facility param * Update requirements for a release-0.4.1 * Handle incorrect env_id Closes-Bug: 1227154 * Import _ not implicit Change-Id: I2744eaeef369220c5a8dabb027ba40622be9d155
This commit is contained in:
parent
ae02a99041
commit
968296bf7e
1
.gitignore
vendored
1
.gitignore
vendored
@ -14,7 +14,6 @@ dist/
|
|||||||
|
|
||||||
#Translation build
|
#Translation build
|
||||||
*.mo
|
*.mo
|
||||||
*.pot
|
|
||||||
|
|
||||||
#SQLite Database files
|
#SQLite Database files
|
||||||
*.sqlite
|
*.sqlite
|
||||||
|
@ -13,8 +13,8 @@ bind_port = 8082
|
|||||||
|
|
||||||
# Set up logging. Make sure the user has permissions to write to this file! To use syslog just set use_syslog parameter value to 'True'.
|
# Set up logging. Make sure the user has permissions to write to this file! To use syslog just set use_syslog parameter value to 'True'.
|
||||||
log_file = /tmp/murano-api.log
|
log_file = /tmp/murano-api.log
|
||||||
use_syslog=False
|
use_syslog = False
|
||||||
syslog-log-facility=LOG_LOCAL0
|
syslog_log_facility = LOG_LOCAL0
|
||||||
|
|
||||||
[database]
|
[database]
|
||||||
#A valid SQLAlchemy connection string for the metadata database
|
#A valid SQLAlchemy connection string for the metadata database
|
@ -12,8 +12,7 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import gettext
|
from muranoapi.openstack.common.gettextutils import _ # noqa
|
||||||
gettext.install('muranoapi', './muranoapi/locale', unicode=1)
|
|
||||||
|
|
||||||
from pbr import version
|
from pbr import version
|
||||||
__version_info = version.VersionInfo('murano-api')
|
__version_info = version.VersionInfo('murano-api')
|
||||||
|
@ -17,6 +17,7 @@ from muranoapi.openstack.common import wsgi
|
|||||||
from muranoapi.db.models import Deployment, Status, Environment
|
from muranoapi.db.models import Deployment, Status, Environment
|
||||||
from muranoapi.db.session import get_session
|
from muranoapi.db.session import get_session
|
||||||
from muranoapi.openstack.common import log as logging
|
from muranoapi.openstack.common import log as logging
|
||||||
|
from muranoapi.openstack.common.gettextutils import _ # noqa
|
||||||
from sqlalchemy import desc
|
from sqlalchemy import desc
|
||||||
from webob import exc
|
from webob import exc
|
||||||
|
|
||||||
@ -64,11 +65,11 @@ class Controller(object):
|
|||||||
def verify_and_get_env(db_session, environment_id, request):
|
def verify_and_get_env(db_session, environment_id, request):
|
||||||
environment = db_session.query(Environment).get(environment_id)
|
environment = db_session.query(Environment).get(environment_id)
|
||||||
if not environment:
|
if not environment:
|
||||||
log.info('Environment with id {0} not found'.format(environment_id))
|
log.info(_('Environment with id {0} not found'.format(environment_id)))
|
||||||
raise exc.HTTPNotFound
|
raise exc.HTTPNotFound
|
||||||
|
|
||||||
if environment.tenant_id != request.context.tenant:
|
if environment.tenant_id != request.context.tenant:
|
||||||
log.info('User is not authorized to access this tenant resources.')
|
log.info(_('User is not authorized to access this tenant resources.'))
|
||||||
raise exc.HTTPUnauthorized
|
raise exc.HTTPUnauthorized
|
||||||
return environment
|
return environment
|
||||||
|
|
||||||
@ -76,11 +77,12 @@ def verify_and_get_env(db_session, environment_id, request):
|
|||||||
def verify_and_get_deployment(db_session, environment_id, deployment_id):
|
def verify_and_get_deployment(db_session, environment_id, deployment_id):
|
||||||
deployment = db_session.query(Deployment).get(deployment_id)
|
deployment = db_session.query(Deployment).get(deployment_id)
|
||||||
if not deployment:
|
if not deployment:
|
||||||
log.info('Deployment with id {0} not found'.format(deployment_id))
|
log.info(_('Deployment with id {0} not found'.format(deployment_id)))
|
||||||
raise exc.HTTPNotFound
|
raise exc.HTTPNotFound
|
||||||
if deployment.environment_id != environment_id:
|
if deployment.environment_id != environment_id:
|
||||||
log.info('Deployment with id {0} not found'
|
log.info(_('Deployment with id {0} not found'
|
||||||
' in environment {1}'.format(deployment_id, environment_id))
|
' in environment {1}'.format(deployment_id,
|
||||||
|
environment_id)))
|
||||||
raise exc.HTTPBadRequest
|
raise exc.HTTPBadRequest
|
||||||
return deployment
|
return deployment
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ from muranoapi.db.services.core_services import CoreServices
|
|||||||
from muranoapi.db.services.environments import EnvironmentServices
|
from muranoapi.db.services.environments import EnvironmentServices
|
||||||
from muranoapi.openstack.common import wsgi
|
from muranoapi.openstack.common import wsgi
|
||||||
from muranoapi.openstack.common import log as logging
|
from muranoapi.openstack.common import log as logging
|
||||||
|
from muranoapi.openstack.common.gettextutils import _ # noqa
|
||||||
|
|
||||||
rabbitmq = config.CONF.rabbitmq
|
rabbitmq = config.CONF.rabbitmq
|
||||||
|
|
||||||
@ -59,7 +60,8 @@ class Controller(object):
|
|||||||
raise exc.HTTPNotFound
|
raise exc.HTTPNotFound
|
||||||
|
|
||||||
if environment.tenant_id != request.context.tenant:
|
if environment.tenant_id != request.context.tenant:
|
||||||
log.info('User is not authorized to access this tenant resources.')
|
log.info(_('User is not authorized to access '
|
||||||
|
'this tenant resources.'))
|
||||||
raise exc.HTTPUnauthorized
|
raise exc.HTTPUnauthorized
|
||||||
|
|
||||||
env = environment.to_dict()
|
env = environment.to_dict()
|
||||||
@ -83,12 +85,13 @@ class Controller(object):
|
|||||||
environment = session.query(Environment).get(environment_id)
|
environment = session.query(Environment).get(environment_id)
|
||||||
|
|
||||||
if environment is None:
|
if environment is None:
|
||||||
log.info('Environment <EnvId {0}> is not found'
|
log.info(_('Environment <EnvId {0}> is not '
|
||||||
.format(environment_id))
|
'found'.format(environment_id)))
|
||||||
raise exc.HTTPNotFound
|
raise exc.HTTPNotFound
|
||||||
|
|
||||||
if environment.tenant_id != request.context.tenant:
|
if environment.tenant_id != request.context.tenant:
|
||||||
log.info('User is not authorized to access this tenant resources.')
|
log.info(_('User is not authorized to access '
|
||||||
|
'this tenant resources.'))
|
||||||
raise exc.HTTPUnauthorized
|
raise exc.HTTPUnauthorized
|
||||||
|
|
||||||
environment.update(body)
|
environment.update(body)
|
||||||
@ -103,12 +106,13 @@ class Controller(object):
|
|||||||
environment = unit.query(Environment).get(environment_id)
|
environment = unit.query(Environment).get(environment_id)
|
||||||
|
|
||||||
if environment is None:
|
if environment is None:
|
||||||
log.info('Environment <EnvId {0}> is not found'
|
log.info(_('Environment <EnvId {0}> '
|
||||||
.format(environment_id))
|
'is not found'.format(environment_id)))
|
||||||
raise exc.HTTPNotFound
|
raise exc.HTTPNotFound
|
||||||
|
|
||||||
if environment.tenant_id != request.context.tenant:
|
if environment.tenant_id != request.context.tenant:
|
||||||
log.info('User is not authorized to access this tenant resources.')
|
log.info(_('User is not authorized to access '
|
||||||
|
'this tenant resources.'))
|
||||||
raise exc.HTTPUnauthorized
|
raise exc.HTTPUnauthorized
|
||||||
|
|
||||||
EnvironmentServices.delete(environment_id, request.context.auth_token)
|
EnvironmentServices.delete(environment_id, request.context.auth_token)
|
||||||
|
@ -19,6 +19,7 @@ from muranoapi import utils
|
|||||||
from muranoapi.db.services.core_services import CoreServices
|
from muranoapi.db.services.core_services import CoreServices
|
||||||
from muranoapi.openstack.common import wsgi
|
from muranoapi.openstack.common import wsgi
|
||||||
from muranoapi.openstack.common import log as logging
|
from muranoapi.openstack.common import log as logging
|
||||||
|
from muranoapi.openstack.common.gettextutils import _ # noqa
|
||||||
from muranocommon.helpers.token_sanitizer import TokenSanitizer
|
from muranocommon.helpers.token_sanitizer import TokenSanitizer
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@ -38,6 +39,7 @@ def normalize_path(f):
|
|||||||
|
|
||||||
|
|
||||||
class Controller(object):
|
class Controller(object):
|
||||||
|
@utils.verify_env
|
||||||
@normalize_path
|
@normalize_path
|
||||||
def get(self, request, environment_id, path):
|
def get(self, request, environment_id, path):
|
||||||
log.debug(_('Services:Get <EnvId: {0}, '
|
log.debug(_('Services:Get <EnvId: {0}, '
|
||||||
@ -49,11 +51,12 @@ class Controller(object):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
result = CoreServices.get_data(environment_id, path, session_id)
|
result = CoreServices.get_data(environment_id, path, session_id)
|
||||||
except (KeyError, ValueError):
|
except (KeyError, ValueError, AttributeError):
|
||||||
raise HTTPNotFound
|
raise HTTPNotFound
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@utils.verify_session
|
@utils.verify_session
|
||||||
|
@utils.verify_env
|
||||||
@normalize_path
|
@normalize_path
|
||||||
def post(self, request, environment_id, path, body):
|
def post(self, request, environment_id, path, body):
|
||||||
secure_data = TokenSanitizer().sanitize(body)
|
secure_data = TokenSanitizer().sanitize(body)
|
||||||
@ -69,6 +72,7 @@ class Controller(object):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
@utils.verify_session
|
@utils.verify_session
|
||||||
|
@utils.verify_env
|
||||||
@normalize_path
|
@normalize_path
|
||||||
def put(self, request, environment_id, path, body):
|
def put(self, request, environment_id, path, body):
|
||||||
log.debug(_('Services:Put <EnvId: {0}, Path: {2}, '
|
log.debug(_('Services:Put <EnvId: {0}, Path: {2}, '
|
||||||
@ -84,6 +88,7 @@ class Controller(object):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
@utils.verify_session
|
@utils.verify_session
|
||||||
|
@utils.verify_env
|
||||||
@normalize_path
|
@normalize_path
|
||||||
def delete(self, request, environment_id, path):
|
def delete(self, request, environment_id, path):
|
||||||
log.debug(_('Services:Put <EnvId: {0}, '
|
log.debug(_('Services:Put <EnvId: {0}, '
|
||||||
|
@ -21,6 +21,8 @@ from muranoapi.db.services.environments import EnvironmentServices
|
|||||||
from muranoapi.db.services.environments import EnvironmentStatus
|
from muranoapi.db.services.environments import EnvironmentStatus
|
||||||
from muranoapi.openstack.common import wsgi
|
from muranoapi.openstack.common import wsgi
|
||||||
from muranoapi.openstack.common import log as logging
|
from muranoapi.openstack.common import log as logging
|
||||||
|
from muranoapi.openstack.common.gettextutils import _ # noqa
|
||||||
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -33,20 +35,21 @@ class Controller(object):
|
|||||||
environment = unit.query(Environment).get(environment_id)
|
environment = unit.query(Environment).get(environment_id)
|
||||||
|
|
||||||
if environment is None:
|
if environment is None:
|
||||||
log.info('Environment <EnvId {0}> is not found'
|
log.info(_('Environment <EnvId {0}> '
|
||||||
.format(environment_id))
|
'is not found'.format(environment_id)))
|
||||||
raise exc.HTTPNotFound
|
raise exc.HTTPNotFound
|
||||||
|
|
||||||
if environment.tenant_id != request.context.tenant:
|
if environment.tenant_id != request.context.tenant:
|
||||||
log.info('User is not authorized to access this tenant resources.')
|
log.info(_('User is not authorized to access '
|
||||||
|
'this tenant resources.'))
|
||||||
raise exc.HTTPUnauthorized
|
raise exc.HTTPUnauthorized
|
||||||
|
|
||||||
# no new session can be opened if environment has deploying status
|
# no new session can be opened if environment has deploying status
|
||||||
env_status = EnvironmentServices.get_status(environment_id)
|
env_status = EnvironmentServices.get_status(environment_id)
|
||||||
if env_status == EnvironmentStatus.deploying:
|
if env_status == EnvironmentStatus.deploying:
|
||||||
log.info('Could not open session for environment <EnvId: {0}>,'
|
log.info(_('Could not open session for environment <EnvId: {0}>,'
|
||||||
'environment has deploying '
|
'environment has deploying '
|
||||||
'status.'.format(environment_id))
|
'status.'.format(environment_id)))
|
||||||
raise exc.HTTPForbidden()
|
raise exc.HTTPForbidden()
|
||||||
|
|
||||||
user_id = request.context.user
|
user_id = request.context.user
|
||||||
@ -61,23 +64,24 @@ class Controller(object):
|
|||||||
session = unit.query(Session).get(session_id)
|
session = unit.query(Session).get(session_id)
|
||||||
|
|
||||||
if session is None:
|
if session is None:
|
||||||
log.error('Session <SessionId {0}> is not found'
|
log.error(_('Session <SessionId {0}> '
|
||||||
''.format(session_id))
|
'is not found'.format(session_id)))
|
||||||
raise exc.HTTPNotFound()
|
raise exc.HTTPNotFound()
|
||||||
|
|
||||||
if session.environment_id != environment_id:
|
if session.environment_id != environment_id:
|
||||||
log.error('Session <SessionId {0}> is not tied with Environment '
|
log.error(_('Session <SessionId {0}> is not tied with Environment '
|
||||||
'<EnvId {1}>'.format(session_id, environment_id))
|
'<EnvId {1}>'.format(session_id, environment_id)))
|
||||||
raise exc.HTTPNotFound()
|
raise exc.HTTPNotFound()
|
||||||
|
|
||||||
user_id = request.context.user
|
user_id = request.context.user
|
||||||
if session.user_id != user_id:
|
if session.user_id != user_id:
|
||||||
log.error('User <UserId {0}> is not authorized to access '
|
log.error(_('User <UserId {0}> is not authorized to access session'
|
||||||
'session <SessionId {1}>.'.format(user_id, session_id))
|
'<SessionId {1}>.'.format(user_id, session_id)))
|
||||||
raise exc.HTTPUnauthorized()
|
raise exc.HTTPUnauthorized()
|
||||||
|
|
||||||
if not SessionServices.validate(session):
|
if not SessionServices.validate(session):
|
||||||
log.error('Session <SessionId {0}> is invalid'.format(session_id))
|
log.error(_('Session <SessionId {0}> '
|
||||||
|
'is invalid'.format(session_id)))
|
||||||
raise exc.HTTPForbidden()
|
raise exc.HTTPForbidden()
|
||||||
|
|
||||||
return session.to_dict()
|
return session.to_dict()
|
||||||
@ -89,24 +93,24 @@ class Controller(object):
|
|||||||
session = unit.query(Session).get(session_id)
|
session = unit.query(Session).get(session_id)
|
||||||
|
|
||||||
if session is None:
|
if session is None:
|
||||||
log.error('Session <SessionId {0}> is not found'
|
log.error(_('Session <SessionId {0}> '
|
||||||
''.format(session_id))
|
'is not found'.format(session_id)))
|
||||||
raise exc.HTTPNotFound()
|
raise exc.HTTPNotFound()
|
||||||
|
|
||||||
if session.environment_id != environment_id:
|
if session.environment_id != environment_id:
|
||||||
log.error('Session <SessionId {0}> is not tied with Environment '
|
log.error(_('Session <SessionId {0}> is not tied with Environment '
|
||||||
'<EnvId {1}>'.format(session_id, environment_id))
|
'<EnvId {1}>'.format(session_id, environment_id)))
|
||||||
raise exc.HTTPNotFound()
|
raise exc.HTTPNotFound()
|
||||||
|
|
||||||
user_id = request.context.user
|
user_id = request.context.user
|
||||||
if session.user_id != user_id:
|
if session.user_id != user_id:
|
||||||
log.error('User <UserId {0}> is not authorized to access '
|
log.error(_('User <UserId {0}> is not authorized to access session'
|
||||||
'session <SessionId {1}>.'.format(user_id, session_id))
|
'<SessionId {1}>.'.format(user_id, session_id)))
|
||||||
raise exc.HTTPUnauthorized()
|
raise exc.HTTPUnauthorized()
|
||||||
|
|
||||||
if session.state == SessionState.deploying:
|
if session.state == SessionState.deploying:
|
||||||
log.error('Session <SessionId: {0}> is in deploying state and '
|
log.error(_('Session <SessionId: {0}> is in deploying state and '
|
||||||
'could not be deleted'.format(session_id))
|
'could not be deleted'.format(session_id)))
|
||||||
raise exc.HTTPForbidden()
|
raise exc.HTTPForbidden()
|
||||||
|
|
||||||
with unit.begin():
|
with unit.begin():
|
||||||
@ -121,22 +125,23 @@ class Controller(object):
|
|||||||
session = unit.query(Session).get(session_id)
|
session = unit.query(Session).get(session_id)
|
||||||
|
|
||||||
if session is None:
|
if session is None:
|
||||||
log.error('Session <SessionId {0}> is not found'
|
log.error(_('Session <SessionId {0}> '
|
||||||
''.format(session_id))
|
'is not found'.format(session_id)))
|
||||||
raise exc.HTTPNotFound()
|
raise exc.HTTPNotFound()
|
||||||
|
|
||||||
if session.environment_id != environment_id:
|
if session.environment_id != environment_id:
|
||||||
log.error('Session <SessionId {0}> is not tied with Environment '
|
log.error(_('Session <SessionId {0}> is not tied with Environment '
|
||||||
'<EnvId {1}>'.format(session_id, environment_id))
|
'<EnvId {1}>'.format(session_id, environment_id)))
|
||||||
raise exc.HTTPNotFound()
|
raise exc.HTTPNotFound()
|
||||||
|
|
||||||
if not SessionServices.validate(session):
|
if not SessionServices.validate(session):
|
||||||
log.error('Session <SessionId {0}> is invalid'.format(session_id))
|
log.error(_('Session <SessionId {0}> '
|
||||||
|
'is invalid'.format(session_id)))
|
||||||
raise exc.HTTPForbidden()
|
raise exc.HTTPForbidden()
|
||||||
|
|
||||||
if session.state != SessionState.open:
|
if session.state != SessionState.open:
|
||||||
log.error('Session <SessionId {0}> is already deployed or '
|
log.error(_('Session <SessionId {0}> is already deployed or '
|
||||||
'deployment is in progress'.format(session_id))
|
'deployment is in progress'.format(session_id)))
|
||||||
raise exc.HTTPForbidden()
|
raise exc.HTTPForbidden()
|
||||||
|
|
||||||
SessionServices.deploy(session, unit, request.context.auth_token)
|
SessionServices.deploy(session, unit, request.context.auth_token)
|
||||||
|
@ -31,6 +31,7 @@ from paste import deploy
|
|||||||
|
|
||||||
from muranoapi.openstack.common import log
|
from muranoapi.openstack.common import log
|
||||||
from muranoapi import __version__ as version
|
from muranoapi import __version__ as version
|
||||||
|
from muranoapi.openstack.common.gettextutils import _ # noqa
|
||||||
|
|
||||||
paste_deploy_opts = [
|
paste_deploy_opts = [
|
||||||
cfg.StrOpt('flavor'),
|
cfg.StrOpt('flavor'),
|
||||||
@ -110,8 +111,8 @@ def setup_logging():
|
|||||||
logging.config.fileConfig(CONF.log_config)
|
logging.config.fileConfig(CONF.log_config)
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
raise RuntimeError("Unable to locate specified logging "
|
raise RuntimeError(_("Unable to locate specified logging "
|
||||||
"config file: %s" % CONF.log_config)
|
"config file: %s" % CONF.log_config))
|
||||||
|
|
||||||
root_logger = logging.root
|
root_logger = logging.root
|
||||||
if CONF.debug:
|
if CONF.debug:
|
||||||
@ -174,7 +175,7 @@ def _get_deployment_config_file():
|
|||||||
if not path:
|
if not path:
|
||||||
path = _get_paste_config_path()
|
path = _get_paste_config_path()
|
||||||
if not path:
|
if not path:
|
||||||
msg = "Unable to locate paste config file for %s." % CONF.prog
|
msg = _("Unable to locate paste config file for %s.") % CONF.prog
|
||||||
raise RuntimeError(msg)
|
raise RuntimeError(msg)
|
||||||
return os.path.abspath(path)
|
return os.path.abspath(path)
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ from muranoapi.common.utils import handle
|
|||||||
from muranoapi.db.models import Status, Session, Environment, Deployment
|
from muranoapi.db.models import Status, Session, Environment, Deployment
|
||||||
from muranoapi.db.session import get_session
|
from muranoapi.db.session import get_session
|
||||||
from muranoapi.openstack.common import log as logging, timeutils, service
|
from muranoapi.openstack.common import log as logging, timeutils, service
|
||||||
|
from muranoapi.openstack.common.gettextutils import _ # noqa
|
||||||
from muranoapi.common import config
|
from muranoapi.common import config
|
||||||
from muranocommon.helpers.token_sanitizer import TokenSanitizer
|
from muranocommon.helpers.token_sanitizer import TokenSanitizer
|
||||||
from muranocommon.messaging import MqClient
|
from muranocommon.messaging import MqClient
|
||||||
|
@ -19,6 +19,7 @@ import eventlet
|
|||||||
from jsonschema import validate
|
from jsonschema import validate
|
||||||
import types
|
import types
|
||||||
from muranoapi.openstack.common import log as logging
|
from muranoapi.openstack.common import log as logging
|
||||||
|
from muranoapi.openstack.common.gettextutils import _ # noqa
|
||||||
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@ -69,7 +70,7 @@ class TraverseHelper(object):
|
|||||||
elif isinstance(source, TraverseHelper.value_type):
|
elif isinstance(source, TraverseHelper.value_type):
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
raise ValueError('Source object or path is malformed')
|
raise ValueError(_('Source object or path is malformed'))
|
||||||
|
|
||||||
return source
|
return source
|
||||||
|
|
||||||
@ -134,7 +135,7 @@ class TraverseHelper(object):
|
|||||||
elif isinstance(node, types.DictionaryType):
|
elif isinstance(node, types.DictionaryType):
|
||||||
del node[key]
|
del node[key]
|
||||||
else:
|
else:
|
||||||
raise ValueError('Source object or path is malformed')
|
raise ValueError(_('Source object or path is malformed'))
|
||||||
|
|
||||||
|
|
||||||
def build_entity_map(value):
|
def build_entity_map(value):
|
||||||
@ -182,7 +183,7 @@ def retry(ExceptionToCheck, tries=4, delay=3, backoff=2):
|
|||||||
except ExceptionToCheck as e:
|
except ExceptionToCheck as e:
|
||||||
|
|
||||||
log.exception(e)
|
log.exception(e)
|
||||||
log.info("Retrying in {0} seconds...".format(mdelay))
|
log.info(_("Retrying in {0} seconds...".format(mdelay)))
|
||||||
|
|
||||||
eventlet.sleep(mdelay)
|
eventlet.sleep(mdelay)
|
||||||
|
|
||||||
|
@ -24,10 +24,11 @@ import os
|
|||||||
from migrate.versioning import api as versioning_api
|
from migrate.versioning import api as versioning_api
|
||||||
from migrate import exceptions as versioning_exceptions
|
from migrate import exceptions as versioning_exceptions
|
||||||
|
|
||||||
from muranoapi.openstack.common.db.sqlalchemy import session
|
|
||||||
from muranoapi.common.config import CONF as conf
|
from muranoapi.common.config import CONF as conf
|
||||||
from muranoapi.openstack.common import log as logging
|
|
||||||
from muranoapi.db import migrate_repo
|
from muranoapi.db import migrate_repo
|
||||||
|
from muranoapi.openstack.common.db.sqlalchemy import session
|
||||||
|
from muranoapi.openstack.common.gettextutils import _ # noqa
|
||||||
|
from muranoapi.openstack.common import log as logging
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
850
muranoapi/locale/muranoapi.pot
Normal file
850
muranoapi/locale/muranoapi.pot
Normal file
@ -0,0 +1,850 @@
|
|||||||
|
# Translations template for murano-api.
|
||||||
|
# Copyright (C) 2014 ORGANIZATION
|
||||||
|
# This file is distributed under the same license as the murano-api project.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
|
||||||
|
#
|
||||||
|
#, fuzzy
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: murano-api 0.4.1.dev1.gf4e754d\n"
|
||||||
|
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||||
|
"POT-Creation-Date: 2014-01-20 13:17+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"
|
||||||
|
|
||||||
|
#: muranoapi/api/v1/environments.py:33
|
||||||
|
msgid "Environments:List"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/api/v1/environments.py:43
|
||||||
|
msgid "Environments:Create <Body {0}>"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/api/v1/environments.py:51
|
||||||
|
msgid "Environments:Show <Id: {0}>"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/api/v1/environments.py:80
|
||||||
|
msgid "Environments:Update <Id: {0}, Body: {1}>"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/api/v1/environments.py:100
|
||||||
|
msgid "Environments:Delete <Id: {0}>"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/api/v1/services.py:44
|
||||||
|
msgid "Services:Get <EnvId: {0}, Path: {1}>"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/api/v1/services.py:61
|
||||||
|
msgid "Services:Post <EnvId: {0}, Path: {2}, Body: {1}>"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/api/v1/services.py:75
|
||||||
|
msgid "Services:Put <EnvId: {0}, Path: {2}, Body: {1}>"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/api/v1/services.py:90
|
||||||
|
msgid "Services:Put <EnvId: {0}, Path: {1}>"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/api/v1/sessions.py:30
|
||||||
|
msgid "Session:Configure <EnvId: {0}>"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/api/v1/sessions.py:58
|
||||||
|
msgid "Session:Show <SessionId: {0}>"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/api/v1/sessions.py:86
|
||||||
|
msgid "Session:Delete <SessionId: {0}>"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/api/v1/sessions.py:118
|
||||||
|
msgid "Session:Deploy <SessionId: {0}>"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/common/config.py:64
|
||||||
|
msgid "A boolean that determines if the database will be automatically created."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/common/config.py:131
|
||||||
|
msgid "Invalid syslog facility"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/common/config.py:205
|
||||||
|
#, python-format
|
||||||
|
msgid "Loading %(app_name)s from %(conf_file)s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/common/config.py:216
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"Unable to load %(app_name)s from configuration file %(conf_file)s.\n"
|
||||||
|
"Got: %(e)r"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/common/service.py:101
|
||||||
|
msgid ""
|
||||||
|
"Got result message from orchestration engine:\n"
|
||||||
|
"{0}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/common/service.py:105
|
||||||
|
msgid "Result for environment {0} is dropped. Environment is deleted"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/common/service.py:112
|
||||||
|
msgid ""
|
||||||
|
"Environment result could not be handled, specified environment does not "
|
||||||
|
"found in database"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/common/service.py:162
|
||||||
|
msgid ""
|
||||||
|
"Got report message from orchestration engine:\n"
|
||||||
|
"{0}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/db/session.py:38
|
||||||
|
msgid "auto-creating DB"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/db/session.py:41
|
||||||
|
msgid "not auto-creating DB"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/eventlet_backdoor.py:141
|
||||||
|
#, python-format
|
||||||
|
msgid "Eventlet backdoor listening on %(port)s for process %(pid)d"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/exception.py:103
|
||||||
|
msgid "Uncaught exception"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/excutils.py:62
|
||||||
|
#, python-format
|
||||||
|
msgid "Original exception being dropped: %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/excutils.py:90
|
||||||
|
#, python-format
|
||||||
|
msgid "Unexpected exception occurred %d time(s)... retrying."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/fileutils.py:64
|
||||||
|
#, python-format
|
||||||
|
msgid "Reloading cached file %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/lockutils.py:100
|
||||||
|
#, python-format
|
||||||
|
msgid "Could not release the acquired lock `%s`"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/lockutils.py:166
|
||||||
|
#, python-format
|
||||||
|
msgid "Got semaphore \"%(lock)s\""
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/lockutils.py:175
|
||||||
|
#, python-format
|
||||||
|
msgid "Attempting to grab file lock \"%(lock)s\""
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/lockutils.py:185
|
||||||
|
#, python-format
|
||||||
|
msgid "Created lock path: %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/lockutils.py:203
|
||||||
|
#, python-format
|
||||||
|
msgid "Got file lock \"%(lock)s\" at %(path)s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/lockutils.py:207
|
||||||
|
#, python-format
|
||||||
|
msgid "Released file lock \"%(lock)s\" at %(path)s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/lockutils.py:244
|
||||||
|
#, python-format
|
||||||
|
msgid "Got semaphore / lock \"%(function)s\""
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/lockutils.py:248
|
||||||
|
#, python-format
|
||||||
|
msgid "Semaphore / lock released \"%(function)s\""
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/log.py:244
|
||||||
|
#, python-format
|
||||||
|
msgid "Deprecated: %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/log.py:336
|
||||||
|
#, python-format
|
||||||
|
msgid "Error loading logging config %(log_config)s: %(err_msg)s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/log.py:386
|
||||||
|
#, python-format
|
||||||
|
msgid "syslog facility must be one of: %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/log.py:556
|
||||||
|
#, python-format
|
||||||
|
msgid "Fatal call to deprecated config: %(msg)s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/loopingcall.py:84
|
||||||
|
#, python-format
|
||||||
|
msgid "task run outlasted interval by %s sec"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/loopingcall.py:91
|
||||||
|
msgid "in fixed duration looping call"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/loopingcall.py:131
|
||||||
|
#, python-format
|
||||||
|
msgid "Dynamic looping call sleeping for %.02f seconds"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/loopingcall.py:138
|
||||||
|
msgid "in dynamic looping call"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/service.py:103
|
||||||
|
#: muranoapi/openstack/common/service.py:271
|
||||||
|
msgid "Full set of CONF:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/service.py:112
|
||||||
|
#: muranoapi/openstack/common/service.py:214
|
||||||
|
#, python-format
|
||||||
|
msgid "Caught %s, exiting"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/service.py:123
|
||||||
|
msgid "Exception during rpc cleanup."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/service.py:159
|
||||||
|
msgid "Parent process has died unexpectedly, exiting"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/service.py:196
|
||||||
|
msgid "Forking too fast, sleeping"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/service.py:219
|
||||||
|
msgid "Unhandled exception"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/service.py:226
|
||||||
|
#, python-format
|
||||||
|
msgid "Started child %d"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/service.py:236
|
||||||
|
#, python-format
|
||||||
|
msgid "Starting %d workers"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/service.py:253
|
||||||
|
#, python-format
|
||||||
|
msgid "Child %(pid)d killed by signal %(sig)d"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/service.py:257
|
||||||
|
#, python-format
|
||||||
|
msgid "Child %(pid)s exited with status %(code)d"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/service.py:261
|
||||||
|
#, python-format
|
||||||
|
msgid "pid %d not in child list"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/service.py:289
|
||||||
|
#, python-format
|
||||||
|
msgid "Caught %s, stopping children"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/service.py:300
|
||||||
|
#, python-format
|
||||||
|
msgid "Waiting on %d children to exit"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/sslutils.py:52
|
||||||
|
#, python-format
|
||||||
|
msgid "Unable to find cert_file : %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/sslutils.py:55
|
||||||
|
#, python-format
|
||||||
|
msgid "Unable to find ca_file : %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/sslutils.py:58
|
||||||
|
#, python-format
|
||||||
|
msgid "Unable to find key_file : %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/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 ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/sslutils.py:100
|
||||||
|
#, python-format
|
||||||
|
msgid "Invalid SSL version : %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/wsgi.py:110
|
||||||
|
#, python-format
|
||||||
|
msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/wsgi.py:372
|
||||||
|
msgid "Unsupported Content-Type"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/wsgi.py:375
|
||||||
|
msgid "Malformed request body"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/wsgi.py:660
|
||||||
|
msgid "Empty body provided in request"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/wsgi.py:666
|
||||||
|
msgid "Unrecognized Content-Type provided in request"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/wsgi.py:670
|
||||||
|
msgid "No Content-Type provided in request"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/wsgi.py:676
|
||||||
|
msgid "Unable to deserialize body as provided Content-Type"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/wsgi.py:726
|
||||||
|
msgid "cannot understand JSON"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/wsgi.py:750
|
||||||
|
msgid "cannot understand XML"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/db/exception.py:44
|
||||||
|
msgid "Invalid Parameter: Unicode is not supported by the current database."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/db/sqlalchemy/session.py:508
|
||||||
|
msgid "DB exception wrapped."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/db/sqlalchemy/session.py:570
|
||||||
|
#, python-format
|
||||||
|
msgid "Got mysql server has gone away: %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/db/sqlalchemy/session.py:650
|
||||||
|
#, python-format
|
||||||
|
msgid "SQL connection failed. %s attempts left."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/db/sqlalchemy/utils.py:49
|
||||||
|
msgid "Sort key supplied was not valid."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/db/sqlalchemy/utils.py:88
|
||||||
|
msgid "Id not in sort_keys; is sort_keys unique?"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/db/sqlalchemy/utils.py:110
|
||||||
|
msgid "Unknown sort direction, must be 'desc' or 'asc'"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/db/sqlalchemy/utils.py:181
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"Please specify column %s in col_name_col_instance param. It is required "
|
||||||
|
"because column has unsupported type by sqlite)."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/db/sqlalchemy/utils.py:187
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"col_name_col_instance param has wrong type of column instance for column "
|
||||||
|
"%s It should be instance of sqlalchemy.Column."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/db/sqlalchemy/utils.py:230
|
||||||
|
#, python-format
|
||||||
|
msgid "Deleting duplicated row with id: %(id)s from table: %(table)s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/db/sqlalchemy/utils.py:252
|
||||||
|
msgid "Unsupported id columns type"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/notifier/api.py:129
|
||||||
|
#, python-format
|
||||||
|
msgid "%s not in valid priorities"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/notifier/api.py:145
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"Problem '%(e)s' attempting to send to notification system. "
|
||||||
|
"Payload=%(payload)s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/notifier/api.py:164
|
||||||
|
#, python-format
|
||||||
|
msgid "Failed to load notifier %s. These notifications will not be sent."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/notifier/rpc_notifier.py:45
|
||||||
|
#: muranoapi/openstack/common/notifier/rpc_notifier2.py:51
|
||||||
|
#, python-format
|
||||||
|
msgid "Could not send notification to %(topic)s. Payload=%(message)s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/__init__.py:106
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"A RPC is being made while holding a lock. The locks currently held are "
|
||||||
|
"%(locks)s. This is probably a bug. Please report it. Include the "
|
||||||
|
"following: [%(stack)s]."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/amqp.py:75
|
||||||
|
msgid "Pool creating new connection"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/amqp.py:202
|
||||||
|
#, python-format
|
||||||
|
msgid "No calling threads waiting for msg_id : %(msg_id)s, message : %(data)s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/amqp.py:205
|
||||||
|
#, python-format
|
||||||
|
msgid "_call_waiters: %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/amqp.py:212
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"Number of call waiters is greater than warning threshhold: %d. There "
|
||||||
|
"could be a MulticallProxyWaiter leak."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/amqp.py:290
|
||||||
|
#, python-format
|
||||||
|
msgid "unpacked context: %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/amqp.py:336
|
||||||
|
#, python-format
|
||||||
|
msgid "UNIQUE_ID is %s."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/amqp.py:408
|
||||||
|
#, python-format
|
||||||
|
msgid "received %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/amqp.py:416
|
||||||
|
#, python-format
|
||||||
|
msgid "no method for message: %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/amqp.py:417
|
||||||
|
#, python-format
|
||||||
|
msgid "No method for message: %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/amqp.py:445
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:280
|
||||||
|
#, python-format
|
||||||
|
msgid "Expected exception during message handling (%s)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/amqp.py:453
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:286
|
||||||
|
msgid "Exception during message handling"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/amqp.py:527
|
||||||
|
#, python-format
|
||||||
|
msgid "Making synchronous call on %s ..."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/amqp.py:530
|
||||||
|
#, python-format
|
||||||
|
msgid "MSG_ID is %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/amqp.py:556
|
||||||
|
#, python-format
|
||||||
|
msgid "Making asynchronous cast on %s..."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/amqp.py:565
|
||||||
|
msgid "Making asynchronous fanout cast..."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/amqp.py:593
|
||||||
|
#, python-format
|
||||||
|
msgid "Sending %(event_type)s on %(topic)s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/common.py:77
|
||||||
|
msgid "An unknown RPC related exception occurred."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/common.py:89
|
||||||
|
msgid "Exception in string format operation"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/common.py:107
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"Remote error: %(exc_type)s %(value)s\n"
|
||||||
|
"%(traceback)s."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/common.py:124
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"Timeout while waiting on RPC response - topic: \"%(topic)s\", RPC method:"
|
||||||
|
" \"%(method)s\" info: \"%(info)s\""
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/common.py:141
|
||||||
|
#: muranoapi/openstack/common/rpc/common.py:142
|
||||||
|
#: muranoapi/openstack/common/rpc/common.py:143
|
||||||
|
msgid "<unknown>"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/common.py:147
|
||||||
|
#, python-format
|
||||||
|
msgid "Found duplicate message(%(msg_id)s). Skipping it."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/common.py:151
|
||||||
|
msgid "Invalid reuse of an RPC connection."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/common.py:155
|
||||||
|
#, python-format
|
||||||
|
msgid "Specified RPC version, %(version)s, not supported by this endpoint."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/common.py:160
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"Specified RPC envelope version, %(version)s, not supported by this "
|
||||||
|
"endpoint."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/common.py:165
|
||||||
|
#, python-format
|
||||||
|
msgid "Specified RPC version cap, %(version_cap)s, is too low"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/common.py:289
|
||||||
|
#, python-format
|
||||||
|
msgid "Returning exception %s to caller"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_kombu.py:162
|
||||||
|
msgid "Failed to process message ... skipping it."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_kombu.py:165
|
||||||
|
msgid "Failed to process message ... will requeue."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_kombu.py:506
|
||||||
|
#, python-format
|
||||||
|
msgid "Reconnecting to AMQP server on %(hostname)s:%(port)d"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_kombu.py:528
|
||||||
|
#, python-format
|
||||||
|
msgid "Connected to AMQP server on %(hostname)s:%(port)d"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_kombu.py:565
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"Unable to connect to AMQP server on %(hostname)s:%(port)d after "
|
||||||
|
"%(max_retries)d tries: %(err_str)s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_kombu.py:579
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"AMQP server on %(hostname)s:%(port)d is unreachable: %(err_str)s. Trying "
|
||||||
|
"again in %(sleep_time)d seconds."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_kombu.py:633
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_qpid.py:492
|
||||||
|
#, python-format
|
||||||
|
msgid "Failed to declare consumer for topic '%(topic)s': %(err_str)s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_kombu.py:651
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_qpid.py:507
|
||||||
|
#, python-format
|
||||||
|
msgid "Timed out waiting for RPC response: %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_kombu.py:655
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_qpid.py:511
|
||||||
|
#, python-format
|
||||||
|
msgid "Failed to consume message from queue: %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_kombu.py:694
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_qpid.py:546
|
||||||
|
#, python-format
|
||||||
|
msgid "Failed to publish message to topic '%(topic)s': %(err_str)s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_qpid.py:161
|
||||||
|
msgid "Failed to process message... skipping it."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_qpid.py:434
|
||||||
|
#, python-format
|
||||||
|
msgid "Unable to connect to AMQP server: %(e)s. Sleeping %(delay)s seconds"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_qpid.py:440
|
||||||
|
#, python-format
|
||||||
|
msgid "Connected to AMQP server on %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_qpid.py:453
|
||||||
|
msgid "Re-established AMQP queues"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_qpid.py:519
|
||||||
|
msgid "Error processing message. Skipping it."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:96
|
||||||
|
msgid "JSON serialization failed."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:101
|
||||||
|
#, python-format
|
||||||
|
msgid "Deserializing: %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:136
|
||||||
|
#, python-format
|
||||||
|
msgid "Connecting to %(addr)s with %(type)s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:137
|
||||||
|
#, python-format
|
||||||
|
msgid "-> Subscribed to %(subscribe)s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:138
|
||||||
|
#, python-format
|
||||||
|
msgid "-> bind: %(bind)s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:146
|
||||||
|
msgid "Could not open socket."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:158
|
||||||
|
#, python-format
|
||||||
|
msgid "Subscribing to %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:200
|
||||||
|
msgid "You cannot recv on this socket."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:205
|
||||||
|
msgid "You cannot send on this socket."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:267
|
||||||
|
#, python-format
|
||||||
|
msgid "Running func with context: %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:305
|
||||||
|
msgid "Sending reply"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:339
|
||||||
|
msgid "RPC message did not include method."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:371
|
||||||
|
msgid "Registering reactor"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:383
|
||||||
|
msgid "In reactor registered"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:387
|
||||||
|
msgid "Consuming socket"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:437
|
||||||
|
#, python-format
|
||||||
|
msgid "Creating proxy for topic: %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:443
|
||||||
|
msgid "Topic contained dangerous characters."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:475
|
||||||
|
msgid "Topic socket file creation failed."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:481
|
||||||
|
#, python-format
|
||||||
|
msgid "Local per-topic backlog buffer full for topic %(topic)s. Dropping message."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:497
|
||||||
|
#, python-format
|
||||||
|
msgid "Required IPC directory does not exist at %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:506
|
||||||
|
#, python-format
|
||||||
|
msgid "Permission denied to IPC directory at %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:509
|
||||||
|
msgid "Could not create ZeroMQ receiver daemon. Socket may already be in use."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:543
|
||||||
|
#, python-format
|
||||||
|
msgid "CONSUMER RECEIVED DATA: %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:562
|
||||||
|
msgid "ZMQ Envelope version unsupported or unknown."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:590
|
||||||
|
msgid "Skipping topic registration. Already registered."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:597
|
||||||
|
#, python-format
|
||||||
|
msgid "Consumer is a zmq.%s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:649
|
||||||
|
msgid "Creating payload"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:662
|
||||||
|
msgid "Creating queue socket for reply waiter"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:675
|
||||||
|
msgid "Sending cast"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:678
|
||||||
|
msgid "Cast sent; Waiting reply"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:681
|
||||||
|
#, python-format
|
||||||
|
msgid "Received message: %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:682
|
||||||
|
msgid "Unpacking response"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:691
|
||||||
|
msgid "Unsupported or unknown ZMQ envelope returned."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:698
|
||||||
|
msgid "RPC Message Invalid."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:721
|
||||||
|
#, python-format
|
||||||
|
msgid "%(msg)s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:724
|
||||||
|
#, python-format
|
||||||
|
msgid "Sending message(s) to: %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:728
|
||||||
|
msgid "No matchmaker results. Not casting."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:731
|
||||||
|
msgid "No match from matchmaker."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/impl_zmq.py:813
|
||||||
|
#, python-format
|
||||||
|
msgid "rpc_zmq_matchmaker = %(orig)s is deprecated; use %(new)s instead"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/matchmaker.py:47
|
||||||
|
msgid "Match not found by MatchMaker."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/matchmaker.py:81
|
||||||
|
msgid "Matchmaker does not implement registration or heartbeat."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/matchmaker.py:217
|
||||||
|
#, python-format
|
||||||
|
msgid "Matchmaker unregistered: %(key)s, %(host)s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/matchmaker.py:229
|
||||||
|
msgid "Register before starting heartbeat."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/matchmaker_ring.py:79
|
||||||
|
#: muranoapi/openstack/common/rpc/matchmaker_ring.py:97
|
||||||
|
#, python-format
|
||||||
|
msgid "No key defining hosts for topic '%s', see ringfile"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: muranoapi/openstack/common/rpc/service.py:49
|
||||||
|
#, python-format
|
||||||
|
msgid "Creating Consumer connection for Service %s"
|
||||||
|
msgstr ""
|
||||||
|
|
@ -16,17 +16,38 @@ import functools
|
|||||||
import logging
|
import logging
|
||||||
from muranoapi.db.services.sessions import SessionServices, SessionState
|
from muranoapi.db.services.sessions import SessionServices, SessionState
|
||||||
from webob import exc
|
from webob import exc
|
||||||
from muranoapi.db.models import Session
|
from muranoapi.db.models import Session, Environment
|
||||||
from muranoapi.db.session import get_session
|
from muranoapi.db.session import get_session
|
||||||
|
from muranoapi.openstack.common.gettextutils import _ # noqa
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def verify_env(func):
|
||||||
|
@functools.wraps(func)
|
||||||
|
def __inner(self, request, environment_id, *args, **kwargs):
|
||||||
|
unit = get_session()
|
||||||
|
environment = unit.query(Environment).get(environment_id)
|
||||||
|
if environment is None:
|
||||||
|
log.info(_("Environment with id '{0}'"
|
||||||
|
" not found".format(environment_id)))
|
||||||
|
raise exc.HTTPNotFound()
|
||||||
|
|
||||||
|
if hasattr(request, 'context'):
|
||||||
|
if environment.tenant_id != request.context.tenant:
|
||||||
|
log.info(_('User is not authorized to access'
|
||||||
|
' this tenant resources'))
|
||||||
|
raise exc.HTTPUnauthorized()
|
||||||
|
|
||||||
|
return func(self, request, environment_id, *args, **kwargs)
|
||||||
|
return __inner
|
||||||
|
|
||||||
|
|
||||||
def verify_session(func):
|
def verify_session(func):
|
||||||
@functools.wraps(func)
|
@functools.wraps(func)
|
||||||
def __inner(self, request, *args, **kwargs):
|
def __inner(self, request, *args, **kwargs):
|
||||||
if hasattr(request, 'context') and not request.context.session:
|
if hasattr(request, 'context') and not request.context.session:
|
||||||
log.info('Session is required for this call')
|
log.info(_('Session is required for this call'))
|
||||||
raise exc.HTTPForbidden()
|
raise exc.HTTPForbidden()
|
||||||
|
|
||||||
session_id = request.context.session
|
session_id = request.context.session
|
||||||
@ -35,16 +56,18 @@ def verify_session(func):
|
|||||||
session = unit.query(Session).get(session_id)
|
session = unit.query(Session).get(session_id)
|
||||||
|
|
||||||
if session is None:
|
if session is None:
|
||||||
log.info('Session <SessionId {0}> is not found'.format(session_id))
|
log.info(_('Session <SessionId {0}> '
|
||||||
|
'is not found'.format(session_id)))
|
||||||
raise exc.HTTPForbidden()
|
raise exc.HTTPForbidden()
|
||||||
|
|
||||||
if not SessionServices.validate(session):
|
if not SessionServices.validate(session):
|
||||||
log.info('Session <SessionId {0}> is invalid'.format(session_id))
|
log.info(_('Session <SessionId {0}> '
|
||||||
|
'is invalid'.format(session_id)))
|
||||||
raise exc.HTTPForbidden()
|
raise exc.HTTPForbidden()
|
||||||
|
|
||||||
if session.state == SessionState.deploying:
|
if session.state == SessionState.deploying:
|
||||||
log.info('Session <SessionId {0}> is already in '
|
log.info(_('Session <SessionId {0}> is already in '
|
||||||
'deployment state'.format(session_id))
|
'deployment state'.format(session_id)))
|
||||||
raise exc.HTTPForbidden()
|
raise exc.HTTPForbidden()
|
||||||
return func(self, request, *args, **kwargs)
|
return func(self, request, *args, **kwargs)
|
||||||
return __inner
|
return __inner
|
||||||
|
@ -30,4 +30,4 @@ passlib
|
|||||||
jsonschema>=1.3.0,!=1.4.0
|
jsonschema>=1.3.0,!=1.4.0
|
||||||
python-keystoneclient>=0.3.2
|
python-keystoneclient>=0.3.2
|
||||||
oslo.config>=1.2.0
|
oslo.config>=1.2.0
|
||||||
murano-common==0.4
|
murano-common==0.4.1
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
name = murano-api
|
name = murano-api
|
||||||
version = 0.4
|
version = 0.4.1
|
||||||
summary = Murano API
|
summary = Murano API
|
||||||
description-file =
|
description-file =
|
||||||
README.rst
|
README.rst
|
||||||
|
5
setup.sh
5
setup.sh
@ -141,11 +141,10 @@ CLONE_FROM_GIT=$1
|
|||||||
fi
|
fi
|
||||||
chmod -R a+rw $LOG_DIR
|
chmod -R a+rw $LOG_DIR
|
||||||
fi
|
fi
|
||||||
# making sample configs
|
log "Copy sample configuration files at \"$ETC_CFG_DIR\""
|
||||||
log "Making sample configuration files at \"$ETC_CFG_DIR\""
|
|
||||||
for file in $(ls $SERVICE_CONTENT_DIRECTORY/etc/murano)
|
for file in $(ls $SERVICE_CONTENT_DIRECTORY/etc/murano)
|
||||||
do
|
do
|
||||||
cp -f "$SERVICE_CONTENT_DIRECTORY/etc/murano/$file" "$ETC_CFG_DIR/$file.sample"
|
cp -f "$SERVICE_CONTENT_DIRECTORY/etc/murano/$file" "$ETC_CFG_DIR/$file"
|
||||||
done
|
done
|
||||||
log "Creating $DB_DIR"
|
log "Creating $DB_DIR"
|
||||||
if [ ! -d "$DB_DIR" ]; then
|
if [ ! -d "$DB_DIR" ]; then
|
||||||
|
Loading…
Reference in New Issue
Block a user