2 # Copyright 2011 OpenStack Foundation
5 # Licensed under the Apache License, Version 2.0 (the "License"); you may
6 # not use this file except in compliance with the License. You may obtain
7 # a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 # License for the specific language governing permissions and limitations
18 Routines for configuring Escalator
23 import logging.handlers
27 from oslo_concurrency import lockutils
28 from oslo_config import cfg
29 from oslo_policy import policy
30 from paste import deploy
32 from escalator import i18n
33 from escalator.version import version_info as version
39 help=_('Partial name of a pipeline in your paste configuration '
40 'file with the service name removed. For example, if '
41 'your paste section name is '
42 '[pipeline:escalator-api-keystone] use the value '
44 cfg.StrOpt('config_file',
45 help=_('Name of the paste configuration file.')),
48 cfg.IntOpt('task_time_to_live',
50 help=_("Time in hours for which a task lives after, either "
51 "succeeding or failing"),
52 deprecated_opts=[cfg.DeprecatedOpt('task_time_to_live',
54 cfg.StrOpt('task_executor',
56 help=_("Specifies which task executor to be used to run the "
58 cfg.StrOpt('work_dir',
60 help=_('Work dir for asynchronous task operations. '
61 'The directory set here will be used to operate over '
62 'images - normally before they are imported in the '
63 'destination store. When providing work dir, make sure '
64 'enough space is provided for concurrent tasks to run '
65 'efficiently without running out of space. A rough '
66 'estimation can be done by multiplying the number of '
67 '`max_workers` - or the N of workers running - by an '
68 'average image size (e.g 500MB). The image size '
69 'estimation should be done based on the average size in '
70 'your deployment. Note that depending on the tasks '
71 'running you may need to multiply this number by some '
72 'factor depending on what the task does. For example, '
73 'you may want to double the available size if image '
74 'conversion is enabled. All this being said, remember '
75 'these are just estimations and you should do them '
76 'based on the worst case scenario and be prepared to '
77 'act in case they were wrong.')),
80 cfg.IntOpt('limit_param_default', default=25,
81 help=_('Default value for the number of items returned by a '
82 'request if not specified explicitly in the request')),
83 cfg.IntOpt('api_limit_max', default=1000,
84 help=_('Maximum permissible number of items that could be '
85 'returned by a request')),
86 cfg.BoolOpt('enable_v1_api', default=True,
87 help=_("Deploy the v1 OPNFV Escalator API.")),
88 cfg.BoolOpt('enable_v2_api', default=True,
89 help=_("Deploy the v2 OpenStack Images API.")),
90 cfg.StrOpt('pydev_worker_debug_host',
91 help=_('The hostname/IP of the pydev process listening for '
92 'debug connections')),
93 cfg.IntOpt('pydev_worker_debug_port', default=5678,
94 help=_('The port on which a pydev process is listening for '
96 cfg.StrOpt('digest_algorithm', default='sha1',
97 help=_('Digest algorithm which will be used for digital '
98 'signature; the default is sha1 the default in Kilo '
99 'for a smooth upgrade process, and it will be updated '
100 'with sha256 in next release(L). Use the command '
101 '"openssl list-message-digest-algorithms" to get the '
102 'available algorithms supported by the version of '
103 'OpenSSL on the platform. Examples are "sha1", '
104 '"sha256", "sha512", etc.')),
108 CONF.register_opts(paste_deploy_opts, group='paste_deploy')
109 CONF.register_opts(task_opts, group='task')
110 CONF.register_opts(common_opts)
111 policy.Enforcer(CONF)
114 def parse_args(args=None, usage=None, default_config_files=None):
115 if "OSLO_LOCK_PATH" not in os.environ:
116 lockutils.set_defaults(tempfile.gettempdir())
120 version=version.cached_version_string(),
122 default_config_files=default_config_files)
125 def _get_deployment_flavor(flavor=None):
127 Retrieve the paste_deploy.flavor config item, formatted appropriately
128 for appending to the application name.
130 :param flavor: if specified, use this setting rather than the
131 paste_deploy.flavor configuration setting
134 flavor = CONF.paste_deploy.flavor
135 return '' if not flavor else ('-' + flavor)
138 def _get_paste_config_path():
139 paste_suffix = '-paste.ini'
140 conf_suffix = '.conf'
142 # Assume paste config is in a paste.ini file corresponding
143 # to the last config file
144 path = CONF.config_file[-1].replace(conf_suffix, paste_suffix)
146 path = CONF.prog + paste_suffix
147 return CONF.find_file(os.path.basename(path))
150 def _get_deployment_config_file():
152 Retrieve the deployment_config_file config item, formatted as an
155 path = CONF.paste_deploy.config_file
157 path = _get_paste_config_path()
159 msg = _("Unable to locate paste config file for %s.") % CONF.prog
160 raise RuntimeError(msg)
161 return os.path.abspath(path)
164 def load_paste_app(app_name, flavor=None, conf_file=None):
166 Builds and returns a WSGI app from a paste config file.
168 We assume the last config file specified in the supplied ConfigOpts
169 object is the paste config file, if conf_file is None.
171 :param app_name: name of the application to load
172 :param flavor: name of the variant of the application to load
173 :param conf_file: path to the paste config file
175 :raises RuntimeError when config file cannot be located or application
176 cannot be loaded from config file
178 # append the deployment flavor to the application name,
179 # in order to identify the appropriate paste pipeline
180 app_name += _get_deployment_flavor(flavor)
183 conf_file = _get_deployment_config_file()
186 logger = logging.getLogger(__name__)
187 logger.debug("Loading %(app_name)s from %(conf_file)s",
188 {'conf_file': conf_file, 'app_name': app_name})
190 app = deploy.loadapp("config:%s" % conf_file, name=app_name)
192 # Log the options used when starting if we're in debug mode...
194 CONF.log_opt_values(logger, logging.DEBUG)
197 except (LookupError, ImportError) as e:
198 msg = (_("Unable to load %(app_name)s from "
199 "configuration file %(conf_file)s."
200 "\nGot: %(e)r") % {'app_name': app_name,
201 'conf_file': conf_file,
204 raise RuntimeError(msg)