Beispiel #1
0
def make_tree_read_only(root):
  """Makes all the files in the directories read only.

  Also makes the directories read only, only if it makes sense on the platform.

  This means no file can be created or deleted.
  """
  err = None
  logging.debug('make_tree_read_only(%s)', root)
  for dirpath, dirnames, filenames in fs.walk(root, topdown=True):
    for filename in filenames:
      e = set_read_only_swallow(os.path.join(dirpath, filename), True)
      if not err:
        err = e
    if sys.platform != 'win32':
      # It must not be done on Windows.
      for dirname in dirnames:
        e = set_read_only_swallow(os.path.join(dirpath, dirname), True)
        if not err:
          err = e
  if sys.platform != 'win32':
    e = set_read_only_swallow(root, True)
    if not err:
      err = e
  if err:
    # pylint: disable=raising-bad-type
    raise err
Beispiel #2
0
def make_tree_deleteable(root):
  """Changes the appropriate permissions so the files in the directories can be
  deleted.

  On Windows, the files are modified. On other platforms, modify the directory.
  It only does the minimum so the files can be deleted safely.

  Warning on Windows: since file permission is modified, the file node is
  modified. This means that for hard-linked files, every directory entry for the
  file node has its file permission modified.
  """
  logging.debug('make_tree_deleteable(%s)', root)
  err = None
  if sys.platform != 'win32':
    e = set_read_only_swallow(root, False)
    if not err:
      err = e
  for dirpath, dirnames, filenames in fs.walk(root, topdown=True):
    if sys.platform == 'win32':
      for filename in filenames:
        e = set_read_only_swallow(os.path.join(dirpath, filename), False)
        if not err:
          err = e
    else:
      for dirname in dirnames:
        e = set_read_only_swallow(os.path.join(dirpath, dirname), False)
        if not err:
          err = e
  if err:
    # pylint: disable=raising-bad-type
    raise err
Beispiel #3
0
    def test_symlink_absolute(self):
        # A symlink to an absolute path is valid.
        # /dir
        # /dir/file
        # /ld -> /dir
        # /lf -> /ld/file
        dirpath = os.path.join(self.tempdir, 'dir')
        filepath = os.path.join(dirpath, 'file')
        fs.mkdir(dirpath)
        write_content(filepath, 'hello')

        linkfile = os.path.join(self.tempdir, 'lf')
        linkdir = os.path.join(self.tempdir, 'ld')
        dstfile = os.path.join(linkdir, 'file')
        fs.symlink(dstfile, linkfile)
        fs.symlink(dirpath, linkdir)

        self.assertEqual(True, fs.islink(linkfile))
        self.assertEqual(True, fs.islink(linkdir))
        self.assertEqual(dstfile, fs.readlink(linkfile))
        self.assertEqual(dirpath, fs.readlink(linkdir))
        self.assertEqual(['file'], fs.listdir(linkdir))
        # /lf resolves to /dir/file.
        self.assertEqual('hello', fs.open(linkfile).read())

        # Ensures that followlinks is respected in walk().
        expected = [
            (self.tempdir, ['dir', 'ld'], ['lf']),
            (dirpath, [], ['file']),
        ]
        actual = [
            (r, sorted(d), sorted(f))
            for r, d, f in sorted(fs.walk(self.tempdir, followlinks=False))
        ]
        self.assertEqual(expected, actual)
        expected = [
            (self.tempdir, ['dir', 'ld'], ['lf']),
            (dirpath, [], ['file']),
            (linkdir, [], ['file']),
        ]
        actual = [
            (r, sorted(d), sorted(f))
            for r, d, f in sorted(fs.walk(self.tempdir, followlinks=True))
        ]
        self.assertEqual(expected, actual)
Beispiel #4
0
def read_tree(path):
    """Returns a dict with {filepath: content}."""
    if not fs.isdir(path):
        return None
    out = {}
    for root, _, filenames in fs.walk(path):
        for filename in filenames:
            p = os.path.join(root, filename)
            out[os.path.relpath(p, path)] = read_file(p)
    return out
