Example #1
0
def test_create_host_folders_successful_create(config_files, monkeypatch):
    with open(config_files, "r") as main_file:
        parser = ConfigurationParser(main_file)

        coordinator = SharedFolderCoordinator(parser)

        def fake_os_path_isdir(*_):
            return False

        monkeypatch.setattr(os.path, 'isdir', fake_os_path_isdir)

        def fake_os_path_exists(*_):
            return False

        monkeypatch.setattr(os.path, 'exists', fake_os_path_exists)

        def fake_mkdir_command(*popenargs, **kwargs):
            if get_command(popenargs) == 'mkdir' and get_sub_command(
                    popenargs) == '-p':
                folder = popenargs[0][-1]
                assert 'valid_folder' in folder or 'work' in folder
                return subprocess.CompletedProcess("fakerun", 0, '')
            else:
                return subprocess.run(*popenargs, **kwargs)

        monkeypatch.setattr(mockablerun, 'run_mockable', fake_mkdir_command)

        coordinator.create_host_folders()  # successful mkdir
Example #2
0
    def dump_plugins(self, plugin_sections):
        result = {}

        for plugin_section in plugin_sections:
            plugins = self.get_ordered_path_items(plugin_section)

            if plugins:
                result[plugin_section] = []

            for plugin in plugins:
                name, resolved_path, node_dict = plugin

                if plugin_section == 'playbooks':
                    sfc = SharedFolderCoordinator(self)
                    node_dict[
                        'edi_shared_folder_mountpoints'] = sfc.get_mountpoints(
                        )

                plugin_info = {
                    name: {
                        'path': resolved_path,
                        'dictionary': node_dict
                    }
                }

                result[plugin_section].append(plugin_info)

        return yaml.dump(result, default_flow_style=False)
Example #3
0
def test_verify_container_mountpoints_failure(config_files, monkeypatch):
    with mocked_executable('lxc', '/here/is/no/lxc'):
        with mocked_lxd_version_check():
            with open(config_files, "r") as main_file:

                def fake_lxc_exec_command(*popenargs, **kwargs):
                    if get_command(popenargs).endswith(
                            'lxc') and get_sub_command(popenargs) == 'exec':
                        if get_command_parameter(popenargs, '--') == 'test':
                            return subprocess.CompletedProcess(
                                "failure", 1, 'failure')
                        else:
                            return subprocess.CompletedProcess(
                                "fakerun", 0, '')
                    else:
                        return subprocess.run(*popenargs, **kwargs)

                monkeypatch.setattr(mockablerun, 'run_mockable',
                                    fake_lxc_exec_command)

                parser = ConfigurationParser(main_file)

                coordinator = SharedFolderCoordinator(parser)
                with pytest.raises(FatalError) as error:
                    coordinator.verify_container_mountpoints('fake-container')
                assert 'fake-container' in error.value.message
                assert '/foo/bar/target_mountpoint' in error.value.message
Example #4
0
    def run_all(self):
        workdir = self.config.get_workdir()

        applied_playbooks = []
        with tempfile.TemporaryDirectory(dir=workdir) as tempdir:
            chown_to_user(tempdir)
            inventory = self._write_inventory_file(tempdir)

            playbook_list = self.config.get_ordered_path_items("playbooks")
            for name, path, extra_vars in playbook_list:
                sfc = SharedFolderCoordinator(self.config)
                extra_vars['edi_shared_folder_mountpoints'] = sfc.get_mountpoints()
                logging.info(("Running playbook {} located in "
                              "{} with extra vars:\n{}"
                              ).format(name, path,
                                       yaml.dump(remove_passwords(extra_vars),
                                                 default_flow_style=False)))

                extra_vars_file = os.path.join(tempdir, ("extra_vars_{}"
                                                         ).format(name))
                with open(extra_vars_file, encoding='utf-8', mode='w') as f:
                    f.write(yaml.dump(extra_vars))

                ansible_user = extra_vars.get("edi_config_management_user_name")
                self._run_playbook(path, inventory, extra_vars_file, ansible_user)
                applied_playbooks.append(name)

        return applied_playbooks
