diff --git a/src/commands/faas/openfaas_container_manager.py b/src/commands/faas/openfaas_container_manager.py index c14515e..ffd086a 100644 --- a/src/commands/faas/openfaas_container_manager.py +++ b/src/commands/faas/openfaas_container_manager.py @@ -1,5 +1,3 @@ -import socket - import docker from common import Container, ContainerManager @@ -12,16 +10,6 @@ def __init__(self, openfaas_container_name) -> None: container = Container(openfaas_container_name, OPENFAAS_IMAGE_NAME) super().__init__(container) - def raise_on_port_in_use(self, ports: list): - for port in ports: - with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: - port_in_use = s.connect_ex(("localhost", port)) == 0 - - if port_in_use: - raise DockerError( - f"Port {port} is already in use. Please stop the service that is currently using this port." - ) - def start_container( self, function_version: str, diff --git a/src/commands/jupyter_notebook/jupyter_notebook_cli.py b/src/commands/jupyter_notebook/jupyter_notebook_cli.py index 31fccdf..0e18afc 100644 --- a/src/commands/jupyter_notebook/jupyter_notebook_cli.py +++ b/src/commands/jupyter_notebook/jupyter_notebook_cli.py @@ -1,12 +1,12 @@ from injector import inject -from common import Command, CommandGroup, Settings, StdoutSeverity +from common import Command, CommandGroup, Settings, StdoutSeverity, CommandOption from common.docker.exceptions import ( DockerContainerDuplicateError, DockerContainerNotFoundError, DockerError, ) - +from click import Path from .jupyter_notebook_container_manager import JupyterNotebookContainerManager @@ -27,14 +27,35 @@ class JupyterNotebookStart(Command): Start a Jupyter Notebook environment. $ das-cli jupyter-notebook start + +Start a Jupyter Notebook environment with a custom working directory. + +$ das-cli jupyter-notebook start --working-dir /path/to/working/directory """ + params = [ + CommandOption( + ["--working-dir", "-w"], + help="The working directory to bind to the Jupyter Notebook container.", + required=False, + default=None, + type=Path( + file_okay=False, + dir_okay=True, + exists=True, + writable=True, + readable=True, + path_type=str, + ), + ) + ] + @inject def __init__(self, settings: Settings) -> None: super().__init__() self._settings = settings - def run(self): + def run(self, working_dir: str | None = None): self._settings.raise_on_missing_file() self.stdout("Starting Jupyter Notebook...") @@ -49,6 +70,7 @@ def run(self): jupyter_notebook_service.start_container( jupyter_notebook_port, + working_dir, ) self.stdout( f"Jupyter Notebook started on port {jupyter_notebook_port}", @@ -119,8 +141,29 @@ class JupyterNotebookRestart(Command): Restart a Jupyter Notebook environment. $ das-cli jupyter-notebook restart + +Restart a Jupyter Notebook environment with a custom working directory. + +$ das-cli jupyter-notebook restart --working-dir /path/to/working/directory """ + params = [ + CommandOption( + ["--working-dir", "-w"], + help="The working directory to bind to the Jupyter Notebook container.", + required=False, + default=None, + type=Path( + file_okay=False, + dir_okay=True, + exists=True, + writable=True, + readable=True, + path_type=str, + ), + ) + ] + @inject def __init__( self, @@ -131,9 +174,9 @@ def __init__( self._jupyter_notebook_start = jupyter_notebook_start self._jupyter_notebook_stop = jupyter_notebook_stop - def run(self): + def run(self, working_dir: str | None = None): self._jupyter_notebook_stop.run() - self._jupyter_notebook_start.run() + self._jupyter_notebook_start.run(working_dir) class JupyterNotebookCli(CommandGroup): diff --git a/src/commands/jupyter_notebook/jupyter_notebook_container_manager.py b/src/commands/jupyter_notebook/jupyter_notebook_container_manager.py index aa77882..a4ca9ce 100644 --- a/src/commands/jupyter_notebook/jupyter_notebook_container_manager.py +++ b/src/commands/jupyter_notebook/jupyter_notebook_container_manager.py @@ -1,4 +1,5 @@ import docker +import os from common import Container, ContainerManager from common.docker.exceptions import DockerError @@ -18,9 +19,17 @@ def __init__(self, jupyter_container_name) -> None: def start_container( self, port: int, + working_dir: str | None = None, ): self.raise_running_container() + volumes = { + (working_dir or os.getcwd()): { + "bind": "/home/jovyan/work", + "mode": "rw" + } + } + try: container = self._start_container( restart_policy={ @@ -30,6 +39,7 @@ def start_container( ports={ "8888/tcp": port, }, + volumes=volumes, ) return container diff --git a/src/common/docker/container_manager.py b/src/common/docker/container_manager.py index 930c68c..9f8fcba 100644 --- a/src/common/docker/container_manager.py +++ b/src/common/docker/container_manager.py @@ -2,6 +2,7 @@ import time from typing import Any, AnyStr, Union +import socket import docker import docker.errors @@ -76,6 +77,17 @@ def _start_container(self, **kwargs) -> Any: except docker.errors.APIError as e: raise DockerError(e.explanation) + + def raise_on_port_in_use(self, ports: list): + for port in ports: + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + port_in_use = s.connect_ex(("localhost", port)) == 0 + + if port_in_use: + raise DockerError( + f"Port {port} is already in use. Please stop the service that is currently using this port." + ) + def raise_running_container(self): if self.is_running(): raise DockerContainerDuplicateError()