Example #1
0
def list_sources(cfg_list, depends, pkg_list):
    src_list = []
    LOG.debug(
        "Looking for data source in: %s,"
        " via packages %s that matches dependencies %s",
        cfg_list,
        pkg_list,
        depends,
    )
    for ds_name in cfg_list:
        if not ds_name.startswith(DS_PREFIX):
            ds_name = "%s%s" % (DS_PREFIX, ds_name)
        m_locs, _looked_locs = importer.find_module(ds_name, pkg_list,
                                                    ["get_datasource_list"])
        if not m_locs:
            LOG.error(
                "Could not import %s. Does the DataSource exist and "
                "is it importable?",
                ds_name,
            )
        for m_loc in m_locs:
            mod = importer.import_module(m_loc)
            lister = getattr(mod, "get_datasource_list")
            matches = lister(depends)
            if matches:
                src_list.extend(matches)
                break
    return src_list
def get_schema() -> dict:
    """Return jsonschema coalesced from all cc_* cloud-config modules."""
    schema_file = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                               "cloud-init-schema.json")
    full_schema = None
    try:
        full_schema = json.loads(load_file(schema_file))
    except Exception as e:
        LOG.warning("Cannot parse JSON schema file %s. %s", schema_file, e)
    if not full_schema:
        LOG.warning(
            "No base JSON schema files found at %s."
            " Setting default empty schema",
            schema_file,
        )
        full_schema = {
            "$defs": {},
            "$schema": "http://json-schema.org/draft-04/schema#",
            "allOf": [],
        }

    # TODO( Drop the get_modules loop when all legacy cc_* schema migrates )
    # Supplement base_schema with any legacy modules which still contain a
    # "schema" attribute. Legacy cc_* modules will be migrated to use the
    # store module schema in the composite cloud-init-schema-<version>.json
    # and will drop "schema" at that point.
    for (_, mod_name) in get_modules().items():
        # All cc_* modules need a "meta" attribute to represent schema defs
        (mod_locs, _) = importer.find_module(mod_name, ["cloudinit.config"],
                                             ["schema"])
        if mod_locs:
            mod = importer.import_module(mod_locs[0])
            full_schema["allOf"].append(mod.schema)
    return full_schema
Example #3
0
def fetch(name):
    locs = importer.find_module(name, ['', __name__], ['Distro'])
    if not locs:
        raise ImportError("No distribution found for distro %s" % (name))
    mod = importer.import_module(locs[0])
    cls = getattr(mod, 'Distro')
    return cls
Example #4
0
 def test_get_hostname_subclass_support(self):
     """Validate get_hostname signature on all subclasses of DataSource."""
     base_args = inspect.getfullargspec(DataSource.get_hostname)
     # Import all DataSource subclasses so we can inspect them.
     modules = util.get_modules_from_dir(
         os.path.dirname(os.path.dirname(__file__)))
     for _loc, name in modules.items():
         mod_locs, _ = importer.find_module(name, ["cloudinit.sources"], [])
         if mod_locs:
             importer.import_module(mod_locs[0])
     for child in DataSource.__subclasses__():
         if "Test" in child.dsname:
             continue
         self.assertEqual(
             base_args,
             inspect.getfullargspec(child.get_hostname),
             "%s does not implement DataSource.get_hostname params" % child,
         )
         for grandchild in child.__subclasses__():
             self.assertEqual(
                 base_args,
                 inspect.getfullargspec(grandchild.get_hostname),
                 "%s does not implement DataSource.get_hostname params" %
                 grandchild,
             )
 def _fixup_modules(self, raw_mods):
     mostly_mods = []
     for raw_mod in raw_mods:
         raw_name = raw_mod["mod"]
         freq = raw_mod.get("freq")
         run_args = raw_mod.get("args") or []
         mod_name = config.form_module_name(raw_name)
         if not mod_name:
             continue
         if freq and freq not in FREQUENCIES:
             LOG.warning(
                 "Config specified module %s has an unknown frequency %s",
                 raw_name,
                 freq,
             )
             # Reset it so when ran it will get set to a known value
             freq = None
         mod_locs, looked_locs = importer.find_module(
             mod_name, ["", type_utils.obj_name(config)], ["handle"]
         )
         if not mod_locs:
             LOG.warning(
                 "Could not find module named %s (searched %s)",
                 mod_name,
                 looked_locs,
             )
             continue
         mod = config.fixup_module(importer.import_module(mod_locs[0]))
         mostly_mods.append([mod, raw_name, freq, run_args])
     return mostly_mods
