Skip to content

Commit c285824

Browse files
committed
Merge branch 'easystack_easyconfigs' of https://github.com/boegel/easybuild-framework into easystack_easyconfigs
2 parents 5a8eb3c + eb0f6db commit c285824

File tree

32 files changed

+770
-119
lines changed

32 files changed

+770
-119
lines changed

.github/workflows/bootstrap_script.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ jobs:
66
runs-on: ubuntu-latest
77
outputs:
88
lmod7: Lmod-7.8.22
9-
lmod8: Lmod-8.4.27
9+
lmod8: Lmod-8.7.6
1010
modulesTcl: modules-tcl-1.147
1111
modules3: modules-3.2.10
1212
modules4: modules-4.1.4

.github/workflows/container_tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ jobs:
3939
cd $HOME
4040
export INSTALL_DEP=$GITHUB_WORKSPACE/easybuild/scripts/install_eb_dep.sh
4141
# install Lmod
42-
source $INSTALL_DEP Lmod-8.4.27 $HOME
42+
source $INSTALL_DEP Lmod-8.7.6 $HOME
4343
# changes in environment are not passed to other steps, so need to create files...
4444
echo $MOD_INIT > mod_init
4545
echo $PATH > path

.github/workflows/eb_command.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ jobs:
3838
cd $HOME
3939
export INSTALL_DEP=$GITHUB_WORKSPACE/easybuild/scripts/install_eb_dep.sh
4040
# install Lmod
41-
source $INSTALL_DEP Lmod-8.4.26 $HOME
41+
source $INSTALL_DEP Lmod-8.7.6 $HOME
4242
# changes in environment are not passed to other steps, so need to create files...
4343
echo $MOD_INIT > mod_init
4444
echo $PATH > path

.github/workflows/unit_tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ jobs:
66
runs-on: ubuntu-latest
77
outputs:
88
lmod7: Lmod-7.8.22
9-
lmod8: Lmod-8.4.27
9+
lmod8: Lmod-8.7.6
1010
modulesTcl: modules-tcl-1.147
1111
modules3: modules-3.2.10
1212
modules4: modules-4.1.4

RELEASE_NOTES

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,49 @@ For more detailed information, please see the git log.
44
These release notes can also be consulted at https://easybuild.readthedocs.io/en/latest/Release_notes.html.
55

66

