spack mirror now checksums fetched archives.

This commit is contained in:
Todd Gamblin 2014-06-24 11:53:44 -07:00
parent b33412e03a
commit 3c3f272280
4 changed files with 42 additions and 25 deletions

View File

@ -105,4 +105,4 @@ except SpackError, e:
tty.die(e.message) tty.die(e.message)
except KeyboardInterrupt: except KeyboardInterrupt:
tty.die("Got a keyboard interrupt from the user.") tty.die("Keyboard interrupt.")

View File

@ -44,6 +44,10 @@
description = "Manage spack mirrors." description = "Manage spack mirrors."
def setup_parser(subparser): 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( sp = subparser.add_subparsers(
metavar='SUBCOMMAND', dest='mirror_command') metavar='SUBCOMMAND', dest='mirror_command')
@ -170,7 +174,7 @@ def mirror_create(args):
os.chdir(working_dir) os.chdir(working_dir)
mirror_file = join_path(args.directory, mirror_path) mirror_file = join_path(args.directory, mirror_path)
if os.path.exists(mirror_file): if os.path.exists(mirror_file):
tty.msg("Already fetched %s. Skipping." % mirror_file) tty.msg("Already fetched %s." % mirror_file)
num_mirrored += 1 num_mirrored += 1
continue continue
@ -181,6 +185,11 @@ def mirror_create(args):
# fetch changes directory into the stage # fetch changes directory into the stage
stage.fetch() 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. # change back and move the new archive into place.
os.chdir(working_dir) os.chdir(working_dir)
shutil.move(stage.archive_file, mirror_file) shutil.move(stage.archive_file, mirror_file)
@ -188,7 +197,7 @@ def mirror_create(args):
num_mirrored += 1 num_mirrored += 1
except Exception, e: 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 num_error += 1
finally: finally:
@ -197,10 +206,10 @@ def mirror_create(args):
# If nothing happened, try to say why. # If nothing happened, try to say why.
if not num_mirrored: if not num_mirrored:
if num_error: if num_error:
tty.warn("No packages added to mirror.", tty.error("No packages added to mirror.",
"All packages failed to fetch.") "All packages failed to fetch.")
else: 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) colify(args.specs, indent=4)

View File

@ -50,7 +50,6 @@
import spack.error import spack.error
import spack.build_environment as build_env import spack.build_environment as build_env
import spack.url as url import spack.url as url
import spack.util.crypto as crypto
from spack.version import * from spack.version import *
from spack.stage import Stage from spack.stage import Stage
from spack.util.web import get_pages from spack.util.web import get_pages
@ -539,7 +538,7 @@ def do_fetch(self):
raise ValueError("Can only fetch concrete packages.") raise ValueError("Can only fetch concrete packages.")
if spack.do_checksum and not self.version in self.versions: 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." "Cannot fetch %s safely; there is no checksum on file for version %s."
% (self.name, self.version), % (self.name, self.version),
"Add a checksum to the package file, or use --no-checksum to " "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: if spack.do_checksum and self.version in self.versions:
digest = self.versions[self.version] digest = self.versions[self.version]
checker = crypto.Checker(digest) self.stage.check(digest)
if checker.check(self.stage.archive_file): tty.msg("Checksum passed for %s@%s" % (self.name, self.version))
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))
def do_stage(self): def do_stage(self):
@ -868,12 +862,6 @@ def __init__(self, message, long_msg=None):
super(FetchError, self).__init__(message, long_msg) 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): class InstallError(spack.error.SpackError):
"""Raised when something goes wrong during install or uninstall.""" """Raised when something goes wrong during install or uninstall."""
def __init__(self, message, long_msg=None): def __init__(self, message, long_msg=None):

View File

@ -32,9 +32,11 @@
import spack import spack
import spack.config import spack.config
import spack.error as serr import spack.error
import spack.util.crypto as crypto
from spack.util.compression import decompressor_for from spack.util.compression import decompressor_for
STAGE_PREFIX = 'spack-stage-' STAGE_PREFIX = 'spack-stage-'
@ -186,8 +188,11 @@ def _setup(self):
@property @property
def archive_file(self): def archive_file(self):
"""Path to the source archive within this stage directory.""" """Path to the source archive within this stage directory."""
for path in (os.path.join(self.path, os.path.basename(self.url)), paths = [os.path.join(self.path, os.path.basename(self.url))]
os.path.join(self.path, os.path.basename(self.mirror_path))): 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): if os.path.exists(path):
return path return path
return None return None
@ -274,6 +279,15 @@ def fetch(self):
return self.archive_file 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): def expand_archive(self):
"""Changes to the stage directory and attempt to expand the downloaded """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 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 return None
class FailedDownloadError(serr.SpackError): class FailedDownloadError(spack.error.SpackError):
"""Raised wen a download fails.""" """Raised wen a download fails."""
def __init__(self, url, msg=""): def __init__(self, url, msg=""):
super(FailedDownloadError, self).__init__( super(FailedDownloadError, self).__init__(
"Failed to fetch file from URL: %s" % url, msg) "Failed to fetch file from URL: %s" % url, msg)
self.url = url 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)