Esempio n. 1
0
 def add_setting(self, config, keys, value=None, forced=False,
                 state=None, comments=None, info=None):
     """Add a setting to the configuration."""
     section, option = self._get_section_option_from_keys(keys)
     id_ = self._get_id_from_section_option(section, option)
     if option is not None and value is None:
         value = ""
     if info is None:
         if option is None:
             info = self.INFO_ADDED_SECT
         else:
             info = self.INFO_ADDED_VAR.format(repr(value))
     if option is not None and config.get([section]) is None:
         self.add_setting(config, [section])
     if config.get([section, option]) is not None:
         if forced:
             return self.change_setting(config, keys, value, state,
                                        comments, info)
         return False
     if value is not None and not isinstance(value, basestring):
         text = "New value {0} for {1} is not a string"
         raise ValueError(text.format(repr(value), id_))
     config.set([section, option], value=value, state=state,
                comments=comments)
     self.add_report(section, option, value, info)
Esempio n. 2
0
 def add_setting(self,
                 config,
                 keys,
                 value=None,
                 forced=False,
                 state=None,
                 comments=None,
                 info=None):
     """Add a setting to the configuration."""
     section, option = self._get_section_option_from_keys(keys)
     id_ = self._get_id_from_section_option(section, option)
     if option is not None and value is None:
         value = ""
     if info is None:
         if option is None:
             info = self.INFO_ADDED_SECT
         else:
             info = self.INFO_ADDED_VAR.format(repr(value))
     if option is not None and config.get([section]) is None:
         self.add_setting(config, [section])
     if config.get([section, option]) is not None:
         if forced:
             return self.change_setting_value(config, keys, value, state,
                                              comments, info)
         return False
     if value is not None and not isinstance(value, basestring):
         text = "New value {0} for {1} is not a string"
         raise ValueError(text.format(repr(value), id_))
     config.set([section, option],
                value=value,
                state=state,
                comments=comments)
     self.add_report(section, option, value, info)
Esempio n. 3
0
def get_node_state_attrs(config, section, option=None, allowed_sections=None):
    """Get Graphviz node attributes like color for a given setting."""
    node_attrs = {}
    if option is None:
        node_attrs["shape"] = SHAPE_NODE_SECTION
    if not config.value.keys():
        # Empty configuration - we can assume pure metadata.
        return node_attrs
    if allowed_sections is None:
        allowed_sections = []
    config_section_node = config.get([section])
    id_ = rose.macro.get_id_from_section_option(section, option)
    state = ""
    config_node = config.get([section, option])
    node_attrs["color"] = COLOUR_IGNORED
    if (config_section_node is not None
            and config_section_node.state != STATE_NORMAL
            and option is not None):
        state = rose.config.STATE_SECT_IGNORED
    if config_node is None:
        node_attrs["color"] = COLOUR_MISSING
    elif config_node.state != STATE_NORMAL:
        state += config_node.state
        if config_node.state == config_node.STATE_USER_IGNORED:
            node_attrs["color"] = COLOUR_USER_IGNORED
    elif not state:
        node_attrs["color"] = COLOUR_ENABLED
    if allowed_sections and section not in allowed_sections:
        node_attrs["shape"] = SHAPE_NODE_EXTERNAL
    if state:
        node_attrs["label"] = state + id_
    return node_attrs
Esempio n. 4
0
    def rename_setting(self, config, keys, new_keys, info=None):
        """Rename a setting in the configuration.

        Args:
            config (rose.config.ConfigNode): The application configuration.
            keys (list): A list defining a hierarchy of node.value 'keys'.
                A section will be a list of one keys, an option will have two.
            new_keys (list): The new hierarchy of node.value 'keys'.
            info (string - optional): A short string containing no new lines,
                describing the addition of the setting.

        Returns:
            None
        """
        section, option = self._get_section_option_from_keys(keys)
        new_section, new_option = self._get_section_option_from_keys(new_keys)
        if option is None:
            if new_option is not None:
                raise TypeError(
                    self.ERROR_RENAME_SECT_TO_OPT.format(
                        section, new_section, new_option))
        elif new_option is None:
            raise TypeError(
                self.ERROR_RENAME_OPT_TO_SECT.format(section, option,
                                                     new_section))
        node = config.get(keys)
        if node is None:
            return
        if info is None:
            if option is None:
                info = self.INFO_RENAMED_SECT.format(section, new_section)
            else:
                info = self.INFO_RENAMED_VAR.format(section, option,
                                                    new_section, new_option)
        if option is None:
            if config.get([new_section]) is not None:
                self.remove_setting(config, [new_section])
            self.add_setting(config, [new_section],
                             value=None,
                             forced=True,
                             state=node.state,
                             comments=node.comments,
                             info=info)
            for option_keys, opt_node in config.walk([section]):
                renamed_option = option_keys[1]
                self.add_setting(config, [new_section, renamed_option],
                                 value=opt_node.value,
                                 forced=True,
                                 state=opt_node.state,
                                 comments=opt_node.comments,
                                 info=info)
        else:
            self.add_setting(config,
                             new_keys,
                             value=node.value,
                             forced=True,
                             state=node.state,
                             comments=node.comments,
                             info=info)
        self.remove_setting(config, keys)
Esempio n. 5
0
def get_node_state_attrs(config, section, option=None, allowed_sections=None):
    """Get Graphviz node attributes like color for a given setting."""
    node_attrs = {}
    if option is None:
        node_attrs["shape"] = SHAPE_NODE_SECTION
    if not config.value.keys():
        # Empty configuration - we can assume pure metadata.
        return node_attrs
    if allowed_sections is None:
        allowed_sections = []
    config_section_node = config.get([section])
    id_ = rose.macro.get_id_from_section_option(section, option)
    state = ""
    config_node = config.get([section, option])
    node_attrs["color"] = COLOUR_IGNORED
    if (config_section_node is not None and
            config_section_node.state != STATE_NORMAL and
            option is not None):
        state = rose.config.STATE_SECT_IGNORED
    if config_node is None:
        node_attrs["color"] = COLOUR_MISSING
    elif config_node.state != STATE_NORMAL:
        state += config_node.state
        if config_node.state == config_node.STATE_USER_IGNORED:
            node_attrs["color"] = COLOUR_USER_IGNORED
    elif not state:
        node_attrs["color"] = COLOUR_ENABLED
    if allowed_sections and section not in allowed_sections:
        node_attrs["shape"] = SHAPE_NODE_EXTERNAL
    if state:
        node_attrs["label"] = state + id_
    return node_attrs
Esempio n. 6
0
    def run_impl_prep(self, config, opts, args, uuid, work_files):
        """Prepare to run the application."""

        if opts.new_mode:
            conf_dir = opts.conf_dir
            if not conf_dir or os.path.abspath(conf_dir) == os.getcwd():
                raise NewModeError(os.getcwd())
            for p in os.listdir("."):
                self.fs_util.delete(p)

        # Dump the actual configuration as rose-app-run.conf
        rose.config.dump(config, "rose-app-run.conf")

        # Environment variables: PATH
        conf_dir = opts.conf_dir
        if conf_dir is None:
            conf_dir = os.getcwd()
        conf_bin_dir = os.path.join(conf_dir, "bin")
        if os.path.isdir(conf_bin_dir):
            value = conf_bin_dir + os.pathsep + os.getenv("PATH")
            config.set(["env", "PATH"], value)
        else:
            config.set(["env", "PATH"], os.getenv("PATH"))

        # Free format files not defined in the configuration file
        # TODO: review location
        conf_file_dir = os.path.join(conf_dir, rose.SUB_CONFIG_FILE_DIR)
        file_section_prefix = self.config_pm.get_processor("file").PREFIX
        if os.path.isdir(conf_file_dir):
            dirs = []
            files = []
            for dirpath, dirnames, filenames in os.walk(conf_file_dir):
                for dirname in dirnames:
                    if dirname.startswith("."):
                        dirnames.remove(dirname)
                dir = dirpath[len(conf_file_dir) + 1 :]
                files += [os.path.join(dir, filename) for filename in filenames]
                if dirpath != conf_file_dir:
                    dirs.append(dir)
            for target in dirs:
                section = file_section_prefix + target
                if config.get([section], no_ignore=True) is None:
                    config.set([section, "mode"], "mkdir")
            for target in files:
                section = file_section_prefix + target
                if config.get([section], no_ignore=True) is None:
                    source = os.path.join(conf_file_dir, target)
                    config.set([section, "source"], source)

        # Process Environment Variables
        self.config_pm(config, "env")

        # Process Files
        self.config_pm(config, "file",
                       no_overwrite_mode=opts.no_overwrite_mode)
