Example #1
0
def _first_accessible_path(paths):
    """Find the first path that is accessible, creating it if necessary."""
    for path in paths:
        try:
            # Ensure the user has access, creating the directory if necessary.
            path = sup.canonicalize_path(path)
            if os.path.exists(path):
                if can_access(path):
                    return path
            else:
                # The path doesn't exist so create it and adjust permissions
                # and group as needed (e.g., shared ``$tempdir``).
                prefix = os.path.sep
                parts = path.strip(os.path.sep).split(os.path.sep)
                for part in parts:
                    prefix = os.path.join(prefix, part)
                    if not os.path.exists(prefix):
                        break
                parent = os.path.dirname(prefix)
                gid = os.stat(parent).st_gid
                mkdirp(path, group=gid, default_perms='parents')

                if can_access(path):
                    return path

        except OSError as e:
            tty.debug('OSError while checking stage path %s: %s' % (
                      path, str(e)))

    return None
Example #2
0
def _create_stage_root(path):
    """Create the stage root directory and ensure appropriate access perms."""
    assert path.startswith(os.path.sep) and len(path.strip()) > 1

    curr_dir = os.path.sep
    parts = path.strip(os.path.sep).split(os.path.sep)
    for i, part in enumerate(parts):
        curr_dir = os.path.join(curr_dir, part)
        if not os.path.exists(curr_dir):
            rest = os.path.join(os.path.sep, *parts[i + 1:])
            user_parts = rest.partition(os.path.sep + getpass.getuser())
            if len(user_parts[0]) > 0:
                # Ensure access controls of subdirs created above `$user`
                # inherit from the parent and share the group.
                stats = os.stat(os.path.dirname(curr_dir))
                curr_dir = ''.join([curr_dir, user_parts[0]])
                mkdirp(curr_dir, group=stats.st_gid, mode=stats.st_mode)

            user_subdirs = ''.join(user_parts[1:])
            if len(user_subdirs) > 0:
                # Ensure access controls of subdirs from `$user` on down are
                # restricted to the user.
                curr_dir = ''.join([curr_dir, user_subdirs])
                mkdirp(curr_dir, mode=stat.S_IRWXU)

            assert os.getuid() == os.stat(curr_dir).st_uid
            break

    if not can_access(path):
        raise OSError(errno.EACCES,
                      'Cannot access %s: Permission denied' % curr_dir)
Example #3
0
def _create_stage_root(path):
    """Create the stage root directory and ensure appropriate access perms."""
    assert path.startswith(os.path.sep) and len(path.strip()) > 1

    err_msg = 'Cannot create stage root {0}: Access to {1} is denied'

    user_uid = os.getuid()

    # Obtain lists of ancestor and descendant paths of the $user node, if any.
    group_paths, user_node, user_paths = partition_path(
        path, getpass.getuser())

    for p in group_paths:
        if not os.path.exists(p):
            # Ensure access controls of subdirs created above `$user` inherit
            # from the parent and share the group.
            par_stat = os.stat(os.path.dirname(p))
            mkdirp(p, group=par_stat.st_gid, mode=par_stat.st_mode)

            p_stat = os.stat(p)
            if par_stat.st_gid != p_stat.st_gid:
                tty.warn(
                    "Expected {0} to have group {1}, but it is {2}".format(
                        p, par_stat.st_gid, p_stat.st_gid))

            if par_stat.st_mode & p_stat.st_mode != par_stat.st_mode:
                tty.warn(
                    "Expected {0} to support mode {1}, but it is {2}".format(
                        p, par_stat.st_mode, p_stat.st_mode))

            if not can_access(p):
                raise OSError(errno.EACCES, err_msg.format(path, p))

    # Add the path ending with the $user node to the user paths to ensure paths
    # from $user (on down) meet the ownership and permission requirements.
    if user_node:
        user_paths.insert(0, user_node)

    for p in user_paths:
        # Ensure access controls of subdirs from `$user` on down are
        # restricted to the user.
        if not os.path.exists(p):
            mkdirp(p, mode=stat.S_IRWXU)

            p_stat = os.stat(p)
            if p_stat.st_mode & stat.S_IRWXU != stat.S_IRWXU:
                tty.error(
                    "Expected {0} to support mode {1}, but it is {2}".format(
                        p, stat.S_IRWXU, p_stat.st_mode))

                raise OSError(errno.EACCES, err_msg.format(path, p))
        else:
            p_stat = os.stat(p)

        if user_uid != p_stat.st_uid:
            tty.warn(
                "Expected user {0} to own {1}, but it is owned by {2}".format(
                    user_uid, p, p_stat.st_uid))
