fix: handle existing git mount dirs and invalid compose ports
- Fix git mount clone to check correct path (repo-clone subdir) - Pull updates instead of re-cloning when git mount dir exists - Add compose file sanitization to remove invalid port 0 mappings - Fixes startup failures for existing instances with old compose files
This commit is contained in:
@@ -130,17 +130,19 @@ async def _resolve_single_git_mount(
|
||||
import hashlib
|
||||
url_hash = hashlib.md5(remote_url.encode()).hexdigest()[:12]
|
||||
repo_name = remote_url.split("/")[-1].replace(".git", "") or "repo"
|
||||
clone_dir = os.path.join(instance_dir, "git-mounts", f"{repo_name}-{url_hash}")
|
||||
clone_parent = os.path.join(instance_dir, "git-mounts", f"{repo_name}-{url_hash}")
|
||||
# clone_repository always creates 'repo-clone' inside the given directory
|
||||
repo_path = os.path.join(clone_parent, "repo-clone")
|
||||
|
||||
# Clone or pull the repository
|
||||
repo_path = clone_dir
|
||||
if not os.path.exists(clone_dir):
|
||||
if not os.path.exists(repo_path):
|
||||
try:
|
||||
os.makedirs(clone_parent, exist_ok=True)
|
||||
repo_path = await asyncio.to_thread(
|
||||
clone_repository,
|
||||
remote_url,
|
||||
None, # No SSH key for now - can be added later
|
||||
os.path.dirname(clone_dir),
|
||||
clone_parent,
|
||||
branch or "main",
|
||||
)
|
||||
logger.debug("Cloned git mount repository %s to %s", remote_url, repo_path)
|
||||
@@ -384,6 +386,47 @@ async def _validate_config_profile(
|
||||
return profile_uuid
|
||||
|
||||
|
||||
def _sanitize_compose_file(compose_path: str) -> None:
|
||||
"""Remove invalid port mappings (target port 0) from compose file."""
|
||||
import yaml
|
||||
from pathlib import Path
|
||||
|
||||
compose_file = Path(compose_path)
|
||||
if not compose_file.exists():
|
||||
return
|
||||
|
||||
content = compose_file.read_text()
|
||||
compose_data = yaml.safe_load(content)
|
||||
|
||||
if not compose_data or "services" not in compose_data:
|
||||
return
|
||||
|
||||
modified = False
|
||||
for service_name, service_config in compose_data["services"].items():
|
||||
if "ports" in service_config:
|
||||
valid_ports = []
|
||||
for port_mapping in service_config["ports"]:
|
||||
if isinstance(port_mapping, str) and ":" in port_mapping:
|
||||
parts = port_mapping.split(":")
|
||||
if len(parts) == 2:
|
||||
host_port, container_port = parts
|
||||
# Skip invalid mappings (target port 0 or empty)
|
||||
if container_port == "0" or not container_port:
|
||||
modified = True
|
||||
continue
|
||||
valid_ports.append(port_mapping)
|
||||
|
||||
if valid_ports:
|
||||
service_config["ports"] = valid_ports
|
||||
else:
|
||||
del service_config["ports"]
|
||||
modified = True
|
||||
break # Only check first service
|
||||
|
||||
if modified:
|
||||
compose_file.write_text(yaml.dump(compose_data, default_flow_style=False))
|
||||
|
||||
|
||||
def _modify_compose_file(
|
||||
compose_path: str,
|
||||
port_override: int | None = None,
|
||||
@@ -996,6 +1039,9 @@ async def start_instance(
|
||||
_modify_compose_file(instance.compose_path, port_override, start_command, working_directory, extra_volumes)
|
||||
logger.debug("Modified compose file for instance %s", instance.id)
|
||||
|
||||
# Sanitize compose file to remove invalid port mappings from old instances
|
||||
_sanitize_compose_file(instance.compose_path)
|
||||
|
||||
# Execute docker compose up with env file
|
||||
logger.debug("Running docker compose up for instance %s (compose_path=%s)", instance.id, instance.compose_path)
|
||||
returncode, stdout, stderr = execute_compose_command(
|
||||
|
||||
Reference in New Issue
Block a user