Esempio n. 7
0
    def add_setting(self, config, keys, value=None, forced=False, state=None, comments=None, info=None):
        """Add a setting to the configuration."""
        section, option = self._get_section_option_from_keys(keys)
        id_ = self._get_id_from_section_option(section, option)
        if option is not None and value is None:
            value = ""
        if info is None:
            if option is None:
                info = self.INFO_ADDED_SECT
            else:
                info = self.INFO_ADDED_VAR.format(repr(value))

        # Search for existing conflicting settings.
        found_setting = False
        if config.get([section, option]) is None:
            strip_dupl = rose.macro.REC_ID_STRIP
            for keys, node in config.walk():
                existing_section = keys[0]
                existing_base_section = rose.macro.REC_ID_STRIP.sub("", existing_section)
                if len(keys) == 1:
                    existing_option = None
                    existing_base_option = None
                else:
                    existing_option = keys[1]
                    existing_base_option = rose.macro.REC_ID_STRIP_DUPL.sub("", existing_option)
                if option is None:
                    # For section 'foo', look for 'foo', 'foo{bar}', 'foo(1)'.
                    if existing_section == section or existing_base_section == section:
                        found_setting = True
                        break
                # For option 'foo', look for 'foo', 'foo(1)'.
                elif existing_section == section and (existing_option == option or existing_base_option == option):
                    found_setting = True
                    break
        else:
            found_setting = True

        # If already added, quit, unless "forced".
        if found_setting:
            if forced:
                # If forced, override the existing properties.
                return self.change_setting_value(config, keys, value, state, comments, info)
            return False

        # Add parent section if missing.
        if option is not None and config.get([section]) is None:
            self.add_setting(config, [section])
        if value is not None and not isinstance(value, basestring):
            text = "New value {0} for {1} is not a string"
            raise ValueError(text.format(repr(value), id_))

        # Set (add) the section/option.
        config.set([section, option], value=value, state=state, comments=comments)
        self.add_report(section, option, value, info)
Esempio n. 8
0
    def rename_setting(self, config, keys, new_keys, info=None):
        """Rename a setting in the configuration.

        Args:
            config (rose.config.ConfigNode): The application configuration.
            keys (list): A list defining a hierarchy of node.value 'keys'.
                A section will be a list of one keys, an option will have two.
            new_keys (list): The new hierarchy of node.value 'keys'.
            info (string - optional): A short string containing no new lines,
                describing the addition of the setting.

        Returns:
            None
        """
        section, option = self._get_section_option_from_keys(keys)
        new_section, new_option = self._get_section_option_from_keys(new_keys)
        if option is None:
            if new_option is not None:
                raise TypeError(self.ERROR_RENAME_SECT_TO_OPT.format(
                    section, new_section, new_option))
        elif new_option is None:
            raise TypeError(self.ERROR_RENAME_OPT_TO_SECT.format(
                section, option, new_section))
        node = config.get(keys)
        if node is None:
            return
        if info is None:
            if option is None:
                info = self.INFO_RENAMED_SECT.format(section, new_section)
            else:
                info = self.INFO_RENAMED_VAR.format(section, option,
                                                    new_section, new_option)
        if option is None:
            if config.get([new_section]) is not None:
                self.remove_setting(config, [new_section])
            self.add_setting(config, [new_section], value=None, forced=True,
                             state=node.state, comments=node.comments,
                             info=info)
            for option_keys, opt_node in config.walk([section]):
                renamed_option = option_keys[1]
                self.add_setting(config, [new_section, renamed_option],
                                 value=opt_node.value, forced=True,
                                 state=opt_node.state,
                                 comments=opt_node.comments, info=info)
        else:
            self.add_setting(config, new_keys, value=node.value, forced=True,
                             state=node.state, comments=node.comments,
                             info=info)
        self.remove_setting(config, keys)
Esempio n. 9
0
 def rename_setting(self, config, keys, new_keys, info=None):
     """Rename a setting in the configuration."""
     section, option = self._get_section_option_from_keys(keys)
     new_section, new_option = self._get_section_option_from_keys(new_keys)
     if option is None:
         if new_option is not None:
             raise TypeError(
                 self.ERROR_RENAME_SECT_TO_OPT.format(
                     section, new_section, new_option))
     elif new_option is None:
         raise TypeError(
             self.ERROR_RENAME_OPT_TO_SECT.format(section, option,
                                                  new_section))
     node = config.get(keys)
     if node is None:
         return
     if info is None:
         if option is None:
             info = self.INFO_RENAMED_SECT.format(section, new_section)
         else:
             info = self.INFO_RENAMED_VAR.format(section, option,
                                                 new_section, new_option)
     if option is None:
         if config.get([new_section]) is not None:
             self.remove_setting(config, [new_section])
         self.add_setting(config, [new_section],
                          value=None,
                          forced=True,
                          state=node.state,
                          comments=node.comments,
                          info=info)
         for option_keys, opt_node in config.walk([section]):
             renamed_option = option_keys[1]
             self.add_setting(config, [new_section, renamed_option],
                              value=opt_node.value,
                              forced=True,
                              state=opt_node.state,
                              comments=opt_node.comments,
                              info=info)
     else:
         self.add_setting(config,
                          new_keys,
                          value=node.value,
                          forced=True,
                          state=node.state,
                          comments=node.comments,
                          info=info)
     self.remove_setting(config, keys)
Esempio n. 10
0
 def change_setting_value(self,
                          config,
                          keys,
                          value,
                          forced=False,
                          comments=None,
                          info=None):
     """Change a setting (option) value in the configuration."""
     section, option = self._get_section_option_from_keys(keys)
     id_ = self._get_id_from_section_option(section, option)
     node = config.get([section, option])
     if node is None:
         if forced:
             return self.add_setting(config, keys, value, node.state,
                                     comments, info)
         return False
     if node.value == value:
         return False
     if option is None:
         text = "Not valid for value change: {0}".format(id_)
         raise TypeError(text)
     if info is None:
         info = self.INFO_CHANGED_VAR.format(repr(node.value), repr(value))
     if value is not None and not isinstance(value, basestring):
         text = "New value {0} for {1} is not a string"
         raise ValueError(text.format(repr(value), id_))
     node.value = value
     if comments is not None:
         node.comments = comments
     self.add_report(section, option, value, info)
Esempio n. 11
0
 def change_setting_value(self, config, keys, value, forced=False,
                          comments=None, info=None):
     """Change a setting (option) value in the configuration."""
     section, option = self._get_section_option_from_keys(keys)
     id_ = self._get_id_from_section_option(section, option)
     node = config.get([section, option])
     if node is None:
         if forced:
             return self.add_setting(config, keys, value=value,
                                     comments=comments, info=info)
         return False
     if node.value == value:
         return False
     if option is None:
         text = "Not valid for value change: {0}".format(id_)
         raise TypeError(text)
     if info is None:
         info = self.INFO_CHANGED_VAR.format(repr(node.value), repr(value))
     if value is not None and not isinstance(value, basestring):
         text = "New value {0} for {1} is not a string"
         raise ValueError(text.format(repr(value), id_))
     node.value = value
     if comments is not None:
         node.comments = comments
     self.add_report(section, option, value, info)
Esempio n. 12
0
def pretty_format_config(config):
    """Improve configuration prettiness."""
    for section in config.value.keys():
        keylist = [section]
        scheme = keylist[0]
        if ":" in scheme:
            scheme = scheme.split(":", 1)[0]
        try:
            scheme_module = getattr(rose.formats, scheme)
            pretty_format_keys = getattr(scheme_module, "pretty_format_keys")
            pretty_format_value = getattr(scheme_module, "pretty_format_value")
        except AttributeError:
            continue
        new_keylist = pretty_format_keys(keylist)
        if new_keylist != keylist:
            node = config.get(keylist)
            config.unset(keylist)
            config.set(new_keylist, node.value, node.state, node.comments)
            section = new_keylist[0]
        for keylist, node in list(config.walk([section])):
            values = rose.variable.array_split(node.value, ",")
            node.value = pretty_format_value(values)   
            new_keylist = pretty_format_keys(keylist)
            if new_keylist != keylist:
                config.unset(keylist)
                config.set(new_keylist, node.value, node.state, node.comments)