Beispiel #5
0
def make_tree_deleteable(root):
  """Changes the appropriate permissions so the files in the directories can be
  deleted.

  On Windows, the files are modified. On other platforms, modify the directory.
  It only does the minimum so the files can be deleted safely.

  Warning on Windows: since file permission is modified, the file node is
  modified. This means that for hard-linked files, every directory entry for the
  file node has its file permission modified.
  """
  logging.debug('make_tree_deleteable(%s)', root)
  err = None
  sudo_failed = False

  def try_sudo(p):
    if sys.platform in ('darwin', 'linux2', 'linux') and not sudo_failed:
      # Try passwordless sudo, just in case. In practice, it is preferable
      # to use linux capabilities.
      with open(os.devnull, 'rb') as f:
        if not subprocess42.call(
            ['sudo', '-n', 'chmod', 'a+rwX,-t', p], stdin=f):
          return False
      logging.debug('sudo chmod %s failed', p)
    return True

  if sys.platform != 'win32':
    e = set_read_only_swallow(root, False)
    if e:
      sudo_failed = try_sudo(root)
    if not err:
      err = e
  for dirpath, dirnames, filenames in fs.walk(root, topdown=True):
    if sys.platform == 'win32':
      for filename in filenames:
        e = set_read_only_swallow(os.path.join(dirpath, filename), False)
        if not err:
          err = e
    else:
      for dirname in dirnames:
        try:
          p = os.path.join(dirpath, dirname)
        except UnicodeDecodeError:
          logging.error('failed to join "%s" with %s and "%s" with %s',
                        map(ord, dirpath), type(dirpath), map(ord, dirname),
                        type(dirname))
          raise
        e = set_read_only_swallow(p, False)
        if e:
          sudo_failed = try_sudo(p)
        if not err:
          err = e
  if err:
    # pylint: disable=raising-bad-type
    raise err
Beispiel #6
0
 def tearDown(self):
     try:
         if self._tempdir:
             for dirpath, dirnames, filenames in fs.walk(self._tempdir, topdown=True):
                 for filename in filenames:
                     file_path.set_read_only(os.path.join(dirpath, filename), False)
                 for dirname in dirnames:
                     file_path.set_read_only(os.path.join(dirpath, dirname), False)
             file_path.rmtree(self._tempdir)
     finally:
         super(FilePathTest, self).tearDown()
Beispiel #7
0
 def tearDown(self):
   try:
     if self._tempdir:
       for dirpath, dirnames, filenames in fs.walk(
           self._tempdir, topdown=True):
         for filename in filenames:
           file_path.set_read_only(os.path.join(dirpath, filename), False)
         for dirname in dirnames:
           file_path.set_read_only(os.path.join(dirpath, dirname), False)
       file_path.rmtree(self._tempdir)
   finally:
     super(FilePathTest, self).tearDown()
Beispiel #8
0
def get_recursive_size(path):
  """Returns the total data size for the specified path."""
  try:
    total = 0
    for root, _, files in fs.walk(path):
      for f in files:
        total += fs.lstat(os.path.join(root, f)).st_size
    return total
  except (IOError, OSError, UnicodeEncodeError) as exc:
    logging.warning('Exception while getting the size of %s:\n%s', path, exc)
    # Returns a negative number to make it clear that something is wrong.
    return -1
Beispiel #9
0
def _get_recursive_size(path):
    """Returns the total data size for the specified path.

  This function can be surprisingly slow on OSX, so its output should be cached.
  """
    try:
        total = 0
        for root, _, files in fs.walk(path):
            for f in files:
                total += fs.lstat(os.path.join(root, f)).st_size
        return total
    except (IOError, OSError, UnicodeEncodeError) as exc:
        logging.warning('Exception while getting the size of %s:\n%s', path,
                        exc)
        return None
