From c75a7f87f3a0738722443ddf0096c5a00eb185bb Mon Sep 17 00:00:00 2001 From: Daniel Hollas Date: Fri, 8 Dec 2023 10:27:50 +0000 Subject: [PATCH 01/11] Support Podman --- README.md | 15 +++++++++++++-- aiidalab_launch/profile.py | 2 +- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 68a24af..dcc2f50 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ AiiDAlab Launch makes it easy to run AiiDAlab on your own workstation or laptop. To use AiiDAlab launch you will have to -1. [Install Docker on your workstation or laptop.](https://docs.docker.com/get-docker/) +1. [Install Docker on your workstation or laptop.](https://docs.docker.com/get-docker/) (you can also use Podman, [see below](README.md#using-podman)) 2. Install AiiDAlab launch with [pipx](https://pypa.github.io/pipx/installation/) (**recommended**): ```console @@ -70,6 +70,17 @@ Please see [here](ssh-forward.md) for instructions on how to run AiiDAlab on a r This package follows the Python compatibility and deprecation schedule specified by [NEP 29](https://numpy.org/neps/nep-0029-deprecation_policy.html). +### Using Podman instead of Docker + +You should be able to use Podman as as a drop-in replacement for Docker, with just a little extra setup. The following was tested on Fedora 39 which comes with Podman pre-installed. + +```console +systemctl --user enable podman.socket +systemctl --user start podman.socket +systemctl --user status podman.socket +export DOCKER_HOST=unix:///run/user/$UID/podman/podman.sock +``` + ## Development ### Setting up a development environment @@ -162,7 +173,7 @@ SOFTWARE. ## Acknowledgements This work is supported by the -[MARVEL National Centre for Competency in Research]() funded by the [Swiss National Science Foundation](), +[MARVEL National Centre for Competency in Research]() funded by the [Swiss National Science Foundation](), the MARKETPLACE project funded by [Horizon 2020](https://ec.europa.eu/programmes/horizon2020/) under the H2020-NMBP-25-2017 call (Grant No. 760173), as well as by the [MaX European Centre of Excellence]() funded by the Horizon 2020 EINFRA-5 program, diff --git a/aiidalab_launch/profile.py b/aiidalab_launch/profile.py index b555258..667d5a0 100644 --- a/aiidalab_launch/profile.py +++ b/aiidalab_launch/profile.py @@ -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 = "docker.io/aiidalab/full-stack:latest" def _valid_volume_name(source: str) -> None: From 8b41ba490dcff06034e60fd676bfd51345fae12c Mon Sep 17 00:00:00 2001 From: Daniel Hollas Date: Fri, 22 Dec 2023 17:26:10 +0100 Subject: [PATCH 02/11] Try specifying a concrete port in conftest.p --- tests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index 93c1cc4..226465d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -78,7 +78,7 @@ def _pull_docker_image(docker_client): # Avoid interfering with used ports on the host system. @pytest.fixture(scope="session", autouse=True) def _default_port(monkeypatch_session): - monkeypatch_session.setattr(aiidalab_launch.profile, "DEFAULT_PORT", None) + monkeypatch_session.setattr(aiidalab_launch.profile, "DEFAULT_PORT", 7777) yield None From a4bc1f85ca8ab88c61de8276d45e2e3cabf6dc4f Mon Sep 17 00:00:00 2001 From: Daniel Hollas Date: Fri, 22 Dec 2023 17:27:14 +0100 Subject: [PATCH 03/11] Add debug print --- .github/workflows/ci.yml | 4 ++-- aiidalab_launch/profile.py | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7d2082a..0f2f49a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,7 +34,7 @@ jobs: python-version: ['3.8', '3.9', '3.10', '3.11'] default-image: - '' # use the application default - - aiidalab/aiidalab-docker-stack:latest + - aiidalab/aiidalab-docker-stack:latest # This is the old stack steps: @@ -55,7 +55,7 @@ jobs: - name: Run tests run: | - pytest -sv --slow --default-image=${{ matrix.default-image }} + pytest -svv --slow --default-image=${{ matrix.default-image }} coverage xml - name: Upload coverage to Codecov diff --git a/aiidalab_launch/profile.py b/aiidalab_launch/profile.py index 667d5a0..4672f60 100644 --- a/aiidalab_launch/profile.py +++ b/aiidalab_launch/profile.py @@ -49,8 +49,8 @@ def _get_configured_host_port(container: Container) -> int | None: try: host_config = container.attrs["HostConfig"] return int(host_config["PortBindings"]["8888/tcp"][0]["HostPort"]) or None - except (KeyError, IndexError, ValueError): - pass + except (KeyError, IndexError, ValueError) as e: + raise return None @@ -158,11 +158,13 @@ def from_container(cls, container: Container) -> Profile: system_user = get_docker_env(container, "SYSTEM_USER") + print(container.image.tags) image_tag = ( DEFAULT_IMAGE if DEFAULT_IMAGE in container.image.tags else container.image.tags[0] ) + print(f"{image_tag!r}") extra_destinations: list[PurePosixPath] = [ PurePosixPath(mount["Destination"]) @@ -178,6 +180,8 @@ def from_container(cls, container: Container) -> Profile: else: extra_mounts.add(":".join([str(src), str(dst), "rw"])) + print(_get_configured_host_port(container)) + return Profile( name=profile_name, port=_get_configured_host_port(container), From aed59166bbaea57acb45bddc7dcb0781cb11d7ce Mon Sep 17 00:00:00 2001 From: Daniel Hollas Date: Mon, 22 Jan 2024 04:58:41 +0000 Subject: [PATCH 04/11] Appease pre-commit --- aiidalab_launch/profile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aiidalab_launch/profile.py b/aiidalab_launch/profile.py index 4672f60..8b23f64 100644 --- a/aiidalab_launch/profile.py +++ b/aiidalab_launch/profile.py @@ -49,7 +49,7 @@ def _get_configured_host_port(container: Container) -> int | None: try: host_config = container.attrs["HostConfig"] return int(host_config["PortBindings"]["8888/tcp"][0]["HostPort"]) or None - except (KeyError, IndexError, ValueError) as e: + except (KeyError, IndexError, ValueError): raise return None From 3ea0a88ea217213353cf02db680eeac493e24ed6 Mon Sep 17 00:00:00 2001 From: Daniel Hollas Date: Mon, 22 Jan 2024 21:55:02 +0000 Subject: [PATCH 05/11] Comment out problematic code --- aiidalab_launch/profile.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/aiidalab_launch/profile.py b/aiidalab_launch/profile.py index 8b23f64..ff7a38d 100644 --- a/aiidalab_launch/profile.py +++ b/aiidalab_launch/profile.py @@ -86,6 +86,7 @@ def __post_init__(self): _valid_volume_name(self.home_mount) + """ This looks like it's not needed? # Normalize extra mount mode to be "rw" by default # so that we match Docker default but are explicit. for extra_mount in self.extra_mounts: @@ -93,6 +94,7 @@ def __post_init__(self): if len(extra_mount.split(":")) == 2: self.extra_mounts.remove(extra_mount) self.extra_mounts.add(f"{extra_mount}:rw") + """ if ( self.image.split(":")[0] == "aiidalab/full-stack" From ab3f94bf4f030f3c4220412723ef722027b8db38 Mon Sep 17 00:00:00 2001 From: Daniel Hollas Date: Mon, 22 Jan 2024 22:08:30 +0000 Subject: [PATCH 06/11] Rollback DEFAULT_IMAGE --- aiidalab_launch/profile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aiidalab_launch/profile.py b/aiidalab_launch/profile.py index ff7a38d..5b6dc0b 100644 --- a/aiidalab_launch/profile.py +++ b/aiidalab_launch/profile.py @@ -31,7 +31,7 @@ def _default_port() -> int: # explicit function required to enable test patchin return DEFAULT_PORT -DEFAULT_IMAGE = "docker.io/aiidalab/full-stack:latest" +DEFAULT_IMAGE = "aiidalab/full-stack:latest" def _valid_volume_name(source: str) -> None: From 3ea81f1df155ea38a64c49cce780f7803315b862 Mon Sep 17 00:00:00 2001 From: Daniel Hollas Date: Mon, 22 Jan 2024 22:14:31 +0000 Subject: [PATCH 07/11] Copy the set during iteration --- aiidalab_launch/profile.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/aiidalab_launch/profile.py b/aiidalab_launch/profile.py index 5b6dc0b..b1f5f49 100644 --- a/aiidalab_launch/profile.py +++ b/aiidalab_launch/profile.py @@ -86,15 +86,13 @@ def __post_init__(self): _valid_volume_name(self.home_mount) - """ This looks like it's not needed? # Normalize extra mount mode to be "rw" by default # so that we match Docker default but are explicit. - for extra_mount in self.extra_mounts: - self.parse_extra_mount(extra_mount) + for extra_mount in self.extra_mounts.copy(): + _, _, _ = self.parse_extra_mount(extra_mount) if len(extra_mount.split(":")) == 2: self.extra_mounts.remove(extra_mount) self.extra_mounts.add(f"{extra_mount}:rw") - """ if ( self.image.split(":")[0] == "aiidalab/full-stack" From aa626e014dda064c54b55aa32ab74fd55091fd17 Mon Sep 17 00:00:00 2001 From: Daniel Hollas Date: Wed, 24 Jan 2024 00:25:22 +0000 Subject: [PATCH 08/11] Fold pre-commit into dev extras --- README.md | 2 +- setup.cfg | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index dcc2f50..52f215e 100644 --- a/README.md +++ b/README.md @@ -85,7 +85,7 @@ export DOCKER_HOST=unix:///run/user/$UID/podman/podman.sock ### Setting up a development environment -To develop this package, first clone it and then install the development dependencies with `pip install -e '.[dev,pre_commit]'`. +To develop this package, first clone it and then install the development dependencies with `pip install -e '.[dev]'`. We recommend to install the [pre-commit](https://pre-commit.com/) hooks to avoid unnecessary iterations when pushing new changes. To install the pre-commit hooks, switch into the repository root directly and execute: ```console diff --git a/setup.cfg b/setup.cfg index be79565..eee41e1 100644 --- a/setup.cfg +++ b/setup.cfg @@ -39,7 +39,6 @@ console_scripts = dev = bumpver==2023.1129 dunamai==1.19.0 -pre_commit = pre-commit==3.5.0 tests = pytest~=7.4.3 From 08a4675b396ca466dd1daa80f958c970ca366f1d Mon Sep 17 00:00:00 2001 From: Daniel Hollas Date: Wed, 24 Jan 2024 01:22:25 +0000 Subject: [PATCH 09/11] Add docker.io prefix again --- aiidalab_launch/profile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aiidalab_launch/profile.py b/aiidalab_launch/profile.py index b1f5f49..de9d34f 100644 --- a/aiidalab_launch/profile.py +++ b/aiidalab_launch/profile.py @@ -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 = "docker.io/aiidalab/full-stack:latest" def _valid_volume_name(source: str) -> None: From 5d58dafc878900fa5a2c39d2aa95abb51629a641 Mon Sep 17 00:00:00 2001 From: Daniel Hollas Date: Sun, 4 Feb 2024 04:42:37 +0000 Subject: [PATCH 10/11] Workround for Docker stripping docker.io --- aiidalab_launch/profile.py | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/aiidalab_launch/profile.py b/aiidalab_launch/profile.py index df41cbd..0b20bed 100644 --- a/aiidalab_launch/profile.py +++ b/aiidalab_launch/profile.py @@ -31,7 +31,9 @@ def _default_port() -> int: # explicit function required to enable test patchin return DEFAULT_PORT -DEFAULT_IMAGE = "docker.io/aiidalab/full-stack:latest" +DEFAULT_REGISTRY = "docker.io" +DEFAULT_IMAGE_PATH = "aiidalab/full-stack:latest" +DEFAULT_IMAGE = f"{DEFAULT_REGISTRY}/{DEFAULT_IMAGE_PATH}" def _valid_volume_name(source: str) -> None: @@ -50,7 +52,7 @@ def _get_configured_host_port(container: Container) -> int | None: host_config = container.attrs["HostConfig"] return int(host_config["PortBindings"]["8888/tcp"][0]["HostPort"]) or None except (KeyError, IndexError, ValueError): - raise + pass return None @@ -158,13 +160,14 @@ def from_container(cls, container: Container) -> Profile: system_user = get_docker_env(container, "SYSTEM_USER") - print(container.image.tags) - image_tag = ( - DEFAULT_IMAGE - if DEFAULT_IMAGE in container.image.tags - else container.image.tags[0] - ) - print(f"{image_tag!r}") + if DEFAULT_IMAGE in container.image.tags: + image_tag = DEFAULT_IMAGE + # Docker seems to strip `docker.io` from the image name + # so we add it back manually. + elif DEFAULT_IMAGE_PATH in container.image.tags: + image_tag = f"{DEFAULT_REGISTRY}/{DEFAULT_IMAGE_PATH}" + else: + image_tag = container.image.tags[0] extra_destinations: list[PurePosixPath] = [ PurePosixPath(mount["Destination"]) @@ -180,8 +183,6 @@ def from_container(cls, container: Container) -> Profile: else: extra_mounts.add(":".join([str(src), str(dst), "rw"])) - print(_get_configured_host_port(container)) - return Profile( name=profile_name, port=_get_configured_host_port(container), From fb3f9fea9eefb9af58e968eed3a0507156b7defe Mon Sep 17 00:00:00 2001 From: Daniel Hollas Date: Sun, 4 Feb 2024 04:53:21 +0000 Subject: [PATCH 11/11] Decrease debug output --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 130c087..86d3fd2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,7 +41,7 @@ jobs: - name: Run tests run: | - pytest -svv --slow --default-image=${{ matrix.default-image }} + pytest -sv --slow --default-image=${{ matrix.default-image }} coverage xml - name: Upload coverage to Codecov