645 lines
27 KiB
Python
Executable File
645 lines
27 KiB
Python
Executable File
# Copyright 2013 OpenStack Foundation
|
|
# All Rights Reserved.
|
|
#
|
|
# 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.
|
|
|
|
"""
|
|
/install endpoint for kolla API
|
|
"""
|
|
import subprocess
|
|
import time
|
|
from oslo_log import log as logging
|
|
from threading import Thread
|
|
import threading
|
|
from daisy import i18n
|
|
import daisy.api.v1
|
|
from daisy.common import exception
|
|
from daisy.common import utils
|
|
import daisy.api.backends.common as daisy_cmn
|
|
import daisy.api.backends.kolla.common as kolla_cmn
|
|
import daisy.api.common as api_cmn
|
|
import daisy.registry.client.v1.api as registry
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
_ = i18n._
|
|
_LE = i18n._LE
|
|
_LI = i18n._LI
|
|
_LW = i18n._LW
|
|
SUPPORTED_PARAMS = daisy.api.v1.SUPPORTED_PARAMS
|
|
SUPPORTED_FILTERS = daisy.api.v1.SUPPORTED_FILTERS
|
|
ACTIVE_IMMUTABLE = daisy.api.v1.ACTIVE_IMMUTABLE
|
|
|
|
|
|
host_os_status = {
|
|
'INIT': 'init',
|
|
'INSTALLING': 'installing',
|
|
'ACTIVE': 'active',
|
|
'FAILED': 'install-failed'
|
|
}
|
|
|
|
kolla_state = kolla_cmn.KOLLA_STATE
|
|
daisy_kolla_path = kolla_cmn.daisy_kolla_path
|
|
install_kolla_progress = 0.0
|
|
install_mutex = threading.Lock()
|
|
daisy_kolla_ver_path = kolla_cmn.daisy_kolla_ver_path
|
|
thread_flag = {}
|
|
|
|
|
|
def update_progress_to_db(req, role_id_list,
|
|
status, progress=0.0):
|
|
"""
|
|
Write install progress and status to db, we use global lock object
|
|
'install_mutex' to make sure this function is thread safety.
|
|
:param req: http req.
|
|
:param role_id_list: Column neeb be update in role table.
|
|
:param status: install status.
|
|
:return:
|
|
"""
|
|
|
|
global install_mutex
|
|
install_mutex.acquire(True)
|
|
role = {}
|
|
for role_id in role_id_list:
|
|
role['status'] = status
|
|
role['progress'] = progress
|
|
daisy_cmn.update_role(req, role_id, role)
|
|
install_mutex.release()
|
|
|
|
|
|
def update_host_progress_to_db(req, role_id_list, host,
|
|
status, message, progress=0.0):
|
|
for role_id in role_id_list:
|
|
role_hosts = daisy_cmn.get_hosts_of_role(req, role_id)
|
|
for role_host in role_hosts:
|
|
if role_host['host_id'] == host['id']:
|
|
role_host['status'] = status
|
|
role_host['progress'] = progress
|
|
role_host['messages'] = message
|
|
daisy_cmn.update_role_host(req, role_host['id'], role_host)
|
|
|
|
|
|
def update_all_host_progress_to_db(req, role_id_list, host_id_list,
|
|
status, message, progress=0.0):
|
|
for host_id in host_id_list:
|
|
for role_id in role_id_list:
|
|
role_hosts = daisy_cmn.get_hosts_of_role(req, role_id)
|
|
for role_host in role_hosts:
|
|
if role_host['host_id'] == host_id:
|
|
role_host['status'] = status
|
|
role_host['progress'] = progress
|
|
role_host['messages'] = message
|
|
daisy_cmn.update_role_host(req, role_host['id'], role_host)
|
|
|
|
|
|
def _ping_hosts_test(ips):
|
|
ping_cmd = 'fping'
|
|
for ip in set(ips):
|
|
ping_cmd = ping_cmd + ' ' + ip
|
|
obj = subprocess.Popen(ping_cmd, shell=True,
|
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
(stdoutput, erroutput) = obj.communicate()
|
|
_returncode = obj.returncode
|
|
if _returncode == 0 or _returncode == 1:
|
|
ping_result = stdoutput.split('\n')
|
|
unreachable_hosts = [result.split()[0] for
|
|
result in ping_result if
|
|
result and result.split()[2] != 'alive']
|
|
else:
|
|
msg = "ping failed beaceuse there is invlid ip in %s", ips
|
|
raise exception.InvalidIP(msg)
|
|
return unreachable_hosts
|
|
|
|
|
|
def _check_ping_hosts(ping_ips, max_ping_times):
|
|
if not ping_ips:
|
|
LOG.info(_("no ip got for ping test"))
|
|
return ping_ips
|
|
ping_count = 0
|
|
time_step = 5
|
|
LOG.info(_("begin ping test for %s"), ','.join(ping_ips))
|
|
while True:
|
|
if ping_count == 0:
|
|
ips = _ping_hosts_test(ping_ips)
|
|
else:
|
|
ips = _ping_hosts_test(ips)
|
|
ping_count += 1
|
|
if ips:
|
|
LOG.debug(_("ping host %s for %s times"
|
|
% (','.join(ips), ping_count)))
|
|
if ping_count >= max_ping_times:
|
|
LOG.info(_("ping host %s timeout for %ss"
|
|
% (','.join(ips), ping_count*time_step)))
|
|
return ips
|
|
time.sleep(time_step)
|
|
else:
|
|
LOG.info(_("ping host %s success"), ','.join(ping_ips))
|
|
time.sleep(120)
|
|
LOG.info(_("120s after ping host %s success"), ','.join(ping_ips))
|
|
return ips
|
|
|
|
|
|
def config_nodes_hosts(host_name_ip_list, host_ip):
|
|
config_scripts = []
|
|
hosts_file = "/etc/hosts"
|
|
for name_ip in host_name_ip_list:
|
|
config_scripts.append("linenumber=`grep -n '%s$' %s | "
|
|
"awk -F ':' '{print $1}'` && "
|
|
"[ ! -z $linenumber ] && "
|
|
"sed -i ${linenumber}d %s" %
|
|
(name_ip.keys()[0],
|
|
hosts_file, hosts_file))
|
|
config_scripts.append("echo '%s %s' >> %s" % (name_ip.values()[0],
|
|
name_ip.keys()[0],
|
|
hosts_file))
|
|
kolla_cmn.run_scrip(config_scripts, host_ip, "ossdbg1",
|
|
msg='Failed to config /etc/hosts on %s' % host_ip)
|
|
|
|
|
|
def _calc_progress(log_file):
|
|
progress = 30
|
|
mariadb_result = subprocess.call(
|
|
'cat %s |grep "Running MariaDB"' % log_file,
|
|
shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
if mariadb_result == 0:
|
|
progress = 35
|
|
rabbitmq_result = subprocess.call(
|
|
'cat %s |grep "Running RabbitMQ"' % log_file,
|
|
shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
if rabbitmq_result == 0:
|
|
progress = 40
|
|
keystone_result = subprocess.call(
|
|
'cat %s |grep "Running Keystone"' % log_file,
|
|
shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
if keystone_result == 0:
|
|
progress = 45
|
|
glance_result = subprocess.call(
|
|
'cat %s |grep "Running Glance"' % log_file,
|
|
shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
if glance_result == 0:
|
|
progress = 50
|
|
cinder_result = subprocess.call(
|
|
'cat %s |grep "Running Cinder"' % log_file,
|
|
shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
if cinder_result == 0:
|
|
progress = 55
|
|
nova_bootstrap_result = subprocess.call(
|
|
'cat %s |grep "Running Nova bootstrap"' % log_file,
|
|
shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
if nova_bootstrap_result == 0:
|
|
progress = 60
|
|
nova_simple_result = subprocess.call(
|
|
'cat %s |grep "Running nova simple"' % log_file, shell=True,
|
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
if nova_simple_result == 0:
|
|
progress = 65
|
|
netron_bootstrap_result = subprocess.call(
|
|
'cat %s |grep "Running Neutron bootstrap"' % log_file, shell=True,
|
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
if netron_bootstrap_result == 0:
|
|
progress = 70
|
|
neutron_lbaas_result = subprocess.call(
|
|
'cat %s |grep "Running Neutron lbaas"' % log_file, shell=True,
|
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
if neutron_lbaas_result == 0:
|
|
progress = 75
|
|
neutron_vpnaas_result = subprocess.call(
|
|
'cat %s |grep "Running Neutron vpnaas"' % log_file, shell=True,
|
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
if neutron_vpnaas_result == 0:
|
|
progress = 80
|
|
heat_result = subprocess.call(
|
|
'cat %s |grep "Running Heat"' % log_file, shell=True,
|
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
if heat_result == 0:
|
|
progress = 85
|
|
horizon_result = subprocess.call(
|
|
'cat %s |grep "Restart horizon"' % log_file, shell=True,
|
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
if horizon_result == 0:
|
|
progress = 90
|
|
return progress
|
|
|
|
|
|
def _get_hosts_id_by_mgnt_ips(req, cluster_id, ips):
|
|
params = {'cluster_id': cluster_id}
|
|
hosts = registry.get_hosts_detail(req.context, **params)
|
|
hosts_needed = []
|
|
for host in hosts:
|
|
host_info = registry.get_host_metadata(req.context,
|
|
host['id'])
|
|
for interface in host_info['interfaces']:
|
|
if interface.get('assigned_networks', None):
|
|
assigned_networks = interface['assigned_networks']
|
|
for assigned_network in assigned_networks:
|
|
if assigned_network['type'] == 'MANAGEMENT' and\
|
|
assigned_network['ip'] in ips:
|
|
hosts_needed.append(host)
|
|
hosts_id_needed = [host_needed['id'] for host_needed in hosts_needed]
|
|
return hosts_id_needed
|
|
|
|
|
|
def configure_external_interface_vlan(req, cluster_id, host_ip):
|
|
cluster_networks = daisy_cmn.get_cluster_networks_detail(req, cluster_id)
|
|
for network in cluster_networks:
|
|
if 'EXTERNAL' in network.get('network_type') and \
|
|
network.get('vlan_id') != None:
|
|
ext_interface = network.get('physnet_name').split("_")[1]
|
|
cmd1 = 'ssh -o StrictHostKeyChecking=no %s \
|
|
"touch /etc/sysconfig/network-scripts/ifcfg-%s.%s"' \
|
|
% (host_ip, ext_interface, network.get('vlan_id'))
|
|
cmd2 = 'echo -e "BOOTPROTO=static\nONBOOT=yes\nDEVICE=%s.%s\n'\
|
|
'VLAN=yes" > /etc/sysconfig/network-scripts/ifcfg-%s.%s' \
|
|
% (ext_interface, network.get('vlan_id'),
|
|
ext_interface, network.get('vlan_id'))
|
|
cmd3 = "ssh -o StrictHostKeyChecking=no %s '%s'" % (host_ip, cmd2)
|
|
|
|
try:
|
|
exc_cmd1 = subprocess.check_output(cmd1,
|
|
shell=True,
|
|
stderr=subprocess.STDOUT)
|
|
exc_cmd2 = subprocess.check_output(cmd3,
|
|
shell=True,
|
|
stderr=subprocess.STDOUT)
|
|
except subprocess.CalledProcessError as e:
|
|
message = "config external interface vlan on %s failed!"\
|
|
% host_ip
|
|
LOG.error(message + e)
|
|
raise exception.InstallException(message)
|
|
else:
|
|
LOG.info(_("config external interface vlan on %s successfully!"
|
|
% host_ip))
|
|
|
|
|
|
def _thread_bin(req, cluster_id, host, root_passwd, fp, host_name_ip_list,
|
|
host_prepare_file, docker_registry_ip, role_id_list):
|
|
host_ip = host['mgtip']
|
|
|
|
config_nodes_hosts(host_name_ip_list, host_ip)
|
|
cmd = 'ssh -o StrictHostKeyChecking=no %s \
|
|
"if [ ! -d %s ];then mkdir %s;fi" ' % \
|
|
(host_ip, host_prepare_file, host_prepare_file)
|
|
daisy_cmn.subprocess_call(cmd, fp)
|
|
|
|
LOG.info("Remote directory created on %s", host_ip)
|
|
|
|
# scp daisy4nfv-jasmine.rpm to the same dir of prepare.sh at target host
|
|
cmd = "scp -o ConnectTimeout=10 \
|
|
/var/lib/daisy/tools/daisy4nfv-jasmine*.rpm \
|
|
root@%s:%s" % (host_ip, host_prepare_file)
|
|
daisy_cmn.subprocess_call(cmd, fp)
|
|
|
|
# scp registry-server.tar to the same dir of prepare.sh at target host
|
|
cmd = "scp -o ConnectTimeout=10 \
|
|
/var/lib/daisy/tools/registry-server.tar \
|
|
root@%s:%s" % (host_ip, host_prepare_file)
|
|
daisy_cmn.subprocess_call(cmd, fp)
|
|
|
|
LOG.info("Files copied successfully to %s", host_ip)
|
|
|
|
cmd = "scp -o ConnectTimeout=10 \
|
|
/var/lib/daisy/kolla/prepare.sh \
|
|
root@%s:%s" % (host_ip, host_prepare_file)
|
|
daisy_cmn.subprocess_call(cmd, fp)
|
|
|
|
cmd = 'ssh -o StrictHostKeyChecking=no %s \
|
|
chmod u+x %s/prepare.sh' % \
|
|
(host_ip, host_prepare_file)
|
|
daisy_cmn.subprocess_call(cmd, fp)
|
|
|
|
LOG.info("Ready to execute prepare.sh on %s", host_ip)
|
|
|
|
try:
|
|
exc_result = subprocess.check_output(
|
|
'ssh -o StrictHostKeyChecking='
|
|
'no %s %s/prepare.sh %s' %
|
|
(host_ip, host_prepare_file, docker_registry_ip),
|
|
shell=True, stderr=subprocess.STDOUT)
|
|
except subprocess.CalledProcessError as e:
|
|
message = "exec prepare.sh on %s failed!", host_ip
|
|
LOG.error(message)
|
|
fp.write(e.output.strip())
|
|
raise exception.InstallException(message)
|
|
else:
|
|
LOG.info("prepare for %s successfully!", host_ip)
|
|
fp.write(exc_result)
|
|
message = "Preparing for installation successful!"
|
|
update_host_progress_to_db(req, role_id_list, host,
|
|
kolla_state['INSTALLING'],
|
|
message, 10)
|
|
|
|
|
|
def thread_bin(req, cluster_id, host, root_passwd, host_name_ip_list,
|
|
host_prepare_file, docker_registry_ip, role_id_list):
|
|
|
|
host_prepare_log = "/var/log/daisy/kolla_%s_%s_prepare.log" %\
|
|
(cluster_id, host['mgtip'])
|
|
with open(host_prepare_log, "w+") as fp:
|
|
try:
|
|
_thread_bin(req, cluster_id, host, root_passwd,
|
|
fp, host_name_ip_list,
|
|
host_prepare_file, docker_registry_ip,
|
|
role_id_list)
|
|
except Exception as e:
|
|
thread_flag['flag'] = False
|
|
message = "Prepare for installation failed!"
|
|
LOG.error(message)
|
|
update_host_progress_to_db(req, role_id_list, host,
|
|
kolla_state['INSTALL_FAILED'],
|
|
message)
|
|
fp.write(utils.exception_to_str(e))
|
|
|
|
|
|
class KOLLAInstallTask(Thread):
|
|
"""
|
|
Class for kolla install openstack.
|
|
"""
|
|
""" Definition for install states."""
|
|
INSTALL_STATES = {
|
|
'INIT': 'init',
|
|
'INSTALLING': 'installing',
|
|
'ACTIVE': 'active',
|
|
'FAILED': 'install-failed'
|
|
}
|
|
|
|
def __init__(self, req, cluster_id):
|
|
super(KOLLAInstallTask, self).__init__()
|
|
self.req = req
|
|
self.cluster_id = cluster_id
|
|
self.progress = 0
|
|
self.state = KOLLAInstallTask.INSTALL_STATES['INIT']
|
|
self.message = ""
|
|
self.kolla_config_file = ''
|
|
self.mgt_ip_list = ''
|
|
self.install_log_fp = None
|
|
self.last_line_num = 0
|
|
self.ping_times = 36
|
|
self.precheck_file = "/var/log/daisy/kolla_%s_precheck.log" %\
|
|
self.cluster_id
|
|
self.log_file = "/var/log/daisy/kolla_%s_deploy.log" % self.cluster_id
|
|
self.host_prepare_file = "/home/kolla"
|
|
self.kolla_file = "/home/kolla_install"
|
|
|
|
def run(self):
|
|
try:
|
|
self._run()
|
|
except (exception.InstallException,
|
|
exception.NotFound,
|
|
exception.InstallTimeoutException,
|
|
exception.SubprocessCmdFailed) as e:
|
|
(role_id_list, host_id_list, hosts_list) = \
|
|
kolla_cmn.get_roles_and_hosts_list(self.req, self.cluster_id)
|
|
update_all_host_progress_to_db(self.req, role_id_list,
|
|
host_id_list,
|
|
kolla_state['INSTALL_FAILED'],
|
|
self.message)
|
|
LOG.error(("deploy openstack failed!"))
|
|
except:
|
|
update_all_host_progress_to_db(self.req, role_id_list,
|
|
host_id_list,
|
|
kolla_state['INSTALL_FAILED'],
|
|
self.message)
|
|
LOG.error("deploy openstack failed with other error")
|
|
|
|
else:
|
|
LOG.info(_("install Kolla for cluster %s successfully."
|
|
% self.cluster_id))
|
|
finally:
|
|
if daisy_cmn.in_cluster_list(self.cluster_id):
|
|
LOG.info("KOLLA install clear install global variables")
|
|
daisy_cmn.cluster_list_delete(self.cluster_id)
|
|
|
|
def _run(self):
|
|
cluster_data = registry.get_cluster_metadata(self.req.context,
|
|
self.cluster_id)
|
|
|
|
(kolla_config, self.mgt_ip_list, host_name_ip_list) = \
|
|
kolla_cmn.get_cluster_kolla_config(self.req, self.cluster_id)
|
|
if not self.mgt_ip_list:
|
|
msg = _("there is no host in cluster %s") % self.cluster_id
|
|
LOG.error(msg)
|
|
raise exception.ThreadBinException(msg)
|
|
|
|
unreached_hosts = _check_ping_hosts(self.mgt_ip_list, self.ping_times)
|
|
if unreached_hosts:
|
|
self.message = "hosts %s ping failed" % unreached_hosts
|
|
LOG.error(self.message)
|
|
raise exception.InstallException(self.message)
|
|
|
|
root_passwd = 'ossdbg1'
|
|
threads_net = []
|
|
for mgnt_ip in self.mgt_ip_list:
|
|
check_hosts_id = _get_hosts_id_by_mgnt_ips(self.req,
|
|
self.cluster_id,
|
|
mgnt_ip.split(","))
|
|
is_ssh_host = daisy_cmn._judge_ssh_host(self.req,
|
|
check_hosts_id[0])
|
|
if not is_ssh_host:
|
|
cmd = '/var/lib/daisy/trustme.sh %s %s' % \
|
|
(mgnt_ip, root_passwd)
|
|
daisy_cmn.subprocess_call(cmd)
|
|
LOG.info(_("Begin to config network on %s" % mgnt_ip))
|
|
ssh_host_info = {'ip': mgnt_ip, 'root_pwd': root_passwd}
|
|
configure_external_interface_vlan(self.req,
|
|
self.cluster_id,
|
|
mgnt_ip)
|
|
|
|
t_net = threading.Thread(target=api_cmn.config_network,
|
|
args=(ssh_host_info, 'kolla'))
|
|
t_net.setDaemon(True)
|
|
t_net.start()
|
|
threads_net.append(t_net)
|
|
try:
|
|
LOG.info(_("config network threads"
|
|
" have started, please waiting...."))
|
|
for t_net in threads_net:
|
|
t_net.join()
|
|
except:
|
|
LOG.error("join config network "
|
|
"thread %s failed!", t_net)
|
|
|
|
time.sleep(20)
|
|
|
|
(role_id_list, host_id_list, hosts_list) = \
|
|
kolla_cmn.get_roles_and_hosts_list(self.req, self.cluster_id)
|
|
self.message = "Begin install"
|
|
update_all_host_progress_to_db(self.req, role_id_list,
|
|
host_id_list, kolla_state['INSTALLING'],
|
|
self.message, 5)
|
|
|
|
docker_registry_ip = kolla_cmn._get_local_ip()
|
|
|
|
# Do prepare.sh for each host
|
|
threads = []
|
|
for host in hosts_list:
|
|
t = threading.Thread(target=thread_bin,
|
|
args=(self.req, self.cluster_id, host,
|
|
root_passwd, host_name_ip_list,
|
|
self.host_prepare_file,
|
|
docker_registry_ip, role_id_list))
|
|
t.setDaemon(True)
|
|
t.start()
|
|
threads.append(t)
|
|
LOG.info("prepare.sh threads for %s started", host['mgtip'])
|
|
|
|
try:
|
|
LOG.info(_("prepare kolla installation threads have started, "
|
|
"please waiting...."))
|
|
for t in threads:
|
|
t.join()
|
|
except:
|
|
LOG.error("join kolla prepare installation "
|
|
"thread %s failed!", t)
|
|
|
|
if thread_flag.get('flag', None) is not None and \
|
|
thread_flag['flag'] == False:
|
|
self.message = "prepare deploy nodes failed!"
|
|
LOG.error(self.message)
|
|
raise exception.InstallException(self.message)
|
|
|
|
# Check, load and multicast version
|
|
if cluster_data.get('tecs_version_id', None):
|
|
vid = cluster_data['tecs_version_id']
|
|
version_info = registry.get_version_metadata(self.req.context,
|
|
vid)
|
|
kolla_version_pkg_file = \
|
|
kolla_cmn.check_and_get_kolla_version(daisy_kolla_ver_path,
|
|
version_info['name'])
|
|
else:
|
|
kolla_version_pkg_file =\
|
|
kolla_cmn.check_and_get_kolla_version(daisy_kolla_ver_path)
|
|
if not kolla_version_pkg_file:
|
|
self.state = kolla_state['INSTALL_FAILED']
|
|
self.message =\
|
|
"kolla version file not found in %s" % daisy_kolla_ver_path
|
|
raise exception.NotFound(message=self.message)
|
|
|
|
try:
|
|
LOG.info(_("load kolla registry..."))
|
|
kolla_cmn.version_load(kolla_version_pkg_file, hosts_list)
|
|
except exception.SubprocessCmdFailed as e:
|
|
self.message = "load kolla registry failed!"
|
|
LOG.error(self.message)
|
|
raise exception.InstallException(self.message)
|
|
|
|
res = kolla_cmn.version_load_mcast(kolla_version_pkg_file,
|
|
hosts_list)
|
|
update_all_host_progress_to_db(self.req, role_id_list,
|
|
host_id_list,
|
|
kolla_state['INSTALLING'],
|
|
self.message, 15)
|
|
|
|
# always call generate_kolla_config_file after version_load()
|
|
LOG.info(_("begin to generate kolla config file ..."))
|
|
(kolla_config, self.mgt_ip_list, host_name_ip_list) = \
|
|
kolla_cmn.get_cluster_kolla_config(self.req, self.cluster_id)
|
|
kolla_cmn.generate_kolla_config_file(self.req, self.cluster_id,
|
|
kolla_config, res)
|
|
LOG.info(_("generate kolla config file in /etc/kolla/ dir..."))
|
|
|
|
# Kolla prechecks
|
|
with open(self.precheck_file, "w+") as fp:
|
|
LOG.info(_("kolla-ansible precheck..."))
|
|
cmd = subprocess.Popen(
|
|
'cd %s/kolla-ansible && ./tools/kolla-ansible prechecks '
|
|
' -i %s/kolla-ansible/ansible/inventory/multinode -vvv' %
|
|
(self.kolla_file, self.kolla_file),
|
|
shell=True, stdout=fp, stderr=fp)
|
|
execute_times = 0
|
|
while True:
|
|
time.sleep(5)
|
|
return_code = cmd.poll()
|
|
if return_code == 0:
|
|
break
|
|
elif return_code == 1:
|
|
self.message = "kolla-ansible preckecks failed!"
|
|
LOG.error(self.message)
|
|
raise exception.InstallException(self.message)
|
|
else:
|
|
if execute_times >= 1440:
|
|
self.message = "kolla-ansible preckecks timeout"
|
|
LOG.error(self.message)
|
|
raise exception.InstallTimeoutException(
|
|
cluster_id=self.cluster_id)
|
|
execute_times += 1
|
|
|
|
self.message = "kolla-ansible preckecks successfully(%d)!" % \
|
|
(return_code)
|
|
self.progress = 20
|
|
update_all_host_progress_to_db(self.req, role_id_list,
|
|
host_id_list,
|
|
kolla_state['INSTALLING'],
|
|
self.message, self.progress)
|
|
|
|
with open(self.log_file, "w+") as fp:
|
|
LOG.info(_("kolla-ansible begin to deploy openstack ..."))
|
|
cmd = subprocess.Popen(
|
|
'cd %s/kolla-ansible && ./tools/kolla-ansible deploy -i '
|
|
'%s/kolla-ansible/ansible/inventory/multinode' %
|
|
(self.kolla_file, self.kolla_file),
|
|
shell=True, stdout=fp, stderr=fp)
|
|
self.message = "begin deploy openstack"
|
|
self.progress = 25
|
|
execute_times = 0
|
|
while True:
|
|
time.sleep(5)
|
|
return_code = cmd.poll()
|
|
if self.progress == 95:
|
|
break
|
|
elif return_code == 0:
|
|
self.progress = 95
|
|
elif return_code == 1:
|
|
self.message = "KOLLA deploy openstack failed"
|
|
LOG.error(self.message)
|
|
raise exception.InstallException(self.message)
|
|
else:
|
|
self.progress = _calc_progress(self.log_file)
|
|
if execute_times >= 1440:
|
|
self.message = "KOLLA deploy openstack timeout"
|
|
LOG.error(self.message)
|
|
raise exception.InstallTimeoutException(
|
|
cluster_id=self.cluster_id)
|
|
else:
|
|
update_all_host_progress_to_db(self.req, role_id_list,
|
|
host_id_list,
|
|
kolla_state['INSTALLING'],
|
|
self.message, self.progress)
|
|
execute_times += 1
|
|
|
|
try:
|
|
LOG.info(_("kolla-ansible post-deploy for each node..."))
|
|
exc_result = subprocess.check_output(
|
|
'cd %s/kolla-ansible && ./tools/kolla-ansible post-deploy '
|
|
' -i %s/kolla-ansible/ansible/inventory/multinode' %
|
|
(self.kolla_file, self.kolla_file),
|
|
shell=True, stderr=subprocess.STDOUT)
|
|
except subprocess.CalledProcessError as e:
|
|
self.message = "kolla-ansible post-deploy failed!"
|
|
LOG.error(self.message)
|
|
fp.write(e.output.strip())
|
|
raise exception.InstallException(self.message)
|
|
else:
|
|
LOG.info(_("kolla-ansible post-deploy successfully!"))
|
|
fp.write(exc_result)
|
|
self.message = "post-deploy successfully!"
|
|
update_all_host_progress_to_db(self.req, role_id_list,
|
|
host_id_list,
|
|
kolla_state['ACTIVE'],
|
|
self.message, 100)
|
|
update_progress_to_db(self.req, role_id_list,
|
|
kolla_state['ACTIVE'], 100)
|
|
for host_id in host_id_list:
|
|
daisy_cmn.update_db_host_status(
|
|
self.req, host_id,
|
|
{'tecs_version_id': cluster_data['tecs_version_id'],
|
|
'tecs_patch_id': ''})
|