1
# Copyright (c) 2013 Mirantis Inc.
3
# Licensed under the Apache License, Version 2.0 (the "License");
4
# you may not use this file except in compliance with the License.
5
# You may obtain a copy of the License at
7
# http://www.apache.org/licenses/LICENSE-2.0
9
# Unless required by applicable law or agreed to in writing, software
10
# distributed under the License is distributed on an "AS IS" BASIS,
11
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13
# See the License for the specific language governing permissions and
14
# limitations under the License.
18
from oslo.config import cfg
20
from sahara import context
21
from sahara import exceptions as ex
22
from sahara.i18n import _
23
from sahara.i18n import _LI
24
from sahara.openstack.common import log
25
from sahara.utils.openstack import nova
26
from sahara.utils import xmlutils as x
30
"topology.node.switch.mapping.impl":
31
"org.apache.hadoop.net.ScriptBasedMapping",
32
"topology.script.file.name":
33
"/etc/hadoop/topology.sh"
36
LOG = log.getLogger(__name__)
39
cfg.BoolOpt('enable_data_locality',
41
help="""Enables data locality for hadoop cluster.
42
Also enables data locality for Swift used by hadoop.
43
If enabled, 'compute_topology' and 'swift_topology'
44
configuration parameters should point to OpenStack and Swift
45
topology correspondingly."""),
46
cfg.BoolOpt('enable_hypervisor_awareness',
48
help="""Enables four-level topology for data locality.
49
Works only if corresponding plugin supports such mode."""),
50
cfg.StrOpt('compute_topology_file',
51
default='etc/sahara/compute.topology',
52
help="""File with nova compute topology.
53
It should contain mapping between nova computes and racks.
58
cfg.StrOpt('swift_topology_file',
59
default='etc/sahara/swift.topology',
60
help="""File with Swift topology.
61
It should contain mapping between Swift nodes and racks.
69
CONF.register_opts(opts)
72
def _read_swift_topology():
73
LOG.debug("Reading Swift nodes topology from %s", CONF.swift_topology_file)
76
with open(CONF.swift_topology_file) as f:
81
(host, path) = line.split()
84
LOG.debug("Unable to read Swift nodes topology from %s",
85
CONF.swift_topology_file)
91
def _read_compute_topology():
92
LOG.debug("Reading compute nodes topology from %s",
93
CONF.compute_topology_file)
95
tenant_id = str(ctx.tenant_id)
98
with open(CONF.compute_topology_file) as f:
103
(host, path) = line.split()
104
# Calulating host id based on tenant id and host
105
# using the same algorithm as in nova
106
# see nova/api/openstack/compute/views/servers.py
107
# def _get_host_id(instance):
108
sha_hash = hashlib.sha224(tenant_id + host)
109
topology[sha_hash.hexdigest()] = path
111
raise ex.NotFoundException(
112
CONF.compute_topology_file,
113
_("Unable to find file %s with compute topology"))
117
def generate_topology_map(cluster, is_node_awareness):
118
mapping = _read_compute_topology()
119
nova_client = nova.client()
120
topology_mapping = {}
121
for ng in cluster.node_groups:
122
for i in ng.instances:
123
# TODO(alazarev) get all servers info with one request
124
ni = nova_client.servers.get(i.instance_id)
126
if hostId not in mapping:
127
raise ex.NotFoundException(
129
_("Was not able to find compute node topology for VM %s"))
130
rack = mapping[hostId]
131
if is_node_awareness:
134
topology_mapping[i.instance_name] = rack
135
topology_mapping[i.management_ip] = rack
136
topology_mapping[i.internal_ip] = rack
138
topology_mapping.update(_read_swift_topology())
140
return topology_mapping
143
def vm_awareness_core_config():
144
c = x.load_hadoop_xml_defaults('topology/resources/core-template.xml')
145
result = [cfg for cfg in c if cfg['value']]
147
if not CONF.enable_hypervisor_awareness:
148
# not leveraging 4-layer approach so override template value
149
param = next((prop for prop in result
150
if prop['name'] == 'net.topology.impl'), None)
152
param['value'] = 'org.apache.hadoop.net.NetworkTopology'
154
LOG.info(_LI("Vm awareness will add following configs in core-site "
155
"params: %s"), result)
159
def vm_awareness_mapred_config():
160
c = x.load_hadoop_xml_defaults('topology/resources/mapred-template.xml')
161
result = [cfg for cfg in c if cfg['value']]
162
LOG.info(_LI("Vm awareness will add following configs in map-red "
163
"params: %s"), result)
167
def vm_awareness_all_config():
168
return vm_awareness_core_config() + vm_awareness_mapred_config()