kolla-mesos/kolla_mesos/configuration.py

178 lines
6.9 KiB
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.
import json
import os.path
from kazoo import exceptions as kz_exceptions
from oslo_config import cfg
from oslo_log import log as logging
import yaml
from kolla_mesos.common import file_utils
from kolla_mesos.common import jinja_utils
from kolla_mesos.common import mesos_utils
from kolla_mesos.common import type_utils
from kolla_mesos import exception
LOG = logging.getLogger()
CONF = cfg.CONF
CONF.import_group('kolla', 'kolla_mesos.config.kolla')
CONF.import_group('kolla', 'kolla_mesos.config.zookeeper')
def write_variables_zookeeper(zk, variables, base_node=None, overwrite=True):
if base_node is None:
base_node = os.path.join('kolla', CONF.kolla.deployment_id)
filter_out = ['groups', 'hostvars', 'kolla_config',
'inventory_hostname']
for var in variables:
if (var in filter_out):
LOG.debug('Var "%s" with value "%s" is filtered out' %
(var, variables[var]))
continue
var_value = variables[var]
if isinstance(variables[var], dict):
var_value = json.dumps(variables[var])
var_path = os.path.join(base_node, 'variables', var)
if not overwrite and zk.exists(var_path):
LOG.debug('NOT Updating "%s" node in zookeeper(overwrite=False).',
var_path)
return
zk.ensure_path(var_path)
if var_value is None:
var_value = ''
zk.set(var_path, var_value.encode('utf-8'))
LOG.debug('Updated "%s" node in zookeeper.' % var_path)
def get_start_config(config_dir, jinja_vars):
start_conf = os.path.join(config_dir,
'common/kolla-start-config.json')
# override container_config_directory
cont_conf_dir = 'zk://%s' % (CONF.zookeeper.host)
jinja_vars['container_config_directory'] = cont_conf_dir
jinja_vars['deployment_id'] = CONF.kolla.deployment_id
kolla_config = jinja_utils.jinja_render(start_conf, jinja_vars)
kolla_config = kolla_config.replace('"', '\\"').replace('\n', '')
return kolla_config
def write_common_config_to_zookeeper(config_dir, zk, jinja_vars,
overwrite=True):
# 1. At first write global tools to ZK. FIXME: Make it a common profile
conf_path = os.path.join(config_dir, 'common',
'common_config.yml.j2')
common_cfg = yaml.load(jinja_utils.jinja_render(conf_path, jinja_vars))
common_node = os.path.join('kolla', 'common')
for script in common_cfg:
script_node = os.path.join(common_node, script)
if not overwrite and zk.exists(script_node):
LOG.debug('NOT Updating "%s" node in zookeeper(overwrite=False).',
script_node)
continue
zk.ensure_path(script_node)
source_path = common_cfg[script]['source']
src_file = source_path
if not source_path.startswith('/'):
src_file = file_utils.find_file(source_path)
with open(src_file) as fp:
content = fp.read()
zk.set(script_node, content.encode('utf-8'))
def get_variables_from_zookeeper(zk, needed_variables):
path = os.path.join('/kolla', CONF.kolla.deployment_id, 'variables')
variables = {}
for var in needed_variables:
try:
variables[str(var)], _stat = zk.get(os.path.join(path, var))
except kz_exceptions.NoNodeError:
raise exception.KollaNotFoundException(var, entity='variable')
return variables
def apply_deployment_vars(jvars):
"""Applies the orchestration logic defined in globals.yml.
If multinode mode is enabled, then it uses the default constraints.
And depending on the 'autodetect_resources' option, it figures out
how many instances of the services should be scheduled.
If multinode mode is disabled, then it checks whether
'mesos_aio_hostname' option is defined. If it is, then the
constraints for the given host are defined. If not, the constraints
disappear.
"""
multinode = type_utils.str_to_bool(jvars['multinode'])
if multinode:
autodetect_resources = type_utils.str_to_bool(
jvars['autodetect_resources'])
if autodetect_resources:
controller_nodes, compute_nodes, storage_nodes, all_nodes = \
mesos_utils.get_number_of_nodes()
else:
try:
controller_nodes = jvars['controller_nodes']
compute_nodes = jvars['compute_nodes']
storage_nodes = jvars['storage_nodes']
except KeyError:
raise exception.UndefinedOption(
'When "autodetect_resources" option is disabled, '
'"controller_nodes", "compute_nodes" and'
'"storage_nodes" have to be defined.')
all_nodes = controller_nodes + compute_nodes + storage_nodes
else:
controller_nodes = 1
compute_nodes = 1
storage_nodes = 1
all_nodes = 1
controller_constraints = ""
compute_constraints = ""
controller_compute_constraints = ""
storage_constraints = ""
mesos_aio_hostname = jvars.get('mesos_aio_hostname')
if mesos_aio_hostname is not None:
constraints = '[["hostname", "CLUSTER", "%s"]]' % \
mesos_aio_hostname
controller_constraints = constraints
compute_constraints = constraints
controller_compute_constraints = constraints
storage_constraints = constraints
jvars.update({
'controller_constraints': controller_constraints,
'compute_constraints': compute_constraints,
'controller_compute_constraints':
controller_compute_constraints,
'storage_constraints': storage_constraints
})
jvars.update({
'controller_nodes': str(controller_nodes),
'compute_nodes': str(compute_nodes),
'storage_nodes': str(storage_nodes),
'all_nodes': str(all_nodes)
})
def get_marathon_framework(jvars):
try:
mframework = jvars['marathon_framework']
except KeyError:
mframework = mesos_utils.get_marathon()
if mframework is not None:
jvars.update({'marathon_framework': mframework})
else:
raise exception.UndefinedOption(
'Please define marathon_framework')
LOG.info('Marathon framework: %s' % mframework)