From b43db9320faf60a6f3b26319f4cf0135fe280fa9 Mon Sep 17 00:00:00 2001 From: Mathieu Virbel Date: Thu, 5 Feb 2026 19:00:53 -0600 Subject: [PATCH] feat: add --no-default-network flag to session create Allow users to prevent automatic connection to the cubbi-network bridge network when creating sessions, useful when only custom networks or Docker's default bridge are needed. --- cubbi/cli.py | 6 +++++ cubbi/container.py | 41 +++++++++++++++---------------- tests/test_integration_docker.py | 42 ++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 21 deletions(-) diff --git a/cubbi/cli.py b/cubbi/cli.py index 959f232..64565ae 100644 --- a/cubbi/cli.py +++ b/cubbi/cli.py @@ -149,6 +149,11 @@ def create_session( network: List[str] = typer.Option( [], "--network", "-N", help="Connect to additional Docker networks" ), + no_default_network: bool = typer.Option( + False, + "--no-default-network", + help="Don't connect to the default Cubbi network", + ), port: List[str] = typer.Option( [], "--port", @@ -419,6 +424,7 @@ def create_session( ssh=ssh, model=final_model, domains=all_domains, + no_default_network=no_default_network, ) if session: diff --git a/cubbi/container.py b/cubbi/container.py index aa18e35..5ff570d 100644 --- a/cubbi/container.py +++ b/cubbi/container.py @@ -249,6 +249,7 @@ class ContainerManager: model: Optional[str] = None, ssh: bool = False, domains: Optional[List[str]] = None, + no_default_network: bool = False, ) -> Optional[Session]: """Create a new Cubbi session @@ -295,8 +296,9 @@ class ContainerManager: if not session_name: session_name = f"cubbi-{session_id}" - # Ensure network exists - self._ensure_network() + # Ensure network exists (skip if user opted out of default network) + if not no_default_network: + self._ensure_network() # Minimal environment variables env_vars = environment or {} @@ -422,7 +424,7 @@ class ContainerManager: ) # Get network list - network_list = [default_network] + network_list = [] if no_default_network else [default_network] # Process MCPs if provided mcp_configs = [] @@ -478,20 +480,16 @@ class ContainerManager: pass # Add user-specified networks - # Default Cubbi network - default_network = self.config_manager.config.docker.get( - "network", "cubbi-network" - ) - - # Get network list, ensuring default is first and no duplicates - network_list_set = {default_network} - if networks: - network_list_set.update(networks) - network_list = ( - [default_network] + [n for n in networks if n != default_network] - if networks - else [default_network] - ) + if no_default_network: + # Only use user-specified networks + network_list = list(networks) if networks else [] + else: + # Get network list, ensuring default is first and no duplicates + network_list = ( + [default_network] + [n for n in networks if n != default_network] + if networks + else [default_network] + ) if networks: for network in networks: @@ -529,7 +527,7 @@ class ContainerManager: "[yellow]Warning: Cannot use --domains with --network. Using domain restrictions only.[/yellow]" ) networks = [] - network_list = [default_network] + network_list = [] if no_default_network else [default_network] # Create network-filter container network_filter_name = f"cubbi-network-filter-{session_id}" @@ -656,9 +654,10 @@ class ContainerManager: # Cannot set hostname when using network_mode else: container_params["hostname"] = session_name - container_params["network"] = network_list[ - 0 - ] # Connect to the first network initially + if network_list: + container_params["network"] = network_list[ + 0 + ] # Connect to the first network initially container = self.client.containers.create(**container_params) diff --git a/tests/test_integration_docker.py b/tests/test_integration_docker.py index b4dd1bc..aba9ee2 100644 --- a/tests/test_integration_docker.py +++ b/tests/test_integration_docker.py @@ -295,6 +295,48 @@ def test_integration_session_create_with_single_port(isolate_cubbi_config): container_manager.close_session(session.id, kill=True) +@requires_docker +def test_integration_session_create_no_default_network( + isolate_cubbi_config, docker_test_network +): + """Test creating a session with no_default_network=True skips the default cubbi-network.""" + session = None + + try: + container_manager = isolate_cubbi_config["container_manager"] + + # Create a session with no_default_network and a custom network + session = container_manager.create_session( + image_name="goose", + session_name=f"cubbi-test-no-default-net-{uuid.uuid4().hex[:8]}", + mount_local=False, + networks=[docker_test_network], + no_default_network=True, + ) + + assert session is not None + assert session.status == "running" + + # Wait for container initialization to complete + init_success = wait_for_container_init(session.container_id) + assert init_success, "Container initialization timed out" + + # Verify network connections + client = docker.from_env() + container = client.containers.get(session.container_id) + container_networks = container.attrs["NetworkSettings"]["Networks"] + + # Container should be connected to the custom test network + assert docker_test_network in container_networks + + # Container should NOT be connected to cubbi-network + assert "cubbi-network" not in container_networks + + finally: + if session and session.container_id: + container_manager.close_session(session.id, kill=True) + + @requires_docker def test_integration_kill_vs_stop_speed(isolate_cubbi_config): """Test that kill is faster than stop for container termination."""