summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTodd Gamblin <tgamblin@llnl.gov>2016-11-07 01:34:30 -0800
committerGitHub <noreply@github.com>2016-11-07 01:34:30 -0800
commit908ba6e3d67feaa7f71db5c889ac05ad4bde58ee (patch)
treea9e6833b20288d679a8a5176f8967083eda45bd5 /lib
parent08477f6624e91a0bb1d8a6736af534b77d0075ba (diff)
downloadspack-908ba6e3d67feaa7f71db5c889ac05ad4bde58ee.tar.gz
spack-908ba6e3d67feaa7f71db5c889ac05ad4bde58ee.tar.bz2
spack-908ba6e3d67feaa7f71db5c889ac05ad4bde58ee.tar.xz
spack-908ba6e3d67feaa7f71db5c889ac05ad4bde58ee.zip
Waste less space when fetching cached archives, simplify fetch messages. (#2264)
* Waste less space when fetching cached archives, simplify fetch messages. - Just symlink cached files into the stage instead of copying them with curl. - Don't copy linked files back into the cache when done fetching. * Fixes for review. * more updates * last update
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/spack/fetch_strategy.py60
-rw-r--r--lib/spack/spack/stage.py3
2 files changed, 39 insertions, 24 deletions
diff --git a/lib/spack/spack/fetch_strategy.py b/lib/spack/spack/fetch_strategy.py
index d1a817d82f..5084a68e08 100644
--- a/lib/spack/spack/fetch_strategy.py
+++ b/lib/spack/spack/fetch_strategy.py
@@ -194,7 +194,7 @@ class URLFetchStrategy(FetchStrategy):
save_file = self.stage.save_filename
partial_file = self.stage.save_filename + '.part'
- tty.msg("Trying to fetch from %s" % self.url)
+ tty.msg("Fetching %s" % self.url)
if partial_file:
save_args = ['-C',
@@ -295,7 +295,7 @@ class URLFetchStrategy(FetchStrategy):
self.stage.chdir()
if not self.archive_file:
raise NoArchiveFileError(
- "URLFetchStrategy couldn't find archive file",
+ "Couldn't find archive file",
"Failed on expand() for URL %s" % self.url)
if not self.extension:
@@ -392,16 +392,34 @@ class CacheURLFetchStrategy(URLFetchStrategy):
@_needs_stage
def fetch(self):
- super(CacheURLFetchStrategy, self).fetch()
+ path = re.sub('^file://', '', self.url)
+
+ # check whether the cache file exists.
+ if not os.path.isfile(path):
+ raise NoCacheError('No cache of %s' % path)
+
+ self.stage.chdir()
+
+ # remove old symlink if one is there.
+ filename = self.stage.save_filename
+ if os.path.exists(filename):
+ os.remove(filename)
+
+ # Symlink to local cached archive.
+ os.symlink(path, filename)
+
+ # Remove link if checksum fails, or subsequent fetchers
+ # will assume they don't need to download.
if self.digest:
try:
self.check()
except ChecksumError:
- # Future fetchers will assume they don't need to
- # download if the file remains
os.remove(self.archive_file)
raise
+ # Notify the user how we fetched.
+ tty.msg('Using cached archive: %s' % path)
+
class VCSFetchStrategy(FetchStrategy):
@@ -907,31 +925,36 @@ class FsCache(object):
self.root = os.path.abspath(root)
def store(self, fetcher, relativeDst):
+ # skip fetchers that aren't cachable
if not fetcher.cachable:
return
+ # Don't store things that are already cached.
+ if isinstance(fetcher, CacheURLFetchStrategy):
+ return
+
dst = join_path(self.root, relativeDst)
mkdirp(os.path.dirname(dst))
fetcher.archive(dst)
def fetcher(self, targetPath, digest, **kwargs):
- url = "file://" + join_path(self.root, targetPath)
- return CacheURLFetchStrategy(url, digest, **kwargs)
+ path = join_path(self.root, targetPath)
+ return CacheURLFetchStrategy(path, digest, **kwargs)
def destroy(self):
shutil.rmtree(self.root, ignore_errors=True)
class FetchError(spack.error.SpackError):
+ """Superclass fo fetcher errors."""
- def __init__(self, msg, long_msg=None):
- super(FetchError, self).__init__(msg, long_msg)
+class NoCacheError(FetchError):
+ """Raised when there is no cached archive for a package."""
-class FailedDownloadError(FetchError):
+class FailedDownloadError(FetchError):
"""Raised wen a download fails."""
-
def __init__(self, url, msg=""):
super(FailedDownloadError, self).__init__(
"Failed to fetch file from URL: %s" % url, msg)
@@ -939,19 +962,14 @@ class FailedDownloadError(FetchError):
class NoArchiveFileError(FetchError):
-
- def __init__(self, msg, long_msg):
- super(NoArchiveFileError, self).__init__(msg, long_msg)
+ """"Raised when an archive file is expected but none exists."""
class NoDigestError(FetchError):
-
- def __init__(self, msg, long_msg=None):
- super(NoDigestError, self).__init__(msg, long_msg)
+ """Raised after attempt to checksum when URL has no digest."""
class InvalidArgsError(FetchError):
-
def __init__(self, pkg, version):
msg = ("Could not construct a fetch strategy for package %s at "
"version %s")
@@ -960,17 +978,11 @@ class InvalidArgsError(FetchError):
class ChecksumError(FetchError):
-
"""Raised when archive fails to checksum."""
- def __init__(self, message, long_msg=None):
- super(ChecksumError, self).__init__(message, long_msg)
-
class NoStageError(FetchError):
-
"""Raised when fetch operations are called before set_stage()."""
-
def __init__(self, method):
super(NoStageError, self).__init__(
"Must call FetchStrategy.set_stage() before calling %s" %
diff --git a/lib/spack/spack/stage.py b/lib/spack/spack/stage.py
index 8377f9651f..4157511ce0 100644
--- a/lib/spack/spack/stage.py
+++ b/lib/spack/spack/stage.py
@@ -425,6 +425,9 @@ class Stage(object):
self.fetcher = fetcher
self.fetcher.fetch()
break
+ except spack.fetch_strategy.NoCacheError as e:
+ # Don't bother reporting when something is not cached.
+ continue
except spack.error.SpackError as e:
tty.msg("Fetching from %s failed." % fetcher)
tty.debug(e)