Repository: conda/conda

Issue:
package cache PermissionsError with repodata_record.json
```
error: PermissionError(13, 'Permission denied')
command: /home/jing/anaconda3/bin/conda upgrade Requests
user_agent: conda/4.4.3 requests/2.18.4 CPython/3.6.1 Linux/4.13.0-21-generic ubuntu/17.10 glibc/2.26
_messageid: -9223372036845975622
_messagetime: 1513948198000 / 2017-12-22 07:09:58
_receipttime: 1513993708752 / 2017-12-22 19:48:28

Traceback (most recent call last):
  File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/core/package_cache.py", line 268, in _make_single_record
    repodata_record = read_repodata_json(extracted_package_dir)
  File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/gateways/disk/read.py", line 123, in read_repodata_json
    with open(join(extracted_package_directory, 'info', 'repodata_record.json')) as fi:
  File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/common/compat.py", line 120, in open
    closefd=closefd)
FileNotFoundError: [Errno 2] No such file or directory: '/home/jing/anaconda3/pkgs/conda-4.3.31-py36_0/info/repodata_record.json'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/exceptions.py", line 722, in __call__
    return func(*args, **kwargs)
  File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/cli/main.py", line 78, in _main
    exit_code = do_call(args, p)
  File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/cli/conda_argparse.py", line 75, in do_call
    exit_code = getattr(module, func_name)(args, parser)
  File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/cli/main_update.py", line 14, in execute
    install(args, parser, 'update')
  File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/cli/install.py", line 239, in install
    handle_txn(progressive_fetch_extract, unlink_link_transaction, prefix, args, newenv)
  File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/cli/install.py", line 256, in handle_txn
    unlink_link_transaction.display_actions(progressive_fetch_extract)
  File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/core/link.py", line 706, in display_actions
    legacy_action_groups = self.make_legacy_action_groups(pfe)
  File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/core/link.py", line 689, in make_legacy_action_groups
    pfe.prepare()
  File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/common/io.py", line 415, in decorated
    return f(*args, **kwds)
  File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/core/package_cache.py", line 525, in prepare
    for prec in self.link_precs)
  File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/core/package_cache.py", line 525, in <genexpr>
    for prec in self.link_precs)
  File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/core/package_cache.py", line 419, in make_actions_for_record
    ), None)
  File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/core/package_cache.py", line 416, in <genexpr>
    pcrec for pcrec in concat(PackageCache(pkgs_dir).query(pref_or_spec)
  File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/core/package_cache.py", line 417, in <genexpr>
    for pkgs_dir in context.pkgs_dirs)
  File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/core/package_cache.py", line 116, in query
    return (pcrec for pcrec in itervalues(self._package_cache_records) if pcrec == param)
  File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/core/package_cache.py", line 209, in _package_cache_records
    self.load()
  File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/core/package_cache.py", line 88, in load
    package_cache_record = self._make_single_record(base_name)
  File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/core/package_cache.py", line 339, in _make_single_record
    write_as_json_to_file(repodata_record_path, repodata_record)
  File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/gateways/disk/create.py", line 61, in write_as_json_to_file
    with open(file_path, str('wb')) as fo:
PermissionError: [Errno 13] Permission denied: '/home/jing/anaconda3/pkgs/conda-4.3.31-py36_0/info/repodata_record.json'

```


