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)
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."
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)

View file

@ -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):

View file

@ -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)