summaryrefslogtreecommitdiff
path: root/cloudinit/mergers/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'cloudinit/mergers/__init__.py')
-rw-r--r--cloudinit/mergers/__init__.py166
1 files changed, 0 insertions, 166 deletions
diff --git a/cloudinit/mergers/__init__.py b/cloudinit/mergers/__init__.py
deleted file mode 100644
index e13f55ac..00000000
--- a/cloudinit/mergers/__init__.py
+++ /dev/null
@@ -1,166 +0,0 @@
-# vi: ts=4 expandtab
-#
-# Copyright (C) 2012 Yahoo! Inc.
-#
-# Author: Joshua Harlow <harlowja@yahoo-inc.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-import re
-
-import six
-
-from cloudinit import importer
-from cloudinit import log as logging
-from cloudinit import type_utils
-
-NAME_MTCH = re.compile(r"(^[a-zA-Z_][A-Za-z0-9_]*)\((.*?)\)$")
-
-LOG = logging.getLogger(__name__)
-DEF_MERGE_TYPE = "list()+dict()+str()"
-MERGER_PREFIX = 'm_'
-MERGER_ATTR = 'Merger'
-
-
-class UnknownMerger(object):
- # Named differently so auto-method finding
- # doesn't pick this up if there is ever a type
- # named "unknown"
- def _handle_unknown(self, _meth_wanted, value, _merge_with):
- return value
-
- # This merging will attempt to look for a '_on_X' method
- # in our own object for a given object Y with type X,
- # if found it will be called to perform the merge of a source
- # object and a object to merge_with.
- #
- # If not found the merge will be given to a '_handle_unknown'
- # function which can decide what to do wit the 2 values.
- def merge(self, source, merge_with):
- type_name = type_utils.obj_name(source)
- type_name = type_name.lower()
- method_name = "_on_%s" % (type_name)
- meth = None
- args = [source, merge_with]
- if hasattr(self, method_name):
- meth = getattr(self, method_name)
- if not meth:
- meth = self._handle_unknown
- args.insert(0, method_name)
- return meth(*args)
-
-
-class LookupMerger(UnknownMerger):
- def __init__(self, lookups=None):
- UnknownMerger.__init__(self)
- if lookups is None:
- self._lookups = []
- else:
- self._lookups = lookups
-
- def __str__(self):
- return 'LookupMerger: (%s)' % (len(self._lookups))
-
- # For items which can not be merged by the parent this object
- # will lookup in a internally maintained set of objects and
- # find which one of those objects can perform the merge. If
- # any of the contained objects have the needed method, they
- # will be called to perform the merge.
- def _handle_unknown(self, meth_wanted, value, merge_with):
- meth = None
- for merger in self._lookups:
- if hasattr(merger, meth_wanted):
- # First one that has that method/attr gets to be
- # the one that will be called
- meth = getattr(merger, meth_wanted)
- break
- if not meth:
- return UnknownMerger._handle_unknown(self, meth_wanted,
- value, merge_with)
- return meth(value, merge_with)
-
-
-def dict_extract_mergers(config):
- parsed_mergers = []
- raw_mergers = config.pop('merge_how', None)
- if raw_mergers is None:
- raw_mergers = config.pop('merge_type', None)
- if raw_mergers is None:
- return parsed_mergers
- if isinstance(raw_mergers, six.string_types):
- return string_extract_mergers(raw_mergers)
- for m in raw_mergers:
- if isinstance(m, (dict)):
- name = m['name']
- name = name.replace("-", "_").strip()
- opts = m['settings']
- else:
- name = m[0]
- if len(m) >= 2:
- opts = m[1:]
- else:
- opts = []
- if name:
- parsed_mergers.append((name, opts))
- return parsed_mergers
-
-
-def string_extract_mergers(merge_how):
- parsed_mergers = []
- for m_name in merge_how.split("+"):
- # Canonicalize the name (so that it can be found
- # even when users alter it in various ways)
- m_name = m_name.lower().strip()
- m_name = m_name.replace("-", "_")
- if not m_name:
- continue
- match = NAME_MTCH.match(m_name)
- if not match:
- msg = ("Matcher identifer '%s' is not in the right format" %
- (m_name))
- raise ValueError(msg)
- (m_name, m_ops) = match.groups()
- m_ops = m_ops.strip().split(",")
- m_ops = [m.strip().lower() for m in m_ops if m.strip()]
- parsed_mergers.append((m_name, m_ops))
- return parsed_mergers
-
-
-def default_mergers():
- return tuple(string_extract_mergers(DEF_MERGE_TYPE))
-
-
-def construct(parsed_mergers):
- mergers_to_be = []
- for (m_name, m_ops) in parsed_mergers:
- if not m_name.startswith(MERGER_PREFIX):
- m_name = MERGER_PREFIX + str(m_name)
- merger_locs, looked_locs = importer.find_module(m_name,
- [__name__],
- [MERGER_ATTR])
- if not merger_locs:
- msg = ("Could not find merger module named '%s' "
- "with attribute '%s' (searched %s)") % (m_name,
- MERGER_ATTR,
- looked_locs)
- raise ImportError(msg)
- else:
- mod = importer.import_module(merger_locs[0])
- mod_attr = getattr(mod, MERGER_ATTR)
- mergers_to_be.append((mod_attr, m_ops))
- # Now form them...
- mergers = []
- root = LookupMerger(mergers)
- for (attr, opts) in mergers_to_be:
- mergers.append(attr(root, opts))
- return root