Beispiel #1
0
def get_rose_vars(srcdir=None, opts=None):
    """Load template variables from Rose suite configuration.

    Loads the Rose suite configuration tree from the filesystem
    using the shell environment.

    Args:
        srcdir(pathlib.Path):
            Path to the Rose suite configuration
            (the directory containing the ``rose-suite.conf`` file).
        opts:
            Options object containing specification of optional
            configuarations set by the CLI.

    Returns:
        dict - A dictionary of sections of rose-suite.conf.
        For each section either a dictionary or None is returned.
        E.g.
            {
                'env': {'MYVAR': 42},
                'empy:suite.rc': None,
                'jinja2:suite.rc': {
                    'myJinja2Var': {'yes': 'it is a dictionary!'}
                }
            }
    """
    # Set up blank page for returns.
    config = {
        'env': {},
        'template_variables': {},
        'templating_detected': None
    }

    # Return a blank config dict if srcdir does not exist
    if not rose_config_exists(srcdir, opts):
        if (
            getattr(opts, "opt_conf_keys", None)
            or getattr(opts, "defines", None)
            or getattr(opts, "rose_template_vars", None)
        ):
            raise NotARoseSuiteException()
        return config

    # Load the raw config tree
    config_tree = rose_config_tree_loader(srcdir, opts)
    deprecation_warnings(config_tree)

    # Extract templatevars from the configuration
    get_rose_vars_from_config_node(
        config,
        config_tree.node,
        os.environ
    )

    # Export environment vars
    for key, val in config['env'].items():
        os.environ[key] = val

    return config
Beispiel #2
0
def test_rose_config_tree_loader_CLI_handling(tmp_path, expect, file, opts):
    """Test interaction of config tree loader with -S and -D.
    """
    source = tmp_path
    (source / 'rose-suite.conf').write_text(file)
    opts = SimpleNamespace(**opts)
    tree = rose_config_tree_loader(source, opts)
    assert node_stripper(tree.node) == expect
Beispiel #3
0
def rose_fileinstall(srcdir=None, opts=None, rundir=None):
    """Call Rose Fileinstall.

    Args:
        srcdir(pathlib.Path):
            Search for a ``rose-suite.conf`` file in this location.
        rundir (pathlib.Path)

    """
    if not rose_config_exists(rundir, opts):
        return False

    # Load the config tree
    config_tree = rose_config_tree_loader(rundir, opts)

    if any(i.startswith('file') for i in config_tree.node.value):
        try:
            startpoint = os.getcwd()
            os.chdir(rundir)
        except FileNotFoundError as exc:
            raise exc
        else:
            # Carry out imports.
            import asyncio
            from metomi.rose.config_processor import ConfigProcessorsManager
            from metomi.rose.popen import RosePopener
            from metomi.rose.reporter import Reporter
            from metomi.rose.fs_util import FileSystemUtil

            # Update config tree with install location
            # NOTE-TO-SELF: value=os.environ["CYLC_WORKFLOW_RUN_DIR"]
            config_tree.node = config_tree.node.set(
                keys=["file-install-root"], value=str(rundir)
            )

            # Artificially set rose to verbose.
            event_handler = Reporter(3)
            fs_util = FileSystemUtil(event_handler)
            popen = RosePopener(event_handler)

            # Get an Asyncio loop if one doesn't exist:
            #   Rose may need an event loop to invoke async interfaces,
            #   doing this here incase we want to go async in cylc-rose.
            # See https://github.com/cylc/cylc-rose/pull/130/files
            try:
                asyncio.get_event_loop()
            except RuntimeError:
                asyncio.set_event_loop(asyncio.new_event_loop())

            # Process fileinstall.
            config_pm = ConfigProcessorsManager(event_handler, popen, fs_util)
            config_pm(config_tree, "file")
        finally:
            os.chdir(startpoint)

    return config_tree.node