Example #6
0
def fetch(name):
    locs = importer.find_module(name, ["", __name__], ["Distro"])
    if not locs:
        raise ImportError("No distribution found for distro %s" % (name))
    mod = importer.import_module(locs[0])
    cls = getattr(mod, "Distro")
    return cls
 def register_handlers_in_dir(path):
     # Attempts to register any handler modules under the given path.
     if not path or not os.path.isdir(path):
         return
     potential_handlers = util.find_modules(path)
     for (fname, mod_name) in potential_handlers.items():
         try:
             mod_locs, looked_locs = importer.find_module(
                 mod_name, [""], ["list_types", "handle_part"]
             )
             if not mod_locs:
                 LOG.warning(
                     "Could not find a valid user-data handler"
                     " named %s in file %s (searched %s)",
                     mod_name,
                     fname,
                     looked_locs,
                 )
                 continue
             mod = importer.import_module(mod_locs[0])
             mod = handlers.fixup_handler(mod)
             types = c_handlers.register(mod)
             if types:
                 LOG.debug(
                     "Added custom handler for %s [%s] from %s",
                     types,
                     mod,
                     fname,
                 )
         except Exception:
             util.logexc(
                 LOG, "Failed to register handler from %s", fname
             )
Example #8
0
 def test_get_hostname_subclass_support(self):
     """Validate get_hostname signature on all subclasses of DataSource."""
     # Use inspect.getfullargspec when we drop py2.6 and py2.7
     get_args = inspect.getargspec  # pylint: disable=W1505
     base_args = get_args(DataSource.get_hostname)  # pylint: disable=W1505
     # Import all DataSource subclasses so we can inspect them.
     modules = util.find_modules(os.path.dirname(os.path.dirname(__file__)))
     for _loc, name in modules.items():
         mod_locs, _ = importer.find_module(name, ['cloudinit.sources'], [])
         if mod_locs:
             importer.import_module(mod_locs[0])
     for child in DataSource.__subclasses__():
         if 'Test' in child.dsname:
             continue
         self.assertEqual(
             base_args,
             get_args(child.get_hostname),  # pylint: disable=W1505
             '%s does not implement DataSource.get_hostname params'
             % child)
         for grandchild in child.__subclasses__():
             self.assertEqual(
                 base_args,
                 get_args(grandchild.get_hostname),  # pylint: disable=W1505
                 '%s does not implement DataSource.get_hostname params'
                 % grandchild)
Example #9
0
def fetch(name):
    locs, looked_locs = importer.find_module(name, ['', __name__], ['Distro'])
    if not locs:
        raise ImportError("No distribution found for distro %s (searched %s)"
                           % (name, looked_locs))
    mod = importer.import_module(locs[0])
    cls = getattr(mod, 'Distro')
    return cls
Example #10
0
def fetch(name: str) -> Type[Distro]:
    locs, looked_locs = importer.find_module(name, ["", __name__], ["Distro"])
    if not locs:
        raise ImportError("No distribution found for distro %s (searched %s)" %
                          (name, looked_locs))
    mod = importer.import_module(locs[0])
    cls = getattr(mod, "Distro")
    return cls
Example #11
0
def get_meta() -> dict:
    """Return metadata coalesced from all cc_* cloud-config module."""
    full_meta = dict()
    for (_, mod_name) in get_modules().items():
        mod_locs, _ = importer.find_module(mod_name, ["cloudinit.config"],
                                           ["meta"])
        if mod_locs:
            mod = importer.import_module(mod_locs[0])
            full_meta[mod.meta["id"]] = mod.meta
    return full_meta
Example #12
0
def get_schema() -> dict:
    """Return jsonschema coalesced from all cc_* cloud-config module."""
    full_schema = {
        "$schema": "http://json-schema.org/draft-04/schema#",
        "id": "cloud-config-schema",
        "allOf": [],
    }

    for (_, mod_name) in get_modules().items():
        (mod_locs, _) = importer.find_module(mod_name, ["cloudinit.config"],
                                             ["schema"])
        if mod_locs:
            mod = importer.import_module(mod_locs[0])
            full_schema["allOf"].append(mod.schema)
    return full_schema
