107 lines
4.2 KiB
Python
107 lines
4.2 KiB
Python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
|
|
# Copyright (C) 2012 Yahoo! Inc. All Rights Reserved.
|
|
#
|
|
# 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 six
|
|
|
|
from anvil import colorizer
|
|
from anvil import log as logging
|
|
from anvil import utils
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
SPECIAL_GROUPS = frozenset(['general'])
|
|
|
|
|
|
class Persona(object):
|
|
|
|
def __init__(self, supports, components, **kwargs):
|
|
self.distro_support = supports or []
|
|
self.source = kwargs.pop('source', None)
|
|
self.wanted_components = utils.group_builds(components)
|
|
self.wanted_subsystems = kwargs.pop('subsystems', {})
|
|
self.component_options = kwargs.pop('options', {})
|
|
self.no_origins = kwargs.pop('no-origin', [])
|
|
self.matched_components = []
|
|
self.distro_updates = kwargs
|
|
|
|
def match(self, distros, origins):
|
|
for group in self.wanted_components:
|
|
for c in group:
|
|
if c not in origins:
|
|
if c in self.no_origins:
|
|
LOG.debug("Automatically enabling component %s, not"
|
|
" present in origins file %s but present in"
|
|
" desired persona %s (origin not required).",
|
|
c, origins.filename, self.source)
|
|
origins[c] = {
|
|
'disabled': False,
|
|
}
|
|
else:
|
|
LOG.warn("Automatically disabling %s, not present in"
|
|
" origin file but present in desired"
|
|
" persona (origin required).",
|
|
colorizer.quote(c, quote_color='red'))
|
|
origins[c] = {
|
|
'disabled': True,
|
|
}
|
|
disabled_components = set(key
|
|
for key, value in six.iteritems(origins)
|
|
if value.get('disabled'))
|
|
self.matched_components = []
|
|
all_components = set()
|
|
for group in self.wanted_components:
|
|
adjusted_group = utils.Group(group.id)
|
|
for c in group:
|
|
if c not in disabled_components:
|
|
adjusted_group.append(c)
|
|
all_components.add(c)
|
|
if adjusted_group:
|
|
for c in SPECIAL_GROUPS:
|
|
if c not in adjusted_group:
|
|
adjusted_group.insert(0, c)
|
|
all_components.add(c)
|
|
self.matched_components.append(adjusted_group)
|
|
|
|
# Pick which of potentially many distros will work...
|
|
distro_names = set()
|
|
selected_distro = None
|
|
for distro in distros:
|
|
distro_names.add(distro.name)
|
|
if distro.name not in self.distro_support:
|
|
continue
|
|
will_work = True
|
|
for component in all_components:
|
|
if not distro.known_component(component):
|
|
will_work = False
|
|
LOG.warning("Persona specified component '%s' but"
|
|
" distro '%s' does not specify it", component,
|
|
distro.name)
|
|
break
|
|
if will_work:
|
|
selected_distro = distro
|
|
break
|
|
if selected_distro is None:
|
|
raise RuntimeError("Persona does not support any of the loaded"
|
|
" distros: %s" % list(distro_names))
|
|
else:
|
|
return selected_distro
|
|
|
|
|
|
def load(fn):
|
|
cls_kvs = utils.load_yaml(fn)
|
|
cls_kvs['source'] = fn
|
|
instance = Persona(**cls_kvs)
|
|
return instance
|