kolla-mesos/kolla_mesos/commands.py

172 lines
5.5 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 os
import socket
import yaml
from oslo_config import cfg
from oslo_log import log as logging
from kolla_mesos.common import jinja_utils
from kolla_mesos.common import mesos_utils
from kolla_mesos.common import zk_utils
from kolla_mesos import service_definition
LOG = logging.getLogger()
CONF = cfg.CONF
CONF.import_group('kolla', 'kolla_mesos.config.kolla')
def _get_task_from_cmd(role, cmd, cmd_info):
reg = '/kolla/%s/status/global/%s/%s' % (CONF.kolla.deployment_id,
role, cmd)
task = {'register': reg, 'requires': []}
dependencies = cmd_info.get('dependencies', None) or []
for dep in dependencies:
path = dep['path']
scope = dep.get('scope', 'global')
if scope == 'global':
task['requires'].append(
'/kolla/%s/status/global/%s' % (CONF.kolla.deployment_id,
path))
elif scope == 'local':
task['requires'].append(
'/kolla/%s/status/%s/%s' % (CONF.kolla.deployment_id,
socket.gethostname(),
path))
return task
def _get_config_tasks(config_path, tasks):
controller_nodes, compute_nodes, storage_nodes, all_nodes = \
mesos_utils.get_number_of_nodes()
mini_vars = {'cinder_volume_driver': 'lvm',
'deployment_id': CONF.kolla.deployment_id,
'controller_nodes': str(controller_nodes),
'compute_nodes': str(compute_nodes),
'storage_nodes': str(storage_nodes),
'all_nodes': str(all_nodes)}
config = yaml.load(jinja_utils.jinja_render(config_path, mini_vars))
def get_commands():
for cmd in config.get('commands', {}):
yield cmd, config['commands'][cmd]
if 'service' in config:
yield 'daemon', config['service']['daemon']
_, _, role = config['name'].split('/')
for cmd, cmd_info in get_commands():
task_name = '%s/%s' % (role, cmd)
tasks[task_name] = _get_task_from_cmd(role, cmd, cmd_info)
return tasks
def get_tasks(config_path):
"""Get list of tasks.
Reads through all the kolla mesos services config files located in
config_path and parses the requirements and resister options.
:returns: a dictionary of all the values registered by tasks
Below is an example of what can be returned::
{
taskpath1: {
'requires': [require1, require2...]
'register': register_path
}
}
taskpath examples -
'keystone/keystone/db_sync',
'keystone/keystone_ansible_tasks/create_database',
"""
tasks = {}
if os.path.isfile(config_path):
_get_config_tasks(config_path, tasks)
else:
for root, _, files in os.walk(config_path):
for name in files:
if 'default.' in name:
continue
fpath = os.path.join(root, name)
_get_config_tasks(fpath, tasks)
return tasks
def get_service_tasks(service_name, service_dir):
if '/' not in service_name:
service_name = service_name.replace('-', '/')
config_path = service_definition.find_service_file(
service_name, service_dir)
return get_tasks(config_path)
def get_status(tasks):
"""Get status from zookeeper.
:returns: the status for each task
Below is an example of what can be returned::
{
task1: {
'register': (register_path, reg_status)
'requirements': {
reqt1_path: reqt_status
reqt2_path: reqt_status
...
}
}
}
Where:
reg_status = 'done', 'running', 'waiting'
reqt_status = '', 'done'
"""
status = {}
with zk_utils.connection() as zk:
# get status of requirements
for task, info in tasks.items():
status[task] = {}
status[task]['requirements'] = {}
for path in info['requires']:
req_status = ''.encode('utf-8')
if zk.exists(path):
req_status, _ = zk.get(path)
status[task]['requirements'][path] = req_status.decode('utf-8')
# get status of registrations
for task, info in tasks.items():
status[task]['register'] = {}
reg_path = info['register']
reg_status = ''.encode('utf-8')
if zk.exists(reg_path):
reg_status, _ = zk.get(reg_path)
status[task]['register'] = (reg_path, reg_status.decode('utf-8'))
return status
def get_service_status(service_name, service_dir):
tasks = get_service_tasks(service_name, service_dir)
return get_status(tasks)
def get_deployment_status(service_dir):
tasks = get_tasks(service_dir)
return get_status(tasks)