Example #13
0
    def _fixup_modules(self, raw_mods) -> List[ModuleDetails]:
        """Convert list of returned from _read_modules() into new format.

        Invalid modules and arguments are ingnored.
        Also ensures that the module has the required meta fields.
        """
        mostly_mods = []
        for raw_mod in raw_mods:
            raw_name = raw_mod["mod"]
            freq = raw_mod.get("freq")
            run_args = raw_mod.get("args") or []
            mod_name = form_module_name(raw_name)
            if not mod_name:
                continue
            if freq and freq not in FREQUENCIES:
                LOG.warning(
                    "Config specified module %s has an unknown frequency %s",
                    raw_name,
                    freq,
                )
                # Misconfigured in /etc/cloud/cloud.cfg. Reset so cc_* module
                # default meta attribute "frequency" value is used.
                freq = None
            mod_locs, looked_locs = importer.find_module(
                mod_name, ["", type_utils.obj_name(config)], ["handle"])
            if not mod_locs:
                LOG.warning(
                    "Could not find module named %s (searched %s)",
                    mod_name,
                    looked_locs,
                )
                continue
            mod = importer.import_module(mod_locs[0])
            validate_module(mod, raw_name)
            if freq is None:
                # Use cc_* module default setting since no cloud.cfg overrides
                freq = mod.meta["frequency"]
            mostly_mods.append(
                ModuleDetails(
                    module=mod,
                    name=raw_name,
                    frequency=freq,
                    run_args=run_args,
                ))
        return mostly_mods
Example #14
0
def list_sources(cfg_list, depends, pkg_list):
    src_list = []
    LOG.debug(("Looking for for data source in: %s,"
               " via packages %s that matches dependencies %s"), cfg_list,
              pkg_list, depends)
    for ds_name in cfg_list:
        if not ds_name.startswith(DS_PREFIX):
            ds_name = '%s%s' % (DS_PREFIX, ds_name)
        m_locs = importer.find_module(ds_name, pkg_list,
                                      ['get_datasource_list'])
        for m_loc in m_locs:
            mod = importer.import_module(m_loc)
            lister = getattr(mod, "get_datasource_list")
            matches = lister(depends)
            if matches:
                src_list.extend(matches)
                break
    return src_list
Example #15
0
def get_schema():
    """Return jsonschema coalesced from all cc_* cloud-config module."""
    global FULL_SCHEMA
    if FULL_SCHEMA:
        return FULL_SCHEMA
    full_schema = {
        '$schema': 'http://json-schema.org/draft-04/schema#',
        'id': 'cloud-config-schema', 'allOf': []}

    configs_dir = os.path.dirname(os.path.abspath(__file__))
    potential_handlers = find_modules(configs_dir)
    for (fname, mod_name) in potential_handlers.items():
        mod_locs, looked_locs = importer.find_module(
            mod_name, ['cloudinit.config'], ['schema'])
        if mod_locs:
            mod = importer.import_module(mod_locs[0])
            full_schema['allOf'].append(mod.schema)
    FULL_SCHEMA = full_schema
    return full_schema
Example #16
0
def get_schema():
    """Return jsonschema coalesced from all cc_* cloud-config module."""
    global FULL_SCHEMA
    if FULL_SCHEMA:
        return FULL_SCHEMA
    full_schema = {
        '$schema': 'http://json-schema.org/draft-04/schema#',
        'id': 'cloud-config-schema', 'allOf': []}

    configs_dir = os.path.dirname(os.path.abspath(__file__))
    potential_handlers = find_modules(configs_dir)
    for (_fname, mod_name) in potential_handlers.items():
        mod_locs, _looked_locs = importer.find_module(
            mod_name, ['cloudinit.config'], ['schema'])
        if mod_locs:
            mod = importer.import_module(mod_locs[0])
            full_schema['allOf'].append(mod.schema)
    FULL_SCHEMA = full_schema
    return full_schema
Example #17
0
def list_sources(cfg_list, depends, pkg_list):
    src_list = []
    LOG.debug(("Looking for for data source in: %s,"
               " via packages %s that matches dependencies %s"),
              cfg_list, pkg_list, depends)
    for ds_name in cfg_list:
        if not ds_name.startswith(DS_PREFIX):
            ds_name = '%s%s' % (DS_PREFIX, ds_name)
        m_locs, _looked_locs = importer.find_module(ds_name,
                                                    pkg_list,
                                                    ['get_datasource_list'])
        for m_loc in m_locs:
            mod = importer.import_module(m_loc)
            lister = getattr(mod, "get_datasource_list")
            matches = lister(depends)
            if matches:
                src_list.extend(matches)
                break
    return src_list