Esempio n. 13
0
    def validate(self, config, meta_config=None):
        self.reports = []
        if meta_config is None:
            meta_config = rose.config.ConfigNode()
        if not hasattr(self, 'trigger_family_lookup'):
            self._setup_triggers(meta_config)
        enabled = rose.config.ConfigNode.STATE_NORMAL
        trig_ignored = rose.config.ConfigNode.STATE_SYST_IGNORED
        user_ignored = rose.config.ConfigNode.STATE_USER_IGNORED
        state_map = {enabled: 'enabled     ',
                     trig_ignored: 'trig-ignored',
                     user_ignored: 'user-ignored'}

        invalid_trigger_reports = self.validate_dependencies(config,
                                                             meta_config)
        if invalid_trigger_reports:
            return invalid_trigger_reports
        macro_config = copy.deepcopy(config)
        trig_config, reports = self.transform(macro_config, meta_config)
        transform_reports = copy.deepcopy(reports)
        del self.reports[:]
        for report in transform_reports:
            config_node = config.get([report.section, report.option])
            trig_config_node = trig_config.get([report.section, report.option])
            if report.option is None:
                value = None
            else:
                value = trig_config_node.value
            after_state_string = state_map[trig_config_node.state].strip()
            info = self.ERROR_BAD_STATE.format(after_state_string)
            self.add_report(report.section, report.option,
                            value, info)
        return self.reports
Esempio n. 14
0
File: macro.py Progetto: csimag/rose
def load_meta_config(config, directory=None, config_type=None,
                     error_handler=None, ignore_meta_error=False):
    """Return the metadata config for a configuration."""
    if error_handler is None:
        error_handler = _report_error
    meta_config = rose.config.ConfigNode()
    meta_list = ["rose-all/" + rose.META_CONFIG_NAME]
    if config_type is not None:
        default_meta_dir = config_type.replace(".", "-")
        meta_list.append(default_meta_dir + "/" + rose.META_CONFIG_NAME)
    config_meta_path, warning = load_meta_path(config, directory)
    if warning is not None and not ignore_meta_error:
        error_handler(text=warning)
    if config_meta_path is not None:
        path = os.path.join(config_meta_path, rose.META_CONFIG_NAME)
        if path not in meta_list:
            meta_list.append(path)
    locator = rose.resource.ResourceLocator(paths=sys.path)
    opt_node = config.get([rose.CONFIG_SECT_TOP,
                           rose.CONFIG_OPT_META_TYPE], no_ignore=True)
    ignore_meta_error = ignore_meta_error or opt_node is None
    config_loader = rose.config.ConfigLoader()
    for meta_key in meta_list:
        try:
            meta_path = locator.locate(meta_key)
        except rose.resource.ResourceError as e:
            if not ignore_meta_error:
                error_handler(text=ERROR_LOAD_META_PATH.format(meta_key))
        else:
            try:
                config_loader.load_with_opts(meta_path, meta_config)
            except rose.config.ConfigSyntaxError as e:
                error_handler(text=str(e))
    return meta_config
Esempio n. 15
0
def load_meta_config(config, directory=None):
    """Return the metadata config for a configuration."""
    meta_config = rose.config.ConfigNode()
    meta_list = ['etc/metadata/all/' + rose.META_CONFIG_NAME]
    config_meta_path = load_meta_path(config, directory)
    if config_meta_path is not None:
        path = os.path.join(config_meta_path, rose.META_CONFIG_NAME)
        if path not in meta_list:
            meta_list.append(path)
    locator = rose.resource.ResourceLocator(paths=sys.path)
    opt_node = config.get([rose.CONFIG_SECT_TOP,
                           rose.CONFIG_OPT_META_TYPE], no_ignore=True)
    ignore_meta_error = opt_node is None
    for meta_key in meta_list:
        try:
            meta_path = locator.locate(meta_key)
        except rose.resource.ResourceError:
            if not ignore_meta_error:
                sys.stderr.write(ERROR_LOAD_META_PATH.format(meta_path))
        else:
            try:
                meta_config = rose.config.load(meta_path, meta_config)
            except rose.config.SyntaxError as e:
                sys.stderr.write(ERROR_LOAD_METADATA.format(meta_path, e))
    return meta_config
Esempio n. 16
0
 def get_prefix_default(cls):
     """Return the default prefix."""
     config = rose.config.default_node()
     node = config.get(["rosie-id", "prefix-default"], no_ignore=True)
     if node is None:
         raise SuiteIdPrefixError()
     return node.value
Esempio n. 17
0
 def transform(self, config, meta_config=None):
     """Return a config and a list of changes, if any."""
     checker = CompulsoryChecker()
     problem_list = checker.validate(config, meta_config)
     missing_sect_opts = []
     for report in problem_list:
         if report.info != checker.WARNING_COMPULSORY_USER_IGNORED:
             missing_sect_opts.append((report.section, report.option))
     missing_sect_opts.sort()
     missing_sect_opts.sort(lambda x, y: cmp(x[1], y[1]))
     for sect, opt in missing_sect_opts:
         if opt is None:
             config.set([sect])
             self.add_report(sect, opt, None,
                             self.ADD_COMPULSORY_SECT)
             continue
         if config.get([sect]) is None:
             config.set([sect])
             self.add_report(sect, None, None,
                             self.ADD_MISSING_SECT)
         var_id = self._get_id_from_section_option(sect, opt)
         metadata = {}
         for key, node in meta_config.get([var_id]).value.items():
             if node.is_ignored():
                 continue
             metadata.update({key: node.value})
         value = rose.variable.get_value_from_metadata(metadata)
         config.set([sect, opt], value)
         self.add_report(sect, opt, value,
                         self.ADD_COMPULSORY_OPT)
     return config, self.reports
Esempio n. 18
0
 def process(self, config, item, orig_keys=None, orig_value=None, **kwargs):
     if item.endswith("(:)"):
         name = item[0:-2]
         sections = filter(lambda key: key.startswith(name),
                                       config.value.keys())
     else:
         sections = filter(lambda key: key == item, config.value.keys())
     if not sections:
         e = UnknownContentError(item)
         raise ConfigProcessError(orig_keys, orig_value, e)
     if item.endswith("(:)"):
         sections.sort(rose.config.sort_settings)
     ret = ""
     for section in sections:
         section_node = config.get([section], no_ignore=True)
         if section_node.state:
             continue
         group = RE_NAMELIST_GROUP.match(section).group(1)
         nlg = "&" + group + "\n"
         for key, node in sorted(section_node.value.items()):
             try:
                 value = env_var_process(node.value)
             except UnboundEnvironmentVariableError as e:
                 raise ConfigProcessError([section, key], node.value, e)
             else:
                 nlg += "%s=%s,\n" % (key, value)
         nlg += "/" + "\n"
         self.manager.event_handler(ConfigProcessNamelistEvent(nlg))
         ret += nlg
     return ret
Esempio n. 19
0
    def get_setting_value(self, config, keys, no_ignore=False):
        """Return the value of a setting or ``None`` if not set.

        Args:
            config (rose.config.ConfigNode): The application configuration.
            keys (list): A list defining a hierarchy of node.value 'keys'.
                A section will be a list of one keys, an option will have two.
            no_ignore (bool - optional): If ``True`` return ``None`` if the
                setting is ignored (else return the value).

        Returns:
            object - The setting value or ``None`` if not defined.
        """
        section, option = self._get_section_option_from_keys(keys)
        if config.get([section, option], no_ignore=no_ignore) is None:
            return None
        return config.get([section, option]).value
Esempio n. 20
0
    def get_setting_value(self, config, keys, no_ignore=False):
        """Return the value of a setting or ``None`` if not set.

        Args:
            config (rose.config.ConfigNode): The application configuration.
            keys (list): A list defining a hierarchy of node.value 'keys'.
                A section will be a list of one keys, an option will have two.
            no_ignore (bool - optional): If ``True`` return ``None`` if the
                setting is ignored (else return the value).

        Returns:
            object - The setting value or ``None`` if not defined.
        """
        section, option = self._get_section_option_from_keys(keys)
        if config.get([section, option], no_ignore=no_ignore) is None:
            return None
        return config.get([section, option]).value
