WIP: Enable multicast

1. When install daisy, save registry-serve.tar into
/var/lib/daisy/tools just like jasmine.rpm

2. During preparation stage, scp registry-serve.tar and jasmine.rpm
to all targets, and install them on the target hosts.

3. Add version_load_mcast() to use jasmines/jasminec to multicast
kolla image, and build registry server on each target hosts.

4. (TODO)
If version_load_mcast() failed (may due to mcast not allowed by
config or mcast failed on server or any client), config kolla to let
it to fallback to use remote docker image registry. If
version_load_mcast() successful, then config kolla to use
127.0.0.1 as docker registyr server IP.

Change-Id: I69cda8c0c259c356459770f4cb2b6f46da868893
Signed-off-by: Zhijiang Hu <hu.zhijiang@zte.com.cn>
This commit is contained in:
Zhijiang Hu 2017-04-11 05:15:02 -04:00 committed by Zhou Ya
parent a25f94f658
commit 314b0c5570
7 changed files with 259 additions and 44 deletions

View File

@ -17,3 +17,8 @@ systemctl stop libvirtd.service
systemctl disable libvirtd.service
systemctl start ntpd.service
yum -y install ansible
# multicast related
prepare_dir=$(dirname $(readlink -f "$0"))
yum install -y $prepare_dir/jasmine*.rpm
docker load < $prepare_dir/registry-server.tar

157
code/daisy/daisy/api/backends/kolla/common.py Normal file → Executable file
View File