Beispiel #4
0
def get_rose_vars(srcdir=None, opts=None):
    """Load template variables from Rose suite configuration.

    Loads the Rose suite configuration tree from the filesystem
    using the shell environment.

    Args:
        srcdir(pathlib.Path):
            Path to the Rose suite configuration
            (the directory containing the ``rose-suite.conf`` file).
        opts:
            Options object containing specification of optional
            configuarations set by the CLI.

    Returns:
        dict - A dictionary of sections of rose-suite.conf.
        For each section either a dictionary or None is returned.
        E.g.
            {
                'env': {'MYVAR': 42},
                'empy:suite.rc': None,
                'jinja2:suite.rc': {
                    'myJinja2Var': {'yes': 'it is a dictionary!'}
                }
            }
    """
    # Set up blank page for returns.
    config = {'env': {}, 'template_variables': {}, 'templating_detected': None}

    # Return a blank config dict if srcdir does not exist
    if not rose_config_exists(srcdir, opts):
        return config

    # Load the raw config tree
    config_tree = rose_config_tree_loader(srcdir, opts)

    # Warn if root-dir set in config:
    if 'root-dir' in config_tree.node:
        LOG.warning('You have set "root-dir", which at Cylc 8 does nothing. '
                    'See Cylc Install documentation.')

    # Extract templatevars from the configuration
    get_rose_vars_from_config_node(config, config_tree.node, os.environ)

    # Export environment vars
    for key, val in config['env'].items():
        os.environ[key] = val

    return config
Beispiel #5
0
def test_rose_config_tree_loader(
    rose_config_template,
    override,
    section,
    exp_ANOTHER_JINJA2_ENV,
    exp_JINJA2_VAR,
    opts_format
):
    """Test reading of empy or jinja2 vars

    Scenarios tested:
        - Read in a basic rose-suite.conf file. Ensure we don't return env,
          just jinja2/empy.
        - Get optional config name from an environment variable.
        - Get optional config name from command line option.
        - Get optional config name from an explicit over-ride string.
    """
    options = None
    if override == 'environment':
        os.environ['ROSE_SUITE_OPT_CONF_KEYS'] = "gravy"
    else:
        # Prevent externally set environment var breaking tests.
        os.environ['ROSE_SUITE_OPT_CONF_KEYS'] = ""
    if opts_format == 'list':
        conf_keys = ['chips']
    else:
        conf_keys = 'chips'
    if override == 'CLI':
        options = SimpleNamespace()
        options.opt_conf_keys = conf_keys
    if override == 'override':
        options = SimpleNamespace()
        options.opt_conf_keys = conf_keys
        options.defines = [
            f"[{section}:suite.rc]Another_Jinja2_var=Variable overridden"
        ]

    result = rose_config_tree_loader(
        rose_config_template(section), options
    ).node.value[section + ':suite.rc'].value
    results = {
        'Another_Jinja2_var': result['Another_Jinja2_var'].value,
        'JINJA2_VAR': result['JINJA2_VAR'].value
    }
    expected = {
        'Another_Jinja2_var': f'{exp_ANOTHER_JINJA2_ENV}',
        'JINJA2_VAR': f'{exp_JINJA2_VAR}'
    }
    assert results == expected
def rose_fileinstall(srcdir=None, opts=None, rundir=None):
    """Call Rose Fileinstall.

    Args:
        srcdir(pathlib.Path):
            Search for a ``rose-suite.conf`` file in this location.
        rundir (pathlib.Path)

    """
    if not rose_config_exists(rundir, opts):
        return False

    # Load the config tree
    config_tree = rose_config_tree_loader(rundir, opts)

    if any(i.startswith('file') for i in config_tree.node.value):
        try:
            startpoint = os.getcwd()
            os.chdir(rundir)
        except FileNotFoundError as exc:
            raise exc
        else:
            # Carry out imports.
            from metomi.rose.config_processor import ConfigProcessorsManager
            from metomi.rose.popen import RosePopener
            from metomi.rose.reporter import Reporter
            from metomi.rose.fs_util import FileSystemUtil

            # Update config tree with install location
            # NOTE-TO-SELF: value=os.environ["CYLC_WORKFLOW_RUN_DIR"]
            config_tree.node = config_tree.node.set(
                keys=["file-install-root"], value=str(rundir)
            )

            # Artificially set rose to verbose.
            event_handler = Reporter(3)
            fs_util = FileSystemUtil(event_handler)
            popen = RosePopener(event_handler)

            # Process files
            config_pm = ConfigProcessorsManager(event_handler, popen, fs_util)
            config_pm(config_tree, "file")
        finally:
            os.chdir(startpoint)

    return config_tree.node