The patch brings a couple of new concepts into cloudinit.
We have a general miniframework for defining plugins and discovering them,
with an actual implementation which uses the *pkgutil* builtin module.
Built atop of this framework, we have a new data source loader, found
in cloudinit.bases.DataSourceLoader. The loader operates on three concepts:
- the *module iterator*, which is used to list modules from a specific
location (in our case, from cloudinit.sources.__path__). The data
source loader takes care to use only the modules that exports a
given API.
- the data source discovery API assumes that each data source module exports
a function called `data_sources`, which should return a tuple of data source
classes that the said module exports. The loader filters the modules
that provides this API.
- the data source loader uses a new concept called *search strategy*
for discovering a potential data source. The search strategies
are classes whose purpose is to select one or more data sources
from a data source stream (any iterable).
There are multiple ways to implement a strategy, the search
can be either serial or parallel, there's no additional requirement
as long as they return an iterable.
Also, the strategies can be stacked together, for instance, having
two strategies, one for selecting only the network data sources
and another for selecting the available data sources from a list
of potential data sources.
This patch also adds a new API that uses the DataSourceLoader
with a given module iterator and strategies for selecting one
data source that cloudinit can use.
Change-Id: I30f312191ce40e45445ed9e3fc8a3d4651903280