Can now mirror tarballs in a local directory.

- Can add tarballs to local directory; no longer have to download from source URL.
This commit is contained in:
Todd Gamblin
2014-01-26 01:03:16 -08:00
parent aaf16a339a
commit 03a32f0d5b
5 changed files with 69 additions and 39 deletions

View File

@@ -104,6 +104,20 @@
# #
sys_type = None sys_type = None
#
# Places to download tarballs from. Examples:
#
# For a local directory:
# mirrors = ['file:///Users/gamblin2/spack-mirror']
#
# For a website:
# mirrors = ['http://spackports.org/spack-mirror/']
#
# For no mirrors:
# mirrors = []
#
mirrors = []
# Important environment variables # Important environment variables
SPACK_NO_PARALLEL_MAKE = 'SPACK_NO_PARALLEL_MAKE' SPACK_NO_PARALLEL_MAKE = 'SPACK_NO_PARALLEL_MAKE'
SPACK_LIB = 'SPACK_LIB' SPACK_LIB = 'SPACK_LIB'

View File

@@ -389,7 +389,10 @@ def stage(self):
raise ValueError("Can only get a stage for a concrete package.") raise ValueError("Can only get a stage for a concrete package.")
if self._stage is None: if self._stage is None:
self._stage = Stage(self.url, str(self.spec)) mirror_path="%s/%s-%s.tar.gz" % (
self.name, self.name, self.version)
self._stage = Stage(
self.url, mirror_path=mirror_path, name=str(self.spec))
return self._stage return self._stage
@@ -688,7 +691,8 @@ def module(self):
def install(self, spec, prefix): def install(self, spec, prefix):
"""Package implementations override this with their own build configuration.""" """Package implementations override this with their own build configuration."""
tty.die("Packages must provide an install method!") configure()
#tty.die("Packages must provide an install method!")
def do_uninstall(self): def do_uninstall(self):

View File

@@ -36,12 +36,12 @@ class Libelf(Package):
versions = { '0.8.13' : '4136d7b4c04df68b686570afa26988ac', versions = { '0.8.13' : '4136d7b4c04df68b686570afa26988ac',
'0.8.12' : 'e21f8273d9f5f6d43a59878dc274fec7', } '0.8.12' : 'e21f8273d9f5f6d43a59878dc274fec7', }
def install(self, spec, prefix): # def install(self, spec, prefix):
configure("--prefix=" + prefix, # configure("--prefix=" + prefix,
"--enable-shared", # "--enable-shared",
"--disable-dependency-tracking", # "--disable-dependency-tracking",
"--disable-debug") # "--disable-debug")
make() # make()
# The mkdir commands in libelf's install can fail in parallel # # The mkdir commands in libelf's install can fail in parallel
make("install", parallel=False) # make("install", parallel=False)

View File

