def check_fails_while_listing_installed(dirname):
        def sabotaged_installed_command(prefix):
            from anaconda_project.internal import conda_api
            raise conda_api.CondaError("sabotage!")

        monkeypatch.setattr('anaconda_project.internal.conda_api.installed',
                            sabotaged_installed_command)

        project_dir_disable_dedicated_env(dirname)
        local_state = LocalStateFile.load_for_directory(dirname)

        requirement = CondaEnvRequirement(
            registry=PluginRegistry(),
            env_specs=dict(
                default=EnvSpec('default', ['not_a_real_package'], [])))
        environ = minimal_environ(PROJECT_DIR=dirname)
        status = requirement.check_status(
            environ, local_state, 'default',
            UserConfigOverrides(inherited_env=environ.get(conda_env_var)))
        assert status.status_description.startswith(
            "Conda failed while listing installed packages in ")
        assert status.status_description.endswith(": sabotage!")
    def check(dirname):
        _monkeypatch_pwd(monkeypatch, dirname)
        local_state = LocalStateFile.load_for_directory(dirname)
        local_state.set_service_run_state('ABC', {
            'shutdown_commands': [_echo_commandline + ['"shutting down ABC"']]
        })
        local_state.set_service_run_state('TEST', {
            'shutdown_commands':
            [_echo_commandline + ['"shutting down TEST"']]
        })
        local_state.save()

        code = _parse_args_and_run_subcommand(
            ['anaconda-project', 'remove-service', 'redis'])
        assert code == 1

        out, err = capsys.readouterr()
        assert '' == out
        expected_err = (
            "Conflicting #1lab_results, found 2 matches, use list-services"
            " to identify which service you want to remove\n")
        assert expected_err == err
Exemple #3
0
    def config_html(dirname):
        FILENAME = os.path.join(dirname, 'data.csv')
        local_state_file = LocalStateFile.load_for_directory(dirname)
        requirement = _download_requirement()
        environ = minimal_environ(PROJECT_DIR=dirname)
        status = requirement.check_status(environ, local_state_file, 'default',
                                          UserConfigOverrides())
        provider = DownloadProvider()
        html = provider.config_html(requirement, environ, local_state_file,
                                    UserConfigOverrides(), status)
        assert 'Download {} to {}'.format(requirement.url,
                                          requirement.filename) in html

        with open(FILENAME, 'w') as f:
            f.write('boo')

        env = minimal_environ(PROJECT_DIR=dirname)
        status = requirement.check_status(env, local_state_file, 'default',
                                          UserConfigOverrides())
        html = provider.config_html(requirement, env, local_state_file,
                                    UserConfigOverrides(), status)
        expected_choice = 'Use already-downloaded file {}'.format(FILENAME)
        assert expected_choice in html
