5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
20 from ansible.errors import AnsibleError
23 def cpulist_to_set(cl):
25 for e in cl.split(','):
30 r.update(map(str, range(int(p[0]), int(p[1]) + 1)))
34 def set_to_cpulist(cs):
36 for k, g in itertools.groupby(enumerate(sorted(cs, key=int)), lambda (i, v): int(v) - i):
39 r.append(str(t[0][1]))
41 r.append('-'.join([str(t[0][1]), str(t[-1][1])]))
45 def _validate_node(topo, node, count):
47 raise AnsibleError("Unknown NUMA node '%s' (known nodes: %s)"
48 % (node, ', '.join(topo.keys())))
49 if len(topo[node]) < count:
50 raise AnsibleError("Cannot allocate %d CPUs in NUMA node '%s' (%d CPUs available)"
51 % (count, node, len(topo[node])))
54 def cpu_topology_alloc(topo, req, where='head'):
56 for node, count in req.iteritems():
57 _validate_node(topo, node, count)
61 for i in topo[node][-count:]:
64 for i in topo[node][:count]:
69 def cpu_topology_trim(topo, req, where='head'):
70 for node, count in req.iteritems():
71 _validate_node(topo, node, count)
75 topo[node] = topo[node][:-count]
77 topo[node] = topo[node][count:]
82 return [int(x) if x.isdigit() else x for x in re.split(r'([0-9]+)', k)]
85 def cpu_topology_defaults(topo, srv, req, is_virtual=False, is_single=False):
101 if 'shared' in req[s]:
102 shared = max(shared, req[s]['shared'])
104 platform = own + shared
108 nodes = [{'node': n, 'count': len(topo[n])} for n in sorted(topo, key=_natural_sort)]
117 if i['node'] not in r:
130 def get_cpu_count_by_percent(topo, percent):
132 n: int(_amount_with_minimum(len(topo[n]), float(percent)))
133 for n in sorted(topo, key=_natural_sort)}
136 def _amount_with_minimum(whole, percent):
137 amount = (whole * percent) / 100.0
138 return amount if 0 < int(amount) else 1
141 class FilterModule(object):
144 'cpulist_to_set': cpulist_to_set,
145 'set_to_cpulist': set_to_cpulist,
146 'cpu_topology_alloc': cpu_topology_alloc,
147 'cpu_topology_trim': cpu_topology_trim,
148 'cpu_topology_defaults': cpu_topology_defaults,
149 'get_cpu_count_by_percent': get_cpu_count_by_percent,