Skip to content

Commit 3445252

Browse files
committed
replace non-constant BWRAP_INFO with private global variable _bwrap_info in tools/bwrap.py + add get_bwrap_info, set_bwrap_info, and update_bwrap_info utility functions
1 parent a45c1ef commit 3445252

3 files changed

Lines changed: 66 additions & 24 deletions

File tree

easybuild/main.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
from easybuild.framework.easyconfig.tools import det_easyconfig_paths, dump_env_script, get_paths_for
6666
from easybuild.framework.easyconfig.tools import parse_easyconfigs, review_pr, run_contrib_checks, skip_available
6767
from easybuild.framework.easyconfig.tweak import obtain_ec_for, tweak
68-
from easybuild.tools.bwrap import BWRAP_INFO, prepare_bwrap
68+
from easybuild.tools.bwrap import get_bwrap_info, prepare_bwrap, update_bwrap_info
6969
from easybuild.tools.config import build_option, find_last_log, get_repository, get_repositorypath
7070
from easybuild.tools.containers.common import containerize
7171
from easybuild.tools.docs import list_software
@@ -590,7 +590,8 @@ def process_eb_args(eb_args, eb_go, cfg_settings, modtool, testing, init_session
590590
_log.experimental("support for building in bwrap namespace (--bwrap)")
591591
# updating modules_to_install because process_eb_args may run multiple times:
592592
# once for each easyconfig in the easystack
593-
BWRAP_INFO['modules_to_install'].update(set(dry_run(easyconfigs, modtool, return_modules_to_install=True)))
593+
modules_to_install = set(dry_run(easyconfigs, modtool, return_modules_to_install=True))
594+
update_bwrap_info('modules_to_install', modules_to_install)
594595
if not options.job:
595596
return True
596597

@@ -851,7 +852,7 @@ def prepare_main(args=None, logfile=None, testing=None):
851852
def rerun_with_bwrap():
852853
"Rerun EasyBuild with bwrap"
853854
eb_cmd = ['python', '-m', EASYBUILD_MAIN] + sys.argv[1:]
854-
full_cmd = BWRAP_INFO['bwrap_cmd'] + eb_cmd + BWRAP_INFO['bwrap_eb_options']
855+
full_cmd = get_wrap_info('bwrap_cmd') + eb_cmd + get_bwrap_info('bwrap_eb_options')
855856

856857
_log.info(f'Rerunning EasyBuild with command: {" ".join(full_cmd)}')
857858
sys.exit(subprocess.run(full_cmd).returncode)
@@ -868,7 +869,7 @@ def main_with_hooks(args=None):
868869

869870
try:
870871
exit_code: EasyBuildExit = main(args=args, prepared_cfg_data=(init_session_state, eb_go, cfg_settings))
871-
if int(exit_code) == 0 and build_option('bwrap') and BWRAP_INFO['modules_to_install']:
872+
if int(exit_code) == 0 and build_option('bwrap') and get_bwrap_info('modules_to_install'):
872873
prepare_bwrap(eb_go.options.bwrap_installpath)
873874
if not eb_go.options.job:
874875
rerun_with_bwrap()

easybuild/tools/bwrap.py

Lines changed: 58 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,11 @@
3939
from easybuild.tools.filetools import mkdir, write_file
4040
from easybuild.tools.utilities import trace_msg
4141

42-
BWRAP_INFO = {
42+
43+
BWRAP_INFO_JSON = 'bwrap_info.json'
44+
45+
# global state to exchange info required when using bwrap between EasyBuild sessions
46+
_bwrap_info = {
4347
'bwrap_cmd': [],
4448
'bwrap_eb_options': [],
4549
'bwrap_installpath': '',
@@ -48,54 +52,91 @@
4852
'modules_to_install': set(),
4953

5054
}
51-
BWRAP_INFO_JSON = 'bwrap_info.json'
5255

5356
_log = fancylogger.getLogger('bwrap', fname=False)
5457

5558

59+
def get_bwrap_info(key):
60+
"""
61+
Get specified info w.r.t. use of bwrap
62+
"""
63+
if key in _bwrap_info:
64+
return _bwrap_info[key]
65+
else:
66+
raise EasyBuildError(f"Unknown key specified to get bwrap info: {key}")
67+
68+
69+
def set_bwrap_info(key, value):
70+
"""
71+
Set specified info w.r.t. use of bwrap
72+
"""
73+
if key in _bwrap_info:
74+
_bwrap_info[key] = value
75+
else:
76+
raise EasyBuildError(f"Unknown key specified to set bwrap info: {key}")
77+
78+
79+
def update_bwrap_info(key, value):
80+
"""
81+
Update specified info w.r.t. use of bwrap
82+
"""
83+
if key in _bwrap_info:
84+
current_value = _bwrap_info[key]
85+
if isinstance(current_value, set) and isinstance(value, set):
86+
current_value.update(value)
87+
else:
88+
raise EasyBuildError("Unknown type of value encountered when updating bwrap info!")
89+
else:
90+
raise EasyBuildError(f"Unknown key specified to update bwrap info: {key}")
91+
92+
5693
def prepare_bwrap(bwrap_installpath):
5794
"""
5895
Prepare for running EasyBuild with bwrap:
59-
- update BWRAP_INFO
60-
- write json metadata file with BWRAP_INFO
96+
- update _bwrap_info
97+
- write json metadata file with contents of _bwrap_info
6198
- set environment variable $EB_BWRAP_CMD
6299
63100
:param bwrap_installpath: bwrap install path
64101
"""
65102

66-
BWRAP_INFO['bwrap_installpath'] = bwrap_installpath
67-
BWRAP_INFO['installpath_software'] = install_path(typ='software')
68-
BWRAP_INFO['installpath_modules'] = install_path(typ='modules')
103+
set_bwrap_info('bwrap_installpath', bwrap_installpath)
104+
105+
installpath_software = install_path(typ='software')
106+
set_bwrap_info('installpath_software', installpath_software)
107+
108+
set_bwrap_info('installpath_modules', install_path(typ='modules'))
69109

70-
installpath_software = BWRAP_INFO['installpath_software']
71110
bwrap_modules_installpath = os.path.join(bwrap_installpath, 'modules')
72111

73112
bwrap_cmd = ['bwrap', '--dev-bind', '/', '/']
74113

75114
# bind mount all software directories
76-
for mod in BWRAP_INFO['modules_to_install']:
115+
for mod in sorted(get_bwrap_info('modules_to_install')):
77116
installdir = os.path.join(os.path.realpath(installpath_software), mod)
78117
bwrap_installdir = os.path.join(bwrap_installpath, 'software', mod)
79118
mkdir(installdir, parents=True)
80119
mkdir(bwrap_installdir, parents=True)
81120
bwrap_cmd.extend(['--bind', bwrap_installdir, installdir])
82121

83-
BWRAP_INFO['bwrap_cmd'] = bwrap_cmd
122+
set_bwrap_info('bwrap_cmd', bwrap_cmd)
123+
bwrap_cmd_str = ' '.join(bwrap_cmd)
84124

85125
# disable `--bwrap` to prepare for a real installation (in bwrap namespace)
86-
BWRAP_INFO['bwrap_eb_options'] = ['--disable-bwrap', f'--installpath-modules={bwrap_modules_installpath}']
126+
bwrap_eb_options = ['--disable-bwrap', f'--installpath-modules={bwrap_modules_installpath}']
127+
set_bwrap_info('bwrap_eb_options', bwrap_eb_options)
87128

88-
_log.info(f'Info needed for bwrap: {BWRAP_INFO}')
129+
_log.info(f'Info needed for bwrap: {_bwrap_info}')
89130

90131
# write json file with bwrap install info into bwrap installpath
91-
bwrap_infopath = os.path.join(BWRAP_INFO['bwrap_installpath'], BWRAP_INFO_JSON)
92-
write_file(bwrap_infopath, json.dumps(BWRAP_INFO, default=list, indent=2, sort_keys=True), backup=True)
132+
bwrap_infopath = os.path.join(bwrap_installpath, BWRAP_INFO_JSON)
133+
write_file(bwrap_infopath, json.dumps(_bwrap_info, default=list, indent=2, sort_keys=True), backup=True)
93134

94135
print_msg('Building/installing in bwrap namespace')
95-
trace_msg(f'bwrap command (to prefix eb command): {" ".join(BWRAP_INFO["bwrap_cmd"])}')
136+
trace_msg(f'bwrap command (to prefix eb command): {bwrap_cmd_str}')
96137
trace_msg(f'bwrap info file: {bwrap_infopath}')
97-
trace_msg(f'bwrap EasyBuild options: {BWRAP_INFO["bwrap_eb_options"]}')
138+
trace_msg(f'bwrap EasyBuild options: {bwrap_eb_options}')
98139

99140
# set environment variable $EB_BWRAP_CMD to make it available for the interactive debug shell
100141
# when rerunning with bwrap
101-
os.environ['EB_BWRAP_CMD'] = ' '.join(BWRAP_INFO['bwrap_cmd'])
142+
os.environ['EB_BWRAP_CMD'] = bwrap_cmd_str

easybuild/tools/parallelbuild.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
from easybuild.framework.easyblock import get_easyblock_instance
4444
from easybuild.framework.easyconfig.easyconfig import ActiveMNS
4545
from easybuild.tools.build_log import EasyBuildError
46-
from easybuild.tools.bwrap import BWRAP_INFO
46+
from easybuild.tools.bwrap import get_bwrap_info
4747
from easybuild.tools.config import build_option, get_repository, get_repositorypath
4848
from easybuild.tools.filetools import get_cwd
4949
from easybuild.tools.module_naming_scheme.utilities import det_full_ec_version
@@ -155,9 +155,9 @@ def submit_jobs(ordered_ecs, cmd_line_opts, testing=False, prepare_first=True, t
155155
# cfr. https://github.com/easybuilders/easybuild-framework/issues/3307
156156
opts.append('--disable-job')
157157

158-
bwrap_cmd = BWRAP_INFO['bwrap_cmd']
158+
bwrap_cmd = get_bwrap_info('bwrap_cmd')
159159
if bwrap_cmd:
160-
opts.extend(BWRAP_INFO['bwrap_eb_options'])
160+
opts.extend(get_bwrap_info('bwrap_eb_options'))
161161

162162
# compose string with command line options, properly quoted and with '%' characters escaped
163163
opts_str = ' '.join(opts).replace('%', '%%')

0 commit comments

Comments
 (0)