feat: add ssh_key_id to config profiles for container key mounting

- Add ssh_key_id column to ConfigProfile model and migration
- Update config profile API to accept/return ssh_key_id
- Include ssh_key_id in ResolvedProfile and resolver logic
- Mount selected SSH key into container home dir at start_instance
- Frontend config profile form with SSH key selector dropdown
- Git mount URL validation defaults to profile's SSH key

Quality gates: pytest (231 passed, 6 pre-existing), tsc --noEmit clean
This commit is contained in:
Alex Blank
2026-05-29 12:53:51 +02:00
parent d413fb84a5
commit 57ff236f2d
11 changed files with 232 additions and 26 deletions
+5
View File
@@ -9,6 +9,7 @@ from src.models.base import Base, TimestampMixin, UUIDPrimaryKeyMixin
if TYPE_CHECKING:
from src.models.project import Project
from src.models.ssh_key import SSHKey
from src.models.tool_type import ToolType
from src.models.user import User
@@ -42,11 +43,15 @@ class ConfigProfile(UUIDPrimaryKeyMixin, TimestampMixin, Base):
git_mounts: Mapped[list] = mapped_column(
JSON, default=list, nullable=False
) # [{"remote_url": "https://github.com/user/repo.git", "source_path": ".", "target_path": "/path", "branch": "main"}, ...]
ssh_key_id: Mapped[uuid.UUID | None] = mapped_column(
UUID(), ForeignKey("ssh_keys.id", ondelete="SET NULL"), nullable=True
)
is_default: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False)
user: Mapped["User"] = relationship()
project: Mapped["Project | None"] = relationship()
tool_type: Mapped["ToolType | None"] = relationship()
ssh_key: Mapped["SSHKey | None"] = relationship()
includes: Mapped[list["ConfigProfileInclude"]] = relationship(
"ConfigProfileInclude",
foreign_keys="ConfigProfileInclude.profile_id",