More impl for devops

This commit is contained in:
dongli 2025-06-07 11:32:48 -07:00
parent 217f33fc17
commit 308f82740d
8 changed files with 112 additions and 45 deletions

View File

@ -18,6 +18,11 @@ class SiteSettings(BaseSettings):
BASE_PATH: str = os.path.dirname(os.path.dirname((os.path.abspath(__file__)))) BASE_PATH: str = os.path.dirname(os.path.dirname((os.path.abspath(__file__))))
BASE_GITEA_URL: str = "https://gitea.freeleaps.mathmast.com"
# TODO: confirm with Zhenyu
BASE_RECONSILE_URL: str = "https://reconcile.freeleaps.mathmast.com"
class Config: class Config:
env_file = ".devbase-webapi.env" env_file = ".devbase-webapi.env"
env_file_encoding = "utf-8" env_file_encoding = "utf-8"

View File

@ -0,0 +1,6 @@
from app.common.daos.code_depot.code_depot_dao import CodeDepotDao
code_depot_dao = CodeDepotDao()
def get_code_depot_dao() -> CodeDepotDao:
return code_depot_dao

View File

@ -0,0 +1,19 @@
from app.common.models.code_depot.code_depot import CodeDepotDoc
class CodeDepotDao():
def __init__(self):
pass
async def get_code_depot_by_product_id(self, product_id: str) -> CodeDepotDoc:
"""
Retrieve code depot by product id
"""
return await CodeDepotDoc.find_one({"product_id": product_id})
async def insert_code_depot(self, code_depot: CodeDepotDoc) -> CodeDepotDoc:
"""
Insert a new code depot into the database
"""
return await CodeDepotDoc.insert_one(code_depot)

View File

@ -2,5 +2,5 @@ from app.common.daos.deployment.deployment_dao import DeploymentDao
deployment_dao = DeploymentDao() deployment_dao = DeploymentDao()
def get_hello_world_dao() -> DeploymentDao: def get_deployment_dao() -> DeploymentDao:
return deployment_dao return deployment_dao

View File

@ -5,9 +5,10 @@ class DeploymentDao():
def __init__(self): def __init__(self):
pass pass
async def create_deployment(self, deployment_data: Deployment): async def create_deployment(self, deployment_data: Deployment) -> Deployment:
# Logic to create a new deployment # Logic to create a new deployment
Deployment.insert(deployment_data) return await Deployment.insert(deployment_data)
async def get_deployments_by_deployment_id(self, deployment_id: str): async def get_deployments_by_deployment_id(self, deployment_id: str):
# Logic to get a deployment by ID # Logic to get a deployment by ID

View File

@ -1,4 +1,6 @@
from app.common.models.code_depot.code_depot import CodeDepotDoc
from app.common.models.deployment.deployment import Deployment from app.common.models.deployment.deployment import Deployment
# list of beanie document models # list of beanie document models,
db_models = [Deployment] # must add here so that the mongo db collection can be automatically created
db_models = [Deployment, CodeDepotDoc]

View File

@ -4,6 +4,7 @@ from typing import List
from fastapi import APIRouter, Depends from fastapi import APIRouter, Depends
from loguru import logger from loguru import logger
from app.common.models import CodeDepotDoc
from app.common.models.deployment.deployment import Deployment, InitDeploymentRequest from app.common.models.deployment.deployment import Deployment, InitDeploymentRequest
from app.routes.deployment.service import DeploymentService, get_deployment_service from app.routes.deployment.service import DeploymentService, get_deployment_service
@ -31,3 +32,16 @@ async def check_deployment_status(
) -> List[Deployment]: ) -> List[Deployment]:
return await service.check_deployment_status(deployment_id) return await service.check_deployment_status(deployment_id)
@router.post("/createDummyCodeDepot")
async def create_dummy_code_depot(
service: DeploymentService = Depends(get_deployment_service)
) -> CodeDepotDoc:
"""
Create a dummy code depot for testing purposes.
"""
try:
depot_name = await service.create_dummy_code_depot()
return depot_name
except Exception as e:
logger.error(f"Failed to create dummy code depot: {e}")
raise e

View File