Example #18
0
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 = importer.find_module(m_name, [__name__], [MERGER_ATTR])
        if not merger_locs:
            msg = ("Could not find merger module named '%s' "
                   "with attribute '%s'") % (m_name, MERGER_ATTR)
            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
Example #19
0
 def _fixup_modules(self, raw_mods):
     mostly_mods = []
     for raw_mod in raw_mods:
         raw_name = raw_mod["mod"]
         freq = raw_mod.get("freq")
         run_args = raw_mod.get("args") or []
         mod_name = config.form_module_name(raw_name)
         if not mod_name:
             continue
         if freq and freq not in FREQUENCIES:
             LOG.warn(("Config specified module %s" " has an unknown frequency %s"), raw_name, freq)
             # Reset it so when ran it will get set to a known value
             freq = None
         mod_locs, looked_locs = importer.find_module(mod_name, ["", type_utils.obj_name(config)], ["handle"])
         if not mod_locs:
             LOG.warn("Could not find module named %s (searched %s)", mod_name, looked_locs)
             continue
         mod = config.fixup_module(importer.import_module(mod_locs[0]))
         mostly_mods.append([mod, raw_name, freq, run_args])
     return mostly_mods
Example #20
0
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 = importer.find_module(m_name,
                                           [__name__],
                                           [MERGER_ATTR])
        if not merger_locs:
            msg = ("Could not find merger module named '%s' "
                   "with attribute '%s'") % (m_name, MERGER_ATTR)
            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
Example #21
0
def load_doc(requested_modules: list) -> str:
    """Load module docstrings

    Docstrings are generated on module load. Reduce, reuse, recycle.
    """
    docs = ""
    all_modules = list(get_modules().values()) + ["all"]
    invalid_docs = set(requested_modules).difference(set(all_modules))
    if invalid_docs:
        error("Invalid --docs value {}. Must be one of: {}".format(
            list(invalid_docs),
            ", ".join(all_modules),
        ))
    for mod_name in all_modules:
        if "all" in requested_modules or mod_name in requested_modules:
            (mod_locs, _) = importer.find_module(mod_name,
                                                 ["cloudinit.config"],
                                                 ["meta"])
            if mod_locs:
                mod = importer.import_module(mod_locs[0])
                docs += mod.__doc__ or ""
    return docs
Example #22
0
 def _fixup_modules(self, raw_mods):
     mostly_mods = []
     for raw_mod in raw_mods:
         raw_name = raw_mod['mod']
         freq = raw_mod.get('freq')
         run_args = raw_mod.get('args') or []
         mod_name = config.form_module_name(raw_name)
         if not mod_name:
             continue
         if freq and freq not in FREQUENCIES:
             LOG.warn(("Config specified module %s"
                       " has an unknown frequency %s"), raw_name, freq)
             # Reset it so when ran it will get set to a known value
             freq = None
         mod_locs = importer.find_module(
             mod_name, ['', type_utils.obj_name(config)], ['handle'])
         if not mod_locs:
             LOG.warn("Could not find module named %s", mod_name)
             continue
         mod = config.fixup_module(importer.import_module(mod_locs[0]))
         mostly_mods.append([mod, raw_name, freq, run_args])
     return mostly_mods
Example #23
0
 def register_handlers_in_dir(path):
     # Attempts to register any handler modules under the given path.
     if not path or not os.path.isdir(path):
         return
     potential_handlers = util.find_modules(path)
     for (fname, mod_name) in potential_handlers.items():
         try:
             mod_locs, looked_locs = importer.find_module(
                 mod_name, [''], ['list_types', 'handle_part'])
             if not mod_locs:
                 LOG.warn("Could not find a valid user-data handler"
                          " named %s in file %s (searched %s)",
                          mod_name, fname, looked_locs)
                 continue
             mod = importer.import_module(mod_locs[0])
             mod = handlers.fixup_handler(mod)
             types = c_handlers.register(mod)
             if types:
                 LOG.debug("Added custom handler for %s [%s] from %s",
                           types, mod, fname)
         except Exception:
             util.logexc(LOG, "Failed to register handler from %s",
                         fname)