Example #5
0
def test_verify_container_mountpoints_connection_failure(
        config_files, monkeypatch):
    with open(config_files, "r") as main_file:

        def fake_lxc_exec_command(*popenargs, **kwargs):
            command = popenargs[0]
            if command[0] == 'lxc' and command[1] == 'exec':
                if command[command.index('--') + 1] == 'true':
                    cmd = [
                        'bash', '-c',
                        '>&2 echo -e "lxc command failed" ; exit 1'
                    ]
                    return subprocess.run(cmd, **kwargs)
                else:
                    return subprocess.CompletedProcess("fakerun", 0, '')
            else:
                return subprocess.run(*popenargs, **kwargs)

        monkeypatch.setattr(mockablerun, 'run_mockable', fake_lxc_exec_command)

        parser = ConfigurationParser(main_file)

        coordinator = SharedFolderCoordinator(parser)
        with pytest.raises(FatalError) as error:
            coordinator.verify_container_mountpoints('fake-container')
        assert 'fake-container' in error.value.message
        assert 'lxc command failed' in error.value.message
Example #6
0
def test_create_host_folders_failed_create(config_files, monkeypatch):
    with open(config_files, "r") as main_file:
        parser = ConfigurationParser(main_file)

        coordinator = SharedFolderCoordinator(parser)

        def fake_os_path_isdir(*_):
            return False

        monkeypatch.setattr(os.path, 'isdir', fake_os_path_isdir)

        def fake_os_path_exists(*_):
            return False

        monkeypatch.setattr(os.path, 'exists', fake_os_path_exists)

        def fake_mkdir_command(*popenargs, **kwargs):
            if get_command(popenargs) == 'mkdir' and get_sub_command(
                    popenargs) == '-p':
                cmd = ['bash', '-c', '>&2 echo -e "no permission" ; exit 1']
                return subprocess.run(cmd, **kwargs)
            else:
                return subprocess.run(*popenargs, **kwargs)

        monkeypatch.setattr(mockablerun, 'run_mockable', fake_mkdir_command)

        with pytest.raises(FatalError) as error:
            coordinator.create_host_folders()  # failed mkdir

        assert 'valid_folder' in error.value.message
        assert 'no permission' in error.value.message
Example #7
0
    def run(self, config_file, include_post_config_profiles=False):
        self._setup_parser(config_file)

        profile_list = self.config.get_ordered_path_items("lxc_profiles")
        profile_name_list = []
        for name, path, dictionary in profile_list:
            logging.info(("Creating profile {} located in "
                          "{} with dictionary:\n{}"
                          ).format(name, path,
                                   yaml.dump(dictionary,
                                             default_flow_style=False)))

            with open(path, encoding="UTF-8", mode="r") as profile_file:
                profile = Template(profile_file.read())
                profile_text = profile.render(dictionary)
                name = self._write_lxc_profile(profile_text)
                profile_name_list.append(name)

        sfc = SharedFolderCoordinator(self.config)
        if include_post_config_profiles:
            sfc_profiles = sfc.get_post_config_profiles()
        else:
            sfc_profiles = sfc.get_pre_config_profiles()

        for profile in sfc_profiles:
            name = self._write_lxc_profile(profile)
            profile_name_list.append(name)

        print_success('The following profiles are now available: {}'.format(', '.join(profile_name_list)))
        return profile_name_list
Example #8
0
def test_get_mountpoints(config_files):
    with open(config_files, "r") as main_file:
        parser = ConfigurationParser(main_file)

        coordinator = SharedFolderCoordinator(parser)
        mountpoints = coordinator.get_mountpoints()
        assert mountpoints[0] == '/foo/bar/target_mountpoint'
        assert len(mountpoints) == 2
Example #9
0
    def _get_playbooks(self):
        augmented_list = []
        playbook_list = self.config.get_ordered_path_items(self.config_section)
        for name, path, extra_vars, _ in playbook_list:
            sfc = SharedFolderCoordinator(self.config)
            extra_vars['edi_shared_folder_mountpoints'] = sfc.get_mountpoints()
            augmented_list.append((name, path, extra_vars))

        return augmented_list
