def verify(self): """Check if the installation at :any:`installation_prefix` is valid. A valid installation provides all expected files and commands. Subclasses may wish to perform additional checks. Raises: SoftwarePackageError: Describs why the installation is invalid. """ LOGGER.debug("Verifying %s installation at '%s'", self.title, self.install_prefix) if not os.path.exists(self.install_prefix): raise SoftwarePackageError("'%s' does not exist" % self.install_prefix) for cmd in self.verify_commands: path = os.path.join(self.bin_path, cmd) if not os.path.exists(path): raise SoftwarePackageError("'%s' is missing" % path) if not os.access(path, os.X_OK): raise SoftwarePackageError( "'%s' exists but is not executable" % path) for lib in self.verify_libraries: path = os.path.join(self.lib_path, lib) if not util.path_accessible(path): # Some systems (e.g. SuSE) append the machine bitwidth to the library path path = os.path.join(self.lib_path + '64', lib) if not util.path_accessible(path): raise SoftwarePackageError("'%s' is not accessible" % path) for header in self.verify_headers: path = os.path.join(self.include_path, header) if not util.path_accessible(path): raise SoftwarePackageError("'%s' is not accessible" % path) LOGGER.debug("%s installation at '%s' is valid", self.name, self.install_prefix)
def make_install(self, flags): """Invoke `make install`. Args: flags (list): Command line flags to pass to `make`. Raises: SoftwarePackageError: Configuration failed. """ assert self._src_prefix LOGGER.debug("Installing %s to '%s'", self.name, self.install_prefix) cmd = ['make', 'install'] + parallel_make_flags() + flags LOGGER.info("Installing %s...", self.title) if util.create_subprocess(cmd, cwd=self._src_prefix, stdout=False, show_progress=True): cmd = ['make', 'install'] + flags if util.create_subprocess(cmd, cwd=self._src_prefix, stdout=False, show_progress=True): util.add_error_stack(self._src_prefix) raise SoftwarePackageError('%s installation failed' % self.title) # Some systems use lib64 instead of lib if os.path.isdir(self.lib_path + '64') and not os.path.isdir(self.lib_path): os.symlink(self.lib_path + '64', self.lib_path)
def make(self, flags): """Invoke `make`. Args: flags (list): Command line flags to pass to `make`. Raises: SoftwarePackageError: Compilation failed. """ assert self._src_prefix LOGGER.debug("Making %s at '%s'", self.name, self._src_prefix) cmd = ['make'] + parallel_make_flags() + flags LOGGER.info("Compiling %s...", self.title) if util.create_subprocess(cmd, cwd=self._src_prefix, stdout=False, show_progress=True): cmd = ['make'] + flags if util.create_subprocess(cmd, cwd=self._src_prefix, stdout=False, show_progress=True): util.add_error_stack(self._src_prefix) raise SoftwarePackageError('%s compilation failed' % self.title)
def configure(self, _): family_flags = {GNU.name: '-GNU', INTEL.name: '-icpc', PGI.name: '-pgCC'} compiler_flag = family_flags.get(self.compilers[CXX].info.family.name, '') cmd = ['./configure', '-prefix=' + self.install_prefix, compiler_flag] LOGGER.info("Configuring PDT...") if util.create_subprocess(cmd, cwd=self._src_prefix, stdout=False, show_progress=True): raise SoftwarePackageError('%s configure failed' % self.title)
def _configure_edg4x_rose(self): LOGGER.info('edg4x-rose parser configuration failed. Retrying...') cwd = os.path.join(self.install_prefix, 'contrib', 'rose', 'edg44', self.tau_magic.name, 'roseparse') if not os.path.exists(cwd): LOGGER.info("roseparse not available on %s. Good luck!", self.tau_magic.name) return if util.create_subprocess(['./configure'], cwd=cwd, stdout=False, show_progress=True): raise SoftwarePackageError('Unable to configure edg4x-rose parsers') LOGGER.info("'edg4x-rose parser configuration successful. Continuing %s verification...", self.title)
def __init__(self, sources, target_arch, target_os, compilers): # PAPI can't be built with IBM compilers so substitute GNU compilers instead if compilers[CC].unwrap().info.family is IBM: try: gnu_compilers = GNU.installation() except ConfigurationError: raise SoftwarePackageError("GNU compilers (required to build PAPI) could not be found.") compilers = compilers.modify(Host_CC=gnu_compilers[CC], Host_CXX=gnu_compilers[CXX]) super(PapiInstallation, self).__init__('papi', 'PAPI', sources, target_arch, target_os, compilers, REPOS, None, LIBRARIES, None) self._xml_event_info = None
def verify(self): super(ScorepInstallation, self).verify() # Use Score-P's `scorep-info` command to check if this Score-P installation # was configured with the flags we need. cmd = [os.path.join(self.bin_path, 'scorep-info'), 'config-summary'] try: stdout = util.get_command_output(cmd) except CalledProcessError as err: raise SoftwarePackageError("%s failed with return code %d: %s" % (cmd, err.returncode, err.output)) flags = self._get_flags() found_flags = set() extra_flags = set() in_section = False for line in stdout.splitlines(): if line.startswith('Configure command:'): in_section = True continue elif in_section: line = line.replace('./configure', '') if not line.startswith(' '): break for flag in flags: if "'%s'" % flag in line: found_flags.add(flag) break else: extra_flags.add(line.replace('\\', '').strip()) # Some extra flags are harmless for flag in list(extra_flags): if flag.startswith("'--prefix="): extra_flags.remove(flag) if found_flags != set(flags): raise SoftwarePackageError( "Score-P installation at '%s' was not configured with flags %s" % (self.install_prefix, ' '.join(flags))) if extra_flags: raise SoftwarePackageError( "Score-P installation at '%s' was configured with extra flags %s" % (self.install_prefix, ' '.join(extra_flags)))
def __init__(self, sources, target_arch, target_os, compilers): # libunwind can't be built with PGI compilers so substitute GNU compilers instead if compilers[CC].unwrap().info.family is PGI: try: gnu_compilers = GNU.installation() except ConfigurationError: raise SoftwarePackageError( "GNU compilers (required to build libunwind) could not be found." ) compilers = compilers.modify(Host_CC=gnu_compilers[CC], Host_CXX=gnu_compilers[CXX]) super(LibunwindInstallation, self).__init__('libunwind', 'libunwind', sources, target_arch, target_os, compilers, REPOS, None, LIBRARIES, HEADERS)
def install(self, force_reinstall=False): """Execute the installation sequence in a sanitized environment. Modifies the system by building and installing software. Args: force_reinstall (bool): If True, reinstall even if the software package passes verification. Raises: SoftwarePackageError: Installation failed. """ for pkg in self.dependencies.itervalues(): pkg.install(force_reinstall) if self.unmanaged or not force_reinstall: try: return self.verify() except SoftwarePackageError as err: if self.unmanaged: raise SoftwarePackageError( "%s source package is unavailable and the installation at '%s' " "is invalid: %s" % (self.title, self.install_prefix, err), "Specify source code path or URL to enable package reinstallation." ) elif not force_reinstall: LOGGER.debug(err) LOGGER.info("Installing %s to '%s'", self.title, self.install_prefix) if os.path.isdir(self.install_prefix): LOGGER.info("Cleaning %s installation prefix '%s'", self.title, self.install_prefix) util.rmtree(self.install_prefix, ignore_errors=True) with new_os_environ(), util.umask(0o002): try: self._src_prefix = self._prepare_src() self.installation_sequence() self.set_group() except Exception as err: LOGGER.info("%s installation failed: %s", self.title, err) #util.add_error_stack(self._src_prefix) raise else: # Delete the decompressed source code to save space. The source archive is retained. LOGGER.debug("Deleting '%s'", self._src_prefix) util.rmtree(self._src_prefix, ignore_errors=True) self._src_prefix = None # Verify the new installation LOGGER.info("Verifying %s installation...", self.title) return self.verify()
def __init__(self, sources, target_arch, target_os, compilers): # PDT 3.22 can't be built with PGI compilers so substitute GNU compilers instead if compilers[CC].unwrap().info.family is PGI: try: gnu_compilers = GNU.installation() except ConfigurationError: raise SoftwarePackageError("GNU compilers (required to build PDT) could not be found.") compilers = compilers.modify(Host_CC=gnu_compilers[CC], Host_CXX=gnu_compilers[CXX]) super(PdtInstallation, self).__init__('pdt', 'PDT', sources, target_arch, target_os, compilers, REPOS, COMMANDS, None, None) self.tau_magic = TauMagic.find((self.target_arch, self.target_os)) # PDT puts installation files (bin, lib, etc.) in a magically named subfolder self._bin_subdir = os.path.join(self.tau_magic.name, 'bin') self._lib_subdir = os.path.join(self.tau_magic.name, 'lib') # Work around brokenness in edg4x-rose installer self._retry_verify = True
def configure(self, flags): """Invoke `configure`. Args: flags (list): Command line flags to pass to `configure`. Raises: SoftwarePackageError: Configuration failed. """ assert self._src_prefix LOGGER.debug("Configuring %s at '%s'", self.name, self._src_prefix) cmd = ['./configure', '--prefix=%s' % self.install_prefix] + flags LOGGER.info("Configuring %s...", self.title) if util.create_subprocess(cmd, cwd=self._src_prefix, stdout=False, show_progress=True): util.add_error_stack(self._src_prefix) raise SoftwarePackageError('%s configure failed' % self.title)
def cmake(self, flags): """Invoke `cmake`. Args: flags (list): Command line flags to pass to `cmake`. Raises: SoftwarePackageError: Configuration failed. """ assert self._src_prefix cmake = self._get_cmake() cmd = [cmake, '-DCMAKE_INSTALL_PREFIX=%s' % self.install_prefix ] + flags LOGGER.info("Executing CMake for %s...", self.title) if util.create_subprocess(cmd, cwd=self._src_prefix, stdout=False, show_progress=True): util.add_error_stack(self._src_prefix) raise SoftwarePackageError('CMake failed for %s' % self.title)