Esempio n. 21
0
 def get_config_meta_flag(self, config):
     """Return the metadata id flag."""
     for keylist in [[rose.CONFIG_SECT_TOP, rose.CONFIG_OPT_META_TYPE],
                     [rose.CONFIG_SECT_TOP, rose.CONFIG_OPT_PROJECT]]:
         type_node = config.get(keylist, no_ignore=True)
         if type_node is not None and type_node.value:
             return type_node.value
     return None
Esempio n. 22
0
 def __init__(self, root=None, prefix=None):
     if root is None:
         config = rose.config.default_node()
         node = config.get(["rosie-ws-client", "ws-root-default"])
         root = node.value
     self.root = root
     if prefix is None:
         prefix = SuiteId.get_prefix_default()
     self.prefix = prefix
Esempio n. 23
0
 def get_output_root(cls):
     """Return the root output directory for suites."""
     config = rose.config.default_node()
     node = config.get(["rosie-id", "output-root"], no_ignore=True)
     if node:
         path = node.value
     else:
         suite_engine_proc = SuiteEngineProcessor.get_processor()
         path = os.path.join("~", suite_engine_proc.RUN_DIR_REL_ROOT)
     return rose.env.env_var_process(os.path.expanduser(path))
Esempio n. 24
0
 def get_prefix_location(cls, prefix=None):
     """Return the repository location of a given prefix."""
     if prefix is None:
         prefix = cls.get_prefix_default()
     key = "prefix-location." + prefix
     config = rose.config.default_node()
     node = config.get(["rosie-id", key], no_ignore=True)
     if node is None:
         raise SuiteIdPrefixError(prefix)
     return node.value.rstrip("/")
Esempio n. 25
0
 def get_prefix_web(cls, prefix=None):
     """Return a url for the prefix repository source url."""
     if prefix is None:
         prefix = cls.get_prefix_default()
     key = "prefix-web." + prefix
     config = rose.config.default_node()
     node = config.get(["rosie-id", key], no_ignore=True)
     if node is None:
         raise SuiteIdPrefixError(prefix)
     return node.value.rstrip("/")
Esempio n. 26
0
 def _remove_setting(self, config, keys, info=None):
     """Remove a setting from the configuration, if it exists."""
     section, option = self._get_section_option_from_keys(keys)
     id_ = self._get_id_from_section_option(section, option)
     if config.get([section, option]) is None:
         return False
     if info is None:
         info = self.INFO_REMOVED
     config.unset([section, option])
     self.add_report(section, option, None, info)
Esempio n. 27
0
 def get_local_copy_root(cls):
     """Return the root directory for hosting the local suite copies."""
     config = rose.config.default_node()
     node = config.get(["rosie-id", "local-copy-root"], no_ignore=True)
     if node:
         local_copy_root = node.value
     else:
         local_copy_root = "$HOME/roses"
     local_copy_root = rose.env.env_var_process(local_copy_root)
     return local_copy_root
Esempio n. 28
0
 def _remove_setting(self, config, keys, info=None):
     """Remove a setting from the configuration, if it exists."""
     section, option = self._get_section_option_from_keys(keys)
     id_ = self._get_id_from_section_option(section, option)
     if config.get([section, option]) is None:
         return False
     if info is None:
         info = self.INFO_REMOVED
     config.unset([section, option])
     self.add_report(section, option, None, info)
Esempio n. 29
0
    def transform(self, config, meta_config=None):
        """Apply metadata trigger expressions to variables."""
        self.reports = []
        meta_config = self._load_meta_config(config, meta_config)
        self._setup_triggers(meta_config)
        self.enabled_dict = {}
        self.ignored_dict = {}
        enabled = rose.config.ConfigNode.STATE_NORMAL
        trig_ignored = rose.config.ConfigNode.STATE_SYST_IGNORED
        user_ignored = rose.config.ConfigNode.STATE_USER_IGNORED
        state_map = {
            enabled: 'enabled     ',
            trig_ignored: 'trig-ignored',
            user_ignored: 'user-ignored'
        }
        id_list = []
        prev_ignoreds = {trig_ignored: [], user_ignored: []}
        for keylist, node in config.walk():
            if len(keylist) == 1:
                n_id = keylist[0]
            else:
                n_id = self._get_id_from_section_option(*keylist)
            id_list.append(n_id)
            if node.state in prev_ignoreds:
                prev_ignoreds[node.state].append(n_id)

        ranked_ids = self._get_ranked_trigger_ids()
        for _, var_id in sorted(ranked_ids):
            self.update(var_id, config, meta_config)

        # Report any discrepancies in ignored status.
        for var_id in id_list:
            section, option = self._get_section_option_from_id(var_id)
            node = config.get([section, option])
            old, new = None, None
            if var_id in self.ignored_dict:
                node.state = trig_ignored
                if not any(var_id in v for v in prev_ignoreds.values()):
                    old, new = state_map[enabled], state_map[trig_ignored]
            elif var_id in prev_ignoreds[trig_ignored]:
                node.state = enabled
                old, new = state_map[trig_ignored], state_map[enabled]
            elif (var_id in prev_ignoreds[user_ignored]
                  and var_id in self._trigger_involved_ids):
                node.state = enabled
                old, new = state_map[user_ignored], state_map[enabled]
            if old != new:
                info = self.WARNING_STATE_CHANGED.format(old, new)
                if option is None:
                    value = None
                else:
                    value = node.value
                self.add_report(section, option, value, info)
        return config, self.reports
Esempio n. 30
0
 def remove_setting(self, config, keys, info=None):
     """Remove a setting from the configuration."""
     section, option = self._get_section_option_from_keys(keys)
     if option is None:
         if config.get([section]) is None:
             return False
         option_node_pairs = config.walk([section])
         for opt_keys, option_node in option_node_pairs:
             opt = opt_keys[1]
             self._remove_setting(config, [section, opt], info)
     return self._remove_setting(config, [section, option], info)
Esempio n. 31
0
 def remove_setting(self, config, keys, info=None):
     """Remove a setting from the configuration."""
     section, option = self._get_section_option_from_keys(keys)
     if option is None:
         if config.get([section]) is None:
             return False
         option_node_pairs = config.walk([section])
         for opt_keys, option_node in option_node_pairs:
             opt = opt_keys[1]
             self._remove_setting(config, [section, opt], info)
     return self._remove_setting(config, [section, option], info)
Esempio n. 32
0
File: db.py Progetto: jimbolton/rose
def test_query_parsing(filters):
    """Test the ability of the query parser to generate logical expressions."""
    url = None
    config = rose.config.default_node()
    for key, node in reversed(config.get(["rosie-db"]).value.items()):
        if key.startswith("db.") and key[3:]:
            url = node.value
            break
    dao = DAO(url)
    dao._connect()
    return str(dao.parse_filters_to_expr(filters))
Esempio n. 33
0
 def _check_suite_version(self, fname):
     """Check the suite is compatible with this version of rose-stem."""
     if not os.path.isfile(fname):
         raise RoseSuiteConfNotFoundException(os.path.dirname(fname))
     config = rose.config.load(fname)
     suite_rose_stem_version = config.get(['ROSE_STEM_VERSION'])
     if suite_rose_stem_version:
         suite_rose_stem_version = int(suite_rose_stem_version.value)
     else:
         suite_rose_stem_version = None
     if not suite_rose_stem_version == ROSE_STEM_VERSION:
         raise RoseStemVersionException(suite_rose_stem_version)