@ -17,6 +17,7 @@
/install endpoint for zenic API
"""
import os
import time
import subprocess
import copy
from oslo_log import log as logging
@ -304,7 +305,158 @@ def check_and_get_kolla_version(daisy_kolla_pkg_path, file_name=None):
return kolla_version_pkg_file
def version_load(kolla_version_pkg_file):
def _get_local_ip():
config = ConfigParser.ConfigParser()
config.read(daisy_cmn.daisy_conf_file)
local_ip = config.get("DEFAULT", "daisy_management_ip")
return local_ip
class MulticastServerTask(object):
"""
Class for server side multicast.
"""
def __init__(self, kolla_version_pkg_file, host_list):
self.kolla_version_pkg_file = kolla_version_pkg_file
self.host_list = host_list
def run(self):
try:
self._run()
except Exception as e:
self.res = -1 # failed
self.res = 0 # successful
def _run(self):
cmd = 'jasmines %s %d < %s/%s' % (_get_local_ip(), # mgt interface
len(self.hosts_list),
# number of clients
daisy_kolla_ver_path,
self.kolla_version_pkg_file)
subprocess.check_output(cmd,
shell=True,
stderr=subprocess.STDOUT)
class MulticastClientTask(object):
"""
Class for client side multicast.
"""
def __init__(self, kolla_version_pkg_file, host):
self.kolla_version_pkg_file = kolla_version_pkg_file
self.host = host
def run(self):
try:
self._run()
except Exception as e:
self.res = -1 # failed
self.res = 0 # successful
def _run(self):
host_ip = self.host['mgtip']
# stop registry server
cmd = 'ssh -o StrictHostKeyChecking=no %s \
docker stop registry' % host_ip
subprocess.check_output(cmd,
shell=True,
stderr=subprocess.STDOUT)
cmd = 'ssh -o StrictHostKeyChecking=no %s \
docker rm -f registry' % host_ip
subprocess.check_output(cmd,
shell=True,
stderr=subprocess.STDOUT)
cmd = 'ssh -o StrictHostKeyChecking=no %s \
"if [ ! -d %s ];then mkdir %s;fi" ' % \
(host_ip, daisy_kolla_ver_path, daisy_kolla_ver_path)
subprocess.check_output(cmd,
shell=True,
stderr=subprocess.STDOUT)
# receive image from daisy server
cmd = 'ssh -o StrictHostKeyChecking=no %s \
jasminec %s %s > %s/%s' % (host_ip,
host_ip,
_get_local_ip(),
daisy_kolla_ver_path,
self.kolla_version_pkg_file)
subprocess.check_output(cmd,
shell=True,
stderr=subprocess.STDOUT)
# clean up the old version files
cmd = 'ssh -o StrictHostKeyChecking=no %s \
rm -rf %s/tmp' % (host_ip,
daisy_kolla_ver_path)
subprocess.check_output(cmd,
shell=True,
stderr=subprocess.STDOUT)
# install the new version files
cmd = 'ssh -o StrictHostKeyChecking=no %s \
cd %s && tar mzxf %s' % (host_ip,
daisy_kolla_ver_path,
kolla_version_pkg_file)
subprocess.check_output(cmd,
shell=True,
stderr=subprocess.STDOUT)
registry_file = daisy_kolla_ver_path + "/tmp/registry"
# start registry server again
cmd = 'ssh -o StrictHostKeyChecking=no %s \
docker run -d -p 4000:5000 --restart=always \
-e REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY=/tmp/registry \
-v %s:/tmp/registry --name registry registry:2'\
% (host_ip, registry_file)
subprocess.check_output(cmd,
shell=True,
stderr=subprocess.STDOUT)
daisy_conf_mcast_enabled = False
def version_load_mcast(kolla_version_pkg_file, hosts_list):
# TODO: impl. daisy_conf_mcast_enabled
if daisy_conf_mcast_enabled != True:
return -1
mcobj = MulticastServerTask(kolla_version_pkg_file, hosts_list)
mcobj.t = threading.Thread(target=mcobj.run)
mcobj.t.start()
mcobjset.append(mcobj)
time.sleep(5) # Wait multicast server ready before start clients
for host in hosts_list:
mcobj = MulticastClientTask(kolla_version_pkg_file, host)
mcobj.t = threading.Thread(target=mcobj.run)
mcobj.t.start()
mcobjset.append(mcobj)
try:
LOG.info(_("jasmine server as well as all jasmine clients started"))
for mcobj in mcobjset:
mcobj.t.join() # wait server as well as all clients end.
except:
LOG.error("jasmine client thread %s failed!" % t)
for mcobj in mcobjset:
if mcobj.res != 0:
return -1
return 0
def version_load(kolla_version_pkg_file, hosts_list):
get_container_id = "docker ps -a |grep registry |awk -F ' ' '{printf $1}' "
container_id = subprocess.check_output(get_container_id, shell=True)
if container_id:
@ -312,11 +464,14 @@ def version_load(kolla_version_pkg_file):
daisy_cmn.subprocess_call(stop_container)
remove_container = 'docker rm %s' % container_id
daisy_cmn.subprocess_call(remove_container)
remove_tmp_registry = 'rm -rf %s/tmp' % daisy_kolla_ver_path
daisy_cmn.subprocess_call(remove_tmp_registry)
tar_for_kolla_version = 'cd %s && tar mzxvf %s' % (daisy_kolla_ver_path,
kolla_version_pkg_file)
subprocess.call(tar_for_kolla_version, shell=True)
registry_file = daisy_kolla_ver_path + "/tmp/registry"
daisy_cmn.subprocess_call(
'docker run -d -p 4000:5000 --restart=always \

View File

@ -214,7 +214,7 @@ def enable_cinder_backend(req, cluster_id, config_data):
# generate kolla's globals.yml file
def update_globals_yml(config_data):
def update_globals_yml(config_data, multicast_flag):
LOG.info(_("begin to update kolla's globals.yml file..."))
Version = config_data['Version'].encode()
Namespace = config_data['Namespace'].encode()
@ -252,7 +252,10 @@ def update_globals_yml(config_data):
'neutron_external_interface': 'eth1'
}
kolla_yml['openstack_release'] = Version
kolla_yml['docker_registry'] = local_ip
if multicast_flag == 0:
pass
else:
kolla_yml['docker_registry'] = local_ip
kolla_yml['docker_namespace'] = Namespace
kolla_yml['kolla_internal_vip_address'] = VIP
kolla_yml['network_interface'] = IntIfMac

103
code/daisy/daisy/api/backends/kolla/install.py Normal file → Executable file
View File

@ -29,7 +29,6 @@ from daisy.common import exception
from daisy.api.backends.kolla import config
import daisy.api.backends.common as daisy_cmn
import daisy.api.backends.kolla.common as kolla_cmn
import ConfigParser
import daisy.api.common as api_cmn
import daisy.registry.client.v1.api as registry
@ -153,13 +152,6 @@ def _check_ping_hosts(ping_ips, max_ping_times):
return ips
def _get_local_ip():
config = ConfigParser.ConfigParser()
config.read(daisy_cmn.daisy_conf_file)
local_ip = config.get("DEFAULT", "daisy_management_ip")
return local_ip
def get_cluster_kolla_config(req, cluster_id):
LOG.info(_("get kolla config from database..."))
mgt_ip_list = set()
@ -201,7 +193,7 @@ def get_cluster_kolla_config(req, cluster_id):
openstack_version = kolla_openstack_version.split(
": ")[1].strip('\"')
LOG.info(_("openstack version is %s" % openstack_version))
docker_registry_ip = _get_local_ip()
docker_registry_ip = kolla_cmn._get_local_ip()
docker_registry = docker_registry_ip + ':4000'
LOG.info(_("get cluster network detail..."))
cluster_networks = daisy_cmn.get_cluster_networks_detail(req, cluster_id)
@ -280,10 +272,10 @@ def get_cluster_kolla_config(req, cluster_id):
return (kolla_config, mgt_ip_list, host_name_ip_list)
def generate_kolla_config_file(req, cluster_id, kolla_config):
def generate_kolla_config_file(req, cluster_id, kolla_config, multicast_flag):
LOG.info(_("generate kolla config..."))
if kolla_config:
config.update_globals_yml(kolla_config)
config.update_globals_yml(kolla_config, multicast_flag)
config.update_password_yml()
config.add_role_to_inventory(kolla_file, kolla_config)
config.enable_cinder_backend(req,
@ -357,19 +349,35 @@ def _thread_bin(req, host, root_passwd, fp, host_name_ip_list,
cmd = '/var/lib/daisy/trustme.sh %s %s' % \
(host_ip, root_passwd)
daisy_cmn.subprocess_call(cmd, fp)
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)
# scp jasmine.rpm to the same dir of prepare.sh at target host
cmd = "scp -o ConnectTimeout=10 \
/var/lib/daisy/tools/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)
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)
try:
exc_result = subprocess.check_output(
'ssh -o StrictHostKeyChecking='
@ -455,30 +463,9 @@ class KOLLAInstallTask(Thread):
daisy_cmn.cluster_list_delete(self.cluster_id)
def _run(self):
# check and get version
cluster_data = registry.get_cluster_metadata(self.req.context,
self.cluster_id)
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)
except exception.SubprocessCmdFailed as e:
self.message = "load kolla registry failed!"
LOG.error(self.message)
raise exception.InstallException(self.message)
(kolla_config, self.mgt_ip_list, host_name_ip_list) = \
get_cluster_kolla_config(self.req, self.cluster_id)
if not self.mgt_ip_list:
@ -489,6 +476,7 @@ class KOLLAInstallTask(Thread):
self.message = "hosts %s ping failed" % unreached_hosts
LOG.error(self.message)
raise exception.InstallException(self.message)
root_passwd = 'ossdbg1'
for mgnt_ip in self.mgt_ip_list:
check_hosts_id = _get_hosts_id_by_mgnt_ips(self.req,
@ -501,17 +489,17 @@ class KOLLAInstallTask(Thread):
on %s" % mgnt_ip))
ssh_host_info = {'ip': mgnt_ip, 'root_pwd': root_passwd}
api_cmn.config_network_new(ssh_host_info, 'kolla')
time.sleep(20)
LOG.info(_("begin to generate kolla config file ..."))
generate_kolla_config_file(self.req, self.cluster_id, kolla_config)
LOG.info(_("generate kolla config file in /etc/kolla/ dir..."))
(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, 0)
docker_registry_ip = _get_local_ip()
docker_registry_ip = kolla_cmn._get_local_ip()
with open(self.log_file, "w+") as fp:
threads = []
for host in hosts_list:
@ -532,6 +520,47 @@ class KOLLAInstallTask(Thread):
LOG.error("join kolla prepare installation "
"thread %s failed!" % t)
# 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)
# Multicast done
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()
# TODO: re-config docker registry server based upon return value of
# kolla_cmn.version_load_mcast
LOG.info(_("begin to generate kolla config file ..."))
generate_kolla_config_file(self.req, self.cluster_id,
kolla_config, res)
LOG.info(_("generate kolla config file in /etc/kolla/ dir..."))
if thread_flag.get('flag', None) and thread_flag['flag'] == False:
self.message = "prepare deploy nodes failed!"
LOG.error(self.message)

17
code/daisy/daisy/api/backends/kolla/upgrade.py Normal file → Executable file
View File

@ -96,12 +96,27 @@ class KOLLAUpgradeTask(Thread):
'UPDATE_FAILED'],
'messages': self.message})
return
kolla_cmn.version_load(kolla_version_pkg_file)
# TODO: Is the hosts argument right?
try:
LOG.info(_("load kolla registry..."))
kolla_cmn.version_load(kolla_version_pkg_file, hosts)
except exception.SubprocessCmdFailed as e:
self.message = "load kolla registry failed!"
LOG.error(self.message)
raise exception.InstallException(self.message)
update_all_host_progress_to_db(self.req, hosts_id_list,
{'progress': 10,
'status': kolla_state[
'UPDATING'],
'messages': self.message})
res = kolla_cmn.version_load_mcast(kolla_version_pkg_file,
hosts_list)
# TODO: re-config docker registry server based upon return value of
# kolla_cmn.version_load_mcast
for host in hosts:
host_meta = daisy_cmn.get_host_detail(self.req, host["host_id"])
host_ip = daisy_cmn.get_management_ip(host_meta)

View File

@ -427,7 +427,7 @@ class TestInstall(test.TestCase):
@mock.patch('daisy.api.backends.kolla.common.get_hosts_of_role')
@mock.patch('daisy.api.backends.kolla.common.get_roles_detail')
@mock.patch('daisy.api.backends.common.get_cluster_networks_detail')
@mock.patch('daisy.api.backends.kolla.install._get_local_ip')
@mock.patch('daisy.api.backends.kolla.common._get_local_ip')
def test_get_cluster_kolla_config(
self, mock_do__get_local_ip,
mock_do_get_cluster_networks_detail,
@ -478,9 +478,10 @@ class TestInstall(test.TestCase):
@mock.patch('daisy.api.backends.common.update_db_host_status')
@mock.patch("daisy.registry.client.v1.api.get_version_metadata")
@mock.patch('daisy.api.backends.kolla.common.version_load')
@mock.patch('daisy.api.backends.kolla.common.version_load_mcast')
@mock.patch('daisy.api.backends.kolla.common.check_and_get_kolla_version')
@mock.patch("daisy.registry.client.v1.api.get_cluster_metadata")
@mock.patch('daisy.api.backends.kolla.install._get_local_ip')
@mock.patch('daisy.api.backends.kolla.common._get_local_ip')
@mock.patch('daisy.api.common.config_network_new')
@mock.patch('daisy.registry.client.v1.client.RegistryClient.do_request')
@mock.patch('daisy.api.backends.kolla.install.update_progress_to_db')
@ -509,7 +510,8 @@ class TestInstall(test.TestCase):
mock_do_update_host_progress_to_db, mock_do_update_progress_to_db,
mock_do_request, mock_do_config_network_new,
mock_do_get_local_ip, mock_do_get_clusters_detail,
mock_do_check_and_get_kolla_version, mock_do_version_load,
mock_do_check_and_get_kolla_version,
mock_do_version_load_mcast, mock_do_version_load,
mock_do_get_version_metadata, mock_do_update_db_host_status):
def mock_get_cluster_kolla_config(*args, **kwargs):
@ -547,6 +549,7 @@ class TestInstall(test.TestCase):
mock_do_get_clusters_detail.side_effect = mock_get_clusters_detail
mock_do_check_and_get_kolla_version.return_value = \
"/var/lib/daisy/versionfile/kolla/test_version"
mock_do_version_load_mcast.return_value = -1
mock_do_get_version_metadata.return_value = {"name": "test_version"}
kolla_config = {}
mgt_ip_list = ['127.0.0.1']

View File

@ -139,6 +139,11 @@ function kolla_install
fi
cp $imagebakdir/registry-server.tar $imagedir
fi
if [ ! -f "/var/lib/daisy/tools/registry-server.tar" ];then
cp $imagedir/registry-server.tar /var/lib/daisy/tools/ # keep jasmine for target hosts
fi
docker load < $imagedir/registry-server.tar
rm -rf $imagedir/tmp
rm -rf $imagedir/registry-*.version