From 3c3f272280c530553322142d9d836c91b1b01137 Mon Sep 17 00:00:00 2001 From: Todd Gamblin Date: Tue, 24 Jun 2014 11:53:44 -0700 Subject: spack mirror now checksums fetched archives. --- bin/spack | 2 +- lib/spack/spack/cmd/mirror.py | 19 ++++++++++++++----- lib/spack/spack/package.py | 18 +++--------------- lib/spack/spack/stage.py | 28 ++++++++++++++++++++++++---- 4 files changed, 42 insertions(+), 25 deletions(-) diff --git a/bin/spack b/bin/spack index df517c1f1d..a0ce203d63 100755 --- a/bin/spack +++ b/bin/spack @@ -105,4 +105,4 @@ except SpackError, e: tty.die(e.message) except KeyboardInterrupt: - tty.die("Got a keyboard interrupt from the user.") + tty.die("Keyboard interrupt.") diff --git a/lib/spack/spack/cmd/mirror.py b/lib/spack/spack/cmd/mirror.py index 494af3f718..813c58b84d 100644 --- a/lib/spack/spack/cmd/mirror.py +++ b/lib/spack/spack/cmd/mirror.py @@ -44,6 +44,10 @@ from spack.util.compression import extension 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) diff --git a/lib/spack/spack/package.py b/lib/spack/spack/package.py index eb0625cb7e..da599037dd 100644 --- a/lib/spack/spack/package.py +++ b/lib/spack/spack/package.py @@ -50,7 +50,6 @@ import spack.spec 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 @@ class Package(object): 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 @@ class Package(object): 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 @@ class FetchError(spack.error.SpackError): 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): diff --git a/lib/spack/spack/stage.py b/lib/spack/spack/stage.py index f679cec282..839555d630 100644 --- a/lib/spack/spack/stage.py +++ b/lib/spack/spack/stage.py @@ -32,9 +32,11 @@ from llnl.util.filesystem import * 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 @@ class Stage(object): @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 @@ class Stage(object): 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) -- cgit v1.2.3-60-g2f50