Exemple #4
0
    def check_provide_contents(dirname):
        environ = dict()
        local_state_file = LocalStateFile.load_for_directory(dirname)
        requirement = EnvVarRequirement(RequirementsRegistry(), env_var="FOO")
        status = requirement.check_status(environ, local_state_file, 'default', UserConfigOverrides())
        context = ProvideContext(environ=environ,
                                 local_state_file=local_state_file,
                                 default_env_spec_name='default',
                                 status=status,
                                 mode=PROVIDE_MODE_DEVELOPMENT,
                                 frontend=NullFrontend())
        workpath = context.ensure_service_directory("foo")
        assert os.path.isdir(workpath)
        assert workpath.endswith("foo")
        parent = os.path.dirname(workpath)
        assert parent.endswith("services")
        parent = os.path.dirname(parent)
        assert parent == dirname

        # be sure we can create if it already exists
        workpath2 = context.ensure_service_directory("foo")
        assert os.path.isdir(workpath2)
        assert workpath == workpath2
    def do_test(dirname):
        io_loop = IOLoop()
        io_loop.make_current()

        events = []

        def event_handler(event):
            events.append(event)

        project = Project(dirname)
        local_state_file = LocalStateFile.load_for_directory(dirname)
        context = ConfigurePrepareContext(dict(), local_state_file, 'default', UserConfigOverrides(), [])
        server = UIServer(project, _no_op_prepare(context), event_handler, io_loop)

        get_response = http_get(io_loop, server.url)
        print(repr(get_response))
        post_response = http_post(io_loop, server.url, body="")
        print(repr(post_response))

        server.unlisten()

        assert len(events) == 1
        assert isinstance(events[0], UIServerDoneEvent)
    def start_local_redis(dirname):
        project = project_no_dedicated_env(dirname)
        result = _prepare_printing_errors(project, environ=minimal_environ())
        assert result

        local_state_file = LocalStateFile.load_for_directory(dirname)
        state = local_state_file.get_service_run_state('REDIS_URL')
        assert 'port' in state
        port = state['port']

        assert dict(REDIS_URL=("redis://localhost:" + str(port)),
                    PROJECT_DIR=project.directory_path) == strip_environ(
                        result.environ)
        assert len(can_connect_args_list) >= 2

        servicedir = os.path.join(dirname, "services")
        redisdir = os.path.join(servicedir, "REDIS_URL")

        pidfile = os.path.join(redisdir, "redis.pid")
        logfile = os.path.join(redisdir, "redis.log")
        assert os.path.exists(pidfile)
        assert os.path.exists(logfile)

        assert real_can_connect_to_socket(host='localhost', port=port)

        # now clean it up
        status = unprepare(project, result)
        assert status

        assert not os.path.exists(pidfile)
        assert not os.path.exists(logfile)
        assert not os.path.exists(redisdir)
        assert not os.path.exists(servicedir)
        assert not real_can_connect_to_socket(host='localhost', port=port)

        local_state_file.load()
        assert dict() == local_state_file.get_service_run_state("REDIS_URL")
Exemple #7
0
def _internal_prepare_in_stages(project, environ_copy, overrides, keep_going_until_success, mode, provide_whitelist,
                                command_name, command, extra_command_args, refresh):
    assert not project.problems
    if mode not in _all_provide_modes:
        raise ValueError("invalid provide mode " + mode)

    assert not (command_name is not None and command is not None)
    assert command_name is None or (command_name in project.commands) or (command_name == 'default')
    assert overrides.env_spec_name is None or overrides.env_spec_name in project.env_specs

    if command is None:
        command = project.command_for_name(command_name)
        # at this point, "command" is only None if there are no
        # commands for this project.
    default_env_name = project.default_env_spec_name_for_command(command)

    our_root = project.directory_path
    local_state = LocalStateFile.load_for_directory(our_root)

    if refresh:
        # To do: move the refresh flag into the provider somehow. Thought: add
        # the refresh flag to overrides, and have the conda env requirements
        # engine interpret that and schedule a refresh and create.
        env_name = overrides.env_spec_name or default_env_name
        _remove_env_path(project.env_specs[env_name].path(our_root), our_root)

    statuses = []
    for requirement in project.requirements(overrides.env_spec_name):
        status = requirement.check_status(environ_copy,
                                          local_state,
                                          default_env_name,
                                          overrides,
                                          latest_provide_result=None)
        statuses.append(status)

    return _first_stage(project, environ_copy, local_state, statuses, keep_going_until_success, mode, provide_whitelist,
                        overrides, command, extra_command_args)
    def check_provide_contents(dirname):
        environ = dict()
        local_state_file = LocalStateFile.load_for_directory(dirname)
        local_state_file.set_service_run_state("myservice", dict(port=42))
        requirement = EnvVarRequirement(PluginRegistry(), env_var="FOO")
        status = requirement.check_status(environ, local_state_file, 'default',
                                          UserConfigOverrides())
        context = ProvideContext(environ=environ,
                                 local_state_file=local_state_file,
                                 default_env_spec_name='default',
                                 status=status,
                                 mode=PROVIDE_MODE_DEVELOPMENT)

        def transform_it(state):
            assert 42 == state['port']
            state['port'] = 43
            state['foo'] = 'bar'
            return 1234

        result = context.transform_service_run_state("myservice", transform_it)
        assert 1234 == result
        assert dict(
            port=43,
            foo='bar') == local_state_file.get_service_run_state("myservice")