Discussion:
```
error: PermissionError(13, 'Permission denied')
command: /anaconda/bin/conda install cmake
user_agent: conda/4.4.3 requests/2.18.4 CPython/3.6.1 Darwin/17.3.0 OSX/10.13.2
_messageid: -9223372036845975560
_messagetime: 1514034249000 / 2017-12-23 07:04:09
_receipttime: 1514022115225 / 2017-12-23 03:41:55

Traceback (most recent call last):
  File "/anaconda/lib/python3.6/site-packages/conda/core/package_cache.py", line 268, in _make_single_record
    repodata_record = read_repodata_json(extracted_package_dir)
  File "/anaconda/lib/python3.6/site-packages/conda/gateways/disk/read.py", line 123, in read_repodata_json
    with open(join(extracted_package_directory, 'info', 'repodata_record.json')) as fi:
  File "/anaconda/lib/python3.6/site-packages/conda/common/compat.py", line 120, in open
    closefd=closefd)
FileNotFoundError: [Errno 2] No such file or directory: '/anaconda/pkgs/astropy-2.0.2-py36hf79c81d_4/info/repodata_record.json'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/anaconda/lib/python3.6/site-packages/conda/exceptions.py", line 722, in __call__
    return func(*args, **kwargs)
  File "/anaconda/lib/python3.6/site-packages/conda/cli/main.py", line 78, in _main
    exit_code = do_call(args, p)
  File "/anaconda/lib/python3.6/site-packages/conda/cli/conda_argparse.py", line 75, in do_call
    exit_code = getattr(module, func_name)(args, parser)
  File "/anaconda/lib/python3.6/site-packages/conda/cli/main_install.py", line 11, in execute
    install(args, parser, 'install')
  File "/anaconda/lib/python3.6/site-packages/conda/cli/install.py", line 239, in install
    handle_txn(progressive_fetch_extract, unlink_link_transaction, prefix, args, newenv)
  File "/anaconda/lib/python3.6/site-packages/conda/cli/install.py", line 256, in handle_txn
    unlink_link_transaction.display_actions(progressive_fetch_extract)
  File "/anaconda/lib/python3.6/site-packages/conda/core/link.py", line 706, in display_actions
    legacy_action_groups = self.make_legacy_action_groups(pfe)
  File "/anaconda/lib/python3.6/site-packages/conda/core/link.py", line 689, in make_legacy_action_groups
    pfe.prepare()
  File "/anaconda/lib/python3.6/site-packages/conda/common/io.py", line 415, in decorated
    return f(*args, **kwds)
  File "/anaconda/lib/python3.6/site-packages/conda/core/package_cache.py", line 525, in prepare
    for prec in self.link_precs)
  File "/anaconda/lib/python3.6/site-packages/conda/core/package_cache.py", line 525, in <genexpr>
    for prec in self.link_precs)
  File "/anaconda/lib/python3.6/site-packages/conda/core/package_cache.py", line 419, in make_actions_for_record
    ), None)
  File "/anaconda/lib/python3.6/site-packages/conda/core/package_cache.py", line 416, in <genexpr>
    pcrec for pcrec in concat(PackageCache(pkgs_dir).query(pref_or_spec)
  File "/anaconda/lib/python3.6/site-packages/conda/core/package_cache.py", line 417, in <genexpr>
    for pkgs_dir in context.pkgs_dirs)
  File "/anaconda/lib/python3.6/site-packages/conda/core/package_cache.py", line 116, in query
    return (pcrec for pcrec in itervalues(self._package_cache_records) if pcrec == param)
  File "/anaconda/lib/python3.6/site-packages/conda/core/package_cache.py", line 209, in _package_cache_records
    self.load()
  File "/anaconda/lib/python3.6/site-packages/conda/core/package_cache.py", line 88, in load
    package_cache_record = self._make_single_record(base_name)
  File "/anaconda/lib/python3.6/site-packages/conda/core/package_cache.py", line 339, in _make_single_record
    write_as_json_to_file(repodata_record_path, repodata_record)
  File "/anaconda/lib/python3.6/site-packages/conda/gateways/disk/create.py", line 61, in write_as_json_to_file
    with open(file_path, str('wb')) as fo:
PermissionError: [Errno 13] Permission denied: '/anaconda/pkgs/astropy-2.0.2-py36hf79c81d_4/info/repodata_record.json'

```
All observed errors are on unix platforms.  Maybe people really are encountering this from using `sudo` when they shouldn't be.

Resolving patch:
diff --git a/conda/core/package_cache.py b/conda/core/package_cache.py
--- a/conda/core/package_cache.py
+++ b/conda/core/package_cache.py
@@ -1,12 +1,14 @@
 # -*- coding: utf-8 -*-
 from __future__ import absolute_import, division, print_function, unicode_literals
 
+from errno import EACCES, EPERM
 from functools import reduce
 from logging import getLogger
 from os import listdir
 from os.path import basename, dirname, join
 from tarfile import ReadError
 
+from conda.exceptions import NotWritableError
 from .path_actions import CacheUrlAction, ExtractPackageAction
 from .. import CondaError, CondaMultiError, conda_signal_handler
 from .._vendor.auxlib.collection import first
@@ -336,7 +338,13 @@ def _make_single_record(self, package_filename):
             if self.is_writable:
                 repodata_record = PackageRecord.from_objects(package_cache_record)
                 repodata_record_path = join(extracted_package_dir, 'info', 'repodata_record.json')
-                write_as_json_to_file(repodata_record_path, repodata_record)
+                try:
+                    write_as_json_to_file(repodata_record_path, repodata_record)
+                except (IOError, OSError) as e:
+                    if e.errno in (EACCES, EPERM) and isdir(dirname(repodata_record_path)):
+                        raise NotWritableError(repodata_record_path, e.errno, caused_by=e)
+                    else:
+                        raise
 
             return package_cache_record
 
diff --git a/conda/exceptions.py b/conda/exceptions.py
--- a/conda/exceptions.py
+++ b/conda/exceptions.py
@@ -614,6 +614,8 @@ def __init__(self, path, errno, **kwargs):
             change them by executing
 
               $ sudo chown %(uid)s:%(gid)s %(path)s
+
+            In general, it's not advisable to use 'sudo conda'.
             """)
             import os
             kwargs.update({


Test patch: