Adding service-per-service support
New config section introduced: services: keystone-db: service_def: mariadb keystone: service_def: keystone mapping: database: keystone-db Defined services can be used in topology definition. In this example keystone-db service will be created from mariadb definition and keystone will use it instead of mariadb. Change-Id: I274826648390b844d240b7ae545c40264f662452
This commit is contained in:
parent
998dae2d40
commit
9942c0e978
@ -56,10 +56,19 @@ class Action(object):
|
|||||||
self.user_parameters = user_parameters
|
self.user_parameters = user_parameters
|
||||||
else:
|
else:
|
||||||
self.user_parameters = ()
|
self.user_parameters = ()
|
||||||
|
self._process_dependencies()
|
||||||
self._create_configmap()
|
self._create_configmap()
|
||||||
self._create_action()
|
self._create_action()
|
||||||
return self.k8s_name
|
return self.k8s_name
|
||||||
|
|
||||||
|
def _process_dependencies(self):
|
||||||
|
services_map = utils.get_deploy_components_info()
|
||||||
|
deps_map = utils.get_dependencies_map(services_map)
|
||||||
|
new_deps = []
|
||||||
|
for dep in self.dependencies:
|
||||||
|
new_deps.extend(utils.extend_dependency(dep, deps_map, {}, {}))
|
||||||
|
self.dependencies = new_deps
|
||||||
|
|
||||||
# configmap methods
|
# configmap methods
|
||||||
|
|
||||||
def _create_configmap(self):
|
def _create_configmap(self):
|
||||||
|
@ -131,7 +131,7 @@ def _cleanup_openstack_environment(configs, auth_url=None, verify=True):
|
|||||||
'is not deployed')
|
'is not deployed')
|
||||||
|
|
||||||
configs['auth_url'] = auth_url or '%s/v3' % utils.address(
|
configs['auth_url'] = auth_url or '%s/v3' % utils.address(
|
||||||
'keystone', configs['keystone']['public_port'], True, True)
|
{}, 'keystone', configs['keystone']['public_port'], True, True)
|
||||||
|
|
||||||
session = _get_session(
|
session = _get_session(
|
||||||
configs['auth_url'], configs['openstack']['user_name'],
|
configs['auth_url'], configs['openstack']['user_name'],
|
||||||
|
@ -3,6 +3,7 @@ import logging
|
|||||||
import os
|
import os
|
||||||
import pkg_resources
|
import pkg_resources
|
||||||
|
|
||||||
|
import jinja2
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
import fuel_ccp
|
import fuel_ccp
|
||||||
@ -60,7 +61,8 @@ def get_config_paths():
|
|||||||
return paths
|
return paths
|
||||||
|
|
||||||
|
|
||||||
def address(service, port=None, external=False, with_scheme=False):
|
@jinja2.contextfunction
|
||||||
|
def address(ctx, service, port=None, external=False, with_scheme=False):
|
||||||
addr = None
|
addr = None
|
||||||
service_name = service.split('-')[0]
|
service_name = service.split('-')[0]
|
||||||
enable_tls = CONF.configs.get(service_name, {}).get(
|
enable_tls = CONF.configs.get(service_name, {}).get(
|
||||||
@ -81,6 +83,15 @@ def address(service, port=None, external=False, with_scheme=False):
|
|||||||
elif port.get('node'):
|
elif port.get('node'):
|
||||||
addr = '%s:%s' % (CONF.configs.k8s_external_ip, port['node'])
|
addr = '%s:%s' % (CONF.configs.k8s_external_ip, port['node'])
|
||||||
|
|
||||||
|
current_service = ctx.get('_current_service')
|
||||||
|
if current_service:
|
||||||
|
current_service_def = CONF.services.get(current_service, {}).get(
|
||||||
|
'service_def')
|
||||||
|
if current_service_def == service:
|
||||||
|
service = current_service
|
||||||
|
else:
|
||||||
|
service = CONF.services.get(current_service, {}).get(
|
||||||
|
'mapping', {}).get(service) or service
|
||||||
if addr is None:
|
if addr is None:
|
||||||
addr = '.'.join((service, CONF.kubernetes.namespace, 'svc',
|
addr = '.'.join((service, CONF.kubernetes.namespace, 'svc',
|
||||||
CONF.kubernetes.cluster_domain))
|
CONF.kubernetes.cluster_domain))
|
||||||
@ -122,10 +133,60 @@ def get_component_name_from_repo_path(path):
|
|||||||
return name
|
return name
|
||||||
|
|
||||||
|
|
||||||
|
def get_service_definitions_map():
|
||||||
|
"""Maps each service definition to its custom services"""
|
||||||
|
s_d_map = {}
|
||||||
|
for service_name, value in CONF.services._items():
|
||||||
|
s_d_map.setdefault(value['service_def'], [])
|
||||||
|
s_d_map[value['service_def']].append(service_name)
|
||||||
|
return s_d_map
|
||||||
|
|
||||||
|
|
||||||
|
def extend_dependency(dep, deps_map, services_map, service_mapping):
|
||||||
|
"""Extends dependencies with service prefix"""
|
||||||
|
dep_name = dep.split(':')[0]
|
||||||
|
if dep_name not in deps_map:
|
||||||
|
# dependency is not a container or job
|
||||||
|
# checking service mapping first
|
||||||
|
if dep_name in service_mapping:
|
||||||
|
dep_name = service_mapping[dep_name]
|
||||||
|
service_ref = services_map[dep_name]
|
||||||
|
elif dep_name in services_map:
|
||||||
|
service_ref = services_map[dep_name]
|
||||||
|
else:
|
||||||
|
raise RuntimeError('Dependency "%s" not found' % dep_name)
|
||||||
|
# adjust deps with container names of the service
|
||||||
|
return ["%s/%s" % (dep_name, cnt['name']) for cnt in service_ref[
|
||||||
|
'service_content']['service']['containers']]
|
||||||
|
|
||||||
|
dep_service_def = deps_map[dep_name]
|
||||||
|
dep_service_name = service_mapping.get(
|
||||||
|
dep_service_def) or dep_service_def
|
||||||
|
return ["%s/%s" % (dep_service_name, dep)]
|
||||||
|
|
||||||
|
|
||||||
|
def process_dependencies(service, deps_map, services_map):
|
||||||
|
service_name = service['service_content']['service']['name']
|
||||||
|
service_mapping = CONF.services.get(service_name, {}).get('mapping', {})
|
||||||
|
containers = service['service_content']['service']['containers']
|
||||||
|
for cont in containers:
|
||||||
|
for cmd in itertools.chain(
|
||||||
|
cont.get('pre', []), [cont.get('daemon', [])],
|
||||||
|
cont.get('post', [])):
|
||||||
|
if cmd.get('dependencies'):
|
||||||
|
new_deps = []
|
||||||
|
for dep in cmd['dependencies']:
|
||||||
|
new_deps.extend(extend_dependency(
|
||||||
|
dep, deps_map, services_map, service_mapping))
|
||||||
|
cmd['dependencies'] = new_deps
|
||||||
|
|
||||||
|
|
||||||
def get_deploy_components_info(rendering_context=None):
|
def get_deploy_components_info(rendering_context=None):
|
||||||
if rendering_context is None:
|
if rendering_context is None:
|
||||||
rendering_context = CONF.configs._dict
|
rendering_context = CONF.configs._dict
|
||||||
components_map = {}
|
service_definitions_map = get_service_definitions_map()
|
||||||
|
services_map = {}
|
||||||
|
custom_services_map = {}
|
||||||
|
|
||||||
for repo in get_repositories_paths():
|
for repo in get_repositories_paths():
|
||||||
service_dir = os.path.join(repo, "service")
|
service_dir = os.path.join(repo, "service")
|
||||||
@ -160,18 +221,44 @@ def get_deploy_components_info(rendering_context=None):
|
|||||||
LOG.debug("Parse service definition: %s", service_file)
|
LOG.debug("Parse service definition: %s", service_file)
|
||||||
service_definition = yaml.load(content)
|
service_definition = yaml.load(content)
|
||||||
service_name = service_definition['service']['name']
|
service_name = service_definition['service']['name']
|
||||||
components_map[service_name] = {
|
services_map[service_name] = {
|
||||||
'component': component,
|
'component': component,
|
||||||
'component_name': component_name,
|
'component_name': component_name,
|
||||||
'service_dir': service_dir,
|
'service_dir': service_dir,
|
||||||
'service_content': service_definition
|
'service_content': service_definition
|
||||||
}
|
}
|
||||||
return components_map
|
for svc in service_definitions_map.get(service_name, ()):
|
||||||
|
LOG.debug("Rendering service definition: %s for '%s' "
|
||||||
|
"service", service_file, svc)
|
||||||
|
context = rendering_context.copy()
|
||||||
|
context['_current_service'] = svc
|
||||||
|
content = jinja_utils.jinja_render(
|
||||||
|
os.path.join(service_dir, service_file),
|
||||||
|
context, functions=[address]
|
||||||
|
)
|
||||||
|
LOG.debug("Parse service definition: %s for '%s' "
|
||||||
|
"service", service_file, svc)
|
||||||
|
service_definition = yaml.load(content)
|
||||||
|
service_definition['service']['name'] = svc
|
||||||
|
custom_services_map[svc] = {
|
||||||
|
'component': component,
|
||||||
|
'component_name': component_name,
|
||||||
|
'service_dir': service_dir,
|
||||||
|
'service_content': service_definition
|
||||||
|
}
|
||||||
|
|
||||||
|
deps_map = get_dependencies_map(services_map)
|
||||||
|
services_map.update(custom_services_map)
|
||||||
|
for svc_name, svc in services_map.items():
|
||||||
|
process_dependencies(svc, deps_map, services_map)
|
||||||
|
|
||||||
|
return services_map
|
||||||
|
|
||||||
|
|
||||||
def get_dependencies_map(components_map):
|
def get_dependencies_map(services_map):
|
||||||
|
"""Maps each container and job to its service"""
|
||||||
deps_map = {}
|
deps_map = {}
|
||||||
for service_name, service in components_map.items():
|
for service_name, service in services_map.items():
|
||||||
containers = service['service_content']['service']['containers']
|
containers = service['service_content']['service']['containers']
|
||||||
for cont in containers:
|
for cont in containers:
|
||||||
deps_map[cont['name']] = service_name
|
deps_map[cont['name']] = service_name
|
||||||
|
@ -12,6 +12,7 @@ from fuel_ccp.config import kubernetes
|
|||||||
from fuel_ccp.config import registry
|
from fuel_ccp.config import registry
|
||||||
from fuel_ccp.config import replicas
|
from fuel_ccp.config import replicas
|
||||||
from fuel_ccp.config import repositories
|
from fuel_ccp.config import repositories
|
||||||
|
from fuel_ccp.config import services
|
||||||
from fuel_ccp.config import sources
|
from fuel_ccp.config import sources
|
||||||
from fuel_ccp.config import url
|
from fuel_ccp.config import url
|
||||||
|
|
||||||
@ -56,7 +57,7 @@ CONF = _Wrapper()
|
|||||||
|
|
||||||
CONFIG_MODULES = [
|
CONFIG_MODULES = [
|
||||||
builder, cli, images, kubernetes, registry, replicas, repositories,
|
builder, cli, images, kubernetes, registry, replicas, repositories,
|
||||||
sources, url, files,
|
sources, url, files, services,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@ -117,7 +118,7 @@ def load_component_defaults():
|
|||||||
from fuel_ccp.common import utils
|
from fuel_ccp.common import utils
|
||||||
|
|
||||||
sections = ['versions', 'sources', 'configs', 'nodes', 'roles', 'replicas',
|
sections = ['versions', 'sources', 'configs', 'nodes', 'roles', 'replicas',
|
||||||
'url', 'files']
|
'url', 'files', 'services']
|
||||||
new_config = _yaml.AttrDict((k, _yaml.AttrDict()) for k in sections)
|
new_config = _yaml.AttrDict((k, _yaml.AttrDict()) for k in sections)
|
||||||
for path in utils.get_config_paths():
|
for path in utils.get_config_paths():
|
||||||
if not os.path.exists(path):
|
if not os.path.exists(path):
|
||||||
@ -134,6 +135,7 @@ def load_component_defaults():
|
|||||||
new_config['configs']['namespace'] = _REAL_CONF.kubernetes.namespace
|
new_config['configs']['namespace'] = _REAL_CONF.kubernetes.namespace
|
||||||
new_config['configs'][
|
new_config['configs'][
|
||||||
'cluster_domain'] = _REAL_CONF.kubernetes.cluster_domain
|
'cluster_domain'] = _REAL_CONF.kubernetes.cluster_domain
|
||||||
|
new_config['configs']['services'] = _REAL_CONF.services
|
||||||
new_config._merge(_REAL_CONF)
|
new_config._merge(_REAL_CONF)
|
||||||
# FIXME workaround to not deep merge 'sources' config
|
# FIXME workaround to not deep merge 'sources' config
|
||||||
for k, v in _REAL_CONF.sources._items():
|
for k, v in _REAL_CONF.sources._items():
|
||||||
|
17
fuel_ccp/config/services.py
Normal file
17
fuel_ccp/config/services.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
SCHEMA = {
|
||||||
|
"services": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": False,
|
||||||
|
"required": ["service_def"],
|
||||||
|
"properties": {
|
||||||
|
"service_def": {"type": "string"},
|
||||||
|
"mapping": {"type": "object"},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DEFAULTS = {
|
||||||
|
"services": {},
|
||||||
|
}
|
@ -12,147 +12,48 @@ Example:
|
|||||||
ccp --config-file=~/ccp.conf show-dep nova-api nova-compute
|
ccp --config-file=~/ccp.conf show-dep nova-api nova-compute
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import itertools
|
||||||
import logging
|
import logging
|
||||||
import re
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from fuel_ccp.common import utils
|
from fuel_ccp.common import utils
|
||||||
from fuel_ccp.validation import base as base_validation
|
from fuel_ccp.validation import base as base_validation
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
YAML_FILE_RE = re.compile(r'\.yaml$')
|
|
||||||
|
def get_service_deps(graph, service):
|
||||||
|
visited, stack = set(), [service]
|
||||||
|
while stack:
|
||||||
|
vertex = stack.pop()
|
||||||
|
if vertex not in visited:
|
||||||
|
visited.add(vertex)
|
||||||
|
stack.extend(graph[vertex] - visited)
|
||||||
|
return visited
|
||||||
|
|
||||||
|
|
||||||
class Node(object):
|
def get_deps_graph(components_map=None):
|
||||||
"""Reperesents dependency. Service or job."""
|
|
||||||
|
|
||||||
def __init__(self, name, sort, dependencies=None, job_parent=None):
|
|
||||||
self.name = name
|
|
||||||
self.sort = sort
|
|
||||||
if sort not in ['service', 'job']:
|
|
||||||
msg = "'sort' attribute must be 'service' or 'job' not \
|
|
||||||
'{sort}'".format(sort=sort)
|
|
||||||
raise ValueError(msg)
|
|
||||||
|
|
||||||
self.dependencies = dependencies or []
|
|
||||||
self.job_parent = job_parent
|
|
||||||
|
|
||||||
if self.sort == 'job' and self.job_parent is None:
|
|
||||||
msg = "'job_parent' attribute for 'job' mustn't be None"
|
|
||||||
raise ValueError(msg)
|
|
||||||
|
|
||||||
def is_service(self):
|
|
||||||
return self.sort == 'service'
|
|
||||||
|
|
||||||
|
|
||||||
def get_deps_map(components_map=None):
|
|
||||||
"""Returns dependencies map."""
|
"""Returns dependencies map."""
|
||||||
components_map = components_map or utils.get_deploy_components_info()
|
components_map = components_map or utils.get_deploy_components_info()
|
||||||
|
deps_graph = {}
|
||||||
deps_map = {}
|
for service_name, service in components_map.items():
|
||||||
for service_name, service_map in components_map.items():
|
deps_graph[service_name] = set()
|
||||||
deps_map[service_name] = Node(
|
containers = service['service_content']['service']['containers']
|
||||||
service_name, 'service', _parse_service_deps(
|
for cont in containers:
|
||||||
service_map['service_content']))
|
for cmd in itertools.chain(
|
||||||
deps_map.update(_parse_pre_and_post_deps(
|
cont.get('pre', []), [cont.get('daemon', [])],
|
||||||
service_map['service_content']))
|
cont.get('post', [])):
|
||||||
|
for dep in cmd.get('dependencies', ()):
|
||||||
return deps_map
|
deps_graph[service_name].add(dep.partition("/")[0])
|
||||||
|
return deps_graph
|
||||||
|
|
||||||
|
|
||||||
def _prepare_deps(deps):
|
def get_deps(components, components_map):
|
||||||
return [dep.partition(":")[0] for dep in deps]
|
deps_graph = get_deps_graph(components_map)
|
||||||
|
|
||||||
|
|
||||||
def _parse_service_deps(service_map):
|
|
||||||
"""Parses service map and finds dependencies of daemons."""
|
|
||||||
dependencies = set()
|
dependencies = set()
|
||||||
for container in service_map['service']['containers']:
|
for component in components:
|
||||||
cont_deps = container['daemon'].get('dependencies', [])
|
dependencies.update(get_service_deps(deps_graph, component))
|
||||||
dependencies.update(_prepare_deps(cont_deps))
|
dependencies.add("etcd")
|
||||||
for pre in container.get('pre', []):
|
return dependencies - set(components)
|
||||||
if pre.get('type') == 'single':
|
|
||||||
dependencies.update([pre['name']])
|
|
||||||
else:
|
|
||||||
deps = _prepare_deps(pre.get('dependencies', []))
|
|
||||||
dependencies.update(deps)
|
|
||||||
for post in container.get('post', []):
|
|
||||||
if post.get('type') != 'single':
|
|
||||||
deps = _prepare_deps(post.get('dependencies', []))
|
|
||||||
dependencies.update(deps)
|
|
||||||
return list(dependencies)
|
|
||||||
|
|
||||||
|
|
||||||
def _parse_pre_and_post_deps(service_map):
|
|
||||||
"""Parses service map and finds pres and their dependencies."""
|
|
||||||
deps = {}
|
|
||||||
for container in service_map['service']['containers']:
|
|
||||||
for pre in container.get('pre', []):
|
|
||||||
pre_deps = _prepare_deps(pre.get('dependencies', []))
|
|
||||||
deps[pre['name']] = Node(pre['name'],
|
|
||||||
'job',
|
|
||||||
pre_deps,
|
|
||||||
service_map['service']['name'])
|
|
||||||
|
|
||||||
for post in container.get('post', []):
|
|
||||||
if post.get('type') == 'single':
|
|
||||||
post_deps = _prepare_deps(post.get('dependencies', []))
|
|
||||||
post_deps.append(service_map['service']['name'])
|
|
||||||
deps[post['name']] = Node(post['name'],
|
|
||||||
'job',
|
|
||||||
post_deps,
|
|
||||||
service_map['service']['name'])
|
|
||||||
return deps
|
|
||||||
|
|
||||||
|
|
||||||
def _calculate_service_deps(service_name, deps_map):
|
|
||||||
if service_name not in deps_map:
|
|
||||||
msg = "Wrong component name '{}'".format(service_name)
|
|
||||||
LOG.error(msg)
|
|
||||||
sys.exit(1)
|
|
||||||
deps = set()
|
|
||||||
job_parents = set()
|
|
||||||
current_iteration_set = {deps_map[service_name]}
|
|
||||||
|
|
||||||
while current_iteration_set:
|
|
||||||
next_iteration_set = set()
|
|
||||||
for dep in current_iteration_set:
|
|
||||||
if deps_map[dep.name].is_service():
|
|
||||||
deps.update([deps_map[dep.name]])
|
|
||||||
else:
|
|
||||||
job_parents.update([dep.job_parent])
|
|
||||||
|
|
||||||
for dep in current_iteration_set:
|
|
||||||
for dependency in deps_map[dep.name].dependencies:
|
|
||||||
next_iteration_set.update([deps_map[dependency]])
|
|
||||||
current_iteration_set = next_iteration_set
|
|
||||||
|
|
||||||
deps = {dep.name for dep in deps}
|
|
||||||
return deps, job_parents
|
|
||||||
|
|
||||||
|
|
||||||
def get_deps(components, components_map=None):
|
|
||||||
deps_map = get_deps_map(components_map)
|
|
||||||
result_deps = set()
|
|
||||||
for service_name in components:
|
|
||||||
deps, job_parents = _calculate_service_deps(service_name, deps_map)
|
|
||||||
checked = {service_name}
|
|
||||||
|
|
||||||
while True:
|
|
||||||
deps.update(job_parents)
|
|
||||||
if not job_parents - checked:
|
|
||||||
break
|
|
||||||
for parent in job_parents - checked:
|
|
||||||
parent_deps, parent_parents = _calculate_service_deps(
|
|
||||||
parent, deps_map)
|
|
||||||
deps.update(parent_deps)
|
|
||||||
checked.update(job_parents - checked)
|
|
||||||
job_parents.update(parent_parents)
|
|
||||||
result_deps.update(deps)
|
|
||||||
result_deps.add('etcd')
|
|
||||||
|
|
||||||
return result_deps - set(components)
|
|
||||||
|
|
||||||
|
|
||||||
def show_dep(components):
|
def show_dep(components):
|
||||||
|
@ -193,10 +193,10 @@ def _create_job_wfs(container, service_name):
|
|||||||
wfs = {}
|
wfs = {}
|
||||||
for job in container.get("pre", ()):
|
for job in container.get("pre", ()):
|
||||||
if _is_single_job(job):
|
if _is_single_job(job):
|
||||||
wfs.update(_create_job_wf(job, service_name))
|
wfs.update(_create_job_wf(job, service_name, container))
|
||||||
for job in container.get("post", ()):
|
for job in container.get("post", ()):
|
||||||
if _is_single_job(job):
|
if _is_single_job(job):
|
||||||
wfs.update(_create_job_wf(job, service_name, True))
|
wfs.update(_create_job_wf(job, service_name, container, True))
|
||||||
return wfs
|
return wfs
|
||||||
|
|
||||||
|
|
||||||
@ -305,7 +305,8 @@ def _get_job(service, container, job, component_name, topology):
|
|||||||
cont_spec = templates.serialize_job_container_spec(container, job)
|
cont_spec = templates.serialize_job_container_spec(container, job)
|
||||||
pod_spec = templates.serialize_job_pod_spec(service, job, cont_spec,
|
pod_spec = templates.serialize_job_pod_spec(service, job, cont_spec,
|
||||||
affinity)
|
affinity)
|
||||||
job_spec = templates.serialize_job(job["name"], pod_spec, component_name,
|
job_name = "%s-%s" % (service["name"], job["name"])
|
||||||
|
job_spec = templates.serialize_job(job_name, pod_spec, component_name,
|
||||||
service["name"])
|
service["name"])
|
||||||
return job_spec
|
return job_spec
|
||||||
|
|
||||||
@ -317,12 +318,12 @@ def _create_command(workflow, cmd):
|
|||||||
workflow.append(cmd_flow)
|
workflow.append(cmd_flow)
|
||||||
|
|
||||||
|
|
||||||
def _create_job_wf(job, service_name, post=False):
|
def _create_job_wf(job, service_name, cont, post=False):
|
||||||
wrk = {}
|
wrk = {}
|
||||||
wrk["name"] = "%s/%s" % (service_name, job["name"])
|
wrk["name"] = "%s/%s" % (service_name, job["name"])
|
||||||
wrk["dependencies"] = job.get("dependencies", [])
|
wrk["dependencies"] = job.get("dependencies", [])
|
||||||
if post:
|
if post:
|
||||||
wrk["dependencies"].append(service_name)
|
wrk["dependencies"].append("%s/%s" % (service_name, cont["name"]))
|
||||||
wrk["job"] = {}
|
wrk["job"] = {}
|
||||||
_fill_cmd(wrk["job"], job)
|
_fill_cmd(wrk["job"], job)
|
||||||
_push_files_to_workflow(wrk, job.get("files"))
|
_push_files_to_workflow(wrk, job.get("files"))
|
||||||
@ -484,7 +485,7 @@ def _create_openrc(config):
|
|||||||
"export OS_PASSWORD=%s" % config['openstack']['user_password'],
|
"export OS_PASSWORD=%s" % config['openstack']['user_password'],
|
||||||
"export OS_IDENTITY_API_VERSION=3",
|
"export OS_IDENTITY_API_VERSION=3",
|
||||||
"export OS_AUTH_URL=%s/v3" %
|
"export OS_AUTH_URL=%s/v3" %
|
||||||
utils.address('keystone', config['keystone']['public_port'], True,
|
utils.address({}, 'keystone', config['keystone']['public_port'], True,
|
||||||
True)
|
True)
|
||||||
]
|
]
|
||||||
if config['security']['tls']['create_certificates']:
|
if config['security']['tls']['create_certificates']:
|
||||||
@ -616,17 +617,6 @@ def _create_registry_secret():
|
|||||||
kubernetes.process_object(secret)
|
kubernetes.process_object(secret)
|
||||||
|
|
||||||
|
|
||||||
def process_dependencies(service, deps_map):
|
|
||||||
containers = service['service_content']['service']['containers']
|
|
||||||
for cont in containers:
|
|
||||||
for cmd in itertools.chain(
|
|
||||||
cont.get('pre', []), [cont['daemon']],
|
|
||||||
cont.get('post', [])):
|
|
||||||
cmd['dependencies'] = ["%s/%s" % (
|
|
||||||
deps_map[dep.split(':')[0]], dep) for dep in cmd.get(
|
|
||||||
'dependencies', [])]
|
|
||||||
|
|
||||||
|
|
||||||
def deploy_components(components_map, components):
|
def deploy_components(components_map, components):
|
||||||
|
|
||||||
topology = _make_topology(CONF.nodes, CONF.roles, CONF.replicas)
|
topology = _make_topology(CONF.nodes, CONF.roles, CONF.replicas)
|
||||||
@ -656,14 +646,11 @@ def deploy_components(components_map, components):
|
|||||||
exports_cm = _create_exports_configmap(exports_map)
|
exports_cm = _create_exports_configmap(exports_map)
|
||||||
exports_ctx = {'files_header': j2_imports_files_header, 'map': exports_map}
|
exports_ctx = {'files_header': j2_imports_files_header, 'map': exports_map}
|
||||||
|
|
||||||
deps_map = utils.get_dependencies_map(components_map)
|
|
||||||
|
|
||||||
configmaps = (start_script_cm, exports_cm)
|
configmaps = (start_script_cm, exports_cm)
|
||||||
|
|
||||||
upgrading_components = {}
|
upgrading_components = {}
|
||||||
for service_name in components:
|
for service_name in components:
|
||||||
service = components_map[service_name]
|
service = components_map[service_name]
|
||||||
process_dependencies(service, deps_map)
|
|
||||||
service["service_content"]['service']['exports_ctx'] = exports_ctx
|
service["service_content"]['service']['exports_ctx'] = exports_ctx
|
||||||
objects_gen = parse_role(service, topology, configmaps)
|
objects_gen = parse_role(service, topology, configmaps)
|
||||||
objects = list(itertools.chain.from_iterable(objects_gen))
|
objects = list(itertools.chain.from_iterable(objects_gen))
|
||||||
|
@ -18,8 +18,6 @@ service:
|
|||||||
- name: chown-logs-dir
|
- name: chown-logs-dir
|
||||||
command: "sudo /bin/chown keystone:keystone /var/log/ccp/keystone"
|
command: "sudo /bin/chown keystone:keystone /var/log/ccp/keystone"
|
||||||
- name: keystone-db-create
|
- name: keystone-db-create
|
||||||
dependencies:
|
|
||||||
- galera
|
|
||||||
type: single
|
type: single
|
||||||
command:
|
command:
|
||||||
mysql -u root -pdb_root_password_custom -h galera -e "create database keystone_db_name_custom;
|
mysql -u root -pdb_root_password_custom -h galera -e "create database keystone_db_name_custom;
|
||||||
@ -28,14 +26,14 @@ service:
|
|||||||
files:
|
files:
|
||||||
- keystone-conf
|
- keystone-conf
|
||||||
dependencies:
|
dependencies:
|
||||||
- keystone-db-create
|
- keystone/keystone-db-create
|
||||||
type: single
|
type: single
|
||||||
command: keystone-manage db_sync
|
command: keystone-manage db_sync
|
||||||
- name: keystone-db-bootstrap
|
- name: keystone-db-bootstrap
|
||||||
files:
|
files:
|
||||||
- keystone-conf
|
- keystone-conf
|
||||||
dependencies:
|
dependencies:
|
||||||
- keystone-db-sync
|
- keystone/keystone-db-sync
|
||||||
type: single
|
type: single
|
||||||
command: keystone-manage bootstrap
|
command: keystone-manage bootstrap
|
||||||
--bootstrap-password os_user_password_custom
|
--bootstrap-password os_user_password_custom
|
||||||
@ -48,8 +46,6 @@ service:
|
|||||||
--bootstrap-internal-url http://keystone:keystone_public_port_custom
|
--bootstrap-internal-url http://keystone:keystone_public_port_custom
|
||||||
|
|
||||||
daemon:
|
daemon:
|
||||||
dependencies:
|
|
||||||
- memcached
|
|
||||||
files:
|
files:
|
||||||
- keystone-conf
|
- keystone-conf
|
||||||
- wsgi-keystone-conf
|
- wsgi-keystone-conf
|
||||||
|
@ -18,8 +18,6 @@ service:
|
|||||||
- name: chown-logs-dir
|
- name: chown-logs-dir
|
||||||
command: "sudo /bin/chown keystone:keystone /var/log/ccp/keystone"
|
command: "sudo /bin/chown keystone:keystone /var/log/ccp/keystone"
|
||||||
- name: keystone-db-create
|
- name: keystone-db-create
|
||||||
dependencies:
|
|
||||||
- galera
|
|
||||||
type: single
|
type: single
|
||||||
command:
|
command:
|
||||||
mysql -u root -pdb_root_password_default -h galera -e "create database keystone_db_name_default;
|
mysql -u root -pdb_root_password_default -h galera -e "create database keystone_db_name_default;
|
||||||
@ -28,14 +26,14 @@ service:
|
|||||||
files:
|
files:
|
||||||
- keystone-conf
|
- keystone-conf
|
||||||
dependencies:
|
dependencies:
|
||||||
- keystone-db-create
|
- keystone/keystone-db-create
|
||||||
type: single
|
type: single
|
||||||
command: keystone-manage db_sync
|
command: keystone-manage db_sync
|
||||||
- name: keystone-db-bootstrap
|
- name: keystone-db-bootstrap
|
||||||
files:
|
files:
|
||||||
- keystone-conf
|
- keystone-conf
|
||||||
dependencies:
|
dependencies:
|
||||||
- keystone-db-sync
|
- keystone/keystone-db-sync
|
||||||
type: single
|
type: single
|
||||||
command: keystone-manage bootstrap
|
command: keystone-manage bootstrap
|
||||||
--bootstrap-password os_user_password_default
|
--bootstrap-password os_user_password_default
|
||||||
@ -48,8 +46,6 @@ service:
|
|||||||
--bootstrap-internal-url http://keystone:keystone_public_port_default
|
--bootstrap-internal-url http://keystone:keystone_public_port_default
|
||||||
|
|
||||||
daemon:
|
daemon:
|
||||||
dependencies:
|
|
||||||
- memcached
|
|
||||||
files:
|
files:
|
||||||
- keystone-conf
|
- keystone-conf
|
||||||
- wsgi-keystone-conf
|
- wsgi-keystone-conf
|
||||||
|
@ -19,8 +19,6 @@ service:
|
|||||||
- name: chown-logs-dir
|
- name: chown-logs-dir
|
||||||
command: "sudo /bin/chown {{ service_name }}:{{ service_name }} /var/log/ccp/{{ service_name }}"
|
command: "sudo /bin/chown {{ service_name }}:{{ service_name }} /var/log/ccp/{{ service_name }}"
|
||||||
- name: {{ service_name }}-db-create
|
- name: {{ service_name }}-db-create
|
||||||
dependencies:
|
|
||||||
- galera
|
|
||||||
type: single
|
type: single
|
||||||
command:
|
command:
|
||||||
mysql -u root -p{{ db_root_password }} -h galera -e "create database {{ keystone_db_name }};
|
mysql -u root -p{{ db_root_password }} -h galera -e "create database {{ keystone_db_name }};
|
||||||
@ -49,8 +47,6 @@ service:
|
|||||||
--bootstrap-internal-url http://{{ service_name }}:{{ keystone_public_port }}
|
--bootstrap-internal-url http://{{ service_name }}:{{ keystone_public_port }}
|
||||||
|
|
||||||
daemon:
|
daemon:
|
||||||
dependencies:
|
|
||||||
- memcached
|
|
||||||
files:
|
files:
|
||||||
- {{ service_name }}-conf
|
- {{ service_name }}-conf
|
||||||
- wsgi-{{ service_name }}-conf
|
- wsgi-{{ service_name }}-conf
|
||||||
|
@ -42,7 +42,7 @@ class TestUtils(base.TestCase):
|
|||||||
res = (
|
res = (
|
||||||
utils.get_deploy_components_info()["keystone"]["service_content"]
|
utils.get_deploy_components_info()["keystone"]["service_content"]
|
||||||
)
|
)
|
||||||
|
print(yaml.dump(res, default_flow_style=False))
|
||||||
with open(os.path.join(base_dir,
|
with open(os.path.join(base_dir,
|
||||||
"service-rendered-example-default.yaml")) as f:
|
"service-rendered-example-default.yaml")) as f:
|
||||||
expected = yaml.load(f)
|
expected = yaml.load(f)
|
||||||
@ -171,4 +171,4 @@ class TestAddress(testscenarios.WithScenarios, base.TestCase):
|
|||||||
self.conf.configs._merge(prepared_conf)
|
self.conf.configs._merge(prepared_conf)
|
||||||
|
|
||||||
self.assertEqual(self.address, utils.address(
|
self.assertEqual(self.address, utils.address(
|
||||||
'service', self.port, self.external, self.with_scheme))
|
{}, 'service', self.port, self.external, self.with_scheme))
|
||||||
|
@ -373,7 +373,7 @@ class TestDeployParseWorkflow(base.TestCase):
|
|||||||
"eric-mom": {
|
"eric-mom": {
|
||||||
"workflow": {
|
"workflow": {
|
||||||
"name": "south-park/eric-mom",
|
"name": "south-park/eric-mom",
|
||||||
"dependencies": ["eric-dad", "south-park"],
|
"dependencies": ["eric-dad", "south-park/kenny"],
|
||||||
"files": [
|
"files": [
|
||||||
{
|
{
|
||||||
"name": "eric",
|
"name": "eric",
|
||||||
|
Loading…
Reference in New Issue
Block a user