Esempio n. 34
0
def load_meta_config_tree(config,
                          directory=None,
                          config_type=None,
                          error_handler=None,
                          ignore_meta_error=False):
    """Return the metadata config tree for a configuration."""
    if error_handler is None:
        error_handler = _report_error
    meta_list = ["rose-all/" + rose.META_CONFIG_NAME]
    if config_type is not None:
        default_meta_dir = config_type.replace(".", "-")
        meta_list.append(default_meta_dir + "/" + rose.META_CONFIG_NAME)
    config_meta_path, warning = load_meta_path(config, directory)
    if warning is not None and not ignore_meta_error:
        error_handler(text=warning)
    locator = rose.resource.ResourceLocator(paths=sys.path)
    opt_node = config.get([rose.CONFIG_SECT_TOP, rose.CONFIG_OPT_META_TYPE],
                          no_ignore=True)
    ignore_meta_error = ignore_meta_error or opt_node is None
    meta_config_tree = None
    meta_config = rose.config.ConfigNode()
    for meta_key in meta_list:
        try:
            meta_path = locator.locate(meta_key)
        except rose.resource.ResourceError:
            if not ignore_meta_error:
                error_handler(text=ERROR_LOAD_META_PATH.format(meta_key))
            continue
        try:
            meta_config_tree = rose.config_tree.ConfigTreeLoader().load(
                os.path.dirname(meta_path),
                rose.META_CONFIG_NAME,
                conf_dir_paths=list(sys.path),
                conf_node=meta_config)
        except rose.config.ConfigSyntaxError as exc:
            error_handler(text=str(exc))
        else:
            meta_config = meta_config_tree.node
    if config_meta_path is None:
        return meta_config_tree
    # Try and get a proper non-default meta config tree.
    try:
        meta_config_tree = rose.config_tree.ConfigTreeLoader().load(
            config_meta_path,
            rose.META_CONFIG_NAME,
            conf_dir_paths=list(sys.path),
            conf_node=meta_config)
    except rose.resource.ResourceError:
        if not ignore_meta_error:
            error_handler(text=ERROR_LOAD_META_PATH.format(meta_key))
    except rose.config.ConfigSyntaxError as exc:
        error_handler(text=str(exc))
    return meta_config_tree
Esempio n. 35
0
 def _remove_setting(self, config, keys, info=None):
     """Remove a setting from the configuration, if it exists."""
     section, option = self._get_section_option_from_keys(keys)
     if config.get([section, option]) is None:
         return False
     if info is None:
         info = self.INFO_REMOVED
     node = config.unset([section, option])
     value = ""
     if node.value:
         value = node.value
     self.add_report(section, option, value, info)
Esempio n. 36
0
 def _check_suite_version(self, fname):
     """Check the suite is compatible with this version of rose-stem."""
     if not os.path.isfile(fname):
         raise RoseSuiteConfNotFoundException(os.path.dirname(fname))
     config = rose.config.load(fname)
     suite_rose_stem_version = config.get(['ROSE_STEM_VERSION'])
     if suite_rose_stem_version:
         suite_rose_stem_version = int(suite_rose_stem_version.value)
     else:
         suite_rose_stem_version = None
     if not suite_rose_stem_version == ROSE_STEM_VERSION:
         raise RoseStemVersionException(suite_rose_stem_version)
Esempio n. 37
0
 def _remove_setting(self, config, keys, info=None):
     """Remove a setting from the configuration, if it exists."""
     section, option = self._get_section_option_from_keys(keys)
     if config.get([section, option]) is None:
         return False
     if info is None:
         info = self.INFO_REMOVED
     node = config.unset([section, option])
     value = ""
     if node.value:
         value = node.value
     self.add_report(section, option, value, info)
Esempio n. 38
0
    def transform(self, config, meta_config=None):
        """Apply metadata trigger expressions to variables."""
        self.reports = []
        meta_config = self._load_meta_config(config, meta_config)
        self._setup_triggers(meta_config)
        self.enabled_dict = {}
        self.ignored_dict = {}
        enabled = rose.config.ConfigNode.STATE_NORMAL
        trig_ignored = rose.config.ConfigNode.STATE_SYST_IGNORED
        user_ignored = rose.config.ConfigNode.STATE_USER_IGNORED
        state_map = {enabled: 'enabled     ',
                     trig_ignored: 'trig-ignored',
                     user_ignored: 'user-ignored'}
        id_list = []
        prev_ignoreds = {trig_ignored: [], user_ignored: []}
        for keylist, node in config.walk():
            if len(keylist) == 1:
                n_id = keylist[0]
            else:
                n_id = self._get_id_from_section_option(*keylist)
            id_list.append(n_id)
            if node.state in prev_ignoreds:
                prev_ignoreds[node.state].append(n_id)

        ranked_ids = self._get_ranked_trigger_ids()
        for rank, var_id in sorted(ranked_ids):
            self.update(var_id, config, meta_config)

        # Report any discrepancies in ignored status.
        for var_id in id_list:
            section, option = self._get_section_option_from_id(var_id)
            node = config.get([section, option])
            old, new = None, None
            if var_id in self.ignored_dict:
                node.state = trig_ignored
                if not any([var_id in v for k, v in prev_ignoreds.items()]):
                    old, new = state_map[enabled], state_map[trig_ignored]
            elif var_id in prev_ignoreds[trig_ignored]:
                node.state = enabled
                old, new = state_map[trig_ignored], state_map[enabled]
            elif (var_id in prev_ignoreds[user_ignored] and
                  var_id in self._trigger_involved_ids):
                node.state = enabled
                old, new = state_map[user_ignored], state_map[enabled]
            if old != new:
                info = self.WARNING_STATE_CHANGED.format(old, new)
                if option is None:
                    value = None
                else:
                    value = node.value
                self.add_report(section, option, value, info)
        return config, self.reports
Esempio n. 39
0
def load_meta_config_tree(config, directory=None, config_type=None,
                          error_handler=None, ignore_meta_error=False):
    """Return the metadata config tree for a configuration."""
    if error_handler is None:
        error_handler = _report_error
    meta_list = ["rose-all/" + rose.META_CONFIG_NAME]
    if config_type is not None:
        default_meta_dir = config_type.replace(".", "-")
        meta_list.append(default_meta_dir + "/" + rose.META_CONFIG_NAME)
    config_meta_path, warning = load_meta_path(config, directory)
    if warning is not None and not ignore_meta_error:
        error_handler(text=warning)
    locator = rose.resource.ResourceLocator(paths=sys.path)
    opt_node = config.get([rose.CONFIG_SECT_TOP,
                           rose.CONFIG_OPT_META_TYPE], no_ignore=True)
    ignore_meta_error = ignore_meta_error or opt_node is None
    meta_config_tree = None
    meta_config = rose.config.ConfigNode()
    for meta_key in meta_list:
        try:
            meta_path = locator.locate(meta_key)
        except rose.resource.ResourceError:
            if not ignore_meta_error:
                error_handler(text=ERROR_LOAD_META_PATH.format(meta_key))
            continue
        try:
            meta_config_tree = rose.config_tree.ConfigTreeLoader().load(
                os.path.dirname(meta_path),
                rose.META_CONFIG_NAME,
                conf_dir_paths=list(sys.path),
                conf_node=meta_config
            )
        except rose.config.ConfigSyntaxError as exc:
            error_handler(text=str(exc))
        else:
            meta_config = meta_config_tree.node
    if config_meta_path is None:
        return meta_config_tree
    # Try and get a proper non-default meta config tree.
    try:
        meta_config_tree = rose.config_tree.ConfigTreeLoader().load(
            config_meta_path,
            rose.META_CONFIG_NAME,
            conf_dir_paths=list(sys.path),
            conf_node=meta_config
        )
    except rose.resource.ResourceError:
        if not ignore_meta_error:
            error_handler(text=ERROR_LOAD_META_PATH.format(meta_key))
    except rose.config.ConfigSyntaxError as exc:
        error_handler(text=str(exc))
    return meta_config_tree
Esempio n. 40
0
 def rename_setting(self, config, keys, new_keys, info=None):
     """Rename a setting in the configuration."""
     section, option = self._get_section_option_from_keys(keys)
     new_section, new_option = self._get_section_option_from_keys(new_keys)
     if option is None:
         if new_option is not None:
             raise TypeError(self.ERROR_RENAME_SECT_TO_OPT.format(section, new_section, new_option))
     elif new_option is None:
         raise TypeError(self.ERROR_RENAME_OPT_TO_SECT.format(section, option, new_section))
     node = config.get(keys)
     if node is None:
         return
     if info is None:
         if option is None:
             info = self.INFO_RENAMED_SECT.format(section, new_section)
         else:
             info = self.INFO_RENAMED_VAR.format(section, option, new_section, new_option)
     if option is None:
         if config.get([new_section]) is not None:
             self.remove_setting(config, [new_section])
         self.add_setting(
             config, [new_section], value=None, forced=True, state=node.state, comments=node.comments, info=info
         )
         for option_keys, opt_node in config.walk([section]):
             renamed_option = option_keys[1]
             self.add_setting(
                 config,
                 [new_section, renamed_option],
                 value=opt_node.value,
                 forced=True,
                 state=opt_node.state,
                 comments=opt_node.comments,
                 info=info,
             )
     else:
         self.add_setting(
             config, new_keys, value=node.value, forced=True, state=node.state, comments=node.comments, info=info
         )
     self.remove_setting(config, keys)
