spack mirror now checksums fetched archives.
This commit is contained in:
		@@ -44,6 +44,10 @@
 | 
			
		||||
description = "Manage spack mirrors."
 | 
			
		||||
 | 
			
		||||
def setup_parser(subparser):
 | 
			
		||||
    subparser.add_argument(
 | 
			
		||||
        '-n', '--no-checksum', action='store_true', dest='no_checksum',
 | 
			
		||||
        help="Do not check fetched packages against checksum")
 | 
			
		||||
 | 
			
		||||
    sp = subparser.add_subparsers(
 | 
			
		||||
        metavar='SUBCOMMAND', dest='mirror_command')
 | 
			
		||||
 | 
			
		||||
@@ -170,7 +174,7 @@ def mirror_create(args):
 | 
			
		||||
            os.chdir(working_dir)
 | 
			
		||||
            mirror_file = join_path(args.directory, mirror_path)
 | 
			
		||||
            if os.path.exists(mirror_file):
 | 
			
		||||
                tty.msg("Already fetched %s. Skipping." % mirror_file)
 | 
			
		||||
                tty.msg("Already fetched %s." % mirror_file)
 | 
			
		||||
                num_mirrored += 1
 | 
			
		||||
                continue
 | 
			
		||||
 | 
			
		||||
@@ -181,6 +185,11 @@ def mirror_create(args):
 | 
			
		||||
                # fetch changes directory into the stage
 | 
			
		||||
                stage.fetch()
 | 
			
		||||
 | 
			
		||||
                if not args.no_checksum and version in pkg.versions:
 | 
			
		||||
                    digest = pkg.versions[version]
 | 
			
		||||
                    stage.check(digest)
 | 
			
		||||
                    tty.msg("Checksum passed for %s@%s" % (pkg.name, version))
 | 
			
		||||
 | 
			
		||||
                # change back and move the new archive into place.
 | 
			
		||||
                os.chdir(working_dir)
 | 
			
		||||
                shutil.move(stage.archive_file, mirror_file)
 | 
			
		||||
@@ -188,7 +197,7 @@ def mirror_create(args):
 | 
			
		||||
                num_mirrored += 1
 | 
			
		||||
 | 
			
		||||
            except Exception, e:
 | 
			
		||||
                 tty.warn("Error while fetching %s.  Skipping." % url, e.message)
 | 
			
		||||
                 tty.warn("Error while fetching %s." % url, e.message)
 | 
			
		||||
                 num_error += 1
 | 
			
		||||
 | 
			
		||||
            finally:
 | 
			
		||||
@@ -197,10 +206,10 @@ def mirror_create(args):
 | 
			
		||||
    # If nothing happened, try to say why.
 | 
			
		||||
    if not num_mirrored:
 | 
			
		||||
        if num_error:
 | 
			
		||||
            tty.warn("No packages added to mirror.",
 | 
			
		||||
                     "All packages failed to fetch.")
 | 
			
		||||
            tty.error("No packages added to mirror.",
 | 
			
		||||
                      "All packages failed to fetch.")
 | 
			
		||||
        else:
 | 
			
		||||
            tty.warn("No packages added to mirror. No versions matched specs:")
 | 
			
		||||
            tty.error("No packages added to mirror. No versions matched specs:")
 | 
			
		||||
            colify(args.specs, indent=4)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -50,7 +50,6 @@
 | 
			
		||||
import spack.error
 | 
			
		||||
import spack.build_environment as build_env
 | 
			
		||||
import spack.url as url
 | 
			
		||||
import spack.util.crypto as crypto
 | 
			
		||||
from spack.version import *
 | 
			
		||||
from spack.stage import Stage
 | 
			
		||||
from spack.util.web import get_pages
 | 
			
		||||
