Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ignore .condarc files during installation #863

Merged
merged 11 commits into from
Nov 8, 2024
6 changes: 3 additions & 3 deletions constructor/header.sh
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,7 @@ if [ "__VIRTUAL_SPECS__" != "" ]; then
CONDA_QUIET="$BATCH" \
CONDA_SOLVER="classic" \
CONDA_PKGS_DIRS="$(mktemp -d)" \
"$CONDA_EXEC" create --dry-run --prefix "$PREFIX/envs/_virtual_specs_checks" --offline __VIRTUAL_SPECS__
"$CONDA_EXEC" create --dry-run --prefix "$PREFIX/envs/_virtual_specs_checks" --offline __VIRTUAL_SPECS__ __NO_RCS_ARG__
fi

# Create $PREFIX/.nonadmin if the installation didn't require superuser permissions
Expand Down Expand Up @@ -561,7 +561,7 @@ CONDA_EXTRA_SAFETY_CHECKS=no \
CONDA_CHANNELS="__CHANNELS__" \
CONDA_PKGS_DIRS="$PREFIX/pkgs" \
CONDA_QUIET="$BATCH" \
"$CONDA_EXEC" install --offline --file "$PREFIX/pkgs/env.txt" -yp "$PREFIX" $shortcuts || exit 1
"$CONDA_EXEC" install --offline --file "$PREFIX/pkgs/env.txt" -yp "$PREFIX" $shortcuts __NO_RCS_ARG__ || exit 1
rm -f "$PREFIX/pkgs/env.txt"