Esempio n. 41
0
def load_override_config():
    """Load any overrides of the above settings."""
    config = rose.config.default_node()
    node = config.get(["rosie-browse"], no_ignore=True)
    if node is None:
        return
    for option, opt_node in node.value.items():
        if opt_node.is_ignored():
            continue
        try:
            cast_value = ast.literal_eval(opt_node.value)
        except Exception:
            cast_value = opt_node.value
        globals()[option.replace("-", "_").upper()] = cast_value
Esempio n. 42
0
    def change_setting_value(self,
                             config,
                             keys,
                             value,
                             forced=False,
                             comments=None,
                             info=None):
        """Change a setting (option) value in the configuration.

        Args:
            config (rose.config.ConfigNode): The application configuration.
            keys (list): A list defining a hierarchy of node.value 'keys'.
                A section will be a list of one keys, an option will have two.
            value (string): The new value. Required for options, can be
                ``None`` for sections.
            forced (bool): Create the setting if it is not present in config.
            comments (list - optional): List of comment lines (strings) for
                the new setting or ``None``.
            info (string - optional): A short string containing no new lines,
                describing the addition of the setting.

        Returns:
            None

        """
        section, option = self._get_section_option_from_keys(keys)
        id_ = self._get_id_from_section_option(section, option)
        node = config.get([section, option])
        if node is None:
            if forced:
                return self.add_setting(config,
                                        keys,
                                        value=value,
                                        comments=comments,
                                        info=info)
            return False
        if node.value == value:
            return False
        if option is None:
            text = "Not valid for value change: {0}".format(id_)
            raise TypeError(text)
        if info is None:
            info = self.INFO_CHANGED_VAR.format(repr(node.value), repr(value))
        if value is not None and not isinstance(value, basestring):
            text = "New value {0} for {1} is not a string"
            raise ValueError(text.format(repr(value), id_))
        node.value = value
        if comments is not None:
            node.comments = comments
        self.add_report(section, option, value, info)
Esempio n. 43
0
def load_meta_path(config=None, directory=None):
    """Retrieve the path to the metadata."""
    if config is None:
        config = rose.config.ConfigNode()
    if directory is not None:
        config_meta_dir = os.path.join(directory, rose.CONFIG_META_DIR)
        if os.path.isdir(config_meta_dir):
            return config_meta_dir
    locator = rose.resource.ResourceLocator(paths=sys.path)
    opt_node = config.get([rose.CONFIG_SECT_TOP,
                           rose.CONFIG_OPT_META_TYPE], no_ignore=True)
    ignore_meta_error = opt_node is None
    if opt_node is None:
        opt_node = config.get([rose.CONFIG_SECT_TOP,
                               rose.CONFIG_OPT_PROJECT], no_ignore=True)
    meta_path = "all" if opt_node is None else opt_node.value
    meta_path = "etc/metadata/" + meta_path
    try:
        meta_path = locator.locate(meta_path)
    except rose.resource.ResourceError:
        if not ignore_meta_error:
            sys.stderr.write(ERROR_LOAD_META_PATH.format(meta_path))
        return None
    return meta_path
Esempio n. 44
0
    def transform(self,
                  config,
                  meta_config=None,
                  opt_non_interactive=False,
                  custom_inspector=False):
        """Transform a configuration by looping over upgrade macros."""
        self.reports = []
        for macro in self.get_macros():
            if self.downgrade:
                func = macro.downgrade
            else:
                func = macro.upgrade
            res = {}
            if not opt_non_interactive:
                arglist = inspect.getargspec(func).args
                defaultlist = inspect.getargspec(func).defaults
                optionals = {}
                while defaultlist is not None and len(defaultlist) > 0:
                    if arglist[-1] not in ["self", "config", "meta_config"]:
                        optionals[arglist[-1]] = defaultlist[-1]
                        arglist = arglist[0:-1]
                        defaultlist = defaultlist[0:-1]
                    else:
                        break

                if optionals:
                    if custom_inspector:
                        res = custom_inspector(optionals, "upgrade_macro")
                    else:
                        res = rose.macro.get_user_values(optionals)
            upgrade_macro_result = func(config, meta_config, **res)
            config, i_changes = upgrade_macro_result
            self.reports += i_changes
        opt_node = config.get(
            [rose.CONFIG_SECT_TOP, rose.CONFIG_OPT_META_TYPE], no_ignore=True)
        new_value = self.meta_flag_no_tag + "/" + self.new_tag
        opt_node.value = new_value
        if self.downgrade:
            info = INFO_DOWNGRADED.format(self.tag, self.new_tag)
        else:
            info = INFO_UPGRADED.format(self.tag, self.new_tag)
        report = rose.macro.MacroReport(rose.CONFIG_SECT_TOP,
                                        rose.CONFIG_OPT_META_TYPE, new_value,
                                        info)
        self.reports += [report]
        return config, self.reports
Esempio n. 45
0
 def _ignore_setting(self, config, keys, info=None, state=None):
     """Set the ignored state of a setting, if it exists."""
     section, option = self._get_section_option_from_keys(keys)
     node = config.get([section, option])
     if node is None or state is None:
         return False
     if option is None:
         value = None
     else:
         value = node.value
     info_text = self.INFO_STATE.format(IGNORE_MAP[node.state],
                                        IGNORE_MAP[state])
     if node.state == state:
         return False
     if info is None:
         info = info_text
     node.state = state
     self.add_report(section, option, value, info)
Esempio n. 46
0
    def remove_setting(self, config, keys, info=None):
        """Remove a setting from the configuration.

        Args:
            config (rose.config.ConfigNode): The application configuration.
            keys (list): A list defining a hierarchy of node.value 'keys'.
                A section will be a list of one keys, an option will have two.
            info (string - optional): A short string containing no new lines,
                describing the addition of the setting.

        Returns:
            None
        """
        section, option = self._get_section_option_from_keys(keys)
        if option is None:
            if config.get([section]) is None:
                return False
            option_node_pairs = config.walk([section])
            for opt_keys, _ in option_node_pairs:
                opt = opt_keys[1]
                self._remove_setting(config, [section, opt], info)
        return self._remove_setting(config, [section, option], info)
Esempio n. 47
0
    def add_setting(self,
                    config,
                    keys,
                    value=None,
                    forced=False,
                    state=None,
                    comments=None,
                    info=None):
        """Add a setting to the configuration."""
        section, option = self._get_section_option_from_keys(keys)
        id_ = self._get_id_from_section_option(section, option)
        if option is not None and value is None:
            value = ""
        if info is None:
            if option is None:
                info = self.INFO_ADDED_SECT
            else:
                info = self.INFO_ADDED_VAR.format(repr(value))

        # Search for existing conflicting settings.
        conflict_id = None
        found_setting = False
        if config.get([section, option]) is None:
            strip_dupl = rose.macro.REC_ID_STRIP
            for key in config.get_value():
                existing_section = key
                if not existing_section.startswith(section):
                    continue
                existing_base_section = (rose.macro.REC_ID_STRIP.sub(
                    "", existing_section))
                if option is None:
                    # For section 'foo', look for 'foo', 'foo{bar}', 'foo(1)'.
                    found_setting = (existing_section == section
                                     or existing_base_section == section)
                else:
                    # For 'foo=bar', don't allow sections 'foo(1)', 'foo{bar}'.
                    found_setting = (existing_section != section
                                     and existing_base_section == section)
                if found_setting:
                    conflict_id = existing_section
                    break
                if option is not None:
                    for keys, node in config.walk([existing_section]):
                        existing_option = keys[1]
                        existing_base_option = (
                            rose.macro.REC_ID_STRIP_DUPL.sub(
                                "", existing_option))
                        # For option 'foo', look for 'foo', 'foo(1)'.
                        if (existing_section == section
                                and (existing_option == option
                                     or existing_base_option == option)):
                            found_setting = True
                            conflict_id = self._get_id_from_section_option(
                                existing_section, existing_option)
                            break
                    if found_setting:
                        break
        else:
            found_setting = True
            conflict_id = None

        # If already added, quit, unless "forced".
        if found_setting:
            if forced and (conflict_id is None or id_ == conflict_id):
                # If forced, override settings for an identical id.
                return self.change_setting_value(config, keys, value, state,
                                                 comments, info)
            if conflict_id:
                self.add_report(section,
                                option,
                                value,
                                self.WARNING_ADD_CLASH.format(
                                    id_, conflict_id),
                                is_warning=True)
            return False

        # Add parent section if missing.
        if option is not None and config.get([section]) is None:
            self.add_setting(config, [section])
        if value is not None and not isinstance(value, basestring):
            text = "New value {0} for {1} is not a string"
            raise ValueError(text.format(repr(value), id_))

        # Set (add) the section/option.
        config.set([section, option],
                   value=value,
                   state=state,
                   comments=comments)
        self.add_report(section, option, value, info)
