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

pkg installer: Fix ownership of files installed into $HOME #784

Merged
merged 13 commits into from
May 8, 2024
Merged
4 changes: 3 additions & 1 deletion constructor/osx/run_installation.sh
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,11 @@ if ! "$PREFIX/bin/python" -V; then
exit 1
fi

# This is unneeded for the default install to ~, but if the user changes the
# This is not needed for the default install to ~, but if the user changes the
# install location, the permissions will default to root unless this is done.
chown -R "$USER" "$PREFIX"
chown -R "$USER" "${HOME}/.conda"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it might also leave a .condarc somewhere if the config file asked for that option. Should we add it here too? e.g.

Suggested change
chown -R "$USER" "${HOME}/.conda"
test -f "${HOME}/.condarc" && chown "$USER" "${HOME}/.condarc"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I tested it, .condarc had the correct ownership, but better safe than sorry.

test -f "${HOME}/.condarc" && chown "${USER}" "${HOME}/.condarc"

notify "Done! Installation is available in $PREFIX."

Expand Down
34 changes: 32 additions & 2 deletions constructor/osx/update_path.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
# Copyright (c) 2012-2017 Anaconda, Inc.
# All rights reserved.

Expand All @@ -8,4 +8,34 @@ set -eux

PREFIX="$2/__NAME_LOWER__"
PREFIX=$(cd "$PREFIX"; pwd)
"$PREFIX/bin/python" -m conda init --all
INIT_FILES=$("$PREFIX/bin/python" -m conda init --all | tee)

# Just like in run_install.sh, the files generated by the installer
# are owned by root when installed outside of $HOME. So, ownership of
# files modified by conda init must be changed to belong to $USER.
# For shells like fish or powershell, conda init creates subdirectories
# inside $HOME and/or $PREFIX, so ensure that parent directories also
# have the correct owner.
if [[ "${USER}" != "root" ]]; then
echo "Fixing permissions..."
read -r -a MODIFIED_FILES <<< "$(\
echo "${INIT_FILES}" |\
awk '/modified/{print $2}' |\
# Only grab files inside $HOME or $PREFIX.
# All init files should be there, but that may change, and it
# is better to miss files than to have an infinite loop below.
grep -E "^(${HOME}|${PREFIX})"\
)"
for file in "${MODIFIED_FILES[@]}"; do
while [[ "${file}" != "${HOME}" ]] && [[ "${file}" != "${PREFIX}" ]]; do
# Check just in case the file wasn't created due to flaky conda init
if [[ -f "${file}" ]] || [[ -d "${file}" ]]; then
OWNER=$(stat -f "%u" "${file}" | id -un)
if [[ "${OWNER}" == "root" ]]; then
chown "${USER}" "${file}"
fi
fi
file="${file%/*}"
done
done
fi
19 changes: 19 additions & 0 deletions news/784-pkg-installation-file-ownership
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
### Enhancements

* <news item>

### Bug fixes

* Fix ownership of files created by the PKG installer outside of `$PREFIX`. (#784)

### Deprecations

* <news item>

### Docs

* <news item>

### Other

* <news item>
26 changes: 26 additions & 0 deletions tests/test_examples.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import getpass
import os
import shutil
import subprocess
Expand Down Expand Up @@ -414,8 +415,33 @@ def test_example_noconda(tmp_path, request):
@pytest.mark.skipif(sys.platform != "darwin", reason="macOS only")
def test_example_osxpkg(tmp_path, request):
input_path = _example_path("osxpkg")
ownership_test_files_home = [
".bash_profile",
".conda",
".condarc",
".config",
".config/fish",
".config/fish/fish.config",
".config/powershell",
".config/powershell/profile.ps1",
".tcshrc",
".xonshrc",
".zshrc",
]
ownership_test_files_home = [Path.home() / file for file in ownership_test_files_home]
# getpass.getuser is more reliable than os.getlogin:
# https://docs.python.org/3/library/os.html#os.getlogin
expected_owner = getpass.getuser()
for installer, install_dir in create_installer(input_path, tmp_path):
_run_installer(input_path, installer, install_dir, request=request)
expected = {}
found = {}
for file in ownership_test_files_home:
if not file.exists():
continue
expected[file] = expected_owner
found[file] = file.owner()
assert expected == found


def test_example_scripts(tmp_path, request):
Expand Down
Loading