def test_template(): """Template test.""" with using_temporary_directory() as tempdir: project_path = copy_sample("sample01", tempdir) project_config_root = os.path.join(project_path, ".docknv") session_file_path = os.path.join(project_config_root, ".docknv.yml") os.makedirs(project_config_root) with io_open(session_file_path, mode="w") as handle: handle.write(CONFIG_DATA) project = Project.load_from_path(project_path) config = project.database.get_configuration("config") # Missing template file with pytest.raises(MissingTemplate): renderer_render_template("toto.sh", config) # Creating file templates_path = os.path.join(project_path, "data", "files") with io_open(os.path.join(templates_path, "toto.sh"), mode="w") as handle: handle.write("...") # Malformed template file with pytest.raises(MalformedTemplate): renderer_render_template("toto.sh", config)
def renderer_render_template(template_path, config): """ Render a Jinja template, using a namespace and environment. :param template_path: Template path (str) :param config: Configuration :rtype: File output name (str) """ config_path = config.session.get_paths().get_user_configuration_root( config.name) environment_data = config.environment_data.data templates_path = os.path.join(config.database.project_path, "data", "files") real_template_path = os.path.join(templates_path, template_path) if not os.path.exists(real_template_path): raise MissingTemplate(real_template_path) if not template_path.endswith(".j2"): raise MalformedTemplate(f"bad extension: {template_path}") # Creating tree local_path = os.path.join(config_path, "data") tpl_output_path = os.path.join(local_path, "templates") destination_path = os.path.join(tpl_output_path, os.path.dirname(template_path)) for path in (local_path, tpl_output_path, destination_path): if not os.path.exists(path): os.makedirs(path) # Loading template with io_open(real_template_path, encoding="utf-8", mode="r") as handle: template = Template(handle.read()) # Rendering template file_output = os.path.join(destination_path, os.path.basename(template_path)[:-3]) rendered_template = template.render(**environment_data) # Newline handle newline = None if template_path.endswith(".sh.j2"): newline = "\n" with io_open(file_output, encoding="utf-8", mode="w", newline=newline) as handle: handle.write(rendered_template) return file_output
def load_from_path(cls, username, project_path): """ Load user session from path. :param username: Username (str) :param project_path: Project path (str) """ session = cls(username, project_path) # Ensure config paths exists project_root = session.get_paths().get_project_root() if not os.path.exists(project_root): os.makedirs(project_root) user_root = session.get_paths().get_user_root() if not os.path.exists(user_root): os.makedirs(user_root) session_file = session.get_paths().get_user_session_file_path() if not os.path.exists(session_file): session.session_data = {"current": None} else: with io_open(session_file, mode="r") as handle: session.session_data = yaml_ordered_load(handle.read()) return session
def env_set_env_value(env_path, key, value): """ Set environment value from file at `env_path`. :param env_path: Environment path (str) :param key: Key (str) :param value: Value (any) """ with io_open(env_path, mode="r") as handle: content = yaml_ordered_load(handle) if content["environment"] is None: content["environment"] = {} content["environment"][key] = value with io_open(env_path, mode="w") as handle: handle.write(yaml_ordered_dump(content))
def test_old_database(): """Test old database.""" with using_temporary_directory() as tempdir: project_path = copy_sample("sample03", tempdir) # Values key should be present db_file = os.path.join(project_path, ".docknv", ".docknv.yml") with io_open(db_file) as handle: data = yaml_ordered_load(handle.read()) assert "values" in data project = Project.load_from_path(project_path) assert len(project.database) == 2 with io_open(db_file) as handle: data = yaml_ordered_load(handle.read()) assert "values" not in data
def save_key_values_to_path(self, path): """ Save export to path. :param path: Path (str) """ with io_open(path, mode="w") as handle: handle.write(self.export_as_key_values())
def save_to_path(self, path): """ Save content to path. :param path: Path (str) """ with io_open(path, mode="w") as handle: handle.write(yaml_ordered_dump(self.content))
def test_lifecycle(): """Lifecycle test.""" with using_temporary_directory() as tempdir: project_path = copy_sample("sample01", tempdir) project_config_root = os.path.join(project_path, ".docknv") session_file_path = os.path.join(project_config_root, ".docknv.yml") os.makedirs(project_config_root) with io_open(session_file_path, mode="w") as handle: handle.write(CONFIG_DATA) project = Project.load_from_path(project_path) lifecycle = project.lifecycle # Should raise, no active configuration with pytest.raises(MissingActiveConfiguration): lifecycle.config.start(dry_run=True) # Active tests project.set_current_configuration("config") lifecycle.config.start(dry_run=True) lifecycle.config.stop(dry_run=True) lifecycle.config.restart(dry_run=True) lifecycle.config.restart(force=True, dry_run=True) # Manual tests lifecycle.config.start(["config", "config2"], dry_run=True) # Service tests lifecycle.service.start("portainer", dry_run=True) lifecycle.service.stop("portainer", dry_run=True) lifecycle.service.restart("portainer", dry_run=True) lifecycle.service.restart("portainer", force=True, dry_run=True) lifecycle.service.execute("portainer", ["toto"], dry_run=True) lifecycle.service.execute("portainer", ["toto", "tutu"], dry_run=True) lifecycle.service.shell("portainer", dry_run=True) lifecycle.service.shell("portainer", shell="/bin/sh", dry_run=True) lifecycle.service.logs("portainer", dry_run=True) lifecycle.service.attach("portainer", dry_run=True) lifecycle.service.build("portainer", dry_run=True) # Update config lifecycle.config.update(dry_run=True) lifecycle.config.update("config2", dry_run=True) lifecycle.config.update(restart=True, dry_run=True) lifecycle.config.build(dry_run=True) lifecycle.config.update(environment="default", dry_run=True) lifecycle.config.update(services=[], dry_run=True) lifecycle.config.update(volumes=[], dry_run=True) lifecycle.config.update(networks=[], dry_run=True) lifecycle.config.update(namespace="", dry_run=True) lifecycle.config.update(namespace="hello", dry_run=True) # Create config lifecycle.config.create(name="tutu", services=["portainer"]) lifecycle.config.ps(dry_run=True)
def load_from_path(cls, path): """ Load from path. :param path: Path (str) """ if not os.path.isfile(path): raise MissingComposefile(path) with io_open(path, mode="r") as handle: content = yaml_ordered_load(handle.read()) return cls(content)
def test_scaffold_config(): """Config scaffold tests.""" with using_temporary_directory() as tempdir: # Copy playground project_path = copy_sample("sample01", tempdir) # Scaffold config scaffold_config(project_path) configfile = os.path.join(project_path, "config.yml") with io_open(configfile, mode="rt") as handle: content = handle.read() assert content == CONFIG_FILE_CONTENT
def image_load_in_memory(project_path, image_name): """ Load a Dockerfile image in memory. :param project_path: Project path (str) :param image_name: Image name (str) :rtype: File content (str) """ if not image_check_dockerfile(project_path, image_name): return None filepath = image_get_dockerfile_path(project_path, image_name) with io_open(filepath, encoding="utf-8", mode="rt") as handle: return handle.read()
def load_from_path(cls, project_path): """ Load from project path. :param project_path: Project path """ project_file_path = project_get_config_path(project_path) if os.path.isfile(project_file_path): with io_open(project_file_path, encoding="utf-8", mode="r") as handle: config_data = yaml_ordered_load(handle.read()) else: raise MissingProject(project_path) return cls(project_path, config_data)
def load_from_project(cls, project_path): """ Load from project. :param project_path: Project path (str) """ paths = composefile_get_composefile_paths(project_path) composefile_content = {} for path in paths: with io_open(path, mode="r") as handle: content = yaml_ordered_load(handle.read()) composefile_content = yaml_merge( [composefile_content, content]) return cls(composefile_content)
def load_from_project(cls, project): """ Load from project. :param project: Project """ project_path = project.project_path project_file_path = database_get_database_path(project_path) if os.path.isfile(project_file_path): with io_open(project_file_path, encoding="utf-8", mode="r") as handle: config_data = yaml_ordered_load(handle.read()) return cls(project, config_data) return cls(project, {})
def test_scaffold_ignore(): """Ignorefile scaffold tests.""" with using_temporary_directory() as tempdir: # Copy playground project_path = copy_sample("sample01", tempdir) # Scaffold ignore scaffold_ignore(project_path) ignorefile = os.path.join(project_path, ".gitignore") with io_open(ignorefile, mode="rt") as handle: content = handle.read() assert content == IGNORE_FILE_CONTENT with mock_input("y"): scaffold_ignore(project_path) with mock_input("n"): scaffold_ignore(project_path) with pytest.raises(MissingProject): scaffold_ignore("/a/b/c/d")
def test_compose(): """Compose test.""" with using_temporary_directory() as tempdir: project_path = copy_sample("sample01", tempdir) project_config_root = os.path.join(project_path, ".docknv") session_file_path = os.path.join(project_config_root, ".docknv.yml") os.makedirs(project_config_root) with io_open(session_file_path, mode="w") as handle: handle.write(CONFIG_DATA) project = Project.load_from_path(project_path) database = project.database compose = ComposeDefinition.load_from_project(project_path) assert len(compose.get_networks()) == 1 assert len(compose.get_volumes()) == 1 assert len(compose.get_services()) == 3 test_path = os.path.join(project_path, "test.yml") compose.save_to_path(test_path) composeclone = ComposeDefinition.load_from_path(test_path) with pytest.raises(MissingComposefile): ComposeDefinition.load_from_path( os.path.join(project_path, "test2.yml")) assert compose.content == composeclone.content # Filter configuration conf = database.get_configuration("config") compose.apply_configuration(conf) assert len(compose.get_services()) == 2 # Namespace conf2 = database.get_configuration("config2") compose = ComposeDefinition.load_from_project(project_path) compose.apply_configuration(conf2) assert len(compose.get_services()) == 2
def _load(project_path, name): path = env_get_yaml_path(project_path, name) if not os.path.isfile(path): raise MissingEnvironment(name) loaded_env = OrderedDict() with io_open(path, mode="r") as handle: env_content = yaml_ordered_load(handle.read()) # Detect imports imports = [] if "imports" in env_content: for entry in env_content["imports"]: imports.append(entry) for imported_env in imports: # Ignore self-import if imported_env == name: continue # Ignore already imported envs if imported_env in imported: continue # Save imported imported.add(imported_env) # Load imported environments result = _load(project_path, imported_env) for key, value in result.data.items(): loaded_env[key] = value # Load environment if env_content.get("environment", None): for key in env_content["environment"]: loaded_env[key] = env_content["environment"][key] return Environment(name, loaded_env)
def save(self): """Save.""" project_file_path = database_get_database_path(self.project_path) with io_open(project_file_path, encoding="utf-8", mode="w") as handle: handle.write(yaml_ordered_dump(self.serialize()))
def save(self): """Save session.""" session_file = self.get_paths().get_user_session_file_path() with io_open(session_file, mode="w") as handle: handle.write(yaml_ordered_dump(self.session_data))