7+
v4.6.0 (July 8th 2022)
8+
----------------------
9+
10+
feature release
11+
12+
- various enhancements, including:
13+
- allow searching for sources/patches in alternative location by specifying 'alt_location' in source/patch spec (#3994)
14+
- show URLs used for download attempts in trace output (#4026)
15+
- add support for setting environment variables via 'pushenv' with modextravars (#4030)
16+
- add support for OneAPI compilers using toolchain option 'oneapi' (#4031, #4032, #4039)
17+
- make check_linked_shared_libs more robust by taking into account that 'ldd' may fail (#4033)
18+
- fall back to sequential extension install if parallel install is not implemented (#4034)
19+
- add support for using template values in name/version of extensions (#4036)
20+
- various bug fixes, including:
21+
- make sure that ARCH constant has 'aarch64' (rather than 'arm64') as value on macOS ARM (#4018)
22+
- tweak 'eb' wrapper script to correctly handle errors when python command being considered fails to run (#4019)
23+
- tweak is_patch_for function to make it more robust (#4028)
24+
- other changes:
25+
- update Lmod used to run tests to version 8.7.6 (#4027, #4030)
26+
- tweak apply_patch to not create .orig files (by default) when applying patch files (#4038)
27+
28+
29+
v4.5.5 (June 8th 2022)
30+
----------------------
31+
32+
update/bugfix release
33+
34+
- various enhancements, including:
35+
- add toolchain definitions for nvompi (NVHPC + OpenMPI) (#3969), nvpsmpi (NVHPC + ParaStationMPI) (#3970), gfbf (GCC, FlexiBLAS, FFTW) (#4006)
36+
- add support for FFTW.MPI toolchain component ($FFT*DIR variables) (#4012)
37+
- add support for customizing EasyBuild command used in jobs via --job-eb-cmd (#4016)
38+
- various bug fixes, including:
39+
- fix copying of easyconfig file with --copy-ec without --rebuild if module is already installed (#3993)
40+
- ignore deprecation warnings regarding cryptography in Python 3.6 + Blowfish with Python 3.10 in test suite output (#3999)
41+
- fix typo in debug log message in easyblock.py (#4000)
42+
- fix printing of list of attempted download URLs when url-encoded characters are used in URL (#4005)
43+
- set $FFT(W)_LIB_DIR to imkl-FFTW's lib path in build environment if usempi toolchain option is enabled (#4011)
44+
- correctly identify Apple Silicon M1 as Arm 64-bit by also considering arm64 next to aarch64 (#4014)
45+
- fix 'eb --show-system-info' on Apple M1 system (#4015)
46+
- other changes:
47+
- change 'eb' command to import easybuild.framework to check if EasyBuild framework is available (#3995, #3998)
48+
49+
750
v4.5.4 (March 31st 2022)
851
------------------------
952

easybuild/base/fancylogger.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -380,9 +380,9 @@ def streamLog(self, levelno, data):
380380

381381
def write_and_flush_stream(hdlr, data=None):
382382
"""Write to stream and flush the handler"""
383-
if (not hasattr(hdlr, 'stream')) or hdlr.stream is None:
383+
if getattr(hdlr, 'stream', None) is None:
384384
# no stream or not initialised.
385-
raise("write_and_flush_stream failed. No active stream attribute.")
385+
raise ValueError("write_and_flush_stream failed. No active stream attribute.")
386386
if data is not None:
387387
hdlr.stream.write(data)
388388
hdlr.flush()

easybuild/framework/easyblock.py

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,8 @@ def fetch_source(self, source, checksum=None, extension=False, download_instruct
373373
:param checksum: checksum corresponding to source
374374
:param extension: flag if being called from collect_exts_file_info()
375375
"""
376-
filename, download_filename, extract_cmd, source_urls, git_config = None, None, None, None, None
376+
filename, download_filename, extract_cmd = None, None, None
377+
source_urls, git_config, alt_location = None, None, None
377378

378379
if source is None:
379380
raise EasyBuildError("fetch_source called with empty 'source' argument")
@@ -387,6 +388,7 @@ def fetch_source(self, source, checksum=None, extension=False, download_instruct
387388
download_filename = source.pop('download_filename', None)
388389
source_urls = source.pop('source_urls', None)
389390
git_config = source.pop('git_config', None)
391+
alt_location = source.pop('alt_location', None)
390392
if source:
391393
raise EasyBuildError("Found one or more unexpected keys in 'sources' specification: %s", source)
392394

@@ -401,7 +403,7 @@ def fetch_source(self, source, checksum=None, extension=False, download_instruct
401403
force_download = build_option('force_download') in [FORCE_DOWNLOAD_ALL, FORCE_DOWNLOAD_SOURCES]
402404
path = self.obtain_file(filename, extension=extension, download_filename=download_filename,
403405
force_download=force_download, urls=source_urls, git_config=git_config,
404-
download_instructions=download_instructions)
406+
download_instructions=download_instructions, alt_location=alt_location)
405407
if path is None:
406408
raise EasyBuildError('No file found for source %s', filename)
407409

@@ -468,7 +470,9 @@ def fetch_patches(self, patch_specs=None, extension=False, checksums=None):
468470
patch_info['postinstall'] = patch_spec in post_install_patches
469471

470472
force_download = build_option('force_download') in [FORCE_DOWNLOAD_ALL, FORCE_DOWNLOAD_PATCHES]
471-
path = self.obtain_file(patch_info['name'], extension=extension, force_download=force_download)
473+
alt_location = patch_info.pop('alt_location', None)
474+
path = self.obtain_file(patch_info['name'], extension=extension, force_download=force_download,
475+
alt_location=alt_location)
472476
if path:
473477
self.log.debug('File %s found for patch %s', path, patch_spec)
474478
patch_info['path'] = path
@@ -517,11 +521,13 @@ def collect_exts_file_info(self, fetch_files=True, verify_checksums=True):
517521
for ext in exts_list:
518522
if isinstance(ext, (list, tuple)) and ext:
519523
# expected format: (name, version, options (dict))
520-
ext_name = ext[0]
524+
# name and version can use templates, resolved via parent EC
525+
526+
ext_name = resolve_template(ext[0], self.cfg.template_values)
521527
if len(ext) == 1:
522528
exts_sources.append({'name': ext_name})
523529
else:
524-
ext_version = ext[1]
530+
ext_version = resolve_template(ext[1], self.cfg.template_values)
525531

526532
# make sure we grab *raw* dict of default options for extension,
527533
# since it may use template values like %(name)s & %(version)s
@@ -687,7 +693,7 @@ def collect_exts_file_info(self, fetch_files=True, verify_checksums=True):
687693
return exts_sources
688694

689695
def obtain_file(self, filename, extension=False, urls=None, download_filename=None, force_download=False,
690-
git_config=None, download_instructions=None):
696+
git_config=None, download_instructions=None, alt_location=None):
691697
"""
692698
Locate the file with the given name
693699
- searches in different subdirectories of source path
@@ -698,11 +704,18 @@ def obtain_file(self, filename, extension=False, urls=None, download_filename=No
698704
:param download_filename: filename with which the file should be downloaded, and then renamed to <filename>
699705
:param force_download: always try to download file, even if it's already available in source path
700706
:param git_config: dictionary to define how to download a git repository
707+
:param download_instructions: instructions to manually add source (used for complex cases)
708+
:param alt_location: alternative location to use instead of self.name
701709
"""
702710
srcpaths = source_paths()
703711

704712
update_progress_bar(PROGRESS_BAR_DOWNLOAD_ALL, label=filename)
705713

714+
if alt_location is None:
715+
location = self.name
716+
else:
717+
location = alt_location
718+
706719
# should we download or just try and find it?
707720
if re.match(r"^(https?|ftp)://", filename):
708721
# URL detected, so let's try and download it
@@ -711,7 +724,7 @@ def obtain_file(self, filename, extension=False, urls=None, download_filename=No
711724
filename = url.split('/')[-1]
712725

713726
# figure out where to download the file to
714-
filepath = os.path.join(srcpaths[0], letter_dir_for(self.name), self.name)
727+
filepath = os.path.join(srcpaths[0], letter_dir_for(location), location)
715728
if extension:
716729
filepath = os.path.join(filepath, "extensions")
717730
self.log.info("Creating path %s to download file to" % filepath)
@@ -750,8 +763,8 @@ def obtain_file(self, filename, extension=False, urls=None, download_filename=No
750763

751764
for path in ebpath + common_filepaths + srcpaths:
752765
# create list of candidate filepaths
753-
namepath = os.path.join(path, self.name)
754-
letterpath = os.path.join(path, letter_dir_for(self.name), self.name)
766+
namepath = os.path.join(path, location)
767+
letterpath = os.path.join(path, letter_dir_for(location), location)
755768

756769
# most likely paths
757770
candidate_filepaths = [
@@ -790,8 +803,8 @@ def obtain_file(self, filename, extension=False, urls=None, download_filename=No
790803

791804
break # no need to try other source paths
792805

793-
name_letter = self.name.lower()[0]
794-
targetdir = os.path.join(srcpaths[0], name_letter, self.name)
806+
name_letter = location.lower()[0]
807+
targetdir = os.path.join(srcpaths[0], name_letter, location)
795808

796809
if foundfile:
797810
if self.dry_run:
@@ -808,7 +821,7 @@ def obtain_file(self, filename, extension=False, urls=None, download_filename=No
808821
source_urls.extend(self.cfg['source_urls'])
809822

810823
# add https://sources.easybuild.io as fallback source URL
811-
source_urls.append(EASYBUILD_SOURCES_URL + '/' + os.path.join(name_letter, self.name))
824+
source_urls.append(EASYBUILD_SOURCES_URL + '/' + os.path.join(name_letter, location))
812825

813826
mkdir(targetdir, parents=True)
814827

@@ -960,7 +973,7 @@ def gen_builddir(self):
960973
if not self.cfg.get('cleanupoldbuild', False):
961974
uniq_builddir = builddir
962975
suff = 0
963-
while(os.path.isdir(uniq_builddir)):
976+
while os.path.isdir(uniq_builddir):
964977
uniq_builddir = "%s.%d" % (builddir, suff)
965978
suff += 1
966979
builddir = uniq_builddir
@@ -1754,7 +1767,13 @@ def install_extensions(self, install=True):
17541767

17551768
if build_option('parallel_extensions_install'):
17561769
self.log.experimental("installing extensions in parallel")
1757-
self.install_extensions_parallel(install=install)
1770+
try:
1771+
self.install_extensions_parallel(install=install)
1772+
except NotImplementedError:
1773+
# If parallel extension install is not supported for this type of extension then install sequentially
1774+
msg = "Parallel extensions install not supported for %s - using sequential install" % self.name
1775+
self.log.experimental(msg)
1776+
self.install_extensions_sequential(install=install)
17581777
else:
17591778
self.install_extensions_sequential(install=install)
17601779

easybuild/framework/easyconfig/constants.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,35 @@
3434
import platform
3535

3636
from easybuild.base import fancylogger
37-
from easybuild.tools.systemtools import get_os_name, get_os_type, get_os_version
37+
from easybuild.tools.build_log import print_warning
38+
from easybuild.tools.systemtools import KNOWN_ARCH_CONSTANTS, get_os_name, get_os_type, get_os_version
3839

3940

4041
_log = fancylogger.getLogger('easyconfig.constants', fname=False)
4142

4243

4344
EXTERNAL_MODULE_MARKER = 'EXTERNAL_MODULE'
4445

46+
47+
def _get_arch_constant():
48+
"""
49+
Get value for ARCH constant.
50+
"""
51+
arch = platform.uname()[4]
52+
53+
# macOS on Arm produces 'arm64' rather than 'aarch64'
54+
if arch == 'arm64':
55+
arch = 'aarch64'
56+
57+
if arch not in KNOWN_ARCH_CONSTANTS:
58+
print_warning("Using unknown value for ARCH constant: %s", arch)
59+
60+
return arch
61+
62+
4563
# constants that can be used in easyconfig
4664
EASYCONFIG_CONSTANTS = {
47-
'ARCH': (platform.uname()[4], "CPU architecture of current system (aarch64, x86_64, ppc64le, ...)"),
65+
'ARCH': (_get_arch_constant(), "CPU architecture of current system (aarch64, x86_64, ppc64le, ...)"),
4866
'EXTERNAL_MODULE': (EXTERNAL_MODULE_MARKER, "External module marker"),
4967
'HOME': (os.path.expanduser('~'), "Home directory ($HOME)"),
5068
'OS_TYPE': (get_os_type(), "System type (e.g. 'Linux' or 'Darwin')"),

easybuild/framework/easyconfig/format/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ def __bool__(self):
117117

118118
def is_valid(self):
119119
"""Check if this is a valid VersionOperator. Suffix can be anything."""
120-
return not(self.version is None or self.operator is None)
120+
return not (self.version is None or self.operator is None)
121121

122122
def set(self, versop_str):
123123
"""

easybuild/main.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@
5555
from easybuild.framework.easyconfig.tools import det_easyconfig_paths, dump_env_script, get_paths_for
5656
from easybuild.framework.easyconfig.tools import parse_easyconfigs, review_pr, run_contrib_checks, skip_available
5757
from easybuild.framework.easyconfig.tweak import obtain_ec_for, tweak
58-
from easybuild.tools.build_log import print_warning
5958
from easybuild.tools.config import find_last_log, get_repository, get_repositorypath, build_option
6059
from easybuild.tools.containers.common import containerize
6160
from easybuild.tools.docs import list_software

0 commit comments

Comments
 (0)