Skip to content

Commit

Permalink
Support create profile with image specified (#181)
Browse files Browse the repository at this point in the history
When creating a new profile, thin commit support to specify the image of the profile rather than create and edit after.
This will allow you to change the default image and start from another image.
  • Loading branch information
unkcpz committed Jul 4, 2023
1 parent 052f354 commit b6b5643
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 9 deletions.
11 changes: 9 additions & 2 deletions aiidalab_launch/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from .application_state import ApplicationState
from .core import LOGGER
from .instance import AiidaLabInstance
from .profile import DEFAULT_PORT, Profile
from .profile import DEFAULT_IMAGE, DEFAULT_PORT, Profile
from .util import confirm_with_value, get_latest_version, spinner, webbrowser_available
from .version import __version__

Expand Down Expand Up @@ -187,9 +187,14 @@ def show_profile(app_state, profile):
type=click.Path(file_okay=False),
help="Specify the path to be mounted as home directory.",
)
@click.option(
"--image",
type=click.STRING,
help="Specify the image to be used for the profile.",
)
@pass_app_state
@click.pass_context
def add_profile(ctx, app_state, port, home_mount, profile):
def add_profile(ctx, app_state, port, home_mount, image, profile):
"""Add a new AiiDAlab profile to the configuration."""
try:
app_state.config.get_profile(profile)
Expand All @@ -201,11 +206,13 @@ def add_profile(ctx, app_state, port, home_mount, profile):
# Determine next available port or use the one provided by the user.
configured_ports = [prof.port for prof in app_state.config.profiles if prof.port]
port = port or (max(configured_ports, default=-1) + 1) or DEFAULT_PORT
image = image or DEFAULT_IMAGE

try:
new_profile = Profile(
name=profile,
port=port,
image=image,
home_mount=home_mount,
)
except ValueError as error: # invalid profile name
Expand Down
8 changes: 4 additions & 4 deletions aiidalab_launch/profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def _default_port() -> int: # explicit function required to enable test patchin
return DEFAULT_PORT


_DEFAULT_IMAGE = "aiidalab/full-stack:latest"
DEFAULT_IMAGE = "aiidalab/full-stack:latest"


def _valid_volume_name(source: str) -> None:
Expand Down Expand Up @@ -67,7 +67,7 @@ class Profile:
port: int | None = field(default_factory=_default_port)
default_apps: list[str] = field(default_factory=lambda: [])
system_user: str = "jovyan"
image: str = _DEFAULT_IMAGE
image: str = DEFAULT_IMAGE
home_mount: str | None = None
extra_mounts: set[str] = field(default_factory=set)

Expand Down Expand Up @@ -159,8 +159,8 @@ def from_container(cls, container: Container) -> Profile:
system_user = get_docker_env(container, "SYSTEM_USER")

image_tag = (
_DEFAULT_IMAGE
if _DEFAULT_IMAGE in container.image.tags
DEFAULT_IMAGE
if DEFAULT_IMAGE in container.image.tags
else container.image.tags[0]
)

Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ classifiers =
[options]
packages = find:
install_requires =
click==8.0.3
click==8.1
click-spinner==0.1.10
docker==5.0.3
packaging==21.3
Expand Down
4 changes: 2 additions & 2 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,15 @@ def _select_default_image(monkeypatch_session, pytestconfig):
_default_image = pytestconfig.getoption("default_image")
if _default_image is not None:
monkeypatch_session.setattr(
aiidalab_launch.profile, "_DEFAULT_IMAGE", _default_image
aiidalab_launch.profile, "DEFAULT_IMAGE", _default_image
)
yield None


@pytest.fixture(scope="session", autouse=True)
def _pull_docker_image(docker_client):
try:
docker_client.images.pull(aiidalab_launch.profile._DEFAULT_IMAGE)
docker_client.images.pull(aiidalab_launch.profile.DEFAULT_IMAGE)
except docker.errors.APIError:
pytest.skip("unable to pull docker image")

Expand Down
25 changes: 25 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,31 @@ def test_add_profile_invalid_name():
assert "Invalid profile name 'new_profile'." in result.output


def test_add_profile_with_options():
runner: CliRunner = CliRunner()

# Add new-profile with options
result: Result = runner.invoke(
cli.cli,
[
"profiles",
"add",
"new-profile",
"--port",
"8900",
"--home-mount",
"/tmp/aiidalab-home",
"--image",
"aiidalab/full-stack:edge",
],
input="n\n",
)
assert result.exit_code == 0

result: Result = runner.invoke(cli.cli, ["profiles", "show", "new-profile"])
assert "aiidalab/full-stack:edge" in result.output


@pytest.mark.slow
@pytest.mark.trylast
@pytest.mark.usefixtures("started_instance")
Expand Down

0 comments on commit b6b5643

Please sign in to comment.