Example #10
0
def test_create_host_folders_folder_exists(config_files, monkeypatch):
    with open(config_files, "r") as main_file:
        parser = ConfigurationParser(main_file)

        coordinator = SharedFolderCoordinator(parser)

        patch_os_path(monkeypatch, True, True)

        coordinator.create_host_folders()  # nothing to do
Example #11
0
def test_get_mandatory_item():
    with pytest.raises(FatalError) as missing:
        SharedFolderCoordinator._get_mandatory_item('some_folder', {}, 'mountpoint')
    assert 'some_folder' in missing.value.message
    assert 'mountpoint' in missing.value.message

    with pytest.raises(FatalError) as subfolder:
        SharedFolderCoordinator._get_mandatory_item('some_folder', {'mountpoint': 'mount/point'}, 'mountpoint')
    assert 'some_folder' in subfolder.value.message
    assert 'mountpoint' in subfolder.value.message
Example #12
0
def test_no_shared_folders_for_distributable_image(config_files, monkeypatch):
    with mocked_executable('lxc'):
        with mocked_lxd_version_check():
            with open(config_files, "r") as main_file:
                with command_context({'edi_create_distributable_image': True}):
                    parser = ConfigurationParser(main_file)

                    coordinator = SharedFolderCoordinator(parser)

                    def fake_os_path_exists(*_):
                        return False

                    monkeypatch.setattr(os.path, 'exists', fake_os_path_exists)

                    def fake_run(*popenargs, **kwargs):
                        # We should not run anything!
                        assert False

                    monkeypatch.setattr(mockablerun, 'run_mockable', fake_run)

                    coordinator.create_host_folders()
                    coordinator.verify_container_mountpoints('does-not-exist')
                    assert coordinator.get_mountpoints() == []
                    assert coordinator.get_pre_config_profiles() == []
                    assert coordinator.get_post_config_profiles() == []
Example #13
0
def test_create_host_folders_not_a_folder(config_files, monkeypatch):
    with open(config_files, "r") as main_file:
        parser = ConfigurationParser(main_file)

        coordinator = SharedFolderCoordinator(parser)

        patch_os_path(monkeypatch, False, True)

        with pytest.raises(FatalError) as error:
            coordinator.create_host_folders()  # exists but not a folder

        assert 'edi_marker_valid_folder' in error.value.message
Example #14
0
def test_pre_config_profiles(config_files):
    expected_profiles = render_expected_profiles()

    with open(config_files, "r") as main_file:
        parser = ConfigurationParser(main_file)

        coordinator = SharedFolderCoordinator(parser)
        profiles = coordinator.get_pre_config_profiles()

        assert len(profiles) == 1

        assert profiles[0][0] == expected_profiles[0]
Example #15
0
def test_without_shared_folders(empty_config_file):
    with open(empty_config_file, "r") as main_file:
        parser = ConfigurationParser(main_file)

        coordinator = SharedFolderCoordinator(parser)
        mountpoints = coordinator.get_mountpoints()
        assert isinstance(mountpoints, list)
        assert len(mountpoints) == 0
        pre = coordinator.get_pre_config_profiles()
        assert isinstance(pre, list)
        assert len(pre) == 0
        post = coordinator.get_post_config_profiles()
        assert isinstance(post, list)
        assert len(post) == 0
Example #16
0
def test_verify_container_mountpoints(config_files, monkeypatch):
    with mocked_executable('lxc', '/here/is/no/lxc'):
        with mocked_lxd_version_check():
            with open(config_files, "r") as main_file:
                def fake_lxc_exec_command(*popenargs, **kwargs):
                    if get_command(popenargs).endswith('lxc') and get_sub_command(popenargs) == 'exec':
                        return subprocess.CompletedProcess("fakerun", 0, '')
                    else:
                        return subprocess.run(*popenargs, **kwargs)

                monkeypatch.setattr(mockablerun, 'run_mockable', fake_lxc_exec_command)

                parser = ConfigurationParser(main_file)

                coordinator = SharedFolderCoordinator(parser)
                coordinator.verify_container_mountpoints('fake-container')
