mirror of
https://github.com/Monadical-SAS/cubbi.git
synced 2025-12-20 20:29:06 +00:00
feat(volume): add the possibilty to mount local directory into the container (like docker volume)
This commit is contained in:
@@ -109,6 +109,9 @@ def create_session(
|
||||
env: List[str] = typer.Option(
|
||||
[], "--env", "-e", help="Environment variables (KEY=VALUE)"
|
||||
),
|
||||
volume: List[str] = typer.Option(
|
||||
[], "--volume", "-v", help="Mount volumes (LOCAL_PATH:CONTAINER_PATH)"
|
||||
),
|
||||
name: Optional[str] = typer.Option(None, "--name", "-n", help="Session name"),
|
||||
no_connect: bool = typer.Option(
|
||||
False, "--no-connect", help="Don't automatically connect to the session"
|
||||
@@ -139,6 +142,29 @@ def create_session(
|
||||
f"[yellow]Warning: Ignoring invalid environment variable format: {var}[/yellow]"
|
||||
)
|
||||
|
||||
# Parse volume mounts
|
||||
volume_mounts = {}
|
||||
for vol in volume:
|
||||
if ":" in vol:
|
||||
local_path, container_path = vol.split(":", 1)
|
||||
# Convert to absolute path if relative
|
||||
if not os.path.isabs(local_path):
|
||||
local_path = os.path.abspath(local_path)
|
||||
|
||||
# Validate local path exists
|
||||
if not os.path.exists(local_path):
|
||||
console.print(
|
||||
f"[yellow]Warning: Local path '{local_path}' does not exist. Volume will not be mounted.[/yellow]"
|
||||
)
|
||||
continue
|
||||
|
||||
# Add to volume mounts
|
||||
volume_mounts[local_path] = {"bind": container_path, "mode": "rw"}
|
||||
else:
|
||||
console.print(
|
||||
f"[yellow]Warning: Ignoring invalid volume format: {vol}. Use LOCAL_PATH:CONTAINER_PATH.[/yellow]"
|
||||
)
|
||||
|
||||
with console.status(f"Creating session with driver '{driver}'..."):
|
||||
session = container_manager.create_session(
|
||||
driver_name=driver,
|
||||
@@ -146,6 +172,7 @@ def create_session(
|
||||
environment=environment,
|
||||
session_name=name,
|
||||
mount_local=not no_mount and user_config.get("defaults.mount_local", True),
|
||||
volumes=volume_mounts,
|
||||
)
|
||||
|
||||
if session:
|
||||
@@ -284,6 +311,9 @@ def quick_create(
|
||||
env: List[str] = typer.Option(
|
||||
[], "--env", "-e", help="Environment variables (KEY=VALUE)"
|
||||
),
|
||||
volume: List[str] = typer.Option(
|
||||
[], "--volume", "-v", help="Mount volumes (LOCAL_PATH:CONTAINER_PATH)"
|
||||
),
|
||||
name: Optional[str] = typer.Option(None, "--name", "-n", help="Session name"),
|
||||
no_connect: bool = typer.Option(
|
||||
False, "--no-connect", help="Don't automatically connect to the session"
|
||||
@@ -303,6 +333,7 @@ def quick_create(
|
||||
driver=driver,
|
||||
project=project,
|
||||
env=env,
|
||||
volume=volume,
|
||||
name=name,
|
||||
no_connect=no_connect,
|
||||
no_mount=no_mount,
|
||||
|
||||
@@ -125,6 +125,7 @@ class ContainerManager:
|
||||
environment: Optional[Dict[str, str]] = None,
|
||||
session_name: Optional[str] = None,
|
||||
mount_local: bool = True,
|
||||
volumes: Optional[Dict[str, Dict[str, str]]] = None,
|
||||
) -> Optional[Session]:
|
||||
"""Create a new MC session
|
||||
|
||||
@@ -134,6 +135,7 @@ class ContainerManager:
|
||||
environment: Optional environment variables
|
||||
session_name: Optional session name
|
||||
mount_local: Whether to mount the current directory to /app
|
||||
volumes: Optional additional volumes to mount (dict of {host_path: {"bind": container_path, "mode": mode}})
|
||||
"""
|
||||
try:
|
||||
# Validate driver exists
|
||||
@@ -178,25 +180,46 @@ class ContainerManager:
|
||||
self.client.images.pull(driver.image)
|
||||
|
||||
# Set up volume mounts
|
||||
volumes = {}
|
||||
session_volumes = {}
|
||||
|
||||
# If project URL is provided, don't mount local directory (will clone into /app)
|
||||
# If no project URL and mount_local is True, mount local directory to /app
|
||||
if not project and mount_local:
|
||||
# Mount current directory to /app in the container
|
||||
current_dir = os.getcwd()
|
||||
volumes[current_dir] = {"bind": "/app", "mode": "rw"}
|
||||
session_volumes[current_dir] = {"bind": "/app", "mode": "rw"}
|
||||
print(f"Mounting local directory {current_dir} to /app")
|
||||
elif project:
|
||||
print(
|
||||
f"Project URL provided - container will clone {project} into /app during initialization"
|
||||
)
|
||||
|
||||
# Add user-specified volumes
|
||||
if volumes:
|
||||
for host_path, mount_spec in volumes.items():
|
||||
container_path = mount_spec["bind"]
|
||||
# Check for conflicts with /app mount
|
||||
if container_path == "/app" and not project and mount_local:
|
||||
print(
|
||||
"[yellow]Warning: Volume mount to /app conflicts with automatic local directory mount. User-specified mount takes precedence.[/yellow]"
|
||||
)
|
||||
# Remove the automatic mount if there's a conflict
|
||||
if current_dir in session_volumes:
|
||||
del session_volumes[current_dir]
|
||||
|
||||
# Add the volume
|
||||
session_volumes[host_path] = mount_spec
|
||||
print(f"Mounting volume: {host_path} -> {container_path}")
|
||||
|
||||
# Set up persistent project configuration
|
||||
project_config_path = self._get_project_config_path(project)
|
||||
print(f"Using project configuration directory: {project_config_path}")
|
||||
|
||||
# Mount the project configuration directory
|
||||
volumes[str(project_config_path)] = {"bind": "/mc-config", "mode": "rw"}
|
||||
session_volumes[str(project_config_path)] = {
|
||||
"bind": "/mc-config",
|
||||
"mode": "rw",
|
||||
}
|
||||
|
||||
# Add environment variables for config path
|
||||
env_vars["MC_CONFIG_DIR"] = "/mc-config"
|
||||
@@ -230,7 +253,7 @@ class ContainerManager:
|
||||
tty=True,
|
||||
stdin_open=True,
|
||||
environment=env_vars,
|
||||
volumes=volumes,
|
||||
volumes=session_volumes,
|
||||
labels={
|
||||
"mc.session": "true",
|
||||
"mc.session.id": session_id,
|
||||
|
||||
Reference in New Issue
Block a user