diff --git a/neurodocker/cli/tests/test_cli.py b/neurodocker/cli/tests/test_cli.py index ba54339e..fe3b0894 100644 --- a/neurodocker/cli/tests/test_cli.py +++ b/neurodocker/cli/tests/test_cli.py @@ -19,7 +19,7 @@ def test_fail_on_empty_args(cmd: str): @pytest.mark.parametrize("cmd", _cmds) -@pytest.mark.parametrize("pkg_manager", ["apt", "yum"]) +@pytest.mark.parametrize("pkg_manager", ["apt", "portage", "yum"]) def test_fail_on_no_base(cmd: str, pkg_manager: str): runner = CliRunner() result = runner.invoke(generate, [cmd, "--pkg-manager", pkg_manager]) @@ -34,7 +34,7 @@ def test_fail_on_no_pkg_manager(cmd: str): @pytest.mark.parametrize("cmd", _cmds) -@pytest.mark.parametrize("pkg_manager", ["apt", "yum"]) +@pytest.mark.parametrize("pkg_manager", ["apt", "portage", "yum"]) def test_minimal_args(cmd: str, pkg_manager: str): runner = CliRunner() result = runner.invoke( @@ -107,7 +107,7 @@ def test_optioneatall_type_issue_498(): @pytest.mark.parametrize("cmd", _cmds) -@pytest.mark.parametrize("pkg_manager", ["apt", "yum"]) +@pytest.mark.parametrize("pkg_manager", ["apt", "portage", "yum"]) def test_all_args(cmd: str, pkg_manager: str): runner = CliRunner() result = runner.invoke( @@ -156,7 +156,7 @@ def test_all_args(cmd: str, pkg_manager: str): # is what registers the templates. Using the `docker` function # (`reproenv generate docker`) directly does not fire `generate`. @pytest.mark.parametrize("cmd", _cmds) -@pytest.mark.parametrize("pkg_manager", ["apt", "yum"]) +@pytest.mark.parametrize("pkg_manager", ["apt", "portage", "yum"]) def test_render_registered(cmd: str, pkg_manager: str): template_path = Path(__file__).parent runner = CliRunner(env={"REPROENV_TEMPLATE_PATH": str(template_path)}) diff --git a/neurodocker/reproenv/renderers.py b/neurodocker/reproenv/renderers.py index 2df1a4c5..89a58679 100644 --- a/neurodocker/reproenv/renderers.py +++ b/neurodocker/reproenv/renderers.py @@ -753,6 +753,8 @@ def _indent_run_instruction(string: str, indent=4) -> str: def _install(pkgs: list[str], pkg_manager: str, opts: str = None) -> str: if pkg_manager == "apt": return _apt_install(pkgs, opts) + elif pkg_manager == "portage": + return _portage_install(pkgs, opts) elif pkg_manager == "yum": return _yum_install(pkgs, opts) # TODO: add debs here? @@ -802,6 +804,25 @@ def install_one(url: str): return s +def _portage_install(pkgs: list[str], opts: str = None, sort=True) -> str: + """Return command to install packages with `portage` (Gentoo). + + `opts` are options passed to `emerge`. + Default is "--autounmask-continue". + """ + pkgs = sorted(pkgs) if sort else pkgs + opts = "--autounmask-continue" if opts is None else opts + + s = """\ +emerge {opts} \\ + {pkgs} +rm -rf /var/tmp/portage/* +""".format( + opts=opts, pkgs=" \\\n ".join(pkgs) + ) + return s.strip() + + def _yum_install(pkgs: list[str], opts: str = None, sort=True) -> str: """Return command to install packages with `yum` (CentOS, Fedora). diff --git a/neurodocker/reproenv/schemas/renderer.json b/neurodocker/reproenv/schemas/renderer.json index 169fa1f9..6597d7ae 100644 --- a/neurodocker/reproenv/schemas/renderer.json +++ b/neurodocker/reproenv/schemas/renderer.json @@ -11,10 +11,12 @@ "type": "string", "enum": [ "apt", + "portage", "yum" ], "examples": [ "apt", + "portage", "yum" ] }, diff --git a/neurodocker/reproenv/types.py b/neurodocker/reproenv/types.py index 17f3c0ab..6cab0f83 100644 --- a/neurodocker/reproenv/types.py +++ b/neurodocker/reproenv/types.py @@ -32,6 +32,7 @@ class _InstallationDependenciesType(TypedDict, total=False): apt: list[str] debs: list[str] + portage: list[str] yum: list[str] diff --git a/neurodocker/templates/gentoo-portage/make.conf b/neurodocker/templates/gentoo-portage/make.conf new file mode 100644 index 00000000..5d2eded2 --- /dev/null +++ b/neurodocker/templates/gentoo-portage/make.conf @@ -0,0 +1,21 @@ +### This file contains system-wide build variables, including Gentoo variables such as USE, which enable/disable optional package features. + +COMMON_FLAGS="-O2 -pipe -march=native" +# Comment the following out on systems with less than 8 threads +MAKEOPTS="--jobs 8 --load-average 9" +CFLAGS="${COMMON_FLAGS}" +CXXFLAGS="${COMMON_FLAGS}" +FCFLAGS="${COMMON_FLAGS}" +FFLAGS="${COMMON_FLAGS}" + +# NOTE: This stage was built with the bindist Use flag enabled + +# This sets the language of build output to English. +# Please keep this setting intact when reporting bugs. +LC_MESSAGES=C + +USE="${USE} science" +ACCEPT_LICENSE="*" + +# Needed in the container environment +#FEATURES="-ipc-sandbox -network-sandbox -pid-sandbox" diff --git a/neurodocker/templates/gentoo-portage/package.accept_keywords/gen b/neurodocker/templates/gentoo-portage/package.accept_keywords/gen new file mode 100644 index 00000000..467373bd --- /dev/null +++ b/neurodocker/templates/gentoo-portage/package.accept_keywords/gen @@ -0,0 +1,2 @@ +### This is needed because ::science packages are generally not marked as stable +*/* ~amd64 diff --git a/neurodocker/templates/gentoo-portage/package.mask/bugs b/neurodocker/templates/gentoo-portage/package.mask/bugs new file mode 100644 index 00000000..1e593ebc --- /dev/null +++ b/neurodocker/templates/gentoo-portage/package.mask/bugs @@ -0,0 +1,2 @@ +### This is empty, thankfully. +### If we find bugs in some version of some package we can blacklist the package, version, or feature that causes it here. diff --git a/neurodocker/templates/gentoo-portage/repos.conf/gentoo b/neurodocker/templates/gentoo-portage/repos.conf/gentoo new file mode 100644 index 00000000..5d53ee40 --- /dev/null +++ b/neurodocker/templates/gentoo-portage/repos.conf/gentoo @@ -0,0 +1,6 @@ +[gentoo] +location = /var/db/repos/gentoo +# We sync manually, but we need sync-uri to be written down somewhere to do so +sync-type = git +sync-uri = https://anongit.gentoo.org/git/repo/gentoo.git +sync-git-verify-commit-signature = yes diff --git a/neurodocker/templates/gentoo-portage/repos.conf/science b/neurodocker/templates/gentoo-portage/repos.conf/science new file mode 100644 index 00000000..4a03df2a --- /dev/null +++ b/neurodocker/templates/gentoo-portage/repos.conf/science @@ -0,0 +1,6 @@ +[science] +location = /var/db/repos/science +# We sync manually, but we need sync-uri to be written down somewhere to do so +sync-type = git +sync-uri = https://anongit.gentoo.org/git/proj/sci.git +priority = 7777 diff --git a/neurodocker/templates/gentoo.yaml b/neurodocker/templates/gentoo.yaml index 3c29b6d0..f72ed953 100644 --- a/neurodocker/templates/gentoo.yaml +++ b/neurodocker/templates/gentoo.yaml @@ -4,6 +4,11 @@ name: gentoo url: https://www.gentoo.org/ binaries: + # ATM template jsonschema demands having urls and instructions. + # In the future we might use urls to point to git repositories + # which are currently under gentoo-portage/ config files. + urls: + something: not-used instructions: | FROM docker.io/gentoo/portage:20240324 as portage FROM docker.io/gentoo/stage3:20240318 @@ -17,7 +22,7 @@ binaries: ARG FEATURES="-ipc-sandbox -network-sandbox -pid-sandbox" # This will be bound, and contents available outside of container RUN mkdir /outputs - COPY .gentoo/portage/ /etc/portage/ + COPY gentoo-portage/ /etc/portage/ # Moving gentoo repo from default rsync to git RUN rm /var/db/repos/gentoo -rf # Cloning manually to prevent vdb update, pinning state via git @@ -46,4 +51,3 @@ binaries: ### Emerge cool stuff here ### Autounmask-continue enables all features on dependencies which the top level packages require ### By default this needs user confirmation which would interrupt the build. - RUN emerge --autounmask-continue afni fsl