Example #17
0
def test_verify_container_mountpoints(config_files, monkeypatch):
    with open(config_files, "r") as main_file:

        def fake_lxc_exec_command(*popenargs, **kwargs):
            command = popenargs[0]
            if command[0] == 'lxc' and command[1] == 'exec':
                return subprocess.CompletedProcess("fakerun", 0, '')
            else:
                return subprocess.run(*popenargs, **kwargs)

        monkeypatch.setattr(mockablerun, 'run_mockable', fake_lxc_exec_command)

        parser = ConfigurationParser(main_file)

        coordinator = SharedFolderCoordinator(parser)
        coordinator.verify_container_mountpoints('fake-container')
Example #18
0
def test_create_host_folders_folder_exists(config_files, monkeypatch):
    with open(config_files, "r") as main_file:
        parser = ConfigurationParser(main_file)

        coordinator = SharedFolderCoordinator(parser)

        def fake_os_path_isdir(*_):
            return True

        monkeypatch.setattr(os.path, 'isdir', fake_os_path_isdir)

        def fake_os_path_exists(*_):
            return True

        monkeypatch.setattr(os.path, 'exists', fake_os_path_exists)

        coordinator.create_host_folders()  # nothing to do
Example #19
0
    def _get_profiles(self, include_post_config_profiles):
        collected_profiles = []
        profile_list = self.config.get_ordered_path_items(self.config_section)
        for name, path, dictionary, _ in profile_list:
            with open(path, encoding="UTF-8", mode="r") as profile_file:
                profile = Template(profile_file.read())
                profile_text = profile.render(dictionary)
                collected_profiles.append(
                    (profile_text, name, path, dictionary))

        sfc = SharedFolderCoordinator(self.config)
        if include_post_config_profiles:
            collected_profiles.extend(sfc.get_post_config_profiles())
        else:
            collected_profiles.extend(sfc.get_pre_config_profiles())

        return collected_profiles
Example #20
0
def test_create_host_folders_not_a_folder(config_files, monkeypatch):
    with open(config_files, "r") as main_file:
        parser = ConfigurationParser(main_file)

        coordinator = SharedFolderCoordinator(parser)

        def fake_os_path_isdir(*_):
            return False

        monkeypatch.setattr(os.path, 'isdir', fake_os_path_isdir)

        def fake_os_path_exists(*_):
            return True

        monkeypatch.setattr(os.path, 'exists', fake_os_path_exists)

        with pytest.raises(FatalError) as error:
            coordinator.create_host_folders()  # exists but not a folder

        assert 'valid_folder' in error.value.message
Example #21
0
    def run(self, container_name, config_file, introspection_method=None):
        self._setup_parser(config_file)
        self.container_name = container_name

        if introspection_method:
            print(introspection_method())
            return self._result()

        Launch().run(container_name, config_file)

        print("Going to configure container {} - be patient.".format(self._result()))

        playbook_runner = PlaybookRunner(self.config, self._result(), "lxd")
        playbook_runner.run_all()

        sfc = SharedFolderCoordinator(self.config)
        sfc.create_host_folders()
        sfc.verify_container_mountpoints(container_name)

        profiles = Profile().run(config_file, include_post_config_profiles=True)
        # TODO: stop container if profiles need to be updated
        apply_profiles(container_name, profiles)
        # TODO: restart container if needed

        print_success("Configured container {}.".format(self._result()))
        return self._result()
Example #22
0
    def _run(self):
        Launch().run(self.container_name, self.config.get_base_config_file())

        print("Going to configure container {} - be patient.".format(
            self._result()))

        playbook_runner = PlaybookRunner(self.config, self._result(),
                                         self.ansible_connection)
        playbook_runner.run_all()

        sfc = SharedFolderCoordinator(self.config)
        sfc.create_host_folders()
        sfc.verify_container_mountpoints(self.container_name)

        profiles = Profile().run(self.config.get_base_config_file(),
                                 include_post_config_profiles=True)
        # TODO: stop container if profiles need to be updated
        apply_profiles(self.container_name, profiles)
        # TODO: restart container if needed

        print_success("Configured container {}.".format(self._result()))
        return self._result()