Beispiel #10
0
def make_tree_files_read_only(root):
  """Makes all the files in the directories read only but not the directories
  themselves.

  This means files can be created or deleted.
  """
  logging.debug('make_tree_files_read_only(%s)', root)
  if sys.platform != 'win32':
    set_read_only(root, False)
  for dirpath, dirnames, filenames in fs.walk(root, topdown=True):
    for filename in filenames:
      set_read_only(os.path.join(dirpath, filename), True)
    if sys.platform != 'win32':
      # It must not be done on Windows.
      for dirname in dirnames:
        set_read_only(os.path.join(dirpath, dirname), False)
Beispiel #11
0
def make_tree_files_read_only(root):
  """Makes all the files in the directories read only but not the directories
  themselves.

  This means files can be created or deleted.
  """
  logging.debug('make_tree_files_read_only(%s)', root)
  if sys.platform != 'win32':
    set_read_only(root, False)
  for dirpath, dirnames, filenames in fs.walk(root, topdown=True):
    for filename in filenames:
      set_read_only(os.path.join(dirpath, filename), True)
    if sys.platform != 'win32':
      # It must not be done on Windows.
      for dirname in dirnames:
        set_read_only(os.path.join(dirpath, dirname), False)
def _get_recursive_size(path):
    """Returns the total data size for the specified path.

  This function can be surprisingly slow on OSX, so its output should be cached.
  """
    try:
        total = 0
        if _use_scandir():

            if sys.platform == 'win32':

                def direntIsJunction(entry):
                    # both st_file_attributes and FILE_ATTRIBUTE_REPARSE_POINT are
                    # windows-only symbols.
                    return bool(entry.stat().st_file_attributes
                                & scandir.FILE_ATTRIBUTE_REPARSE_POINT)
            else:

                def direntIsJunction(_entry):
                    return False

            stack = [path]
            while stack:
                for entry in scandir.scandir(stack.pop()):
                    if entry.is_symlink() or direntIsJunction(entry):
                        continue
                    if entry.is_file():
                        total += entry.stat().st_size
                    elif entry.is_dir():
                        stack.append(entry.path)
                    else:
                        logging.warning('non directory/file entry: %s', entry)
            return total

        for root, _, files in fs.walk(path):
            for f in files:
                st = fs.lstat(os.path.join(root, f))
                if stat.S_ISLNK(st.st_mode):
                    continue
                total += st.st_size
        return total
    except (IOError, OSError, UnicodeEncodeError) as exc:
        logging.warning('Exception while getting the size of %s:\n%s', path,
                        exc)
        return None
Beispiel #13
0
def make_tree_writeable(root):
  """Makes all the files in the directories writeable.

  Also makes the directories writeable, only if it makes sense on the platform.

  It is different from make_tree_deleteable() because it unconditionally affects
  the files.
  """
  logging.debug('make_tree_writeable(%s)', root)
  if sys.platform != 'win32':
    set_read_only(root, False)
  for dirpath, dirnames, filenames in fs.walk(root, topdown=True):
    for filename in filenames:
      set_read_only(os.path.join(dirpath, filename), False)
    if sys.platform != 'win32':
      # It must not be done on Windows.
      for dirname in dirnames:
        set_read_only(os.path.join(dirpath, dirname), False)
Beispiel #14
0
def make_tree_writeable(root):
  """Makes all the files in the directories writeable.

  Also makes the directories writeable, only if it makes sense on the platform.

  It is different from make_tree_deleteable() because it unconditionally affects
  the files.
  """
  logging.debug('make_tree_writeable(%s)', root)
  if sys.platform != 'win32':
    set_read_only(root, False)
  for dirpath, dirnames, filenames in fs.walk(root, topdown=True):
    for filename in filenames:
      set_read_only(os.path.join(dirpath, filename), False)
    if sys.platform != 'win32':
      # It must not be done on Windows.
      for dirname in dirnames:
        set_read_only(os.path.join(dirpath, dirname), False)