heat-all: all-in-one heat launcher

This patch implements a new heat-all command that can be used
to launch a single process version of the configured heat services.
The end user can control which services are launched by setting
'enabled_services' in the heat config file:

[heat_all]
  enabled_services = api,engine

One use case for this launcher would be to launch a single process heat
using rpc_backend = fake, connection=sqlite://heat.db, to have access
to a minimal all in one Heat API/Engine for TripleO undercloud
deployments via Heat templates.

Change-Id: Ic35bdc455fe1397ac575522af0c8fca96dd95676
This commit is contained in:
Dan Prince 2016-07-26 13:55:20 -04:00
parent 0a2e21b40f
commit 1486289a75
6 changed files with 174 additions and 54 deletions

91
heat/cmd/all.py Normal file
View File

@ -0,0 +1,91 @@
#!/usr/bin/env python
#
# 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.
"""Heat All Server.
An OpenStack Heat server that can run all services.
"""
import eventlet
eventlet.monkey_patch(os=False)
import six
import sys
from heat.cmd import api
from heat.cmd import api_cfn
from heat.cmd import api_cloudwatch
from heat.cmd import engine
from heat.common import config
from heat.common import messaging
from heat import version
from oslo_config import cfg
import oslo_i18n as i18n
from oslo_log import log as logging
from oslo_service import systemd
i18n.enable_lazy()
LOG = logging.getLogger('heat.all')
API_LAUNCH_OPTS = {'setup_logging': False}
LAUNCH_SERVICES = {
'engine': [engine.launch_engine, {'setup_logging': False}],
'api': [api.launch_api, API_LAUNCH_OPTS],
'api_cfn': [api_cfn.launch_cfn_api, API_LAUNCH_OPTS],
'api_cloudwatch': [api_cloudwatch.launch_cloudwatch_api, API_LAUNCH_OPTS],
}
services_opt = cfg.ListOpt(
'enabled_services',
default=['engine', 'api', 'api_cfn'],
help='Specifies the heat services that are enabled when running heat-all. '
'Valid options are all or any combination of '
'api, engine, api_cfn, or api_cloudwatch.'
)
cfg.CONF.register_opt(services_opt, group='heat_all')
def _start_service_threads(services):
threads = []
for option in services:
launch_func = LAUNCH_SERVICES[option][0]
kwargs = LAUNCH_SERVICES[option][1]
threads.append(eventlet.spawn(launch_func, **kwargs))
return threads
def launch_all(setup_logging=True):
if setup_logging:
logging.register_options(cfg.CONF)
cfg.CONF(project='heat', prog='heat-all',
version=version.version_info.version_string())
if setup_logging:
logging.setup(cfg.CONF, 'heat-all')
config.set_config_defaults()
messaging.setup()
return _start_service_threads(set(cfg.CONF.heat_all.enabled_services))
def main():
try:
threads = launch_all()
services = [thread.wait() for thread in threads]
systemd.notify_once()
[service.wait() for service in services]
except RuntimeError as e:
msg = six.text_type(e)
sys.exit("ERROR: %s" % msg)

View File

@ -41,11 +41,12 @@ i18n.enable_lazy()
LOG = logging.getLogger('heat.api')
def main():
try:
def launch_api(setup_logging=True):
if setup_logging:
logging.register_options(cfg.CONF)
cfg.CONF(project='heat', prog='heat-api',
version=version.version_info.version_string())
if setup_logging:
logging.setup(cfg.CONF, 'heat-api')
config.set_config_defaults()
messaging.setup()
@ -60,6 +61,12 @@ def main():
gmr.TextGuruMeditation.setup_autorun(version)
server = wsgi.Server('heat-api', cfg.CONF.heat_api)
server.start(app, default_port=port)
return server
def main():
try:
server = launch_api()
systemd.notify_once()
server.wait()
except RuntimeError as e:

View File

@ -43,12 +43,13 @@ i18n.enable_lazy()
LOG = logging.getLogger('heat.api.cfn')
def main():
try:
def launch_cfn_api(setup_logging=True):
if setup_logging:
logging.register_options(cfg.CONF)
cfg.CONF(project='heat',
prog='heat-api-cfn',
version=version.version_info.version_string())
if setup_logging:
logging.setup(cfg.CONF, 'heat-api-cfn')
logging.set_defaults()
config.set_config_defaults()
@ -64,6 +65,12 @@ def main():
gmr.TextGuruMeditation.setup_autorun(version)
server = wsgi.Server('heat-api-cfn', cfg.CONF.heat_api_cfn)
server.start(app, default_port=port)
return server
def main():
try:
server = launch_cfn_api()
systemd.notify_once()
server.wait()
except RuntimeError as e:

View File

@ -43,12 +43,13 @@ i18n.enable_lazy()
LOG = logging.getLogger('heat.api.cloudwatch')
def main():
try:
def launch_cloudwatch_api(setup_logging=True):
if setup_logging:
logging.register_options(cfg.CONF)
cfg.CONF(project='heat',
prog='heat-api-cloudwatch',
version=version.version_info.version_string())
if setup_logging:
logging.setup(cfg.CONF, 'heat-api-cloudwatch')
logging.set_defaults()
config.set_config_defaults()
@ -65,6 +66,12 @@ def main():
server = wsgi.Server('heat-api-cloudwatch',
cfg.CONF.heat_api_cloudwatch)
server.start(app, default_port=port)
return server
def main():
try:
server = launch_cloudwatch_api()
systemd.notify_once()
server.wait()
except RuntimeError as e:

View File

@ -44,10 +44,12 @@ i18n.enable_lazy()
LOG = logging.getLogger('heat.engine')
def main():
def launch_engine(setup_logging=True):
if setup_logging:
logging.register_options(cfg.CONF)
cfg.CONF(project='heat', prog='heat-engine',
version=version.version_info.version_string())
if setup_logging:
logging.setup(cfg.CONF, 'heat-engine')
logging.set_defaults()
messaging.setup()
@ -76,4 +78,9 @@ def main():
# We create the periodic tasks here, which mean they are created
# only in the parent process when num_engine_workers>1 is specified
srv.create_periodic_tasks()
return launcher
def main():
launcher = launch_engine()
launcher.wait()

View File

@ -30,6 +30,7 @@ scripts =
[entry_points]
console_scripts =
heat-all = heat.cmd.all:main
heat-api = heat.cmd.api:main
heat-api-cfn = heat.cmd.api_cfn:main
heat-api-cloudwatch = heat.cmd.api_cloudwatch:main