diff --git a/neurodocker/cli/generate.py b/neurodocker/cli/generate.py index 26267923..d670d319 100644 --- a/neurodocker/cli/generate.py +++ b/neurodocker/cli/generate.py @@ -307,6 +307,8 @@ def _get_params_for_registered_templates() -> list[click.Parameter]: names_tmpls = list(registered_templates_items()) names_tmpls.sort(key=lambda r: r[0]) # sort by name for name, tmpl in names_tmpls: + if name.startswith("_"): # Templates starting with _ are private + continue hlp = _create_help_for_template(Template(tmpl)) param = OptionEatAll( [f"--{name.lower()}"], type=KeyValuePair(), multiple=True, help=hlp @@ -438,6 +440,18 @@ def _base_generate( `generate singularity`. The difference between those two is the renderer used. """ renderer_dict = _params_to_renderer_dict(ctx=ctx, pkg_manager=pkg_manager) + + # Make sure to add default instructions if they are available among the templates + if "_default" in registered_templates(): + # Add header to the instructions, after the base image. + renderer_dict["instructions"].insert(1, {"name": "_default", "kwds": {}}) + # Use default entrypoint if user did not specify one. + instruction_names = [instr["name"] for instr in renderer_dict["instructions"]] + if "entrypoint" not in instruction_names: + renderer_dict["instructions"].append( + {"name": "entrypoint", "kwds": {"args": ["/neurodocker/startup.sh"]}} + ) + r = renderer.from_dict(renderer_dict) # Print the instructions in JSON if that's what the user wants. diff --git a/neurodocker/cli/tests/test_cli.py b/neurodocker/cli/tests/test_cli.py index ba54339e..88dcf475 100644 --- a/neurodocker/cli/tests/test_cli.py +++ b/neurodocker/cli/tests/test_cli.py @@ -177,3 +177,43 @@ def test_render_registered(cmd: str, pkg_manager: str): assert result.exit_code == 0, result.output assert "jq-1.5/jq-linux64" in result.output assert "jq-1.6/jq-linux64" in result.output + + +# Test that we add the default header and default/custom entrypoints +@pytest.mark.parametrize("cmd", _cmds) +@pytest.mark.parametrize("pkg_manager", ["apt", "yum"]) +@pytest.mark.parametrize("entrypoint", ["default", "custom"]) +def test_default_header_and_entrypoint(cmd: str, pkg_manager: str, entrypoint: str): + runner = CliRunner() + cmd_ = [ + cmd, + "--base-image", + "debian:buster", + "--pkg-manager", + pkg_manager, + ] + if entrypoint == "custom": + cmd_.extend(["--entrypoint", "I", "decide"]) + result = runner.invoke(generate, cmd_) + assert result.exit_code == 0, result.output + + if cmd == "docker": + assert ( + 'ND_ENTRYPOINT="/neurodocker/startup.sh"\n' + 'RUN export ND_ENTRYPOINT="/neurodocker/startup.sh"' + ) in result.output + + if entrypoint == "default": + assert '\nENTRYPOINT ["/neurodocker/startup.sh"]\n' in result.output + else: + assert '\nENTRYPOINT ["I", "decide"]\n' in result.output + else: + assert ( + '\nexport ND_ENTRYPOINT="/neurodocker/startup.sh"\n\n' + '%post\nexport ND_ENTRYPOINT="/neurodocker/startup.sh"\n' + ) in result.output + + if entrypoint == "default": + assert "%runscript\n/neurodocker/startup.sh\n" in result.output + else: + assert "%runscript\nI decide\n" in result.output diff --git a/neurodocker/templates/_header.yaml b/neurodocker/templates/_default.yaml similarity index 69% rename from neurodocker/templates/_header.yaml rename to neurodocker/templates/_default.yaml index 6a09a4bb..98a401ff 100644 --- a/neurodocker/templates/_header.yaml +++ b/neurodocker/templates/_default.yaml @@ -4,7 +4,7 @@ # TODO: read this about locales http://jaredmarkell.com/docker-and-locales/ -name: _header +name: _default url: n/a # Not actually source, but we do not want to provide URLs. source: @@ -28,14 +28,14 @@ source: LC_ALL: en_US.UTF-8 ND_ENTRYPOINT: /neurodocker/startup.sh instructions: | - export ND_ENTRYPOINT="{{ _header._env['ND_ENTRYPOINT'] }}" - {{ _header.install_dependencies() }} - {%- if _header.pkg_manager == "apt" %} - sed -i -e 's/# {{ _header._env['LC_ALL'] }} UTF-8/{{ _header._env['LC_ALL'] }} UTF-8/' /etc/locale.gen + export ND_ENTRYPOINT="{{ self.env['ND_ENTRYPOINT'] }}" + {{ self.install_dependencies() }} + {%- if self.pkg_manager == "apt" %} + sed -i -e 's/# {{ self.env['LC_ALL'] }} UTF-8/{{ self.env['LC_ALL'] }} UTF-8/' /etc/locale.gen dpkg-reconfigure --frontend=noninteractive locales - update-locale LANG="{{ _header._env['LANG'] }}" - {%- elif _header.pkg_manager == "yum" %} - localedef -i {{ _header._env['LC_ALL'].split('.')[0] }} -f {{ _header._env['LC_ALL'].split('.')[1] }} {{ _header._env['LC_ALL'] }} + update-locale LANG="{{ self.env['LANG'] }}" + {%- elif self.pkg_manager == "yum" %} + localedef -i {{ self.env['LC_ALL'].split('.')[0] }} -f {{ self.env['LC_ALL'].split('.')[1] }} {{ self.env['LC_ALL'] }} {%- endif %} chmod 777 /opt && chmod a+s /opt mkdir -p /neurodocker