@ -3,9 +3,14 @@ from collections import defaultdict
from datetime import datetime, timedelta from datetime import datetime, timedelta
from typing import List from typing import List
from fastapi import HTTPException import httpx
from fastapi import HTTPException, Depends
from app.common.config.site_settings import site_settings
from app.common.daos.code_depot import get_code_depot_dao, CodeDepotDao
from app.common.daos.deployment import DeploymentDao, get_deployment_dao
from app.common.models import Deployment from app.common.models import Deployment
from app.common.models.code_depot.code_depot import CodeDepotDoc, DepotStatus
from app.common.models.deployment.deployment import InitDeploymentRequest from app.common.models.deployment.deployment import InitDeploymentRequest
@ -16,27 +21,25 @@ class DeploymentService:
async def init_deployment( async def init_deployment(
self, self,
request: InitDeploymentRequest request: InitDeploymentRequest,
dao: DeploymentDao = Depends(get_deployment_dao)
) -> Deployment: ) -> Deployment:
""" """
""" """
# TODO validate permission with user_id # TODO validate permission with user_id
# currently skip # currently skip
git_url = await self._retrieve_git_url_by_product_id(request.product_id) code_depot = await self._get_code_depot_by_product_id(request.product_id)
git_url = await self._compose_git_url(code_depot.depot_name)
product_initialized = await self._check_if_project_initialized(git_url, request.product_id)
if not product_initialized:
await self._init_product(git_url, request.product_id)
# retrieve project name # retrieve project name
project_name = "TODO" project_name = "TODO"
# retrieve product info # retrieve product info, depot name should be the same as product name
product_id = request.product_id product_id = request.product_id
product_name = "TODO" product_name = code_depot.depot_name
deployment = Deployment.model_construct( deployment = Deployment.model_construct(
deployment_id = str(uuid.uuid4()), deployment_id = str(uuid.uuid4()),
@ -57,8 +60,8 @@ class DeploymentService:
) )
await self._start_deployment(deployment) await self._start_deployment(deployment)
res = await dao.create_deployment(deployment)
res = await deployment.insert()
return res return res
async def check_deployment_status( async def check_deployment_status(
@ -111,47 +114,64 @@ class DeploymentService:
return True return True
async def _retrieve_git_url_by_product_id( async def _get_code_depot_by_product_id(
self, self,
product_id: str product_id: str,
code_depot_dao: CodeDepotDao = Depends(get_code_depot_dao)
) -> CodeDepotDoc:
"""
Retrieve code depot by product id
"""
code_depot = await code_depot_dao.get_code_depot_by_product_id(product_id)
if not code_depot:
raise HTTPException(status_code=404,
detail="Code depot not found for the given product id, "
"please initialize the product first"
)
return code_depot
async def _compose_git_url(
self,
code_depot_name: str,
gitea_base_url: str = site_settings.BASE_GITEA_URL
) -> str: ) -> str:
""" """
Retrieve git url by product id Retrieve git url by product id
""" """
# TODO implement this function return f"{gitea_base_url}/prodcuts/{code_depot_name.lower()}.git"
return "TODO-git_url"
async def _check_if_project_initialized(
self,
git_url: str,
product_id: str
) -> bool:
"""
Check if the project has been initialized
"""
# TODO implement this function
return True
async def _init_product(
self,
git_url: str,
product_id: str
) -> bool:
"""
Initialize the product
"""
# TODO implement this function
pass
async def _start_deployment( async def _start_deployment(
self, self,
deployment: Deployment deployment: Deployment,
reconsile_base_url: str = site_settings.BASE_RECONSILE_URL,
) -> bool: ) -> bool:
""" """
Start the deployment Start the deployment
""" """
# TODO implement this function async with httpx.AsyncClient() as client:
pass response = await client.post(
f"{reconsile_base_url}/api/devops/reconcile",
json=deployment.model_dump()
)
if response.status_code != 200:
raise HTTPException(status_code=response.status_code, detail=response.text)
return True
async def create_dummy_code_depot(
self,
code_depot_dao: CodeDepotDao = Depends(get_code_depot_dao)
) -> CodeDepotDoc:
"""
Create a dummy code depot for testing purposes.
"""
depot_name = f"dummy-depot-{uuid.uuid4()}"
code_depot = CodeDepotDoc(
depot_name=depot_name,
product_id="dummy-product-id",
depot_status=DepotStatus.CREATED
)
return await code_depot.insert_one(code_depot)
deployment_service = DeploymentService() deployment_service = DeploymentService()