diff --git a/changelog.d/20231009_185242_michael.hanke_noexe.md b/changelog.d/20231009_185242_michael.hanke_noexe.md new file mode 100644 index 00000000..341a40ea --- /dev/null +++ b/changelog.d/20231009_185242_michael.hanke_noexe.md @@ -0,0 +1,9 @@ +### 🚀 Enhancements and New Features + +- A new placeholder `{python}` is supported by container execution. + It resolves to the Python interpreter executable running DataLad + on container execution. This solves portability issues with the + previous approach of hard-coding a command name on container + configuration. + Fixes https://github.com/datalad/datalad-container/issues/226 via + https://github.com/datalad/datalad-container/pull/227 (by @mih) diff --git a/datalad_container/containers_add.py b/datalad_container/containers_add.py index 8a5efcdd..3840e05a 100644 --- a/datalad_container/containers_add.py +++ b/datalad_container/containers_add.py @@ -65,7 +65,8 @@ def _guess_call_fmt(ds, name, url): elif url.startswith('shub://') or url.startswith('docker://'): return 'singularity exec {img} {cmd}' elif url.startswith('dhub://'): - return op.basename(sys.executable) + ' -m datalad_container.adapters.docker run {img} {cmd}' + # {python} is replaced with sys.executable on *execute* + return '{python} -m datalad_container.adapters.docker run {img} {cmd}' def _ensure_datalad_remote(repo): @@ -143,6 +144,9 @@ class ContainersAdd(Interface): replaced with the desired command. Additional placeholders: '{img_dspath}' is relative path to the dataset containing the image, '{img_dirpath}' is the directory containing the '{img}'. + '{python}' expands to the path of the Python executable that is + running the respective DataLad session, for example a + 'datalad containers-run' command. """, metavar="FORMAT", constraints=EnsureStr() | EnsureNone(), diff --git a/datalad_container/containers_run.py b/datalad_container/containers_run.py index d99e0d02..d7b4e796 100644 --- a/datalad_container/containers_run.py +++ b/datalad_container/containers_run.py @@ -4,6 +4,7 @@ import logging import os.path as op +import sys from datalad.interface.base import Interface from datalad.interface.base import build_doc @@ -115,6 +116,10 @@ def __call__(cmd, container_name=None, dataset=None, 'Convert it to a plain string.'.format(callspec)) try: cmd_kwargs = dict( + # point to the python installation that runs *this* code + # we know that it would have things like the docker + # adaptor installed with this extension package + python=sys.executable, img=image_path, cmd=cmd, img_dspath=image_dspath,