summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/spack/spack/fetch_strategy.py24
-rw-r--r--lib/spack/spack/stage.py12
2 files changed, 34 insertions, 2 deletions
diff --git a/lib/spack/spack/fetch_strategy.py b/lib/spack/spack/fetch_strategy.py
index 4ea87bea7e..ce2c4e30c7 100644
--- a/lib/spack/spack/fetch_strategy.py
+++ b/lib/spack/spack/fetch_strategy.py
@@ -157,12 +157,26 @@ class URLFetchStrategy(FetchStrategy):
tty.msg("Already downloaded %s" % self.archive_file)
return
+ possible_files = self.stage.expected_archive_files
+ save_file = None
+ partial_file = None
+ if possible_files:
+ save_file = self.stage.expected_archive_files[0]
+ partial_file = self.stage.expected_archive_files[0] + '.part'
+
tty.msg("Trying to fetch from %s" % self.url)
- curl_args = ['-O', # save file to disk
+ if partial_file:
+ save_args = ['-C', '-', # continue partial downloads
+ '-o', partial_file] # use a .part file
+ else:
+ save_args = ['-O']
+
+ curl_args = save_args + [
'-f', # fail on >400 errors
'-D', '-', # print out HTML headers
- '-L', self.url, ]
+ '-L', # resolve 3xx redirects
+ self.url, ]
if sys.stdout.isatty():
curl_args.append('-#') # status bar when using a tty
@@ -178,6 +192,9 @@ class URLFetchStrategy(FetchStrategy):
if self.archive_file:
os.remove(self.archive_file)
+ if partial_file and os.path.exists(partial_file):
+ os.remove(partial_file)
+
if spack.curl.returncode == 22:
# This is a 404. Curl will print the error.
raise FailedDownloadError(
@@ -209,6 +226,9 @@ class URLFetchStrategy(FetchStrategy):
"'spack clean <package>' to remove the bad archive, then fix",
"your internet gateway issue and install again.")
+ if save_file:
+ os.rename(partial_file, save_file)
+
if not self.archive_file:
raise FailedDownloadError(self.url)
diff --git a/lib/spack/spack/stage.py b/lib/spack/spack/stage.py
index d711752c20..84c47ee660 100644
--- a/lib/spack/spack/stage.py
+++ b/lib/spack/spack/stage.py
@@ -211,6 +211,18 @@ class Stage(object):
return False
@property
+ def expected_archive_files(self):
+ """Possible archive file paths."""
+ paths = []
+ if isinstance(self.fetcher, fs.URLFetchStrategy):
+ paths.append(os.path.join(self.path, os.path.basename(self.fetcher.url)))
+
+ if self.mirror_path:
+ paths.append(os.path.join(self.path, os.path.basename(self.mirror_path)))
+
+ return paths
+
+ @property
def archive_file(self):
"""Path to the source archive within this stage directory."""
paths = []