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,
|
||||
modify_compose_file,
|
||||
normalize_git_mount,
|
||||
prepare_manifest_instance,
|
||||
pull_repository_updates,
|
||||
resolve_git_mount_mappings,
|
||||
resolve_git_mounts,
|
||||
@@ -104,6 +105,8 @@ from src.services.tool.instance_service import (
|
||||
logger = logging.getLogger(__name__)
|
||||
_event_bus = InstanceEventBus()
|
||||
|
||||
router = APIRouter(prefix="/projects", tags=["tool-instances"])
|
||||
|
||||
|
||||
@router.post(
|
||||
"/{project_id}/repositories/{repo_id}/instances",
|
||||
@@ -257,6 +260,11 @@ async def create_instance(
|
||||
ssh_key_path = os.path.join(ssh_dir, "id_ed25519")
|
||||
|
||||
# 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(
|
||||
remote_url=repo.remote_url,
|
||||
ssh_key_path=ssh_key_path,
|
||||
@@ -298,16 +306,16 @@ async def create_instance(
|
||||
# Create new local branch if requested
|
||||
if data.clone_mode == "clone" and data.new_branch:
|
||||
try:
|
||||
result = subprocess.run(
|
||||
git_result = subprocess.run(
|
||||
["git", "-C", repo_path, "checkout", "-b", data.new_branch],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
if result.returncode != 0:
|
||||
if git_result.returncode != 0:
|
||||
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(
|
||||
"Created local branch %s in cloned repository", data.new_branch
|
||||
)
|
||||
@@ -421,6 +429,11 @@ services:
|
||||
"USER_ID": str(user_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(
|
||||
tool_type.compose_template, variables
|
||||
)
|
||||
@@ -1912,9 +1925,10 @@ async def check_instance_tunnel_health(
|
||||
|
||||
# If container is not running, override error message
|
||||
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:
|
||||
response["error"] += f" (exit code: {container_info['exit_code']})"
|
||||
error_msg += f" (exit code: {container_info['exit_code']})"
|
||||
response["error"] = error_msg
|
||||
|
||||
return response
|
||||
|
||||
|
||||
@@ -71,6 +71,7 @@ from src.auth.dependencies import _get_owned_project, _get_user
|
||||
logger = logging.getLogger(__name__)
|
||||
_event_bus = InstanceEventBus()
|
||||
|
||||
|
||||
async def resolve_git_mounts(
|
||||
session: AsyncSession,
|
||||
resolved: ResolvedProfile,
|
||||
@@ -399,9 +400,6 @@ def expand_glob_source(source_path: str, repo_path: str) -> list[str]:
|
||||
return results
|
||||
|
||||
|
||||
router = APIRouter(prefix="/projects", tags=["tool-instances"])
|
||||
|
||||
|
||||
async def validate_config_profile(
|
||||
session: AsyncSession,
|
||||
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)
|
||||
|
||||
|
||||
|
||||
async def prepare_manifest_instance(
|
||||
session: AsyncSession,
|
||||
instance: ToolInstance,
|
||||
@@ -882,5 +879,3 @@ async def prepare_manifest_instance(
|
||||
|
||||
home_dir = get_manifest_home_dir(manifest)
|
||||
return image_tag, compose_content, manifest, home_dir
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user