Exemple #9
0
    def start_local_redis(dirname):
        project = project_no_dedicated_env(dirname)
        result = test_redis_provider._prepare_printing_errors(
            project, environ=minimal_environ())
        assert result

        local_state_file = LocalStateFile.load_for_directory(dirname)
        state = local_state_file.get_service_run_state('REDIS_URL')
        assert 'port' in state
        port = state['port']

        assert dict(REDIS_URL=("redis://localhost:" + str(port)),
                    PROJECT_DIR=project.directory_path) == strip_environ(
                        result.environ)
        assert len(can_connect_args_list) >= 2

        pidfile = os.path.join(dirname, "services/REDIS_URL/redis.pid")
        logfile = os.path.join(dirname, "services/REDIS_URL/redis.log")
        assert os.path.exists(pidfile)
        assert os.path.exists(logfile)

        assert real_can_connect_to_socket(host='localhost', port=port)

        # now clean it up
        code = _parse_args_and_run_subcommand([
            'anaconda-project', 'remove-service', 'REDIS_URL', '--directory',
            dirname
        ])
        assert code == 0

        assert not os.path.exists(pidfile)
        assert not os.path.exists(os.path.join(dirname, "services"))
        assert not real_can_connect_to_socket(host='localhost', port=port)

        local_state_file.load()
        assert dict() == local_state_file.get_service_run_state("REDIS_URL")
Exemple #10
0
def project_dir_disable_dedicated_env(dirname):
    """Modify project config to disable having a dedicated environment."""
    local_state = LocalStateFile.load_for_directory(dirname)
    local_state.set_value('inherit_environment', True)
    local_state.save()
 def check_file(dirname):
     filename = os.path.join(dirname, relative_name)
     assert os.path.exists(filename)
     local_state_file = LocalStateFile.load_for_directory(dirname)
     state = local_state_file.get_service_run_state("foobar")
     assert dict(port=42, shutdown_commands=[["foo"]]) == state
 def check_file(dirname):
     filename = os.path.join(dirname, DEFAULT_LOCAL_STATE_FILENAME)
     assert os.path.exists(filename)
     local_state_file = LocalStateFile.load_for_directory(dirname)
     state = local_state_file.get_service_run_state("foobar")
     assert dict() == state
 def check_cannot_use_non_dict(dirname):
     local_state_file = LocalStateFile.load_for_directory(dirname)
     with pytest.raises(ValueError) as excinfo:
         local_state_file.set_service_run_state("foo", 42)
     assert "service state should be a dict" in repr(excinfo.value)
Exemple #14
0
 def check(dirname):
     local_state_file = LocalStateFile.load_for_directory(dirname)
     status = shutdown_service_run_state(local_state_file, 'foo')
     assert status
     assert status.status_description == 'Nothing to do to shut down foo.'
