Spaces:
Running
Running
| """ | |
| Docker file generation service. | |
| """ | |
| from typing import Union | |
| from pathlib import Path | |
| from fastapi import HTTPException, status | |
| from jinja2 import Environment, Template | |
| from app.core.config import Settings | |
| from app.models.schemas import DockerfileConfig, DockerComposeConfig | |
| class DockerGenerator: | |
| """Service for generating Docker files and configurations.""" | |
| def __init__(self, template_env: Environment, settings: Settings, logger): | |
| self.template_env = template_env | |
| self.settings = settings | |
| self.logger = logger | |
| def generate_dockerfile(self, config: DockerfileConfig, file_id: str) -> str: | |
| """ | |
| Generate a Dockerfile based on stack type and configuration. | |
| """ | |
| stack = config.stackType.lower() | |
| # Map stack to template | |
| template_map = { | |
| "nodejs": "docker/dockerfile_nodejs.j2", | |
| "python": "docker/dockerfile_python.j2", | |
| "php": "docker/dockerfile_php.j2", | |
| "go": "docker/dockerfile_go.j2", | |
| "java": "docker/dockerfile_java.j2", | |
| "dotnet": "docker/dockerfile_dotnet.j2", | |
| "ruby": "docker/dockerfile_ruby.j2", | |
| } | |
| template_name = template_map.get(stack) | |
| if not template_name: | |
| raise ValueError(f"Unsupported stack type: {stack}") | |
| try: | |
| # Read template from disk | |
| template_path = self.settings.templates_dir / template_name | |
| with open(template_path, 'r', encoding='utf-8') as f: | |
| template_content = f.read() | |
| # Render using Jinja2 | |
| template = Template( | |
| template_content, | |
| trim_blocks=True, | |
| lstrip_blocks=True | |
| ) | |
| dockerfile_content = template.render(config=config, file_id=file_id) | |
| return dockerfile_content | |
| except Exception as e: | |
| self.logger.error(f"Failed to generate Dockerfile: {str(e)}") | |
| raise HTTPException( | |
| status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, | |
| detail=f"Failed to generate Dockerfile: {str(e)}" | |
| ) | |
| def generate_docker_compose(self, config: DockerComposeConfig, file_id: str) -> str: | |
| """ | |
| Generate a docker-compose.yml based on configuration. | |
| """ | |
| template_name = "docker/docker-compose.yml.j2" | |
| try: | |
| # Read template from disk | |
| template_path = self.settings.templates_dir / template_name | |
| with open(template_path, 'r', encoding='utf-8') as f: | |
| template_content = f.read() | |
| # Render using Jinja2 | |
| template = Template( | |
| template_content, | |
| trim_blocks=True, | |
| lstrip_blocks=True | |
| ) | |
| compose_content = template.render(config=config, file_id=file_id) | |
| return compose_content | |
| except Exception as e: | |
| self.logger.error(f"Failed to generate docker-compose: {str(e)}") | |
| raise HTTPException( | |
| status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, | |
| detail=f"Failed to generate docker-compose: {str(e)}" | |
| ) | |
| def generate_dockerignore(self, config: Union[DockerfileConfig, DockerComposeConfig], file_id: str) -> str: | |
| """ | |
| Generate a .dockerignore file. | |
| """ | |
| template_name = "docker/dockerignore.j2" | |
| try: | |
| # Read template from disk | |
| template_path = self.settings.templates_dir / template_name | |
| with open(template_path, 'r', encoding='utf-8') as f: | |
| template_content = f.read() | |
| # Render using Jinja2 | |
| template = Template( | |
| template_content, | |
| trim_blocks=True, | |
| lstrip_blocks=True | |
| ) | |
| dockerignore_content = template.render(config=config, file_id=file_id) | |
| return dockerignore_content | |
| except Exception as e: | |
| self.logger.error(f"Failed to generate .dockerignore: {str(e)}") | |
| raise HTTPException( | |
| status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, | |
| detail=f"Failed to generate .dockerignore: {str(e)}" | |
| ) | |
| def generate_env_example(self, config: DockerComposeConfig, file_id: str) -> str: | |
| """ | |
| Generate a .env.example file for docker-compose. | |
| """ | |
| template_name = "docker/env.example.j2" | |
| try: | |
| # Read template from disk | |
| template_path = self.settings.templates_dir / template_name | |
| with open(template_path, 'r', encoding='utf-8') as f: | |
| template_content = f.read() | |
| # Render using Jinja2 | |
| template = Template( | |
| template_content, | |
| trim_blocks=True, | |
| lstrip_blocks=True | |
| ) | |
| env_content = template.render(config=config, file_id=file_id) | |
| return env_content | |
| except Exception as e: | |
| self.logger.error(f"Failed to generate .env.example: {str(e)}") | |
| raise HTTPException( | |
| status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, | |
| detail=f"Failed to generate .env.example: {str(e)}" | |
| ) | |
| def generate_build_script(self, config: DockerComposeConfig, file_id: str) -> str: | |
| """ | |
| Generate a docker-build.sh helper script. | |
| """ | |
| template_name = "docker/docker-build.sh.j2" | |
| try: | |
| # Read template from disk | |
| template_path = self.settings.templates_dir / template_name | |
| with open(template_path, 'r', encoding='utf-8') as f: | |
| template_content = f.read() | |
| # Render using Jinja2 | |
| template = Template( | |
| template_content, | |
| trim_blocks=True, | |
| lstrip_blocks=True | |
| ) | |
| script_content = template.render(config=config, file_id=file_id) | |
| return script_content | |
| except Exception as e: | |
| self.logger.error(f"Failed to generate build script: {str(e)}") | |
| raise HTTPException( | |
| status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, | |
| detail=f"Failed to generate build script: {str(e)}" | |
| ) | |