|
35 | 35 |
|
36 | 36 | from easybuild.base import fancylogger |
37 | 37 | from easybuild.tools.build_log import EasyBuildError, print_msg |
38 | | -from easybuild.tools.config import install_path |
| 38 | +from easybuild.tools.config import install_path, ConfigurationVariables |
39 | 39 | from easybuild.tools.filetools import mkdir, write_file |
40 | 40 | from easybuild.tools.utilities import trace_msg |
41 | 41 |
|
|
47 | 47 | 'bwrap_cmd': [], |
48 | 48 | 'bwrap_eb_options': [], |
49 | 49 | 'bwrap_installpath': '', |
| 50 | + 'bwrap_installpath_software': '', |
| 51 | + 'bwrap_installpath_modules': '', |
50 | 52 | 'installpath_modules': '', |
51 | 53 | 'installpath_software': '', |
52 | 54 | 'modules_to_install': set(), |
@@ -107,23 +109,42 @@ def prepare_bwrap(bwrap_installpath): |
107 | 109 |
|
108 | 110 | set_bwrap_info('installpath_modules', install_path(typ='modules')) |
109 | 111 |
|
110 | | - bwrap_modules_installpath = os.path.join(bwrap_installpath, 'modules') |
| 112 | + variables = ConfigurationVariables() |
| 113 | + bwrap_installpath_software = os.path.join(bwrap_installpath, variables['subdir_software']) |
| 114 | + bwrap_installpath_modules = os.path.join(bwrap_installpath, variables['subdir_modules']) |
| 115 | + set_bwrap_info('bwrap_installpath_software', bwrap_installpath_software) |
| 116 | + set_bwrap_info('bwrap_installpath_modules', bwrap_installpath_modules) |
111 | 117 |
|
112 | 118 | bwrap_cmd = ['bwrap', '--dev-bind', '/', '/'] |
113 | 119 |
|
114 | 120 | # bind mount all software directories |
115 | 121 | for mod in sorted(get_bwrap_info('modules_to_install')): |
116 | 122 | installdir = os.path.join(os.path.realpath(installpath_software), mod) |
117 | | - bwrap_installdir = os.path.join(bwrap_installpath, 'software', mod) |
118 | | - mkdir(installdir, parents=True) |
| 123 | + bwrap_installdir = os.path.join(bwrap_installpath_software, mod) |
| 124 | + use_overlayfs = False |
| 125 | + try: |
| 126 | + mkdir(installdir, parents=True) |
| 127 | + except EasyBuildError: |
| 128 | + # if we can't create the external installation directory, try to use overlayfs |
| 129 | + use_overlayfs = True |
119 | 130 | mkdir(bwrap_installdir, parents=True) |
120 | | - bwrap_cmd.extend(['--bind', bwrap_installdir, installdir]) |
| 131 | + if use_overlayfs: |
| 132 | + bwrap_workdir = os.path.join(bwrap_installpath, 'workdir', mod) |
| 133 | + mkdir(bwrap_workdir, parents=True) |
| 134 | + # go up the tree until we find a directory that exists |
| 135 | + while not os.path.exists(installdir): |
| 136 | + installdir = os.path.dirname(installdir) |
| 137 | + bwrap_installdir = os.path.dirname(bwrap_installdir) |
| 138 | + opts = ['--overlay-src', installdir, '--overlay', bwrap_installdir, bwrap_workdir, installdir] |
| 139 | + else: |
| 140 | + opts = ['--bind', bwrap_installdir, installdir] |
| 141 | + bwrap_cmd.extend(opts) |
121 | 142 |
|
122 | 143 | set_bwrap_info('bwrap_cmd', bwrap_cmd) |
123 | 144 | bwrap_cmd_str = ' '.join(bwrap_cmd) |
124 | 145 |
|
125 | 146 | # disable `--bwrap` to prepare for a real installation (in bwrap namespace) |
126 | | - bwrap_eb_options = ['--disable-bwrap', f'--installpath-modules={bwrap_modules_installpath}'] |
| 147 | + bwrap_eb_options = ['--disable-bwrap', f'--installpath-modules={bwrap_installpath_modules}'] |
127 | 148 | set_bwrap_info('bwrap_eb_options', bwrap_eb_options) |
128 | 149 |
|
129 | 150 | _log.info(f'Info needed for bwrap: {_bwrap_info}') |
|
0 commit comments