#The templating doesn't support nested if statements
Expand Down Expand Up @@ -606,7 +606,7 @@ for env_pkgs in "${PREFIX}"/pkgs/envs/*/; do
CONDA_CHANNELS="$env_channels" \
CONDA_PKGS_DIRS="$PREFIX/pkgs" \
CONDA_QUIET="$BATCH" \
"$CONDA_EXEC" install --offline --file "${env_pkgs}env.txt" -yp "$PREFIX/envs/$env_name" $env_shortcuts || exit 1
"$CONDA_EXEC" install --offline --file "${env_pkgs}env.txt" -yp "$PREFIX/envs/$env_name" $env_shortcuts __NO_RCS_ARG__ || exit 1
rm -f "${env_pkgs}env.txt"
done
#endif
Expand Down
9 changes: 9 additions & 0 deletions constructor/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,15 @@ def main_build(dir_path, output_dir='.', platform=cc_platform,
)
)

# Add --no-rc option to CONDA_EXE command so that existing
# .condarc files do not pollute the installation process.
if exe_type == StandaloneExe.CONDA and exe_version and exe_version >= Version("24.9.0"):
info["_ignore_condarcs_arg"] = "--no-rc"
elif exe_type == StandaloneExe.MAMBA:
info["_ignore_condarcs_arg"] = "--no-rc"
else:
info["_ignore_condarcs_arg"] = ""

if 'pkg' in itypes:
if (domains := info.get('pkg_domains')) is not None:
domains = {key: str(val).lower() for key, val in domains.items()}
Expand Down
4 changes: 2 additions & 2 deletions constructor/nsis/main.nsi.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -1263,7 +1263,7 @@ Section "Install"
System::Call 'kernel32::SetEnvironmentVariable(t,t)i("CONDA_SOLVER", "classic").r0'
SetDetailsPrint TextOnly
${Print} "Checking virtual specs compatibility: @VIRTUAL_SPECS_DEBUG@"
push '"$INSTDIR\_conda.exe" create --dry-run --prefix "$INSTDIR\envs\_virtual_specs_checks" --offline @VIRTUAL_SPECS@'
push '"$INSTDIR\_conda.exe" create --dry-run --prefix "$INSTDIR\envs\_virtual_specs_checks" --offline @VIRTUAL_SPECS@ @NO_RCS_ARG@'
push 'Failed to check virtual specs: @VIRTUAL_SPECS_DEBUG@'
push 'WithLog'
call AbortRetryNSExecWait
Expand Down Expand Up @@ -1325,7 +1325,7 @@ Section "Install"

${If} $Ana_ClearPkgCache_State = ${BST_CHECKED}
${Print} "Clearing package cache..."
push '"$INSTDIR\_conda.exe" clean --all --force-pkgs-dirs --yes'
push '"$INSTDIR\_conda.exe" clean --all --force-pkgs-dirs --yes @NO_RCS_ARG@'
push 'Failed to clear package cache'
push 'WithLog'
call AbortRetryNSExecWait
Expand Down
2 changes: 1 addition & 1 deletion constructor/osx/prepare_installation.sh
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ if [ "__VIRTUAL_SPECS__" != "" ]; then
notify 'Checking virtual specs compatibility: __VIRTUAL_SPECS__'
CONDA_SOLVER="classic" \
CONDA_PKGS_DIRS="$(mktemp -d)" \
"$CONDA_EXEC" create --dry-run --prefix "$PREFIX/envs/_virtual_specs_checks" --offline __VIRTUAL_SPECS__
"$CONDA_EXEC" create --dry-run --prefix "$PREFIX/envs/_virtual_specs_checks" --offline __VIRTUAL_SPECS__ __NO_RCS_ARG__
fi

# Create $PREFIX/.nonadmin if the installation didn't require superuser permissions
Expand Down
4 changes: 2 additions & 2 deletions constructor/osx/run_installation.sh
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ CONDA_SAFETY_CHECKS=disabled \
CONDA_EXTRA_SAFETY_CHECKS=no \
CONDA_CHANNELS=__CHANNELS__ \
CONDA_PKGS_DIRS="$PREFIX/pkgs" \
"$CONDA_EXEC" install --offline --file "$PREFIX/pkgs/env.txt" -yp "$PREFIX" $shortcuts; then
"$CONDA_EXEC" install --offline --file "$PREFIX/pkgs/env.txt" -yp "$PREFIX" $shortcuts __NO_RCS_ARG__; then
echo "ERROR: could not complete the conda install"
exit 1
fi
Expand Down Expand Up @@ -94,7 +94,7 @@ for env_pkgs in "${PREFIX}"/pkgs/envs/*/; do
CONDA_EXTRA_SAFETY_CHECKS=no \
CONDA_CHANNELS="$env_channels" \
CONDA_PKGS_DIRS="$PREFIX/pkgs" \
"$CONDA_EXEC" install --offline --file "${env_pkgs}env.txt" -yp "$PREFIX/envs/$env_name" $env_shortcuts || exit 1
"$CONDA_EXEC" install --offline --file "${env_pkgs}env.txt" -yp "$PREFIX/envs/$env_name" $env_shortcuts __NO_RCS_ARG__ || exit 1
# Move the prepackaged history file into place
mv "${env_pkgs}/conda-meta/history" "$PREFIX/envs/$env_name/conda-meta/history"
rm -f "${env_pkgs}env.txt"
Expand Down
1 change: 1 addition & 0 deletions constructor/osxpkg.py
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,7 @@ def move_script(src, dst, info, ensure_shebang=False, user_script_type=None):
'ENABLE_SHORTCUTS': str(info['_enable_shortcuts']).lower(),
'REGISTER_ENVS': str(info.get("register_envs", True)).lower(),
'VIRTUAL_SPECS': shlex.join(info.get("virtual_specs", ())),
'NO_RCS_ARG': info.get('_ignore_condarcs_arg', ''),
}
data = preprocess(data, ppd)
custom_variables = info.get('script_env_variables', {})
Expand Down
3 changes: 2 additions & 1 deletion constructor/shar.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ def get_header(conda_exec, tarball, info):
'SHORTCUTS': shortcuts_flags(info),
'REGISTER_ENVS': str(info.get("register_envs", True)).lower(),
'TOTAL_INSTALLATION_SIZE_KB': str(approx_size_kb(info, "total")),
'VIRTUAL_SPECS': shlex.join(info.get("virtual_specs", ()))
'VIRTUAL_SPECS': shlex.join(info.get("virtual_specs", ())),
'NO_RCS_ARG': info.get('_ignore_condarcs_arg', ''),
}
if has_license:
replace['LICENSE'] = read_ascii_only(info['license_file'])
Expand Down
7 changes: 5 additions & 2 deletions constructor/winexe.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,10 @@ def setup_envs_commands(info, dir_path):
# Run conda install
${{If}} $Ana_CreateShortcuts_State = ${{BST_CHECKED}}
${{Print}} "Installing packages for {name}, creating shortcuts if necessary..."
push '"$INSTDIR\_conda.exe" install --offline -yp "{prefix}" --file "{env_txt}" {shortcuts}'
push '"$INSTDIR\_conda.exe" install --offline -yp "{prefix}" --file "{env_txt}" {shortcuts} {no_rcs_arg}'
${{Else}}
${{Print}} "Installing packages for {name}..."
push '"$INSTDIR\_conda.exe" install --offline -yp "{prefix}" --file "{env_txt}" --no-shortcuts'
push '"$INSTDIR\_conda.exe" install --offline -yp "{prefix}" --file "{env_txt}" --no-shortcuts {no_rcs_arg}'
${{EndIf}}
push 'Failed to link extracted packages to {prefix}!'
push 'WithLog'
Expand Down Expand Up @@ -167,6 +167,7 @@ def setup_envs_commands(info, dir_path):
channels=','.join(get_final_channels(info)),
shortcuts=shortcuts_flags(info),
register_envs=str(info.get("register_envs", True)).lower(),
no_rcs_arg=info.get("_ignore_condarcs_arg", ""),
).splitlines()
# now we generate one more block per extra env, if present
for env_name in info.get("_extra_envs_info", {}):
Expand All @@ -190,6 +191,7 @@ def setup_envs_commands(info, dir_path):
channels=",".join(get_final_channels(channel_info)),
shortcuts=shortcuts_flags(env_info),
register_envs=str(info.get("register_envs", True)).lower(),
no_rcs_arg=info.get("_ignore_condarcs_arg", ""),
).splitlines()