@@ -539,7 +538,7 @@ def do_fetch(self):
 | 
			
		||||
            raise ValueError("Can only fetch concrete packages.")
 | 
			
		||||
 | 
			
		||||
        if spack.do_checksum and not self.version in self.versions:
 | 
			
		||||
            raise ChecksumError(
 | 
			
		||||
            raise FetchError(
 | 
			
		||||
                "Cannot fetch %s safely; there is no checksum on file for version %s."
 | 
			
		||||
                % (self.name, self.version),
 | 
			
		||||
                "Add a checksum to the package file, or use --no-checksum to "
 | 
			
		||||
@@ -549,13 +548,8 @@ def do_fetch(self):
 | 
			
		||||
 | 
			
		||||
        if spack.do_checksum and self.version in self.versions:
 | 
			
		||||
            digest = self.versions[self.version]
 | 
			
		||||
            checker = crypto.Checker(digest)
 | 
			
		||||
            if checker.check(self.stage.archive_file):
 | 
			
		||||
                tty.msg("Checksum passed for %s" % self.name)
 | 
			
		||||
            else:
 | 
			
		||||
                raise ChecksumError(
 | 
			
		||||
                    "%s checksum failed for %s." % (checker.hash_name, self.name),
 | 
			
		||||
                    "Expected %s but got %s." % (digest, checker.sum))
 | 
			
		||||
            self.stage.check(digest)
 | 
			
		||||
            tty.msg("Checksum passed for %s@%s" % (self.name, self.version))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def do_stage(self):
 | 
			
		||||
@@ -868,12 +862,6 @@ def __init__(self, message, long_msg=None):
 | 
			
		||||
        super(FetchError, self).__init__(message, long_msg)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ChecksumError(FetchError):
 | 
			
		||||
    """Raised when archive fails to checksum."""
 | 
			
		||||
    def __init__(self, message, long_msg):
 | 
			
		||||
        super(ChecksumError, self).__init__(message, long_msg)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class InstallError(spack.error.SpackError):
 | 
			
		||||
    """Raised when something goes wrong during install or uninstall."""
 | 
			
		||||
    def __init__(self, message, long_msg=None):
 | 
			
		||||
 
 | 
			
		||||
@@ -32,9 +32,11 @@
 | 
			
		||||
 | 
			
		||||
import spack
 | 
			
		||||
import spack.config
 | 
			
		||||
import spack.error as serr
 | 
			
		||||
import spack.error
 | 
			
		||||
import spack.util.crypto as crypto
 | 
			
		||||
from spack.util.compression import decompressor_for
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
STAGE_PREFIX = 'spack-stage-'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -186,8 +188,11 @@ def _setup(self):
 | 
			
		||||
    @property
 | 
			
		||||
    def archive_file(self):
 | 
			
		||||
        """Path to the source archive within this stage directory."""
 | 
			
		||||
        for path in (os.path.join(self.path, os.path.basename(self.url)),
 | 
			
		||||
                     os.path.join(self.path, os.path.basename(self.mirror_path))):
 | 
			
		||||
        paths = [os.path.join(self.path, os.path.basename(self.url))]
 | 
			
		||||
        if self.mirror_path:
 | 
			
		||||
            paths.append(os.path.join(self.path, os.path.basename(self.mirror_path)))
 | 
			
		||||
 | 
			
		||||
        for path in paths:
 | 
			
		||||
            if os.path.exists(path):
 | 
			
		||||
                return path
 | 
			
		||||
        return None
 | 
			
		||||
@@ -274,6 +279,15 @@ def fetch(self):
 | 
			
		||||
        return self.archive_file
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def check(self, digest):
 | 
			
		||||
        """Check the downloaded archive against a checksum digest"""
 | 
			
		||||
        checker = crypto.Checker(digest)
 | 
			
		||||
        if not checker.check(self.archive_file):
 | 
			
		||||
            raise ChecksumError(
 | 
			
		||||
                "%s checksum failed for %s." % (checker.hash_name, self.archive_file),
 | 
			
		||||
                "Expected %s but got %s." % (digest, checker.sum))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def expand_archive(self):
 | 
			
		||||
        """Changes to the stage directory and attempt to expand the downloaded
 | 
			
		||||
           archive.  Fail if the stage is not set up or if the archive is not yet
 | 
			
		||||
@@ -380,9 +394,15 @@ def find_tmp_root():
 | 
			
		||||
    return None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class FailedDownloadError(serr.SpackError):
 | 
			
		||||
class FailedDownloadError(spack.error.SpackError):
 | 
			
		||||
    """Raised wen a download fails."""
 | 
			
		||||
    def __init__(self, url, msg=""):
 | 
			
		||||
        super(FailedDownloadError, self).__init__(
 | 
			
		||||
            "Failed to fetch file from URL: %s" % url, msg)
 | 
			
		||||
        self.url = url
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ChecksumError(spack.error.SpackError):
 | 
			
		||||
    """Raised when archive fails to checksum."""
 | 
			
		||||
    def __init__(self, message, long_msg):
 | 
			
		||||
        super(ChecksumError, self).__init__(message, long_msg)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user