5ed0f74a9c
There should be a way to declaratively describe each space type and strategy of its allocation. Implements blueprint: dynamic-allocation Change-Id: I66c2f0b90fb94b0496b5d341817688a042161318
92 lines
2.9 KiB
Python
92 lines
2.9 KiB
Python
# Copyright 2016 Mirantis, Inc.
|
|
#
|
|
# 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.
|
|
|
|
from oslo_log import log
|
|
|
|
from bareon_allocator.objects import Disk
|
|
from bareon_allocator.objects import Space
|
|
from bareon_allocator.parsers import ExpressionsParser
|
|
|
|
|
|
LOG = log.getLogger(__name__)
|
|
|
|
|
|
class DynamicSchemaParser(object):
|
|
|
|
def __init__(self, hw_info, schema):
|
|
self.hw_info = hw_info
|
|
self.schema = schema
|
|
self.raw_disks = self.hw_info['disks']
|
|
self.rendered_spaces = []
|
|
self.disks = []
|
|
self.spaces = []
|
|
# TODO(eli): In the future should be moved into config.
|
|
self.strategies = {
|
|
'vg': {'strategy': 'container'},
|
|
'lv': {'strategy': 'elastic'},
|
|
'partitions': {'strategy': 'elastic'}
|
|
}
|
|
|
|
self.parse()
|
|
self.post_parse()
|
|
|
|
def parse(self):
|
|
self.render_expressions()
|
|
|
|
self.disks = [
|
|
Disk(**disk)
|
|
for disk in self.raw_disks]
|
|
|
|
for s in self.rendered_spaces:
|
|
strategy = self.strategies.get(s['type'], {}).get('strategy')
|
|
if strategy == 'elastic':
|
|
self.spaces.append(Space(**s))
|
|
elif strategy is None:
|
|
LOG.warn('There is not strategy for space %s', s)
|
|
|
|
def post_parse(self):
|
|
# Add fake volume Unallocated, in order to be able
|
|
# to have only volumes with minimal size, without
|
|
# additional space allocation
|
|
self.spaces.append(Space(
|
|
id='unallocated',
|
|
type='unallocated',
|
|
none_order=True,
|
|
weight=0))
|
|
|
|
def render_expressions(self):
|
|
self.rendered_spaces = self._convert_disks_to_indexes(
|
|
ExpressionsParser(self.schema, self.hw_info).parse(),
|
|
self.hw_info)
|
|
|
|
def _convert_disks_to_indexes(self, spaces, hw_info):
|
|
"""Convert disks to indexes.
|
|
|
|
Convert disks which are specified in `best_with_disks`
|
|
to a list of indexes in `disks` list.
|
|
"""
|
|
for i, space in enumerate(spaces):
|
|
|
|
if space.get('best_with_disks'):
|
|
disks_ids = set()
|
|
for disk in space['best_with_disks']:
|
|
try:
|
|
disks_ids.add(disk['id'])
|
|
except ValueError as exc:
|
|
LOG.warn('Warning: %s', exc)
|
|
|
|
spaces[i]['best_with_disks'] = disks_ids
|
|
|
|
return spaces
|