More impl for devops
This commit is contained in:
parent
217f33fc17
commit
308f82740d
@ -18,6 +18,11 @@ class SiteSettings(BaseSettings):
|
||||
|
||||
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:
|
||||
env_file = ".devbase-webapi.env"
|
||||
env_file_encoding = "utf-8"
|
||||
|
||||
6
apps/devops/app/common/daos/code_depot/__init__.py
Normal file
6
apps/devops/app/common/daos/code_depot/__init__.py
Normal 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
|
||||
19
apps/devops/app/common/daos/code_depot/code_depot_dao.py
Normal file
19
apps/devops/app/common/daos/code_depot/code_depot_dao.py
Normal 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)
|
||||
@ -2,5 +2,5 @@ from app.common.daos.deployment.deployment_dao import DeploymentDao
|
||||
|
||||
deployment_dao = DeploymentDao()
|
||||
|
||||
def get_hello_world_dao() -> DeploymentDao:
|
||||
def get_deployment_dao() -> DeploymentDao:
|
||||
return deployment_dao
|
||||
@ -5,9 +5,10 @@ class DeploymentDao():
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
async def create_deployment(self, deployment_data: Deployment):
|
||||
async def create_deployment(self, deployment_data: Deployment) -> 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):
|
||||
# Logic to get a deployment by ID
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
from app.common.models.code_depot.code_depot import CodeDepotDoc
|
||||
from app.common.models.deployment.deployment import Deployment
|
||||
|
||||
# list of beanie document models
|
||||
db_models = [Deployment]
|
||||
# list of beanie document models,
|
||||
# must add here so that the mongo db collection can be automatically created
|
||||
db_models = [Deployment, CodeDepotDoc]
|
||||
@ -4,6 +4,7 @@ from typing import List
|
||||
from fastapi import APIRouter, Depends
|
||||
from loguru import logger
|
||||
|
||||
from app.common.models import CodeDepotDoc
|
||||
from app.common.models.deployment.deployment import Deployment, InitDeploymentRequest
|
||||
from app.routes.deployment.service import DeploymentService, get_deployment_service
|
||||
|
||||
@ -31,3 +32,16 @@ async def check_deployment_status(
|
||||
) -> List[Deployment]:
|
||||
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
|
||||
|
||||
@ -3,9 +3,14 @@ from collections import defaultdict
|
||||
from datetime import datetime, timedelta
|
||||
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.code_depot.code_depot import CodeDepotDoc, DepotStatus
|
||||
from app.common.models.deployment.deployment import InitDeploymentRequest
|
||||
|
||||
|
||||
@ -16,27 +21,25 @@ class DeploymentService:
|
||||
|
||||
async def init_deployment(
|
||||
self,
|
||||
request: InitDeploymentRequest
|
||||
request: InitDeploymentRequest,
|
||||
dao: DeploymentDao = Depends(get_deployment_dao)
|
||||
) -> Deployment:
|
||||
"""
|
||||
"""
|
||||
# TODO validate permission with user_id
|
||||
# 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
|
||||
project_name = "TODO"
|
||||
|
||||
# retrieve product info
|
||||
# retrieve product info, depot name should be the same as product name
|
||||
product_id = request.product_id
|
||||
product_name = "TODO"
|
||||
|
||||
|
||||
product_name = code_depot.depot_name
|
||||
|
||||
deployment = Deployment.model_construct(
|
||||
deployment_id = str(uuid.uuid4()),
|
||||
@ -57,8 +60,8 @@ class DeploymentService:
|
||||
)
|
||||
|
||||
await self._start_deployment(deployment)
|
||||
res = await dao.create_deployment(deployment)
|
||||
|
||||
res = await deployment.insert()
|
||||
return res
|
||||
|
||||
async def check_deployment_status(
|
||||
@ -111,47 +114,64 @@ class DeploymentService:
|
||||
|
||||
return True
|
||||
|
||||
async def _retrieve_git_url_by_product_id(
|
||||
async def _get_code_depot_by_product_id(
|
||||
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:
|
||||
"""
|
||||
Retrieve git url by product id
|
||||
"""
|
||||
# TODO implement this function
|
||||
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
|
||||
return f"{gitea_base_url}/prodcuts/{code_depot_name.lower()}.git"
|
||||
|
||||
async def _start_deployment(
|
||||
self,
|
||||
deployment: Deployment
|
||||
deployment: Deployment,
|
||||
reconsile_base_url: str = site_settings.BASE_RECONSILE_URL,
|
||||
) -> bool:
|
||||
"""
|
||||
Start the deployment
|
||||
"""
|
||||
# TODO implement this function
|
||||
pass
|
||||
async with httpx.AsyncClient() as client:
|
||||
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()
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user