Esempio n. 48
0
    def add_setting(self,
                    config,
                    keys,
                    value=None,
                    forced=False,
                    state=None,
                    comments=None,
                    info=None):
        """Add a setting to the configuration."""
        section, option = self._get_section_option_from_keys(keys)
        id_ = self._get_id_from_section_option(section, option)
        if option is not None and value is None:
            value = ""
        if info is None:
            if option is None:
                info = self.INFO_ADDED_SECT
            else:
                info = self.INFO_ADDED_VAR.format(repr(value))

        # Search for existing conflicting settings.
        found_setting = False
        if config.get([section, option]) is None:
            strip_dupl = rose.macro.REC_ID_STRIP
            for keys, node in config.walk():
                existing_section = keys[0]
                existing_base_section = (rose.macro.REC_ID_STRIP.sub(
                    "", existing_section))
                if len(keys) == 1:
                    existing_option = None
                    existing_base_option = None
                else:
                    existing_option = keys[1]
                    existing_base_option = (rose.macro.REC_ID_STRIP_DUPL.sub(
                        "", existing_option))
                if option is None:
                    # For section 'foo', look for 'foo', 'foo{bar}', 'foo(1)'.
                    if (existing_section == section
                            or existing_base_section == section):
                        found_setting = True
                        break
                # For option 'foo', look for 'foo', 'foo(1)'.
                elif (existing_section == section
                      and (existing_option == option
                           or existing_base_option == option)):
                    found_setting = True
                    break
        else:
            found_setting = True

        # If already added, quit, unless "forced".
        if found_setting:
            if forced:
                # If forced, override the existing properties.
                return self.change_setting_value(config, keys, value, state,
                                                 comments, info)
            return False

        # Add parent section if missing.
        if option is not None and config.get([section]) is None:
            self.add_setting(config, [section])
        if value is not None and not isinstance(value, basestring):
            text = "New value {0} for {1} is not a string"
            raise ValueError(text.format(repr(value), id_))

        # Set (add) the section/option.
        config.set([section, option],
                   value=value,
                   state=state,
                   comments=comments)
        self.add_report(section, option, value, info)
Esempio n. 49
0
def add_trigger_graph(graph,
                      config,
                      meta_config,
                      err_reporter,
                      allowed_sections=None):
    """Add trigger-related nodes and edges to the graph."""
    trigger = rose.macros.trigger.TriggerMacro()
    bad_reports = trigger.validate_dependencies(config, meta_config)
    if bad_reports:
        err_reporter(
            rose.macro.get_reports_as_text(bad_reports,
                                           "trigger.TriggerMacro"))
        return None
    ids = []
    for keylist, node in meta_config.walk(no_ignore=True):
        id_ = keylist[0]
        if (id_.startswith(rose.META_PROP_NS + rose.CONFIG_DELIMITER)
                or id_.startswith(rose.SUB_CONFIG_FILE_DIR + ":*")):
            continue
        if isinstance(node.value, dict):
            section, option = (rose.macro.get_section_option_from_id(id_))
            if not allowed_sections or (allowed_sections
                                        and section in allowed_sections):
                ids.append(id_)
    ids.sort(rose.config.sort_settings)
    delim = rose.CONFIG_DELIMITER
    for id_ in ids:
        section, option = rose.macro.get_section_option_from_id(id_)
        node_attrs = get_node_state_attrs(config,
                                          section,
                                          option,
                                          allowed_sections=allowed_sections)
        graph.add_node(id_, **node_attrs)
    for setting_id, id_value_dict in sorted(
            trigger.trigger_family_lookup.items()):
        section, option = rose.macro.get_section_option_from_id(setting_id)
        section_node = config.get([section], no_ignore=True)
        node = config.get([section, option])
        if node is None:
            setting_value = None
        else:
            setting_value = node.value
        setting_is_section_ignored = (option is None and section_node is None)
        for dependent_id, values in sorted(id_value_dict.items()):
            dep_section, dep_option = rose.macro.get_section_option_from_id(
                dependent_id)
            if (allowed_sections
                    and (section not in allowed_sections
                         and dep_section not in allowed_sections)):
                continue
            if not values:
                values = [None]
            has_success = False
            if setting_value is not None:
                for value in values:
                    if value is None:
                        if (node.state == node.STATE_NORMAL
                                and not setting_is_section_ignored):
                            has_success = True
                            break
                    elif trigger._check_values_ok(setting_value, setting_id,
                                                  [value]):
                        has_success = True
                        break
            for value in values:
                value_id = setting_id + "=" + str(value)
                dependent_attrs = {}
                if setting_value is None:
                    dependent_attrs["color"] = COLOUR_MISSING
                else:
                    dependent_attrs["color"] = COLOUR_IGNORED
                    if value is None:
                        if (node.state == node.STATE_NORMAL
                                and not setting_is_section_ignored):
                            dependent_attrs["color"] = COLOUR_ENABLED
                    elif trigger._check_values_ok(setting_value, setting_id,
                                                  [value]):
                        dependent_attrs["color"] = COLOUR_ENABLED
                if not graph.has_node(setting_id):
                    node_attrs = get_node_state_attrs(
                        config,
                        section,
                        option,
                        allowed_sections=allowed_sections)
                    graph.add_node(setting_id, **node_attrs)
                if not graph.has_node(dependent_id):
                    node_attrs = get_node_state_attrs(
                        config,
                        dep_section,
                        dep_option,
                        allowed_sections=allowed_sections)
                    graph.add_node(dependent_id, **node_attrs)
                if not graph.has_node(value_id):
                    node_attrs = {
                        "style": "filled",
                        "label": value,
                        "shape": "box"
                    }
                    node_attrs.update(dependent_attrs)
                    graph.add_node(value_id, **node_attrs)
                edge_attrs = {}
                edge_attrs.update(dependent_attrs)
                if setting_value is not None:
                    edge_attrs["label"] = setting_value
                graph.add_edge(setting_id, value_id, **edge_attrs)
                if dependent_attrs["color"] == COLOUR_IGNORED and has_success:
                    dependent_attrs["arrowhead"] = STYLE_ARROWHEAD_EMPTY
                graph.add_edge(value_id, dependent_id, **dependent_attrs)