@@ -65,7 +65,7 @@ class Stage(object):
similar, and are intended to persist for only one run of spack. similar, and are intended to persist for only one run of spack.
""" """
def __init__(self, url, name=None): def __init__(self, url, **kwargs):
"""Create a stage object. """Create a stage object.
Parameters: Parameters:
url URL of the archive to be downloaded into this stage. url URL of the archive to be downloaded into this stage.
@@ -75,9 +75,11 @@ def __init__(self, url, name=None):
stage object later). If name is not provided, then this stage object later). If name is not provided, then this
stage will be given a unique name automatically. stage will be given a unique name automatically.
""" """
self.name = kwargs.get('name')
self.mirror_path = kwargs.get('mirror_path')
self.tmp_root = find_tmp_root() self.tmp_root = find_tmp_root()
self.url = url self.url = url
self.name = name
self.path = None # This will be set after setup is called. self.path = None # This will be set after setup is called.
@@ -210,6 +212,30 @@ def chdir(self):
tty.die("Setup failed: no such directory: " + self.path) tty.die("Setup failed: no such directory: " + self.path)
def fetch_from_url(self, url):
try:
# Run curl but grab the mime type from the http headers
headers = spack.curl('-#', # status bar
'-O', # save file to disk
'-D', '-', # print out HTML headers
'-L', url, return_output=True)
except:
# clean up archive on failure.
if self.archive_file:
os.remove(self.archive_file)
raise
# Check if we somehow got an HTML file rather than the archive we
# asked for. We only look at the last content type, to handle
# redirects properly.
content_types = re.findall(r'Content-Type:[^\r\n]+', headers)
if content_types and 'text/html' in content_types[-1]:
tty.warn("The contents of " + self.archive_file + " look like HTML.",
"The checksum will likely be bad. If it is, you can use",
"'spack clean --all' to remove the bad archive, then fix",
"your internet gateway issue and install again.")
def fetch(self): def fetch(self):
"""Downloads the file at URL to the stage. Returns true if it was downloaded, """Downloads the file at URL to the stage. Returns true if it was downloaded,
false if it already existed.""" false if it already existed."""
@@ -218,29 +244,15 @@ def fetch(self):
tty.msg("Already downloaded %s." % self.archive_file) tty.msg("Already downloaded %s." % self.archive_file)
else: else:
tty.msg("Fetching %s" % self.url) urls = [self.url]
if self.mirror_path:
urls += ["%s/%s" % (m, self.mirror_path) for m in spack.mirrors]
try: for url in urls:
# Run curl but grab the mime type from the http headers tty.msg("Trying to fetch from %s" % url)
headers = spack.curl('-#', # status bar self.fetch_from_url(url)
'-O', # save file to disk
'-D', '-', # print out HTML headers
'-L', self.url, return_output=True)
except:
# clean up archive on failure.
if self.archive_file: if self.archive_file:
os.remove(self.archive_file) break
raise
# Check if we somehow got an HTML file rather than the archive we
# asked for. We only look at the last content type, to handle
# redirects properly.
content_types = re.findall(r'Content-Type:[^\r\n]+', headers)
if content_types and 'text/html' in content_types[-1]:
tty.warn("The contents of " + self.archive_file + " look like HTML.",
"The checksum will likely be bad. If it is, you can use",
"'spack clean --all' to remove the bad archive, then fix",
"your internet gateway issue and install again.")
if not self.archive_file: if not self.archive_file:
raise FailedDownloadError(url) raise FailedDownloadError(url)

View File

@@ -189,7 +189,7 @@ def check_destroy(self, stage, stage_name):
def checkSetupAndDestroy(self, stage_name=None): def checkSetupAndDestroy(self, stage_name=None):
stage = Stage(archive_url, stage_name) stage = Stage(archive_url, name=stage_name)
stage.setup() stage.setup()
self.check_setup(stage, stage_name) self.check_setup(stage, stage_name)
@@ -218,7 +218,7 @@ def test_setup_and_destroy_no_name_without_tmp(self):
def test_chdir(self): def test_chdir(self):
stage = Stage(archive_url, stage_name) stage = Stage(archive_url, name=stage_name)
stage.chdir() stage.chdir()
self.check_setup(stage, stage_name) self.check_setup(stage, stage_name)
@@ -229,7 +229,7 @@ def test_chdir(self):
def test_fetch(self): def test_fetch(self):
stage = Stage(archive_url, stage_name) stage = Stage(archive_url, name=stage_name)
stage.fetch() stage.fetch()
self.check_setup(stage, stage_name) self.check_setup(stage, stage_name)
@@ -241,7 +241,7 @@ def test_fetch(self):
def test_expand_archive(self): def test_expand_archive(self):
stage = Stage(archive_url, stage_name) stage = Stage(archive_url, name=stage_name)
stage.fetch() stage.fetch()
self.check_setup(stage, stage_name) self.check_setup(stage, stage_name)
@@ -255,7 +255,7 @@ def test_expand_archive(self):
def test_expand_archive(self): def test_expand_archive(self):
stage = Stage(archive_url, stage_name) stage = Stage(archive_url, name=stage_name)
stage.fetch() stage.fetch()
self.check_setup(stage, stage_name) self.check_setup(stage, stage_name)
@@ -271,7 +271,7 @@ def test_expand_archive(self):
def test_restage(self): def test_restage(self):
stage = Stage(archive_url, stage_name) stage = Stage(archive_url, name=stage_name)
stage.fetch() stage.fetch()
stage.expand_archive() stage.expand_archive()