Logo Search packages:      
Sourcecode: zeroinstall-injector version File versions

def zeroinstall::zerostore::manifest::copy_tree_with_verify (   source,
  target,
  manifest_data,
  required_digest 
)

Copy directory source to be a subdirectory of target if it matches the required_digest.
manifest_data is normally source/.manifest. source and manifest_data are not trusted
(will typically be under the control of another user).
The copy is first done to a temporary directory in target, then renamed to the final name
only if correct. Therefore, an invalid 'target/required_digest' will never exist.
A successful return means than target/required_digest now exists (whether we created it or not).

Definition at line 238 of file manifest.py.

00238                                                                          :
      """Copy directory source to be a subdirectory of target if it matches the required_digest.
      manifest_data is normally source/.manifest. source and manifest_data are not trusted
      (will typically be under the control of another user).
      The copy is first done to a temporary directory in target, then renamed to the final name
      only if correct. Therefore, an invalid 'target/required_digest' will never exist.
      A successful return means than target/required_digest now exists (whether we created it or not)."""
      import tempfile, shutil
      from logging import info

      alg, digest_value = splitID(required_digest)

      if isinstance(alg, OldSHA1):
            raise SafeException("Sorry, the 'sha1' algorithm does not support copying.")

      digest = alg.new_digest()
      digest.update(manifest_data)
      manifest_digest = alg.getID(digest)

      if manifest_digest != required_digest:
            raise zerostore.BadDigest("Manifest has been tampered with!\n"
                        "Manifest digest: " + manifest_digest + "\n"
                        "Directory name : " + required_digest)

      target_impl = os.path.join(target, required_digest)
      if os.path.isdir(target_impl):
            info("Target directory '%s' already exists", target_impl)
            return

      # We've checked that the source's manifest matches required_digest, so it
      # is what we want. Make a list of all the files we need to copy...

      wanted = _parse_manifest(manifest_data)

      tmpdir = tempfile.mkdtemp(prefix = 'tmp-copy-', dir = target)

      try:
            _copy_files(alg, wanted, source, tmpdir)

            if wanted:
                  raise SafeException('Copy failed; files missing from source:\n- ' +
                                  '\n- '.join(wanted.keys()))

            # Check that the copy is correct
            actual_digest = alg.getID(add_manifest_file(tmpdir, alg))
            if actual_digest != required_digest:
                  raise SafeException(("Copy failed; double-check of target gave the wrong digest.\n"
                                   "Unless the target was modified during the copy, this is a BUG\n"
                                   "in 0store and should be reported.\n"
                                   "Expected: %s\n"
                                   "Actual:   %s") % (required_digest, actual_digest)) 
            os.rename(tmpdir, target_impl)
            # TODO: catch already-exists, delete tmpdir and return success
      except:
            info("Deleting tmpdir '%s'" % tmpdir)
            shutil.rmtree(tmpdir)
            raise

def _parse_manifest(manifest_data):


Generated by  Doxygen 1.6.0   Back to index