def get_build_stats(app, start_time, command_line): """ Return build statistics for this build """ time_now = time.time() build_time = round(time_now - start_time, 2) buildstats = OrderedDict([ ('easybuild-framework_version', str(FRAMEWORK_VERSION)), ('easybuild-easyblocks_version', str(EASYBLOCKS_VERSION)), ('timestamp', int(time_now)), ('build_time', build_time), ('install_size', det_size(app.installdir)), ('command_line', command_line), ('modules_tool', app.modules_tool.buildstats()), ]) for key, val in sorted(get_system_info().items()): buildstats.update({key: val}) return buildstats
def avail_easyconfig_params(easyblock, output_format=FORMAT_TXT): """ Compose overview of available easyconfig parameters, in specified format. """ params = copy.deepcopy(DEFAULT_CONFIG) # include list of extra parameters (if any) extra_params = {} app = get_easyblock_class(easyblock, error_on_missing_easyblock=False) if app is not None: extra_params = app.extra_options() params.update(extra_params) # compose title title = "Available easyconfig parameters" if extra_params: title += " (* indicates specific to the %s easyblock)" % app.__name__ # group parameters by category grouped_params = OrderedDict() for category in sorted_categories(): # exclude hidden parameters if category[1].upper() in [HIDDEN]: continue grpname = category[1] grouped_params[grpname] = {} for name, (dflt, descr, cat) in sorted(params.items()): if cat == category: if name in extra_params: # mark easyblock-specific parameters name = '%s*' % name grouped_params[grpname].update({name: (descr, dflt)}) if not grouped_params[grpname]: del grouped_params[grpname] # compose output, according to specified format (txt, rst, ...) return generate_doc('avail_easyconfig_params_%s' % output_format, [title, grouped_params])
def sanity_check_step(self): """Custom sanity check for EasyBuild.""" # check whether easy-install.pth contains correct entries easy_install_pth = os.path.join(self.installdir, self.pylibdir, 'easy-install.pth') if os.path.exists(easy_install_pth): easy_install_pth_txt = read_file(easy_install_pth) ignore_pkgs = ['setuptools', 'vsc-install'] if LooseVersion(self.version) > LooseVersion('3.999'): ignore_pkgs.append('vsc-base') for pkg in [ p for p in self.easybuild_pkgs if p not in ignore_pkgs ]: if pkg == 'vsc-base': # don't include strict version check for vsc-base pkg_regex = re.compile(r"^\./%s" % pkg.replace('-', '_'), re.M) else: major_minor_version = '.'.join(self.version.split('.')[:2]) pkg_regex = re.compile( r"^\./%s-%s" % (pkg.replace('-', '_'), major_minor_version), re.M) if not pkg_regex.search(easy_install_pth_txt): raise EasyBuildError( "Failed to find pattern '%s' in %s: %s", pkg_regex.pattern, easy_install_pth, easy_install_pth_txt) # list of dirs to check, by package # boolean indicates whether dir is expected to reside in Python lib/pythonX/site-packages dir subdirs_by_pkg = { 'easybuild-framework': [('easybuild/framework', True), ('easybuild/tools', True)], 'easybuild-easyblocks': [('easybuild/easyblocks', True)], 'easybuild-easyconfigs': [('easybuild/easyconfigs', False)], } if LooseVersion(self.version) >= LooseVersion('2.0') and LooseVersion( self.version) < LooseVersion('3.999'): subdirs_by_pkg.update({ 'vsc-base': [('vsc/utils', True)], }) # final list of directories to check, by setup tool # order matters, e.g. setuptools before distutils eb_dirs = OrderedDict() eb_dirs['setuptools'] = [] eb_dirs['distutils.core'] = flatten( [x for x in subdirs_by_pkg.values()]) # determine setup tool (setuptools or distutils) setup_tool = None for tool in eb_dirs.keys(): self.log.debug("Trying %s.." % tool) try: exec("from %s import setup" % tool) setup_tool = tool break except ImportError: pass self.log.debug('setup_tool: %s' % setup_tool) # for a setuptools installation, we need to figure out the egg dirs, # since we don't know the individual package versions if setup_tool == 'setuptools': try: installed_dirs = os.listdir( os.path.join(self.installdir, self.pylibdir)) for (pkg, subdirs) in subdirs_by_pkg.items(): sel_dirs = [ x for x in installed_dirs if x.startswith(pkg.replace('-', '_')) ] if not len(sel_dirs) == 1: raise EasyBuildError( "Failed to isolate installed egg dir for %s", pkg) for (subdir, _) in subdirs: # eggs always go in Python lib/pythonX/site-packages dir with setuptools eb_dirs['setuptools'].append( (os.path.join(sel_dirs[0], subdir), True)) except OSError as err: raise EasyBuildError( "Failed to determine sanity check dir paths: %s", err) # set of sanity check paths to check for EasyBuild custom_paths = { 'files': ['bin/eb'], 'dirs': [self.pylibdir] + [[x, os.path.join(self.pylibdir, x)][y] for (x, y) in eb_dirs[setup_tool]], } # make sure we don't trip over deprecated behavior in old EasyBuild versions eb_cmd = 'eb' if LooseVersion(self.version) <= LooseVersion('1.16.0'): eb_cmd = 'EASYBUILD_DEPRECATED=1.0 eb' # set of sanity check commands to run for EasyBuild custom_commands = [ # this may spit out a wrong version, but that should be safe to ignore # occurs when the EasyBuild being used is newer than the EasyBuild being installed (eb_cmd, '--version'), (eb_cmd, '-a'), (eb_cmd, '-e ConfigureMake -a'), ] # (temporary) cleanse copy of initial environment to avoid conflict with (potentially) loaded EasyBuild module self.real_initial_environ = copy.deepcopy(self.initial_environ) for env_var in ['_LMFILES_', 'LOADEDMODULES']: if env_var in self.initial_environ: self.initial_environ.pop(env_var) os.environ.pop(env_var) self.log.debug( "Unset $%s in current env and copy of original env to make sanity check work" % env_var) super(EB_EasyBuildMeta, self).sanity_check_step(custom_paths=custom_paths, custom_commands=custom_commands)
def configure_step(self): """Custom configuration procedure for ALADIN.""" # unset $LIBRARY_PATH set by modules of dependencies, because it may screw up linking if 'LIBRARY_PATH' in os.environ: self.log.debug("Unsetting $LIBRARY_PATH (was: %s)" % os.environ['LIBRARY_PATH']) self.orig_library_path = os.environ.pop('LIBRARY_PATH') # build auxiliary libraries auxlibs_dir = None my_gnu = None if self.toolchain.comp_family() == toolchain.GCC: my_gnu = 'y' # gfortran for var in ['CFLAGS', 'CXXFLAGS', 'F90FLAGS', 'FFLAGS']: flags = os.getenv(var) env.setvar(var, "%s -fdefault-real-8 -fdefault-double-8" % flags) self.log.info("Updated %s to '%s'" % (var, os.getenv(var))) elif self.toolchain.comp_family() == toolchain.INTELCOMP: my_gnu = 'i' # icc/ifort else: raise EasyBuildError("Don't know how to set 'my_gnu' variable in auxlibs build script.") self.log.info("my_gnu set to '%s'" % my_gnu) tmp_installroot = tempfile.mkdtemp(prefix='aladin_auxlibs_') try: cwd = os.getcwd() os.chdir(self.builddir) builddirs = os.listdir(self.builddir) auxlibs_dir = [x for x in builddirs if x.startswith('auxlibs_installer')][0] os.chdir(auxlibs_dir) auto_driver = 'driver_automatic' for line in fileinput.input(auto_driver, inplace=1, backup='.orig.eb'): line = re.sub(r"^(my_gnu\s*=\s*).*$", r"\1%s" % my_gnu, line) line = re.sub(r"^(my_r32\s*=\s*).*$", r"\1n", line) # always 64-bit real precision line = re.sub(r"^(my_readonly\s*=\s*).*$", r"\1y", line) # make libs read-only after build line = re.sub(r"^(my_installroot\s*=\s*).*$", r"\1%s" % tmp_installroot, line) sys.stdout.write(line) run_cmd("./%s" % auto_driver) os.chdir(cwd) except OSError as err: raise EasyBuildError("Failed to build ALADIN: %s", err) # build gmkpack, update PATH and set GMKROOT # we build gmkpack here because a config file is generated in the gmkpack isntall path try: gmkpack_dir = [x for x in builddirs if x.startswith('gmkpack')][0] os.chdir(os.path.join(self.builddir, gmkpack_dir)) qa = { 'Do you want to run the configuration file maker assistant now (y) or later [n] ?': 'n', } run_cmd_qa("./build_gmkpack", qa) os.chdir(cwd) paths = os.getenv('PATH').split(':') paths.append(os.path.join(self.builddir, gmkpack_dir, 'util')) env.setvar('PATH', ':'.join(paths)) env.setvar('GMKROOT', os.path.join(self.builddir, gmkpack_dir)) except OSError as err: raise EasyBuildError("Failed to build gmkpack: %s", err) # generate gmkpack configuration file self.conf_file = 'ALADIN_%s' % self.version self.conf_filepath = os.path.join(self.builddir, 'gmkpack_support', 'arch', '%s.x' % self.conf_file) try: if os.path.exists(self.conf_filepath): os.remove(self.conf_filepath) self.log.info("Removed existing gmpack config file %s" % self.conf_filepath) archdir = os.path.dirname(self.conf_filepath) if not os.path.exists(archdir): mkdir(archdir, parents=True) except OSError as err: raise EasyBuildError("Failed to remove existing file %s: %s", self.conf_filepath, err) mpich = 'n' known_mpi_libs = [toolchain.MPICH, toolchain.MPICH2, toolchain.INTELMPI] if self.toolchain.options.get('usempi', None) and self.toolchain.mpi_family() in known_mpi_libs: mpich = 'y' qpref = 'Please type the ABSOLUTE name of ' qsuff = ', or ignore (environment variables allowed) :' qsuff2 = ', or ignore : (environment variables allowed) :' comp_fam = self.toolchain.comp_family() if comp_fam == toolchain.GCC: gribdir = 'GNU' elif comp_fam == toolchain.INTELCOMP: gribdir = 'INTEL' else: raise EasyBuildError("Don't know which grib lib dir to use for compiler %s", comp_fam) aux_lib_gribex = os.path.join(tmp_installroot, gribdir, 'lib', 'libgribex.a') aux_lib_ibm = os.path.join(tmp_installroot, gribdir, 'lib', 'libibmdummy.a') grib_api_lib = os.path.join(get_software_root('grib_api'), 'lib', 'libgrib_api.a') grib_api_f90_lib = os.path.join(get_software_root('grib_api'), 'lib', 'libgrib_api_f90.a') grib_api_inc = os.path.join(get_software_root('grib_api'), 'include') jasperlib = os.path.join(get_software_root('JasPer'), 'lib', 'libjasper.a') mpilib = os.path.join(os.getenv('MPI_LIB_DIR'), os.getenv('MPI_LIB_SHARED')) # netCDF netcdf = get_software_root('netCDF') netcdf_fortran = get_software_root('netCDF-Fortran') if netcdf: netcdfinc = os.path.join(netcdf, 'include') if netcdf_fortran: netcdflib = os.path.join(netcdf_fortran, get_software_libdir('netCDF-Fortran'), 'libnetcdff.a') else: netcdflib = os.path.join(netcdf, get_software_libdir('netCDF'), 'libnetcdff.a') if not os.path.exists(netcdflib): raise EasyBuildError("%s does not exist", netcdflib) else: raise EasyBuildError("netCDF(-Fortran) not available") ldpaths = [ldflag[2:] for ldflag in os.getenv('LDFLAGS').split(' ')] # LDFLAGS have form '-L/path/to' lapacklibs = [] for lib in os.getenv('LAPACK_STATIC_LIBS').split(','): libpaths = [os.path.join(ldpath, lib) for ldpath in ldpaths] lapacklibs.append([libpath for libpath in libpaths if os.path.exists(libpath)][0]) lapacklib = ' '.join(lapacklibs) blaslibs = [] for lib in os.getenv('BLAS_STATIC_LIBS').split(','): libpaths = [os.path.join(ldpath, lib) for ldpath in ldpaths] blaslibs.append([libpath for libpath in libpaths if os.path.exists(libpath)][0]) blaslib = ' '.join(blaslibs) qa = { 'Do you want to run the configuration file maker assistant now (y) or later [n] ?': 'y', 'Do you want to setup your configuration file for MPICH (y/n) [n] ?': mpich, 'Please type the directory name where to find a dummy file mpif.h or ignore :': os.getenv('MPI_INC_DIR'), '%sthe library gribex or emos%s' % (qpref, qsuff2): aux_lib_gribex, '%sthe library ibm%s' % (qpref, qsuff): aux_lib_ibm, '%sthe library grib_api%s' % (qpref, qsuff): grib_api_lib, '%sthe library grib_api_f90%s' % (qpref, qsuff): grib_api_f90_lib, '%sthe JPEG auxilary library if enabled by Grib_api%s' % (qpref, qsuff2): jasperlib, '%sthe library netcdf%s' % (qpref, qsuff): netcdflib, '%sthe library lapack%s' % (qpref, qsuff): lapacklib, '%sthe library blas%s' % (qpref, qsuff): blaslib, '%sthe library mpi%s' % (qpref, qsuff): mpilib, '%sa MPI dummy library for serial executions, or ignore :' % qpref: '', 'Please type the directory name where to find grib_api headers, or ignore :': grib_api_inc, 'Please type the directory name where to find fortint.h or ignore :': '', 'Please type the directory name where to find netcdf headers, or ignore :': netcdfinc, 'Do you want to define CANARI (y/n) [y] ?': 'y', 'Please type the name of the script file used to generate a preprocessed blacklist file, or ignore :': '', 'Please type the name of the script file used to recover local libraries (gget), or ignore :': '', 'Please type the options to tune the gnu compilers, or ignore :': os.getenv('F90FLAGS'), } f90_seq = os.getenv('F90_SEQ') if not f90_seq: # F90_SEQ is only defined when usempi is enabled f90_seq = os.getenv('F90') stdqa = OrderedDict([ (r'Confirm library .* is .*', 'y'), # this one needs to be tried first! (r'.*fortran 90 compiler name .*\s*:\n\(suggestions\s*: .*\)', f90_seq), (r'.*fortran 90 compiler interfaced with .*\s*:\n\(suggestions\s*: .*\)', f90_seq), (r'Please type the ABSOLUTE name of .*library.*, or ignore\s*[:]*\s*[\n]*.*', ''), (r'Please .* to save this draft configuration file :\n.*', '%s.x' % self.conf_file), ]) no_qa = [ ".*ignored.", ] env.setvar('GMKTMP', self.builddir) env.setvar('GMKFILE', self.conf_file) run_cmd_qa("gmkfilemaker", qa, std_qa=stdqa, no_qa=no_qa) # set environment variables for installation dirs env.setvar('ROOTPACK', os.path.join(self.installdir, 'rootpack')) env.setvar('ROOTBIN', os.path.join(self.installdir, 'rootpack')) env.setvar('HOMEPACK', os.path.join(self.installdir, 'pack')) env.setvar('HOMEBIN', os.path.join(self.installdir, 'pack')) # patch config file to include right Fortran compiler flags regex_subs = [(r"^(FRTFLAGS\s*=.*)$", r"\1 %s" % os.getenv('FFLAGS'))] apply_regex_substitutions(self.conf_filepath, regex_subs)
def install_step(self): """Install ABAQUS using 'setup'.""" if LooseVersion(self.version) >= LooseVersion('2016'): change_dir(os.path.join(self.cfg['start_dir'], '1')) qa = { "Enter selection (default: Install):": '', "Enter selection (default: Close):": '', } no_qa = [ '___', r"\(\d+\s*[KM]B\)", r'\.\.\.$', ] # Match string for continuing on with the selected items nextstr = r"Enter selection \(default: Next\):\s*" # Allow for selection or deselection of components from lines of the form: # 5 [*] Tosca Fluid # This uses nextstr to make sure we only match the latest output in the Q&A process; # negative lookahead (?!___) is used to exclude ___...___ lines, to avoid matching across questions selectionstr = r"\s*(?P<nr>[-0-9]+) %%s %%s[ \w]*\n((?!%s)(?!___)[\S ]*\n)*%s$" % ( nextstr, nextstr) # ensure question patterns are considered in order by using an OrderedDict instance, # rather than a regular dictionary (where there's no guarantee on key order in general) std_qa = OrderedDict() # Enable Extended Product Documentation std_qa[selectionstr % (r"\[ \]", "Extended Product Documentation")] = "%(nr)s" # Enable Abaqus CAE (docs) std_qa[selectionstr % (r"\[ \]", "Abaqus CAE")] = "%(nr)s" # enable all ABAQUS components std_qa[selectionstr % (r"\[ \]", "Abaqus.*")] = "%(nr)s" std_qa[selectionstr % (r"\[ \]", "Cosimulation Services")] = "%(nr)s" # enable 3DSFlow Solver (used to be called "Abaqus/CFD Solver") std_qa[selectionstr % (r"\[ \]", "3DSFlow Solver")] = "%(nr)s" # disable/enable fe-safe components if self.cfg['with_fe_safe']: std_qa[selectionstr % (r"\[ \]", ".*fe-safe")] = "%(nr)s" else: std_qa[selectionstr % (r"\[*\]", ".*fe-safe")] = "%(nr)s" # Disable/enable Tosca if self.cfg['with_tosca']: std_qa[selectionstr % (r"\[\ \]", "Tosca")] = "%(nr)s" else: std_qa[selectionstr % (r"\[\*\]", "Tosca")] = "%(nr)s" # disable CloudView std_qa[ r"(?P<cloudview>[0-9]+) \[X\] Search using CloudView\nEnter selection:"] = '%(cloudview)s\n\n' # accept default port for documentation server std_qa[r"Check that the port is free.\nDefault \[[0-9]+\]:"] = '\n' # disable feedback by users std_qa[ r"(?P<feedback>[0-9]+) \[X\] Allow users to send feedback.\nEnter selection:"] = '%(feedback)s\n\n' # disable reverse proxy std_qa[ r"(?P<proxy>[0-9]+) \[X\] Use a reverse proxy.\nEnter selection:"] = '%(proxy)s\n\n' # Disable Isight std_qa[selectionstr % (r"\[\*\]", "Isight")] = "%(nr)s" # Disable Search using EXALEAD std_qa[ r"\s*(?P<exalead>[0-9]+) \[X\] Search using EXALEAD\nEnter selection:"] = '%(exalead)s\n\n' # Directories cae_subdir = os.path.join(self.installdir, 'cae') sim_subdir = os.path.join(self.installdir, 'sim') std_qa[r"Default.*SIMULIA/EstProducts.*:"] = cae_subdir std_qa[r"SIMULIA[0-9]*doc.*:"] = os.path.join( self.installdir, 'doc') std_qa[r"SimulationServices.*:"] = sim_subdir std_qa[ r"Choose the CODE installation directory.*:\n.*\n\n.*:"] = sim_subdir std_qa[r"SIMULIA/CAE.*:"] = cae_subdir std_qa[ r"location of your Abaqus services \(solvers\).*(\n.*){8}:\s*"] = sim_subdir std_qa[r"Default.*SIMULIA/Commands\]:\s*"] = os.path.join( self.installdir, 'Commands') std_qa[r"Default.*SIMULIA/CAE/plugins.*:\s*"] = os.path.join( self.installdir, 'plugins') std_qa[r"Default.*SIMULIA/Isight.*:\s*"] = os.path.join( self.installdir, 'Isight') std_qa[r"Default.*SIMULIA/fe-safe/.*:"] = os.path.join( self.installdir, 'fe-safe') std_qa[r"Default.*SIMULIA/Tosca.*:"] = os.path.join( self.installdir, 'tosca') # paths to STAR-CCM+, FLUENT are requested when Tosca is also installed; # these do not strictly need to be specified at installation time, so we don't std_qa[r"STAR-CCM.*\n((?!___)[\S ]*\n)*\nDefault \[\]:"] = '' std_qa[r"FLUENT.*\n((?!___)[\S ]*\n)*\nDefault \[\]:"] = '' std_qa[ r"location of your existing ANSA installation.*(\n.*){8}:"] = '' std_qa[r"FLUENT Path.*(\n.*){7}:"] = '' std_qa[ r"working directory to be used by Tosca Fluid\s*(\n.*)*Default \[/usr/temp\]:\s*"] = '/tmp' # License server std_qa[ r"License Server [0-9]+\s*(\n.*){3}:"] = 'abaqusfea' # bypass value for license server std_qa[r"License Server . \(redundant\)\s*(\n.*){3}:"] = '' std_qa[r"License Server Configuration((?!___).*\n)*" + nextstr] = '' std_qa[r"Please choose an action:"] = '1' if LooseVersion(self.version) >= LooseVersion('2022'): java_root = get_software_root('Java') if java_root: std_qa[ r"Please enter .*Java Runtime Environment.* path.(\n.*)+Default \[\]:"] = java_root std_qa[ r"Please enter .*Java Runtime Environment.* path.(\n.*)+Default \[.+\]:"] = '' else: raise EasyBuildError( "Java is a required dependency for ABAQUS versions >= 2022, but it is missing" ) # Continue std_qa[nextstr] = '' run_cmd_qa('./StartTUI.sh', qa, no_qa=no_qa, std_qa=std_qa, log_all=True, simple=True, maxhits=1000) else: change_dir(self.builddir) if self.cfg['install_cmd'] is None: self.cfg['install_cmd'] = "%s/%s-%s/setup" % ( self.builddir, self.name, self.version.split('-')[0]) self.cfg['install_cmd'] += " -replay %s" % self.replayfile if LooseVersion(self.version) < LooseVersion("6.13"): self.cfg['install_cmd'] += " -nosystemcheck" super(EB_ABAQUS, self).install_step() if LooseVersion(self.version) >= LooseVersion('2016'): # also install hot fixes (if any) hotfixes = [src for src in self.src if 'CFA' in src['name']] if hotfixes: # first install Part_3DEXP_SimulationServices hotfix(es), if any hotfixes_3dexp = [ src for src in self.src if 'CFA' in src['name'] and '3DEXP' in src['name'] ] if hotfixes_3dexp: hotfix_dir = os.path.join( self.builddir, 'Part_3DEXP_SimulationServices.Linux64', '1', 'Software') change_dir(hotfix_dir) # SIMULIA_ComputeServices part subdirs = glob.glob( 'HF_SIMULIA_ComputeServices.HF*.Linux64') if len(subdirs) == 1: subdir = subdirs[0] else: raise EasyBuildError( "Failed to find expected subdir for hotfix: %s", subdirs) cwd = change_dir(os.path.join(subdir, '1')) std_qa = OrderedDict() std_qa[r"Enter selection \(default: Next\):"] = '' std_qa[ "Choose the .*installation directory.*\n.*\n\n.*:"] = os.path.join( self.installdir, 'sim') std_qa[r"Enter selection \(default: Install\):"] = '' run_cmd_qa('./StartTUI.sh', {}, std_qa=std_qa, log_all=True, simple=True, maxhits=100) # F_CAASIMULIAComputeServicesBuildTime part change_dir(cwd) subdirs = glob.glob( 'HF_CAASIMULIAComputeServicesBuildTime.HF*.Linux64') if len(subdirs) == 1: subdir = subdirs[0] else: raise EasyBuildError( "Failed to find expected subdir for hotfix: %s", subdirs) cwd = change_dir(os.path.join(cwd, subdir, '1')) run_cmd_qa('./StartTUI.sh', {}, std_qa=std_qa, log_all=True, simple=True, maxhits=100) change_dir(cwd) # next install Part_SIMULIA_Abaqus_CAE hotfix (ABAQUS versions <= 2020) hotfix_dir = os.path.join(self.builddir, 'Part_SIMULIA_Abaqus_CAE.Linux64', '1', 'Software') if os.path.exists(hotfix_dir): change_dir(hotfix_dir) subdirs = glob.glob('SIMULIA_Abaqus_CAE.HF*.Linux64') if len(subdirs) == 1: subdir = subdirs[0] else: raise EasyBuildError( "Failed to find expected subdir for hotfix: %s", subdirs) cwd = change_dir(os.path.join(subdir, '1')) std_qa = OrderedDict() std_qa[r"Enter selection \(default: Next\):"] = '' std_qa[ "Choose the .*installation directory.*\n.*\n\n.*:"] = os.path.join( self.installdir, 'cae') std_qa[r"Enter selection \(default: Install\):"] = '' std_qa[ r"\[1\] Continue\n(?:.|\n)*Please choose an action:"] = '1' std_qa[ r"\[2\] Continue\n(?:.|\n)*Please choose an action:"] = '2' no_qa = [ r"Please be patient; it will take a few minutes to complete\.\n(\.)*" ] run_cmd_qa('./StartTUI.sh', {}, no_qa=no_qa, std_qa=std_qa, log_all=True, simple=True, maxhits=100) change_dir(cwd) # install SIMULIA Established Products hotfix (ABAQUS versions > 2020) hotfixes_estprd = [ src for src in self.src if 'CFA' in src['name'] and 'EstPrd' in src['name'] ] if hotfixes_estprd: hotfix_dir = os.path.join(self.builddir, 'Part_SIMULIA_EstPrd.Linux64', '1', 'Software') change_dir(hotfix_dir) subdirs = glob.glob('SIMULIA_EstPrd.HF*.Linux64') if len(subdirs) == 1: subdir = subdirs[0] else: raise EasyBuildError( "Failed to find expected subdir for hotfix: %s", subdirs) cwd = change_dir(os.path.join(subdir, '1')) no_qa = [ '___', '...', r'\(\d+[KM]B\)', ] std_qa = OrderedDict() std_qa[r"Enter selection \(default: Next\):"] = '' std_qa[ "Choose the .*installation directory.*\n.*\n\n.*:"] = os.path.join( self.installdir, 'cae') std_qa[r"Enter selection \(default: Install\):"] = '' std_qa[ r"The Abaqus commands directory.*:\n.*\n+Actions:\n.*\n_+\n\nPlease.*:"] = '1' std_qa[r"Enter selection \(default: Close\):"] = '' run_cmd_qa('./StartTUI.sh', {}, no_qa=no_qa, std_qa=std_qa, log_all=True, simple=True, maxhits=100) change_dir(cwd) # create 'abaqus' symlink for main command, which is not there anymore starting with ABAQUS 2022 if LooseVersion(self.version) >= LooseVersion('2022'): commands_dir = os.path.join(self.installdir, 'Commands') abaqus_cmd = os.path.join(commands_dir, 'abaqus') if os.path.exists(abaqus_cmd): self.log.info( "Main 'abaqus' command already found at %s, no need to create symbolic link", abaqus_cmd) else: abq_ver_cmd = os.path.join(commands_dir, 'abq%s' % self.version) self.log.info( "Creating symbolic link 'abaqus' for main command %s", abq_ver_cmd) if os.path.exists(abq_ver_cmd): cwd = change_dir(commands_dir) symlink(os.path.basename(abq_ver_cmd), os.path.basename(abaqus_cmd)) change_dir(cwd) else: raise EasyBuildError( "Path to main command %s does not exist!", abq_ver_cmd)
def check_easybuild_deps(modtool): """ Check presence and version of required and optional EasyBuild dependencies, and report back to terminal. """ version_regex = re.compile(r'\s(?P<version>[0-9][0-9.]+[a-z]*)') checks_data = OrderedDict() def extract_version(tool): """Helper function to extract (only) version for specific command line tool.""" out = get_tool_version(tool, ignore_ec=True) res = version_regex.search(out) if res: version = res.group('version') else: version = "UNKNOWN version" return version python_version = extract_version(sys.executable) opt_dep_versions = {} for key in EASYBUILD_OPTIONAL_DEPENDENCIES: pkg = EASYBUILD_OPTIONAL_DEPENDENCIES[key][0] if pkg is None: pkg = key.lower() try: mod = __import__(pkg) except ImportError: mod = None if mod: dep_version = det_pypkg_version(key, mod, import_name=pkg) else: dep_version = False opt_dep_versions[key] = dep_version checks_data['col_titles'] = ('name', 'version', 'used for') req_deps_key = "Required dependencies" checks_data[req_deps_key] = OrderedDict() checks_data[req_deps_key]['Python'] = (python_version, None) checks_data[req_deps_key]['modules tool:'] = (str(modtool), None) opt_deps_key = "Optional dependencies" checks_data[opt_deps_key] = {} for key in opt_dep_versions: checks_data[opt_deps_key][key] = (opt_dep_versions[key], EASYBUILD_OPTIONAL_DEPENDENCIES[key][1]) sys_tools_key = "System tools" checks_data[sys_tools_key] = {} for tool in SYSTEM_TOOLS: tool_info = None cmd = SYSTEM_TOOL_CMDS.get(tool, tool) if which(cmd): version = extract_version(cmd) if version.startswith('UNKNOWN'): tool_info = None else: tool_info = version else: tool_info = False checks_data[sys_tools_key][tool] = (tool_info, None) return checks_data
def install_step(self): """Install ABAQUS using 'setup'.""" if LooseVersion(self.version) >= LooseVersion('2016'): change_dir(os.path.join(self.cfg['start_dir'], '1')) qa = { "Enter selection (default: Install):": '', "Enter selection (default: Close):": '', } no_qa = [ '___', r"\(\d+\s*[KM]B\)", ] # Match string for continuing on with the selected items nextstr = r"Enter selection \(default: Next\):\s*" # Allow for selection or deselection of components from lines of the form: # 5 [*] Tosca Fluid # This uses nextstr to make sure we only match the latest output in the Q&A process; # negative lookahead (?!___) is used to exclude ___...___ lines, to avoid matching across questions selectionstr = r"\s*(?P<nr>[-0-9]+) %%s %%s[ \w]*\n((?!%s)(?!___)[\S ]*\n)*%s$" % (nextstr, nextstr) # ensure question patterns are considered in order by using an OrderedDict instance, # rather than a regular dictionary (where there's no guarantee on key order in general) std_qa = OrderedDict() # Enable Extended Product Documentation std_qa[selectionstr % (r"\[ \]", "Extended Product Documentation")] = "%(nr)s" # Enable Abaqus CAE (docs) std_qa[selectionstr % (r"\[ \]", "Abaqus CAE")] = "%(nr)s" # Disable Tosca std_qa[selectionstr % (r"\[\*\]", "Tosca")] = "%(nr)s" # Disable Isight std_qa[selectionstr % (r"\[\*\]", "Isight")] = "%(nr)s" # Disable Search using EXALEAD std_qa[r"\s*(?P<exalead>[0-9]+) \[X\] Search using EXALEAD\nEnter selection:"] = '%(exalead)s\n\n' # Directories cae_subdir = os.path.join(self.installdir, 'cae') sim_subdir = os.path.join(self.installdir, 'sim') std_qa[r"Default.*SIMULIA/EstProducts.*:"] = cae_subdir std_qa[r"SIMULIA[0-9]*doc.*:"] = os.path.join(self.installdir, 'doc') std_qa[r"SimulationServices.*:"] = sim_subdir std_qa[r"Choose the CODE installation directory.*:\n.*\n\n.*:"] = sim_subdir std_qa[r"SIMULIA/CAE.*:"] = cae_subdir std_qa[r"location of your Abaqus services \(solvers\).*(\n.*){8}:\s*"] = sim_subdir std_qa[r"Default.*SIMULIA/Commands\]:\s*"] = os.path.join(self.installdir, 'Commands') std_qa[r"Default.*SIMULIA/CAE/plugins.*:\s*"] = os.path.join(self.installdir, 'plugins') std_qa[r"Default.*SIMULIA/Isight.*:\s*"] = os.path.join(self.installdir, 'Isight') std_qa[r"Default.*SIMULIA/fe-safe/.*:"] = os.path.join(self.installdir, 'fe-safe') std_qa[r"Default.*SIMULIA/Tosca.*:"] = os.path.join(self.installdir, 'tosca') std_qa[r"location of your existing ANSA installation.*(\n.*){8}:"] = '' std_qa[r"FLUENT Path.*(\n.*){7}:"] = '' std_qa[r"working directory to be used by Tosca Fluid\s*(\n.*)*Default \[/usr/temp\]:\s*"] = '/tmp' # License server std_qa[r"License Server [0-9]+\s*(\n.*){3}:"] = 'abaqusfea' # bypass value for license server std_qa[r"License Server . \(redundant\)\s*(\n.*){3}:"] = '' std_qa[r"License Server Configuration((?!___).*\n)*" + nextstr] = '' std_qa[r"Please choose an action:"] = '1' # Continue std_qa[nextstr] = '' run_cmd_qa('./StartTUI.sh', qa, no_qa=no_qa, std_qa=std_qa, log_all=True, simple=True, maxhits=100) else: change_dir(self.builddir) if self.cfg['install_cmd'] is None: self.cfg['install_cmd'] = "%s/%s-%s/setup" % (self.builddir, self.name, self.version.split('-')[0]) self.cfg['install_cmd'] += " -replay %s" % self.replayfile if LooseVersion(self.version) < LooseVersion("6.13"): self.cfg['install_cmd'] += " -nosystemcheck" super(EB_ABAQUS, self).install_step() if LooseVersion(self.version) >= LooseVersion('2016'): # also install hot fixes (if any) hotfixes = [src for src in self.src if 'CFA' in src['name']] if hotfixes: # first install Part_3DEXP_SimulationServices hotfix(es), if any hotfixes_3dexp = [src for src in self.src if 'CFA' in src['name'] and '3DEXP' in src['name']] if hotfixes_3dexp: hotfix_dir = os.path.join(self.builddir, 'Part_3DEXP_SimulationServices.Linux64', '1', 'Software') change_dir(hotfix_dir) # SIMULIA_ComputeServices part subdirs = glob.glob('HF_SIMULIA_ComputeServices.HF*.Linux64') if len(subdirs) == 1: subdir = subdirs[0] else: raise EasyBuildError("Failed to find expected subdir for hotfix: %s", subdirs) cwd = change_dir(os.path.join(subdir, '1')) std_qa = OrderedDict() std_qa[r"Enter selection \(default: Next\):"] = '' std_qa["Choose the .*installation directory.*\n.*\n\n.*:"] = os.path.join(self.installdir, 'sim') std_qa[r"Enter selection \(default: Install\):"] = '' run_cmd_qa('./StartTUI.sh', {}, std_qa=std_qa, log_all=True, simple=True, maxhits=100) # F_CAASIMULIAComputeServicesBuildTime part change_dir(cwd) subdirs = glob.glob('HF_CAASIMULIAComputeServicesBuildTime.HF*.Linux64') if len(subdirs) == 1: subdir = subdirs[0] else: raise EasyBuildError("Failed to find expected subdir for hotfix: %s", subdirs) change_dir(os.path.join(cwd, subdir, '1')) run_cmd_qa('./StartTUI.sh', {}, std_qa=std_qa, log_all=True, simple=True, maxhits=100) # next install Part_SIMULIA_Abaqus_CAE hotfix hotfix_dir = os.path.join(self.builddir, 'Part_SIMULIA_Abaqus_CAE.Linux64', '1', 'Software') change_dir(hotfix_dir) subdirs = glob.glob('SIMULIA_Abaqus_CAE.HF*.Linux64') if len(subdirs) == 1: subdir = subdirs[0] else: raise EasyBuildError("Failed to find expected subdir for hotfix: %s", subdirs) cwd = change_dir(os.path.join(subdir, '1')) std_qa = OrderedDict() std_qa[r"Enter selection \(default: Next\):"] = '' std_qa["Choose the .*installation directory.*\n.*\n\n.*:"] = os.path.join(self.installdir, 'cae') std_qa[r"Enter selection \(default: Install\):"] = '' std_qa[r"\[1\] Continue\n(?:.|\n)*Please choose an action:"] = '1' std_qa[r"\[2\] Continue\n(?:.|\n)*Please choose an action:"] = '2' no_qa = [r"Please be patient; it will take a few minutes to complete\.\n(\.)*"] run_cmd_qa('./StartTUI.sh', {}, no_qa=no_qa, std_qa=std_qa, log_all=True, simple=True, maxhits=100)