Esempio n. 50
0
    def add_setting(self,
                    config,
                    keys,
                    value=None,
                    forced=False,
                    state=None,
                    comments=None,
                    info=None):
        """Add a setting to the configuration.

        Args:
            config (rose.config.ConfigNode): The application configuration.
            keys (list): A list defining a hierarchy of node.value 'keys'.
                A section will be a list of one keys, an option will have two.
            value (string - optional): String denoting the new setting value.
                Required for options but not for settings.
            forced (bool - optional)
                If True override value if the setting already exists.
            state (str - optional):
                The state of the new setting - should be one of the
                ``rose.config.ConfigNode`` states e.g.
                ``rose.config.ConfigNode.STATE_USER_IGNORED``. Defaults to
                ``rose.config.ConfigNode.STATE_NORMAL``.
            comments (list - optional): List of comment lines (strings) for
                the new setting or ``None``.
            info (string - optional): A short string containing no new lines,
                describing the addition of the setting.

        Returns:
            None
        """
        section, option = self._get_section_option_from_keys(keys)
        id_ = self._get_id_from_section_option(section, option)
        if option is not None and value is None:
            value = ""
        if info is None:
            if option is None:
                info = self.INFO_ADDED_SECT
            else:
                info = self.INFO_ADDED_VAR.format(repr(value))

        # Search for existing conflicting settings.
        conflict_id = None
        found_setting = False
        if config.get([section, option]) is None:
            for key in config.get_value():
                existing_section = key
                if not existing_section.startswith(section):
                    continue
                existing_base_section = (rose.macro.REC_ID_STRIP.sub(
                    "", existing_section))
                if option is None:
                    # For section 'foo', look for 'foo', 'foo{bar}', 'foo(1)'.
                    found_setting = (existing_section == section
                                     or existing_base_section == section)
                else:
                    # For 'foo=bar', don't allow sections 'foo(1)', 'foo{bar}'.
                    found_setting = (existing_section != section
                                     and existing_base_section == section)
                if found_setting:
                    conflict_id = existing_section
                    break
                if option is not None:
                    for keys, _ in config.walk([existing_section]):
                        existing_option = keys[1]
                        existing_base_option = (
                            rose.macro.REC_ID_STRIP_DUPL.sub(
                                "", existing_option))
                        # For option 'foo', look for 'foo', 'foo(1)'.
                        if (existing_section == section
                                and (existing_option == option
                                     or existing_base_option == option)):
                            found_setting = True
                            conflict_id = self._get_id_from_section_option(
                                existing_section, existing_option)
                            break
                    if found_setting:
                        break
        else:
            found_setting = True
            conflict_id = None

        # If already added, quit, unless "forced".
        if found_setting:
            if forced and (conflict_id is None or id_ == conflict_id):
                # If forced, override settings for an identical id.
                return self.change_setting_value(config, keys, value, state,
                                                 comments, info)
            if conflict_id:
                self.add_report(section,
                                option,
                                value,
                                self.WARNING_ADD_CLASH.format(
                                    id_, conflict_id),
                                is_warning=True)
            return False

        # Add parent section if missing.
        if option is not None and config.get([section]) is None:
            self.add_setting(config, [section])
        if value is not None and not isinstance(value, basestring):
            text = "New value {0} for {1} is not a string"
            raise ValueError(text.format(repr(value), id_))

        # Set (add) the section/option.
        config.set([section, option],
                   value=value,
                   state=state,
                   comments=comments)
        self.add_report(section, option, value, info)
Esempio n. 51
0
File: macro.py Progetto: kaday/rose
def load_meta_path(config=None, directory=None, is_upgrade=False,
                   locator=None):
    """Retrieve the path to the configuration metadata directory.

    Arguments:
        config - a rose config, perhaps with a meta= or project= flag
        directory - the directory of the rose config file
        is_upgrade - if True, load the path in an upgrade-specific way
        locator - a rose.resource.ResourceLocator instance.

    Returns the path to(or None) and a warning message (or None).

    """
    if config is None:
        config = rose.config.ConfigNode()
    warning = None
    if directory is not None and not is_upgrade:
        config_meta_dir = os.path.join(directory, rose.CONFIG_META_DIR)
        meta_file = os.path.join(config_meta_dir, rose.META_CONFIG_NAME)
        if os.path.isfile(meta_file):
            return config_meta_dir, warning
    if locator is None:
        locator = rose.resource.ResourceLocator(paths=sys.path)
    opt_node = config.get([rose.CONFIG_SECT_TOP,
                           rose.CONFIG_OPT_META_TYPE], no_ignore=True)
    ignore_meta_error = opt_node is None
    if opt_node is None:
        opt_node = config.get([rose.CONFIG_SECT_TOP,
                               rose.CONFIG_OPT_PROJECT], no_ignore=True)
    if opt_node is None or not opt_node.value:
        meta_keys = ["rose-all"]
    else:
        key = opt_node.value
        if "/" not in key:
            key = key + "/" + rose.META_DEFAULT_VN_DIR
        meta_keys = [key]
        if is_upgrade:
            meta_keys = [key.split("/")[0]]
        else:
            default_key = (key.rsplit("/", 1)[0] + "/" +
                           rose.META_DEFAULT_VN_DIR)
            if default_key != key:
                meta_keys.append(default_key)
    for i, meta_key in enumerate(meta_keys):
        path = os.path.join(meta_key, rose.META_CONFIG_NAME)
        if is_upgrade:
            path = meta_key
        try:
            meta_path = locator.locate(path)
        except rose.resource.ResourceError:
            continue
        else:
            if not ignore_meta_error and i > 0:
                warning = ERROR_LOAD_CHOSEN_META_PATH.format(meta_keys[0],
                                                             meta_keys[i])
            if is_upgrade:
                return meta_path, warning
            return os.path.dirname(meta_path), warning
    if not ignore_meta_error:
        warning = ERROR_LOAD_META_PATH.format(meta_keys[0])
    return None, warning
Esempio n. 52
0
 def _get_error_report_for_id(self, variable_id, config, error_string):
     section, option = self._get_section_option_from_id(variable_id)
     node = config.get([section, option])
     value = None if node is None else node.value
     self.add_report(section, option, value, error_string)
     return self.reports
Esempio n. 53
0
 def validate_dependencies(self, config, meta_config):
     """Validate the trigger setup - e.g. check for cyclic dependencies."""
     self.reports = []
     if meta_config is None:
         meta_config = rose.config.ConfigNode()
     if not hasattr(self, 'trigger_family_lookup'):
         self._setup_triggers(meta_config)
     config_sections = config.value.keys()
     meta_settings = [k for k in meta_config.value.keys()
                      if not meta_config.value[k].is_ignored()]
     allowed_repetitions = {}
     trigger_ids = self.trigger_family_lookup.keys()
     trigger_ids.sort()
     for var_id in trigger_ids:
         allowed_repetitions[var_id] = 0
     for id_value_dict in self.trigger_family_lookup.values():
         for var_id in id_value_dict:
             allowed_repetitions.setdefault(var_id, 0)
             allowed_repetitions[var_id] += 1
     for start_id in trigger_ids:
         id_value_dict = self._get_family_dict(start_id, config,
                                               meta_config)
         triggered_ids = id_value_dict.keys()
         triggered_ids.sort()
         if self._check_is_id_dupl(start_id, meta_config):
             st_sect, st_opt = self._get_section_option_from_id(start_id)
             for tr_id in triggered_ids:
                 tr_sect, tr_opt = self._get_section_option_from_id(tr_id)
                 if tr_sect != st_sect:
                     return self._get_error_report_for_id(
                         start_id, config,
                         self.ERROR_DUPL_TRIG.format(st_sect))
         for value_list in id_value_dict.values():
             for string in [s for s in value_list if s is not None]:
                 if self.rec_rule.search(string):
                     try:
                         self.evaluate_trig_rule(string, start_id, '')
                     except rose.macros.rule.RuleValueError:
                         continue
                     except Exception:
                         return self._get_error_report_for_id(
                             start_id, config,
                             self.ERROR_BAD_EXPR.format(string))
         stack = [(start_id, triggered_ids)]
         id_list = []
         while stack:
             var_id, child_ids = stack[0]
             base_id = self._get_stripped_id(var_id, meta_config)
             if base_id not in meta_settings:
                 return self._get_error_report_for_id(
                     var_id, config, self.ERROR_MISSING_METADATA)
             id_list.append(var_id)
             child_ids.sort()
             if var_id in config_sections:
                 child_ids += config.get([var_id]).value.keys()
             for child_id in child_ids:
                 base_id = self._get_stripped_id(child_id, meta_config)
                 if base_id not in meta_settings:
                     return self._get_error_report_for_id(
                         child_id, config, self.ERROR_MISSING_METADATA)
                 if child_id in self.trigger_family_lookup:
                     grandchildren = (
                         self.trigger_family_lookup[child_id].keys())
                     grandchildren.sort()
                     stack.insert(1, (child_id, grandchildren))
                     if (id_list.count(child_id) + 1 >
                             allowed_repetitions[child_id] and
                             id_list.count(child_id) >= 2):
                         # Then it may be looping cyclically.
                         duplicate_seq = self._get_dup_sequence(id_list,
                                                                child_id)
                         if duplicate_seq:
                             return self._get_error_report_for_id(
                                 var_id, config,
                                 self.ERROR_CYCLIC.format(child_id, var_id))
             stack.pop(0)
     return []
Esempio n. 54
0
 def get_setting_value(self, config, keys, no_ignore=False):
     """Return the value of a setting."""
     section, option = self._get_section_option_from_keys(keys)
     if config.get([section, option], no_ignore=no_ignore) is None:
         return None
     return config.get([section, option]).value