01b5835a10
This also does the uid/gid matching in python rather than piping a docker run to grep. Change-Id: I2bc364f71855f3c5a4021dfe86d2df6e45a9d197
201 lines
6.6 KiB
Python
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)
|