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
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)
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
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
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
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
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
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
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
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
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
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() == []
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
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]
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
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')
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')
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
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
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
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()
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()