fix: move router to api layer and add missing imports/guards
- Move APIRouter definition from instance_service.py back to tool_instances.py (service files should not define FastAPI routers) - Add missing prepare_manifest_instance import in tool_instances.py - Guard repo.remote_url before clone_repository call - Guard tool_type.compose_template before render_compose_template call - Rename subprocess result variable to avoid shadowing SQLAlchemy Result - Build error message as local string to avoid None/bool type issues Quality gates: py_compile pass, LSP clean
This commit is contained in:
@@ -92,6 +92,7 @@ from src.services.tool.instance_service import (
|
|||||||
expand_glob_source,
|
expand_glob_source,
|
||||||
modify_compose_file,
|
modify_compose_file,
|
||||||
normalize_git_mount,
|
normalize_git_mount,
|
||||||
|
prepare_manifest_instance,
|
||||||
pull_repository_updates,
|
pull_repository_updates,
|
||||||
resolve_git_mount_mappings,
|
resolve_git_mount_mappings,
|
||||||
resolve_git_mounts,
|
resolve_git_mounts,
|
||||||
@@ -104,6 +105,8 @@ from src.services.tool.instance_service import (
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
_event_bus = InstanceEventBus()
|
_event_bus = InstanceEventBus()
|
||||||
|
|
||||||
|
router = APIRouter(prefix="/projects", tags=["tool-instances"])
|
||||||
|
|
||||||
|
|
||||||
@router.post(
|
@router.post(
|
||||||
"/{project_id}/repositories/{repo_id}/instances",
|
"/{project_id}/repositories/{repo_id}/instances",
|
||||||
@@ -257,6 +260,11 @@ async def create_instance(
|
|||||||
ssh_key_path = os.path.join(ssh_dir, "id_ed25519")
|
ssh_key_path = os.path.join(ssh_dir, "id_ed25519")
|
||||||
|
|
||||||
# Clone repository
|
# Clone repository
|
||||||
|
if not repo.remote_url:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail="Repository has no remote URL configured",
|
||||||
|
)
|
||||||
clone_path = clone_repository(
|
clone_path = clone_repository(
|
||||||
remote_url=repo.remote_url,
|
remote_url=repo.remote_url,
|
||||||
ssh_key_path=ssh_key_path,
|
ssh_key_path=ssh_key_path,
|
||||||
@@ -298,16 +306,16 @@ async def create_instance(
|
|||||||
# Create new local branch if requested
|
# Create new local branch if requested
|
||||||
if data.clone_mode == "clone" and data.new_branch:
|
if data.clone_mode == "clone" and data.new_branch:
|
||||||
try:
|
try:
|
||||||
result = subprocess.run(
|
git_result = subprocess.run(
|
||||||
["git", "-C", repo_path, "checkout", "-b", data.new_branch],
|
["git", "-C", repo_path, "checkout", "-b", data.new_branch],
|
||||||
capture_output=True,
|
capture_output=True,
|
||||||
text=True,
|
text=True,
|
||||||
)
|
)
|
||||||
if result.returncode != 0:
|
if git_result.returncode != 0:
|
||||||
logger.error(
|
logger.error(
|
||||||
"Failed to create branch %s: %s", data.new_branch, result.stderr
|
"Failed to create branch %s: %s", data.new_branch, git_result.stderr
|
||||||
)
|
)
|
||||||
raise RuntimeError(f"Failed to create branch: {result.stderr}")
|
raise RuntimeError(f"Failed to create branch: {git_result.stderr}")
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"Created local branch %s in cloned repository", data.new_branch
|
"Created local branch %s in cloned repository", data.new_branch
|
||||||
)
|
)
|
||||||
@@ -421,6 +429,11 @@ services:
|
|||||||
"USER_ID": str(user_id),
|
"USER_ID": str(user_id),
|
||||||
"PROJECT_ID": str(project_id),
|
"PROJECT_ID": str(project_id),
|
||||||
}
|
}
|
||||||
|
if not tool_type.compose_template:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||||
|
detail="Tool type has no compose template configured",
|
||||||
|
)
|
||||||
compose_content = render_compose_template(
|
compose_content = render_compose_template(
|
||||||
tool_type.compose_template, variables
|
tool_type.compose_template, variables
|
||||||
)
|
)
|
||||||
@@ -1912,9 +1925,10 @@ async def check_instance_tunnel_health(
|
|||||||
|
|
||||||
# If container is not running, override error message
|
# If container is not running, override error message
|
||||||
if not container_healthy:
|
if not container_healthy:
|
||||||
response["error"] = f"Container is {container_info['status']}"
|
error_msg = f"Container is {container_info['status']}"
|
||||||
if container_info["exit_code"] is not None:
|
if container_info["exit_code"] is not None:
|
||||||
response["error"] += f" (exit code: {container_info['exit_code']})"
|
error_msg += f" (exit code: {container_info['exit_code']})"
|
||||||
|
response["error"] = error_msg
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ from src.auth.dependencies import _get_owned_project, _get_user
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
_event_bus = InstanceEventBus()
|
_event_bus = InstanceEventBus()
|
||||||
|
|
||||||
|
|
||||||
async def resolve_git_mounts(
|
async def resolve_git_mounts(
|
||||||
session: AsyncSession,
|
session: AsyncSession,
|
||||||
resolved: ResolvedProfile,
|
resolved: ResolvedProfile,
|
||||||
@@ -399,9 +400,6 @@ def expand_glob_source(source_path: str, repo_path: str) -> list[str]:
|
|||||||
return results
|
return results
|
||||||
|
|
||||||
|
|
||||||
router = APIRouter(prefix="/projects", tags=["tool-instances"])
|
|
||||||
|
|
||||||
|
|
||||||
async def validate_config_profile(
|
async def validate_config_profile(
|
||||||
session: AsyncSession,
|
session: AsyncSession,
|
||||||
profile_id: str | None,
|
profile_id: str | None,
|
||||||
@@ -741,7 +739,6 @@ def ensure_backend_network_in_compose(compose_path: str) -> None:
|
|||||||
logger.info("Injected backend network '%s' into compose file", network_name)
|
logger.info("Injected backend network '%s' into compose file", network_name)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async def prepare_manifest_instance(
|
async def prepare_manifest_instance(
|
||||||
session: AsyncSession,
|
session: AsyncSession,
|
||||||
instance: ToolInstance,
|
instance: ToolInstance,
|
||||||
@@ -882,5 +879,3 @@ async def prepare_manifest_instance(
|
|||||||
|
|
||||||
home_dir = get_manifest_home_dir(manifest)
|
home_dir = get_manifest_home_dir(manifest)
|
||||||
return image_tag, compose_content, manifest, home_dir
|
return image_tag, compose_content, manifest, home_dir
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user