python-tripleoclient/tripleoclient/heat_launcher.py
Steve Baker 01b5835a10 Improve undercloud deploy logging
This also does the uid/gid matching in python rather than piping a
docker run to grep.

Change-Id: I2bc364f71855f3c5a4021dfe86d2df6e45a9d197
2017-06-29 09:56:17 +12:00

201 lines
6.6 KiB
Python

# Copyright 2017 Red Hat, 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.
#
from __future__ import print_function
import logging
import os
import signal
import subprocess
import tempfile
log = logging.getLogger(__name__)
class HeatBaseLauncher(object):
# The init function will need permission to touch these files
# and chown them accordingly for the heat user
def __init__(self, api_port, ks_port, container_image, user='heat'):
self.api_port = api_port
self.ks_port = ks_port
self.policy_file = os.path.join(os.path.dirname(__file__),
'noauth_policy.json')
self.install_tmp = tempfile.mkdtemp(prefix='undercloud_deploy-')
self.container_image = container_image
self.user = user
self.sql_db = os.path.join(self.install_tmp, 'heat.sqlite')
self.log_file = os.path.join(self.install_tmp, 'heat.log')
self.config_file = os.path.join(self.install_tmp, 'heat.conf')
self._write_heat_config(self.config_file,
self.sql_db,
self.log_file,
api_port,
ks_port,
self.policy_file)
uid = int(self.get_heat_uid())
gid = int(self.get_heat_gid())
os.chown(self.install_tmp, uid, gid)
os.chown(self.config_file, uid, gid)
def _write_heat_config(self, config_file, sqlite_db, log_file, api_port,
ks_port, policy_file):
heat_config = '''
[DEFAULT]
log_file = %(log_file)s
rpc_backend = fake
rpc_poll_timeout = 60
rpc_response_timeout = 600
deferred_auth_method = password
num_engine_workers=1
convergence_engine = false
max_json_body_size = 8388608
default_deployment_signal_transport = HEAT_SIGNAL
max_nested_stack_depth = 6
[heat_all]
enabled_services = api,engine
[heat_api]
workers = 1
bind_host = 127.0.0.1
bind_port = %(api_port)s
[database]
connection = sqlite:///%(sqlite_db)s.db
[paste_deploy]
flavor = noauth
api_paste_config = /usr/share/heat/api-paste-dist.ini
[oslo_policy]
policy_file = %(policy_file)s
[clients_keystone]
auth_uri=http://127.0.0.1:%(ks_port)s
[keystone_authtoken]
auth_type = password
auth_url=http://127.0.0.1:%(ks_port)s
[yaql]
memory_quota=900000
limit_iterators=9000
''' % {'sqlite_db': sqlite_db, 'log_file': log_file,
'api_port': api_port, 'ks_port': ks_port,
'policy_file': policy_file}
with open(config_file, 'w') as temp_file:
temp_file.write(heat_config)
class HeatDockerLauncher(HeatBaseLauncher):
def __init__(self, api_port, ks_port, container_image, user='heat'):
super(HeatDockerLauncher, self).__init__(api_port, ks_port,
container_image, user)
def launch_heat(self):
cmd = [
'docker', 'run',
'--name', 'heat_all',
'--user', self.user,
'--net', 'host',
'--volume', '%(conf)s:/etc/heat/heat.conf' % {'conf':
self.config_file},
'--volume', '%(inst_tmp)s:%(inst_tmp)s:rw' % {'inst_tmp':
self.install_tmp},
'--volume', '%(pfile)s:%(pfile)s:ro' % {'pfile':
self.policy_file},
self.container_image, 'heat-all'
]
log.debug(' '.join(cmd))
subprocess.check_call(cmd)
def heat_db_sync(self):
cmd = [
'docker', 'run', '--rm',
'--user', self.user,
'--volume', '%(conf)s:/etc/heat/heat.conf' % {'conf':
self.config_file},
'--volume', '%(inst_tmp)s:%(inst_tmp)s:rw' % {'inst_tmp':
self.install_tmp},
self.container_image,
'heat-manage', 'db_sync']
log.debug(' '.join(cmd))
subprocess.check_call(cmd)
def get_heat_uid(self):
cmd = [
'docker', 'run', '--rm',
self.container_image,
'getent', 'passwd'
]
log.debug(' '.join(cmd))
p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
result = p.communicate()[0]
for line in result.split("\n"):
if line.startswith('%s:' % self.user):
return line.split(':')[2]
raise Exception('Could not find heat uid')
def get_heat_gid(self):
cmd = [
'docker', 'run', '--rm',
self.container_image,
'getent', 'group'
]
log.debug(' '.join(cmd))
p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
result = p.communicate()[0]
for line in result.split("\n"):
if line.startswith('%s:' % self.user):
return line.split(':')[2]
raise Exception('Could not find heat gid')
def kill_heat(self, pid):
cmd = ['docker', 'rm', '-f', 'heat_all']
log.debug(' '.join(cmd))
subprocess.check_call(cmd)
class HeatNativeLauncher(HeatBaseLauncher):
def __init__(self, api_port, ks_port, container_image, user='heat'):
super(HeatNativeLauncher, self).__init__(api_port, ks_port,
container_image, user)
def launch_heat(self):
os.execvp('heat-all', ['heat-all', '--config-file', self.config_file])
def heat_db_sync(self):
subprocess.check_call(['heat-manage', '--config-file',
self.config_file, 'db_sync'])
def get_heat_uid(self):
p = subprocess.Popen(["getent", "passwd", "|", "grep", "heat"],
stdout=subprocess.PIPE)
return p.communicate()[0].rstrip().split(':')[2]
def get_heat_gid(self):
p = subprocess.Popen(["getent", "group", "|", "grep", "heat"],
stdout=subprocess.PIPE)
return p.communicate()[0].rstrip().split(':')[2]
def kill_heat(self, pid):
os.kill(pid, signal.SIGKILL)