fix(uid): use symlink instead of volume for persistent volume in the container

This commit is contained in:
2025-04-01 17:01:25 -06:00
parent f8b8639bb0
commit dd5b9ec213
5 changed files with 81 additions and 47 deletions

View File

@@ -188,10 +188,6 @@ class ContainerManager:
if gid is not None:
env_vars["TARGET_GID"] = str(gid)
# Add project URL to environment if provided
if project:
env_vars["MC_PROJECT_URL"] = project
# Pass API keys from host environment to container for local development
api_keys = [
"OPENAI_API_KEY",
@@ -236,6 +232,7 @@ class ContainerManager:
# Clear project for container environment since we're mounting
project = None
elif is_git_repo:
env_vars["MC_PROJECT_URL"] = project
print(
f"Git repository URL provided - container will clone {project} into /app during initialization"
)
@@ -273,6 +270,7 @@ class ContainerManager:
# Create driver-specific config directories and set up direct volume mounts
if driver.persistent_configs:
persistent_links_data = [] # To store "source:target" pairs for symlinks
print("Setting up persistent configuration directories:")
for config in driver.persistent_configs:
# Get target directory path on host
@@ -291,13 +289,21 @@ class ContainerManager:
target_dir.parent.mkdir(parents=True, exist_ok=True)
# File will be created by the container if needed
# Mount persistent config directly to container path
session_volumes[str(target_dir)] = {
"bind": config.source,
"mode": "rw",
}
# --- REMOVED adding to session_volumes ---
# We will create symlinks inside the container instead of direct mounts
# Store the source and target paths for the init script
# Note: config.target is the path *within* /mc-config
persistent_links_data.append(f"{config.source}:{config.target}")
print(
f" - Created direct volume mount: {target_dir} -> {config.source}"
f" - Prepared host path {target_dir} for symlink target {config.target}"
)
# Set environment variable with semicolon-separated link pairs
if persistent_links_data:
env_vars["MC_PERSISTENT_LINKS"] = ";".join(persistent_links_data)
print(
f"Setting MC_PERSISTENT_LINKS={env_vars['MC_PERSISTENT_LINKS']}"
)
# Default MC network
@@ -634,7 +640,7 @@ class ContainerManager:
return False
container_id = session_obj.container_id
print(
f"[yellow]Warning: Session data missing for {session_id}. Attaching as default container user.[/yellow]"
f"[yellow]Warning: Session data missing for {session_id}. Connecting as default container user.[/yellow]"
)
else:
container_id = session_data.get("container_id")
@@ -660,18 +666,19 @@ class ContainerManager:
return False
try:
# Attach to the container's main process TTY
# This allows seeing the output of --run command followed by the shell
# The user context (UID/GID) is determined when the container is created,
# attach respects that context.
# Use exec instead of attach to avoid container exit on Ctrl+C
print(
f"Attaching to session {session_id} (container: {container_id[:12]})..."
f"Connecting to session {session_id} (container: {container_id[:12]})..."
)
print("Type 'exit' or Ctrl+P, Ctrl+Q (by default) to detach.")
cmd = ["docker", "attach", container_id]
print("Type 'exit' to detach from the session.")
# Use execvp to replace the current process with docker attach
# This provides a more seamless shell experience
# Use docker exec to start a new bash process in the container
# This leverages the init-status.sh script in bash.bashrc
# which will check initialization status
cmd = ["docker", "exec", "-it", container_id, "bash", "-l"]
# Use execvp to replace the current process with docker exec
# This provides a seamless shell experience
os.execvp("docker", cmd)
# execvp does not return if successful
return True # Should not be reached if execvp succeeds