mirror of
https://github.com/pypa/pip
synced 2023-12-13 21:30:23 +01:00
Warn if the cache/log directory is not owned by the current user
This commit is contained in:
parent
6531a2db3e
commit
4f40530493
|
@ -23,6 +23,7 @@ from pip.status_codes import (
|
|||
)
|
||||
from pip.utils import appdirs, get_prog, normalize_path
|
||||
from pip.utils.deprecation import RemovedInPip8Warning
|
||||
from pip.utils.filesystem import check_path_owner
|
||||
from pip.utils.logging import IndentingFormatter
|
||||
from pip.utils.outdated import pip_version_check
|
||||
|
||||
|
@ -113,6 +114,13 @@ class Command(object):
|
|||
else:
|
||||
level = "INFO"
|
||||
|
||||
# Compute the path for our debug log.
|
||||
debug_log_path = os.path.join(appdirs.user_log_dir("pip"), "debug.log")
|
||||
|
||||
# Ensure that the path for our debug log is owned by the current user
|
||||
# and if it is not, disable the debug log.
|
||||
write_debug_log = check_path_owner(debug_log_path, os.geteuid())
|
||||
|
||||
logging_dictConfig({
|
||||
"version": 1,
|
||||
"disable_existing_loggers": False,
|
||||
|
@ -136,9 +144,7 @@ class Command(object):
|
|||
"debug_log": {
|
||||
"level": "DEBUG",
|
||||
"class": "pip.utils.logging.BetterRotatingFileHandler",
|
||||
"filename": os.path.join(
|
||||
appdirs.user_log_dir("pip"), "debug.log",
|
||||
),
|
||||
"filename": debug_log_path,
|
||||
"maxBytes": 10 * 1000 * 1000, # 10 MB
|
||||
"backupCount": 1,
|
||||
"delay": True,
|
||||
|
@ -156,7 +162,7 @@ class Command(object):
|
|||
"level": level,
|
||||
"handlers": list(filter(None, [
|
||||
"console",
|
||||
"debug_log",
|
||||
"debug_log" if write_debug_log else None,
|
||||
"user_log" if options.log else None,
|
||||
])),
|
||||
},
|
||||
|
@ -178,6 +184,17 @@ class Command(object):
|
|||
),
|
||||
})
|
||||
|
||||
# We add this warning here instead of up above, because the logger
|
||||
# hasn't been configured until just now.
|
||||
if not write_debug_log:
|
||||
logger.warning(
|
||||
"The directory '%s' or its parent directory is not owned by "
|
||||
"the current user and the debug log has been disabled. Please "
|
||||
"check the permissions and owner of that directory. If "
|
||||
"executing pip with sudo, you may want the -H flag.",
|
||||
os.path.dirname(debug_log_path),
|
||||
)
|
||||
|
||||
if options.log_explicit_levels:
|
||||
warnings.warn(
|
||||
"--log-explicit-levels has been deprecated and will be removed"
|
||||
|
|
|
@ -23,6 +23,7 @@ from pip.exceptions import InstallationError, HashMismatch
|
|||
from pip.models import PyPI
|
||||
from pip.utils import (splitext, rmtree, format_size, display_path,
|
||||
backup_dir, ask_path_exists, unpack_file)
|
||||
from pip.utils.filesystem import check_path_owner
|
||||
from pip.utils.ui import DownloadProgressBar, DownloadProgressSpinner
|
||||
from pip.locations import write_delete_marker_file
|
||||
from pip.vcs import vcs
|
||||
|
@ -225,7 +226,31 @@ class SafeFileCache(FileCache):
|
|||
not be accessible or writable.
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(SafeFileCache, self).__init__(*args, **kwargs)
|
||||
|
||||
# Check to ensure that the directory containing our cache directory
|
||||
# is owned by the user current executing pip. If it does not exist
|
||||
# we will check the parent directory until we find one that does exist.
|
||||
# If it is not owned by the user executing pip then we will disable
|
||||
# the cache and log a warning.
|
||||
if not check_path_owner(self.directory, os.geteuid()):
|
||||
logger.warning(
|
||||
"The directory '%s' or its parent directory is not owned by "
|
||||
"the current user and the cache has been disabled. Please "
|
||||
"check the permissions and owner of that directory. If "
|
||||
"executing pip with sudo, you may want the -H flag.",
|
||||
self.directory,
|
||||
)
|
||||
|
||||
# Set our directory to None to disable the Cache
|
||||
self.directory = None
|
||||
|
||||
def get(self, *args, **kwargs):
|
||||
# If we don't have a directory, then the cache should be a no-op.
|
||||
if self.directory is None:
|
||||
return
|
||||
|
||||
try:
|
||||
return super(SafeFileCache, self).get(*args, **kwargs)
|
||||
except (LockError, OSError, IOError):
|
||||
|
@ -235,6 +260,10 @@ class SafeFileCache(FileCache):
|
|||
pass
|
||||
|
||||
def set(self, *args, **kwargs):
|
||||
# If we don't have a directory, then the cache should be a no-op.
|
||||
if self.directory is None:
|
||||
return
|
||||
|
||||
try:
|
||||
return super(SafeFileCache, self).set(*args, **kwargs)
|
||||
except (LockError, OSError, IOError):
|
||||
|
@ -244,6 +273,10 @@ class SafeFileCache(FileCache):
|
|||
pass
|
||||
|
||||
def delete(self, *args, **kwargs):
|
||||
# If we don't have a directory, then the cache should be a no-op.
|
||||
if self.directory is None:
|
||||
return
|
||||
|
||||
try:
|
||||
return super(SafeFileCache, self).delete(*args, **kwargs)
|
||||
except (LockError, OSError, IOError):
|
||||
|
|
18
pip/utils/filesystem.py
Normal file
18
pip/utils/filesystem.py
Normal file
|
@ -0,0 +1,18 @@
|
|||
import os.path
|
||||
|
||||
from pip.compat import get_path_uid
|
||||
|
||||
|
||||
def check_path_owner(path, uid):
|
||||
previous = None
|
||||
while path != previous:
|
||||
if os.path.lexists(path):
|
||||
# Actually do the ownership check
|
||||
try:
|
||||
if get_path_uid(path) != os.geteuid():
|
||||
return False
|
||||
except OSError:
|
||||
return False
|
||||
return True
|
||||
else:
|
||||
previous, path = path, os.path.dirname(path)
|
Loading…
Reference in a new issue