return [line.strip() for line in lines]
Expand Down Expand Up @@ -404,6 +406,7 @@ def make_nsi(
# This is the same but without quotes so we can print it fine
('@VIRTUAL_SPECS_DEBUG@', " ".join([spec for spec in info.get("virtual_specs", ())])),
('@LICENSEFILENAME@', basename(info.get('license_file', 'placeholder_license.txt'))),
('@NO_RCS_ARG@', info.get('_ignore_condarcs_arg', '')),
]:
data = data.replace(key, value)

Expand Down
19 changes: 19 additions & 0 deletions news/863-ignore-condarc-files
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
### Enhancements

* <news item>

### Bug fixes

* Ignore pre-existing .condarc files to prevent these configuration files from interfering with the installation process. (#542 and #568 via #863)

### Deprecations

* <news item>

### Docs

* <news item>

### Other

* <news item>
44 changes: 44 additions & 0 deletions tests/test_examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -842,3 +842,47 @@ def test_virtual_specs_ok(tmp_path, 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",
)
def test_ignore_condarc_files(tmp_path, monkeypatch, request):
# Create a bogus .condarc file that would result in errors if read.
# conda searches inside XDG_CONFIG_HOME on all systems, which is a
# a safer directory to monkeypatch, especially on Windows where patching
# HOME or USERPROFILE breaks installer builds.
# mamba does not search this directory, so use HOME as a fallback.
# Since micromamba is not supported on Windows, this is not a problem.
if CONDA_EXE == StandaloneExe.MAMBA:
monkeypatch.setenv("HOME", str(tmp_path))
condarc = tmp_path / ".condarc"
else:
monkeypatch.setenv("XDG_CONFIG_HOME", str(tmp_path))
condarc = tmp_path / "conda" / ".condarc"
condarc.parent.mkdir(parents=True, exist_ok=True)
condarc.write_text("safety_checks:\n - very safe\n")
recipe_path = _example_path("customize_controls")
input_path = tmp_path / "input"
shutil.copytree(str(recipe_path), str(input_path))
# Rewrite installer name to avoid duplicate artifacts
construct_yaml = input_path / "construct.yaml"
content = construct_yaml.read_text()
construct_yaml.write_text(content.replace("name: NoCondaOptions", "name: NoCondaRC"))
for installer, install_dir in create_installer(input_path, tmp_path):
proc = _run_installer(
input_path,
installer,
install_dir,
request=request,
check_subprocess=True,
uninstall=True,
)
if CONDA_EXE == StandaloneExe.MAMBA and installer.suffix == ".sh":
# micromamba loads the rc files even for constructor subcommands.
# This cannot be turned off with --no-rc, which causes four errors
# in stderr. If there are more, other micromamba calls have read
# the bogus .condarc file.
# pkg installers unfortunately do not output any errors into the log.
assert proc.stderr.count("Bad conversion of configurable") == 4
Loading