Example #4
0
def create_stage_root(path):
    # type: (str) -> None
    """Create the stage root directory and ensure appropriate access perms."""
    assert os.path.isabs(path) and len(path.strip()) > 1

    err_msg = 'Cannot create stage root {0}: Access to {1} is denied'

    user_uid = getuid()

    # Obtain lists of ancestor and descendant paths of the $user node, if any.
    group_paths, user_node, user_paths = partition_path(
        path, getpass.getuser())

    for p in group_paths:
        if not os.path.exists(p):
            # Ensure access controls of subdirs created above `$user` inherit
            # from the parent and share the group.
            par_stat = os.stat(os.path.dirname(p))
            mkdirp(p, group=par_stat.st_gid, mode=par_stat.st_mode)

            p_stat = os.stat(p)
            if par_stat.st_gid != p_stat.st_gid:
                tty.warn(
                    "Expected {0} to have group {1}, but it is {2}".format(
                        p, par_stat.st_gid, p_stat.st_gid))

            if par_stat.st_mode & p_stat.st_mode != par_stat.st_mode:
                tty.warn(
                    "Expected {0} to support mode {1}, but it is {2}".format(
                        p, par_stat.st_mode, p_stat.st_mode))

            if not can_access(p):
                raise OSError(errno.EACCES, err_msg.format(path, p))

    # Add the path ending with the $user node to the user paths to ensure paths
    # from $user (on down) meet the ownership and permission requirements.
    if user_node:
        user_paths.insert(0, user_node)

    for p in user_paths:
        # Ensure access controls of subdirs from `$user` on down are
        # restricted to the user.
        owner_uid = get_owner_uid(p)
        if user_uid != owner_uid:
            tty.warn(
                "Expected user {0} to own {1}, but it is owned by {2}".format(
                    user_uid, p, owner_uid))

    spack_src_subdir = os.path.join(path, _source_path_subdir)
    # When staging into a user-specified directory with `spack stage -p <PATH>`, we need
    # to ensure the `spack-src` subdirectory exists, as we can't rely on it being
    # created automatically by spack. It's not clear why this is the case for `spack
    # stage -p`, but since `mkdirp()` is idempotent, this should not change the behavior
    # for any other code paths.
    if not os.path.isdir(spack_src_subdir):
        mkdirp(spack_src_subdir, mode=stat.S_IRWXU)
Example #5
0
def _first_accessible_path(paths):
    """Find the first path that is accessible, creating it if necessary."""
    for path in paths:
        try:
            # Ensure the user has access, creating the directory if necessary.
            if os.path.exists(path):
                if can_access(path):
                    return path
            else:
                # Now create the stage root with the proper group/perms.
                _create_stage_root(path)
                return path

        except OSError as e:
            tty.debug('OSError while checking stage path %s: %s' %
                      (path, str(e)))

    return None
Example #6
0
def _first_accessible_path(paths):
    """Find a tmp dir that exists that we can access."""
    for path in paths:
        try:
            # try to create the path if it doesn't exist.
            path = canonicalize_path(path)
            mkdirp(path)

            # ensure accessible
            if not can_access(path):
                continue

            # return it if successful.
            return path

        except OSError:
            tty.debug('OSError while checking temporary path: %s' % path)
            continue

    return None
Example #7
0
File: stage.py Project: LLNL/spack
def _first_accessible_path(paths):
    """Find a tmp dir that exists that we can access."""
    for path in paths:
        try:
            # try to create the path if it doesn't exist.
            path = canonicalize_path(path)
            mkdirp(path)

            # ensure accessible
            if not can_access(path):
                continue

            # return it if successful.
            return path

        except OSError:
            tty.debug('OSError while checking temporary path: %s' % path)
            continue

    return None
Example #8
0
def ensure_access(file):
    """Ensure we can access a directory and die with an error if we can't."""
    if not can_access(file):
        tty.die("Insufficient permissions for %s" % file)
Example #9
0
def _can_revert_update(scope_dir, cfg_file, bkp_file):
    dir_ok = fs.can_write_to_dir(scope_dir)
    cfg_ok = not os.path.exists(cfg_file) or fs.can_access(cfg_file)
    bkp_ok = fs.can_access(bkp_file)
    return dir_ok and cfg_ok and bkp_ok
Example #10
0
def _can_update_config_file(scope_dir, cfg_file):
    dir_ok = fs.can_write_to_dir(scope_dir)
    cfg_ok = fs.can_access(cfg_file)
    return dir_ok and cfg_ok
Example #11
0
File: stage.py Project: LLNL/spack
def ensure_access(file=spack.paths.stage_path):
    """Ensure we can access a directory and die with an error if we can't."""
    if not can_access(file):
        tty.die("Insufficient permissions for %s" % file)