Bugfix: stage directory permissions and cleaning (#12733)
* This updates stage names to use "spack-stage-" as a prefix.
This avoids removing non-Spack directories in "spack clean" as
c141e99
did (in this case so long as they don't contain the
prefix "spack-stage-"), and also addresses a follow-up issue
where Spack stage directories were not removed.
* Spack now does more-stringent checking of expected permissions for
staging directories. For a given stage root that includes a user
component, all directories before the user component that are
created by Spack are expected to match the permissions of their
parent; the user component and all deeper directories are expected
to be accessible to the user (read/write/execute).
This commit is contained in:

committed by
Peter Scheibel

parent
e17df2e8f5
commit
1ef71376f2
@@ -49,6 +49,8 @@
|
||||
'is_exe',
|
||||
'join_path',
|
||||
'mkdirp',
|
||||
'partition_path',
|
||||
'prefixes',
|
||||
'remove_dead_links',
|
||||
'remove_if_dead_link',
|
||||
'remove_linked_tree',
|
||||
@@ -1608,3 +1610,70 @@ def search_paths_for_executables(*path_hints):
|
||||
executable_paths.append(bin_dir)
|
||||
|
||||
return executable_paths
|
||||
|
||||
|
||||
def partition_path(path, entry=None):
|
||||
"""
|
||||
Split the prefixes of the path at the first occurrence of entry and
|
||||
return a 3-tuple containing a list of the prefixes before the entry, a
|
||||
string of the prefix ending with the entry, and a list of the prefixes
|
||||
after the entry.
|
||||
|
||||
If the entry is not a node in the path, the result will be the prefix list
|
||||
followed by an empty string and an empty list.
|
||||
"""
|
||||
paths = prefixes(path)
|
||||
|
||||
if entry is not None:
|
||||
# Derive the index of entry within paths, which will correspond to
|
||||
# the location of the entry in within the path.
|
||||
try:
|
||||
entries = path.split(os.sep)
|
||||
i = entries.index(entry)
|
||||
if '' in entries:
|
||||
i -= 1
|
||||
return paths[:i], paths[i], paths[i + 1:]
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
return paths, '', []
|
||||
|
||||
|
||||
def prefixes(path):
|
||||
"""
|
||||
Returns a list containing the path and its ancestors, top-to-bottom.
|
||||
|
||||
The list for an absolute path will not include an ``os.sep`` entry.
|
||||
For example, assuming ``os.sep`` is ``/``, given path ``/ab/cd/efg``
|
||||
the resulting paths will be, in order: ``/ab``, ``/ab/cd``, and
|
||||
``/ab/cd/efg``
|
||||
|
||||
The list for a relative path starting ``./`` will not include ``.``.
|
||||
For example, path ``./hi/jkl/mn`` results in a list with the following
|
||||
paths, in order: ``./hi``, ``./hi/jkl``, and ``./hi/jkl/mn``.
|
||||
|
||||
Parameters:
|
||||
path (str): the string used to derive ancestor paths
|
||||
|
||||
Returns:
|
||||
A list containing ancestor paths in order and ending with the path
|
||||
"""
|
||||
if not path:
|
||||
return []
|
||||
|
||||
parts = path.strip(os.sep).split(os.sep)
|
||||
if path.startswith(os.sep):
|
||||
parts.insert(0, os.sep)
|
||||
paths = [os.path.join(*parts[:i + 1]) for i in range(len(parts))]
|
||||
|
||||
try:
|
||||
paths.remove(os.sep)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
try:
|
||||
paths.remove('.')
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
return paths
|
||||
|
Reference in New Issue
Block a user