|
39 | 39 | from easybuild.tools.filetools import mkdir, write_file |
40 | 40 | from easybuild.tools.utilities import trace_msg |
41 | 41 |
|
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 = { |
43 | 47 | 'bwrap_cmd': [], |
44 | 48 | 'bwrap_eb_options': [], |
45 | 49 | 'bwrap_installpath': '', |
|
48 | 52 | 'modules_to_install': set(), |
49 | 53 |
|
50 | 54 | } |
51 | | -BWRAP_INFO_JSON = 'bwrap_info.json' |
52 | 55 |
|
53 | 56 | _log = fancylogger.getLogger('bwrap', fname=False) |
54 | 57 |
|
55 | 58 |
|
| 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 | + |
56 | 93 | def prepare_bwrap(bwrap_installpath): |
57 | 94 | """ |
58 | 95 | 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 |
61 | 98 | - set environment variable $EB_BWRAP_CMD |
62 | 99 |
|
63 | 100 | :param bwrap_installpath: bwrap install path |
64 | 101 | """ |
65 | 102 |
|
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')) |
69 | 109 |
|
70 | | - installpath_software = BWRAP_INFO['installpath_software'] |
71 | 110 | bwrap_modules_installpath = os.path.join(bwrap_installpath, 'modules') |
72 | 111 |
|
73 | 112 | bwrap_cmd = ['bwrap', '--dev-bind', '/', '/'] |
74 | 113 |
|
75 | 114 | # 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')): |
77 | 116 | installdir = os.path.join(os.path.realpath(installpath_software), mod) |
78 | 117 | bwrap_installdir = os.path.join(bwrap_installpath, 'software', mod) |
79 | 118 | mkdir(installdir, parents=True) |
80 | 119 | mkdir(bwrap_installdir, parents=True) |
81 | 120 | bwrap_cmd.extend(['--bind', bwrap_installdir, installdir]) |
82 | 121 |
|
83 | | - BWRAP_INFO['bwrap_cmd'] = bwrap_cmd |
| 122 | + set_bwrap_info('bwrap_cmd', bwrap_cmd) |
| 123 | + bwrap_cmd_str = ' '.join(bwrap_cmd) |
84 | 124 |
|
85 | 125 | # 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) |
87 | 128 |
|
88 | | - _log.info(f'Info needed for bwrap: {BWRAP_INFO}') |
| 129 | + _log.info(f'Info needed for bwrap: {_bwrap_info}') |
89 | 130 |
|
90 | 131 | # 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) |
93 | 134 |
|
94 | 135 | 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}') |
96 | 137 | 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}') |
98 | 139 |
|
99 | 140 | # set environment variable $EB_BWRAP_CMD to make it available for the interactive debug shell |
100 | 141 | # when rerunning with bwrap |
101 | | - os.environ['EB_BWRAP_CMD'] = ' '.join(BWRAP_INFO['bwrap_cmd']) |
| 142 | + os.environ['EB_BWRAP_CMD'] = bwrap_cmd_str |
0 commit comments