Exemple #15
0
 def check_not_set(dirname):
     local_state = LocalStateFile.load_for_directory(dirname)
     requirement = RedisRequirement(registry=RequirementsRegistry(), env_var="REDIS_URL")
     status = requirement.check_status(dict(), local_state, 'default', UserConfigOverrides())
     assert not status
     assert "Environment variable REDIS_URL is not set." == status.status_description
    def prepare_after_setting_scope(dirname):
        local_state = LocalStateFile.load_for_directory(dirname)
        requirement = _redis_requirement()
        provider = RedisProvider()
        environ = minimal_environ()
        config = provider.read_config(requirement, environ, local_state, 'default', UserConfigOverrides())
        assert config['source'] == 'find_all'
        provider.set_config_values_as_strings(requirement,
                                              environ,
                                              local_state,
                                              'default',
                                              UserConfigOverrides(),
                                              dict(source='find_project'))
        config = provider.read_config(requirement, environ, local_state, 'default', UserConfigOverrides())
        assert config['source'] == 'find_project'
        provider.set_config_values_as_strings(requirement,
                                              environ,
                                              local_state,
                                              'default',
                                              UserConfigOverrides(),
                                              dict(source='find_all'))
        config = provider.read_config(requirement, environ, local_state, 'default', UserConfigOverrides())
        assert config['source'] == 'find_all'
        provider.set_config_values_as_strings(requirement,
                                              environ,
                                              local_state,
                                              'default',
                                              UserConfigOverrides(),
                                              dict(source='environ'))
        config = provider.read_config(requirement, environ, local_state, 'default', UserConfigOverrides())
        assert config['source'] == 'find_all'  # default if no env var set
        provider.set_config_values_as_strings(requirement,
                                              environ,
                                              local_state,
                                              'default',
                                              UserConfigOverrides(),
                                              dict(source='environ'))
        environ_with_redis_url = environ.copy()
        environ_with_redis_url['REDIS_URL'] = 'blah'
        config = provider.read_config(requirement, environ_with_redis_url, local_state, 'default',
                                      UserConfigOverrides())
        assert config['source'] == 'environ'  # default when the env var IS set

        # use local variable when env var not set
        provider.set_config_values_as_strings(requirement,
                                              environ,
                                              local_state,
                                              'default',
                                              UserConfigOverrides(),
                                              dict(source='variables',
                                                   value='foo'))
        config = provider.read_config(requirement, environ, local_state, 'default', UserConfigOverrides())
        assert config['source'] == 'variables'
        assert config['value'] == 'foo'

        # use local variable when env var _is_ set
        provider.set_config_values_as_strings(requirement,
                                              environ_with_redis_url,
                                              local_state,
                                              'default',
                                              UserConfigOverrides(),
                                              dict(source='variables',
                                                   value='foo'))
        config = provider.read_config(requirement, environ, local_state, 'default', UserConfigOverrides())
        assert config['source'] == 'variables'
        assert config['value'] == 'foo'

        # set to use system, which should override using the local state
        provider.set_config_values_as_strings(requirement,
                                              environ,
                                              local_state,
                                              'default',
                                              UserConfigOverrides(),
                                              dict(source='find_system'))
        config = provider.read_config(requirement, environ, local_state, 'default', UserConfigOverrides())
        assert config['source'] == 'find_system'

        project = project_no_dedicated_env(dirname)
        result = _prepare_printing_errors(project, environ=minimal_environ())
        assert result
        assert dict(REDIS_URL="redis://localhost:6379",
                    PROJECT_DIR=project.directory_path) == strip_environ(result.environ)
        assert dict(host='localhost', port=6379, timeout_seconds=0.5) == can_connect_args
Exemple #17
0
def unprepare(project, prepare_result, whitelist=None):
    """Attempt to clean up project-scoped resources allocated by prepare().

    This will retain any user configuration choices about how to
    provide requirements, but it stops project-scoped services.
    Global system services or other services potentially shared
    among projects will not be stopped.

    To stop a single service, use ``whitelist=["SERVICE_VARIABLE"]``.

    Args:
        project (Project): the project
        prepare_result (PrepareResult): result from the previous prepare
        whitelist (iterable of str or type): ONLY call shutdown commands for the listed env vars' requirements

    Returns:
        a ``Status`` instance
    """
    if project.problems:
        errors = []
        for problem in project.problems:
            errors.append(problem)
        return SimpleStatus(success=False,
                            description="Unable to load the project.",
                            errors=errors)

    local_state_file = LocalStateFile.load_for_directory(
        project.directory_path)

    # note: if the prepare_result was a failure before statuses
    # were even checked, then statuses could be empty
    failed_statuses = []
    failed_requirements = []
    success_statuses = []
    for status in prepare_result.statuses:
        requirement = status.requirement
        if not _in_provide_whitelist(whitelist, requirement):
            continue

        provider = status.provider
        unprovide_status = provider.unprovide(requirement,
                                              prepare_result.environ,
                                              local_state_file,
                                              prepare_result.overrides, status)
        if not unprovide_status:
            failed_requirements.append(requirement)
            failed_statuses.append(unprovide_status)
        else:
            success_statuses.append(unprovide_status)

    if not failed_statuses:
        if len(success_statuses) > 1:
            logs = [status.status_description for status in success_statuses]
            return SimpleStatus(success=True,
                                description="Success.",
                                logs=logs)
        elif len(success_statuses) > 0:
            return success_statuses[0]
        else:
            return SimpleStatus(success=True,
                                description="Nothing to clean up.")
    elif len(failed_statuses) == 1:
        return failed_statuses[0]
    else:
        all_errors = [
            error for status in failed_statuses for error in status.errors
        ]
        all_names = sorted([
            req.env_var for req in failed_requirements
            if isinstance(req, EnvVarRequirement)
        ])
        return SimpleStatus(success=False,
                            description=("Failed to clean up %s." %
                                         ", ".join(all_names)),
                            errors=all_errors)