do_install : can stop at an arbitrary phase
The mechanism would be simpler if we could leverage exceptions to raise signals. Unfortunately forking does not permit to do so.
This commit is contained in:
parent
a43c63f149
commit
857d7bfe0f
1 changed files with 53 additions and 59 deletions
|
@ -104,10 +104,6 @@ def phase_wrapper(spec, prefix):
|
||||||
# and give them the chance to fail
|
# and give them the chance to fail
|
||||||
for check in self.sanity_checks:
|
for check in self.sanity_checks:
|
||||||
check(instance)
|
check(instance)
|
||||||
# Permit instance to drive the execution
|
|
||||||
if self.name == instance.last_phase:
|
|
||||||
raise StopIteration('Stopping at \'{0}\' phase'.format(self.name))
|
|
||||||
|
|
||||||
|
|
||||||
return phase_wrapper
|
return phase_wrapper
|
||||||
|
|
||||||
|
@ -1015,14 +1011,6 @@ def do_install(self,
|
||||||
make_jobs -- Number of make jobs to use for install. Default is ncpus
|
make_jobs -- Number of make jobs to use for install. Default is ncpus
|
||||||
run_tests -- Runn tests within the package's install()
|
run_tests -- Runn tests within the package's install()
|
||||||
"""
|
"""
|
||||||
#if allowed_phases is None:
|
|
||||||
# allowed_phases = self.phases
|
|
||||||
# FIXME : Refine the error message
|
|
||||||
last_phase = kwargs.get('stop_at', None)
|
|
||||||
if last_phase is not None and last_phase not in self.phases:
|
|
||||||
raise KeyError('phase {0} is not among the allowed phases for package {1}'.format(last_phase, self))
|
|
||||||
self.last_phase = last_phase
|
|
||||||
|
|
||||||
if not self.spec.concrete:
|
if not self.spec.concrete:
|
||||||
raise ValueError("Can only install concrete packages.")
|
raise ValueError("Can only install concrete packages.")
|
||||||
|
|
||||||
|
@ -1059,6 +1047,16 @@ def do_install(self,
|
||||||
# Set run_tests flag before starting build.
|
# Set run_tests flag before starting build.
|
||||||
self.run_tests = run_tests
|
self.run_tests = run_tests
|
||||||
|
|
||||||
|
last_phase = kwargs.get('stop_at', None)
|
||||||
|
phases_to_be_executed = self.phases
|
||||||
|
# We want to stop early
|
||||||
|
if last_phase is not None:
|
||||||
|
if last_phase not in self.phases:
|
||||||
|
raise KeyError('phase {0} is not among the allowed phases for package {1}'.format(last_phase, self))
|
||||||
|
idx = self.phases.index(last_phase)
|
||||||
|
phases_to_be_executed = self.phases[:idx + 1]
|
||||||
|
keep_stage = True
|
||||||
|
|
||||||
# Set parallelism before starting build.
|
# Set parallelism before starting build.
|
||||||
self.make_jobs = make_jobs
|
self.make_jobs = make_jobs
|
||||||
|
|
||||||
|
@ -1074,70 +1072,65 @@ def build_process():
|
||||||
else:
|
else:
|
||||||
self.do_stage()
|
self.do_stage()
|
||||||
|
|
||||||
tty.msg("Building %s" % self.name)
|
tty.msg("Building {0} [{1}]".format(self.name, type(self).__base__ ))
|
||||||
|
|
||||||
self.stage.keep = keep_stage
|
self.stage.keep = keep_stage
|
||||||
self.build_directory = join_path(self.stage.path, 'spack-build')
|
self.build_directory = join_path(self.stage.path, 'spack-build')
|
||||||
self.source_directory = self.stage.source_path
|
self.source_directory = self.stage.source_path
|
||||||
|
|
||||||
with self.stage:
|
try:
|
||||||
# Run the pre-install hook in the child process after
|
with self.stage:
|
||||||
# the directory is created.
|
# Run the pre-install hook in the child process after
|
||||||
spack.hooks.pre_install(self)
|
# the directory is created.
|
||||||
|
spack.hooks.pre_install(self)
|
||||||
if fake:
|
if fake:
|
||||||
self.do_fake_install()
|
self.do_fake_install()
|
||||||
else:
|
else:
|
||||||
# Do the real install in the source directory.
|
# Do the real install in the source directory.
|
||||||
self.stage.chdir_to_source()
|
self.stage.chdir_to_source()
|
||||||
|
# Save the build environment in a file before building.
|
||||||
# Save the build environment in a file before building.
|
env_path = join_path(os.getcwd(), 'spack-build.env')
|
||||||
env_path = join_path(os.getcwd(), 'spack-build.env')
|
|
||||||
|
|
||||||
try:
|
|
||||||
# Redirect I/O to a build log (and optionally to
|
# Redirect I/O to a build log (and optionally to
|
||||||
# the terminal)
|
# the terminal)
|
||||||
log_path = join_path(os.getcwd(), 'spack-build.out')
|
log_path = join_path(os.getcwd(), 'spack-build.out')
|
||||||
log_file = open(log_path, 'w')
|
|
||||||
# FIXME : refactor this assignment
|
# FIXME : refactor this assignment
|
||||||
self.log_path = log_path
|
self.log_path = log_path
|
||||||
self.env_path = env_path
|
self.env_path = env_path
|
||||||
with log_output(log_file, verbose, sys.stdout.isatty(),
|
dump_environment(env_path)
|
||||||
True):
|
for phase_name, phase in zip(phases_to_be_executed, self._InstallPhase_phases):
|
||||||
dump_environment(env_path)
|
log_file = open(log_path, 'a')
|
||||||
try:
|
tty.msg('Executing phase : \'{0}\''.format(phase_name))
|
||||||
for phase in self._InstallPhase_phases:
|
with log_output(log_file, verbose, sys.stdout.isatty(), True):
|
||||||
# TODO : Log to screen the various phases
|
getattr(self, phase)(self.spec, self.prefix)
|
||||||
getattr(self, phase)(self.spec, self.prefix)
|
if len(phases_to_be_executed) != len(self._InstallPhase_phases):
|
||||||
self.log()
|
return
|
||||||
except AttributeError as e:
|
self.log()
|
||||||
# FIXME : improve error messages
|
# Run post install hooks before build stage is removed.
|
||||||
raise ProcessError(e.message, long_message='')
|
spack.hooks.post_install(self)
|
||||||
except ProcessError as e:
|
|
||||||
# Annotate ProcessErrors with the location of
|
|
||||||
# the build log
|
|
||||||
e.build_log = log_path
|
|
||||||
raise e
|
|
||||||
|
|
||||||
# Run post install hooks before build stage is removed.
|
# Stop timer.
|
||||||
spack.hooks.post_install(self)
|
self._total_time = time.time() - start_time
|
||||||
|
build_time = self._total_time - self._fetch_time
|
||||||
|
|
||||||
# Stop timer.
|
tty.msg("Successfully installed %s" % self.name,
|
||||||
self._total_time = time.time() - start_time
|
"Fetch: %s. Build: %s. Total: %s." %
|
||||||
build_time = self._total_time - self._fetch_time
|
(_hms(self._fetch_time), _hms(build_time),
|
||||||
|
_hms(self._total_time)))
|
||||||
|
print_pkg(self.prefix)
|
||||||
|
|
||||||
tty.msg("Successfully installed %s" % self.name,
|
except ProcessError as e:
|
||||||
"Fetch: %s. Build: %s. Total: %s." %
|
# Annotate ProcessErrors with the location of
|
||||||
(_hms(self._fetch_time), _hms(build_time),
|
# the build log
|
||||||
_hms(self._total_time)))
|
e.build_log = log_path
|
||||||
print_pkg(self.prefix)
|
raise e
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Create the install prefix and fork the build process.
|
if len(phases_to_be_executed) == len(self.phases):
|
||||||
spack.install_layout.create_install_directory(self.spec)
|
# Create the install prefix and fork the build process.
|
||||||
|
spack.install_layout.create_install_directory(self.spec)
|
||||||
except directory_layout.InstallDirectoryAlreadyExistsError:
|
except directory_layout.InstallDirectoryAlreadyExistsError:
|
||||||
# FIXME : refactor this as a prerequisites to configure
|
# FIXME : refactor this as a prerequisites to configure
|
||||||
if 'install' in self.phases:
|
if 'install' in phases_to_be_executed:
|
||||||
# Abort install if install directory exists.
|
# Abort install if install directory exists.
|
||||||
# But do NOT remove it (you'd be overwriting someone else's stuff)
|
# But do NOT remove it (you'd be overwriting someone else's stuff)
|
||||||
tty.warn("Keeping existing install prefix in place.")
|
tty.warn("Keeping existing install prefix in place.")
|
||||||
|
@ -1163,7 +1156,8 @@ def build_process():
|
||||||
|
|
||||||
# note: PARENT of the build process adds the new package to
|
# note: PARENT of the build process adds the new package to
|
||||||
# the database, so that we don't need to re-read from file.
|
# the database, so that we don't need to re-read from file.
|
||||||
spack.installed_db.add(self.spec, self.prefix, explicit=explicit)
|
if len(phases_to_be_executed) == len(self.phases):
|
||||||
|
spack.installed_db.add(self.spec, self.prefix, explicit=explicit)
|
||||||
|
|
||||||
def log(self):
|
def log(self):
|
||||||
# Copy provenance into the install directory on success
|
# Copy provenance into the install directory on success
|
||||||
|
|
Loading…
Reference in a new issue