diff --git a/CONSTRUCT.md b/CONSTRUCT.md index 831af3d06..1c978d434 100644 --- a/CONSTRUCT.md +++ b/CONSTRUCT.md @@ -122,8 +122,10 @@ A list of virtual packages that must be satisfied at install time. Virtual packages must start with `__`. For example, `__osx>=11` or `__glibc>=2.24`. These specs are dry-run solved offline by the bundled `--conda-exe` binary. In SH installers, `__glibc>=x.y` and `__osx>=x.y` specs can be checked with -Bash only. In PKG installers, `__osx` specs can be checked natively without -the solver being involved as long as only `>=`, `<` or `,` are used. +Bash only. The detected version can be overriden with environment variables +`CONDA_OVERRIDE_GLIBC` and `CONDA_OVERRIDE_OSX`, respectively. In PKG +installers, `__osx` specs can be checked natively without the solver being +involved as long as only `>=`, `<` or `,` are used. ### `exclude` diff --git a/constructor/construct.py b/constructor/construct.py index f556f566f..210c157c5 100644 --- a/constructor/construct.py +++ b/constructor/construct.py @@ -88,8 +88,10 @@ packages must start with `__`. For example, `__osx>=11` or `__glibc>=2.24`. These specs are dry-run solved offline by the bundled `--conda-exe` binary. In SH installers, `__glibc>=x.y` and `__osx>=x.y` specs can be checked with -Bash only. In PKG installers, `__osx` specs can be checked natively without -the solver being involved as long as only `>=`, `<` or `,` are used. +Bash only. The detected version can be overriden with environment variables +`CONDA_OVERRIDE_GLIBC` and `CONDA_OVERRIDE_OSX`, respectively. In PKG +installers, `__osx` specs can be checked natively without the solver being +involved as long as only `>=`, `<` or `,` are used. '''), ('exclude', False, list, ''' diff --git a/constructor/header.sh b/constructor/header.sh index 923efe62a..fc7434435 100644 --- a/constructor/header.sh +++ b/constructor/header.sh @@ -23,44 +23,47 @@ fi #if osx and min_osx_version min_osx_version="__MIN_OSX_VERSION__" -system_osx_version=$(SYSTEM_VERSION_COMPAT=0 sw_vers -productVersion) +system_osx_version="${CONDA_OVERRIDE_OSX:-$(SYSTEM_VERSION_COMPAT=0 sw_vers -productVersion)}" # shellcheck disable=SC2183 disable=SC2046 int_min_osx_version="$(printf "%02d%02d%02d" $(echo "$min_osx_version" | sed 's/\./ /g'))" # shellcheck disable=SC2183 disable=SC2046 int_system_osx_version="$(printf "%02d%02d%02d" $(echo "$system_osx_version" | sed 's/\./ /g'))" -if [ "$int_system_osx_version" -lt "$int_min_osx_version" ]; then +if [ "$int_system_osx_version" -lt "$int_min_osx_version" ]; then echo "Installer requires macOS >=${min_osx_version}, but system has ${system_osx_version}." exit 1 fi #endif #if linux and min_glibc_version min_glibc_version="__MIN_GLIBC_VERSION__" -case "$(ldd --version 2>&1)" in - *musl*) - # musl ldd will report musl version; call libc.so directly - # see https://github.com/conda/constructor/issues/850#issuecomment-2343756454 - libc_so="$(find /lib /usr/local/lib /usr/lib -name 'libc.so.*' -print -quit 2>/dev/null)" - if [ -z "${libc_so}" ]; then - libc_so="$(strings /etc/ld.so.cache | grep '^/.*/libc\.so.*' | head -1)" - fi - if [ -z "${libc_so}" ]; then - echo "Warning: Couldn't find libc.so; won't be able to determine GLIBC version!" >&2 - echo "Override by setting CONDA_OVERRIDE_GLIBC" >&2 - system_glibc_version="${CONDA_OVERRIDE_GLIBC:-0.0}" - else - system_glibc_version=$("${libc_so}" --version | awk 'NR==1{ sub(/\.$/, ""); print $NF}') - fi - ;; - *) - # ldd reports glibc in the last field of the first line - system_glibc_version=$(ldd --version | awk 'NR==1{print $NF}') - ;; -esac +system_glibc_version="${CONDA_OVERRIDE_GLIBC:-}" +if [ "${system_glibc_version}" = "" ]; then + case "$(ldd --version 2>&1)" in + *musl*) + # musl ldd will report musl version; call libc.so directly + # see https://github.com/conda/constructor/issues/850#issuecomment-2343756454 + libc_so="$(find /lib /usr/local/lib /usr/lib -name 'libc.so.*' -print -quit 2>/dev/null)" + if [ -z "${libc_so}" ]; then + libc_so="$(strings /etc/ld.so.cache | grep '^/.*/libc\.so.*' | head -1)" + fi + if [ -z "${libc_so}" ]; then + echo "Warning: Couldn't find libc.so; won't be able to determine GLIBC version!" >&2 + echo "Override by setting CONDA_OVERRIDE_GLIBC" >&2 + system_glibc_version="0.0" + else + system_glibc_version=$("${libc_so}" --version | awk 'NR==1{ sub(/\.$/, ""); print $NF}') + fi + ;; + *) + # ldd reports glibc in the last field of the first line + system_glibc_version=$(ldd --version | awk 'NR==1{print $NF}') + ;; + esac +fi # shellcheck disable=SC2183 disable=SC2046 int_min_glibc_version="$(printf "%02d%02d%02d" $(echo "$min_glibc_version" | sed 's/\./ /g'))" # shellcheck disable=SC2183 disable=SC2046 int_system_glibc_version="$(printf "%02d%02d%02d" $(echo "$system_glibc_version" | sed 's/\./ /g'))" -if [ "$int_system_glibc_version" -lt "$int_min_glibc_version" ]; then +if [ "$int_system_glibc_version" -lt "$int_min_glibc_version" ]; then echo "Installer requires GLIBC >=${min_glibc_version}, but system has ${system_glibc_version}." exit 1 fi @@ -481,7 +484,7 @@ mkdir -p "$TMP" # but we haven't created $PREFIX/pkgs yet... give it a temp location # shellcheck disable=SC2050 if [ "__VIRTUAL_SPECS__" != "" ]; then - echo 'Checking virtual specs compatibility: __VIRTUAL_SPECS__' + echo "Checking virtual specs compatibility:" __VIRTUAL_SPECS__ CONDA_QUIET="$BATCH" \ CONDA_SOLVER="classic" \ CONDA_PKGS_DIRS="$(mktemp -d)" \ diff --git a/docs/source/construct-yaml.md b/docs/source/construct-yaml.md index 831af3d06..1c978d434 100644 --- a/docs/source/construct-yaml.md +++ b/docs/source/construct-yaml.md @@ -122,8 +122,10 @@ A list of virtual packages that must be satisfied at install time. Virtual packages must start with `__`. For example, `__osx>=11` or `__glibc>=2.24`. These specs are dry-run solved offline by the bundled `--conda-exe` binary. In SH installers, `__glibc>=x.y` and `__osx>=x.y` specs can be checked with -Bash only. In PKG installers, `__osx` specs can be checked natively without -the solver being involved as long as only `>=`, `<` or `,` are used. +Bash only. The detected version can be overriden with environment variables +`CONDA_OVERRIDE_GLIBC` and `CONDA_OVERRIDE_OSX`, respectively. In PKG +installers, `__osx` specs can be checked natively without the solver being +involved as long as only `>=`, `<` or `,` are used. ### `exclude` diff --git a/news/888-overrides-vpkgs b/news/888-overrides-vpkgs new file mode 100644 index 000000000..a74bd1325 --- /dev/null +++ b/news/888-overrides-vpkgs @@ -0,0 +1,19 @@ +### Enhancements + +* Allow `__glibc` and `__osx` overrides with `CONDA_OVERRIDE_GLIBC` and `CONDA_OVERRIDE_OSX` environment variables, respectively (`.sh` installers only). (#888) + +### Bug fixes + +* + +### Deprecations + +* + +### Docs + +* + +### Other + +* diff --git a/tests/test_examples.py b/tests/test_examples.py index 3e4405f1f..f16200f44 100644 --- a/tests/test_examples.py +++ b/tests/test_examples.py @@ -339,7 +339,11 @@ def _sort_by_extension(path): ) yield installer, install_dir if KEEP_ARTIFACTS_PATH: - shutil.move(str(installer), str(KEEP_ARTIFACTS_PATH)) + try: + shutil.move(str(installer), str(KEEP_ARTIFACTS_PATH)) + except shutil.Error: + # Some tests reuse the examples for different checks; ignore errors + pass @lru_cache(maxsize=None) @@ -844,6 +848,24 @@ def test_virtual_specs_ok(tmp_path, request): ) +@pytest.mark.skipif(sys.platform.startswith("win"), reason="Unix only") +def test_virtual_specs_override(tmp_path, request, monkeypatch): + input_path = _example_path("virtual_specs_failed") + for installer, install_dir in create_installer(input_path, tmp_path): + if installer.name.endswith(".pkg"): + continue + monkeypatch.setenv("CONDA_OVERRIDE_GLIBC", "20") + monkeypatch.setenv("CONDA_OVERRIDE_OSX", "30") + _run_installer( + input_path, + installer, + install_dir, + request=request, + check_subprocess=True, + uninstall=True, + ) + + @pytest.mark.xfail( CONDA_EXE == StandaloneExe.CONDA and CONDA_EXE_VERSION < Version("24.9.0"), reason="Pre-existing .condarc breaks installation",