Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 1 | # |
| 2 | # Sanity check the users setup for common misconfigurations |
| 3 | # |
| 4 | |
| 5 | SANITY_REQUIRED_UTILITIES ?= "patch diffstat makeinfo git bzip2 tar \ |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 6 | gzip gawk chrpath wget cpio perl file which" |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 7 | |
| 8 | def bblayers_conf_file(d): |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 9 | return os.path.join(d.getVar('TOPDIR'), 'conf/bblayers.conf') |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 10 | |
| 11 | def sanity_conf_read(fn): |
| 12 | with open(fn, 'r') as f: |
| 13 | lines = f.readlines() |
| 14 | return lines |
| 15 | |
| 16 | def sanity_conf_find_line(pattern, lines): |
| 17 | import re |
| 18 | return next(((index, line) |
| 19 | for index, line in enumerate(lines) |
| 20 | if re.search(pattern, line)), (None, None)) |
| 21 | |
| 22 | def sanity_conf_update(fn, lines, version_var_name, new_version): |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 23 | index, line = sanity_conf_find_line(r"^%s" % version_var_name, lines) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 24 | lines[index] = '%s = "%d"\n' % (version_var_name, new_version) |
| 25 | with open(fn, "w") as f: |
| 26 | f.write(''.join(lines)) |
| 27 | |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 28 | # Functions added to this variable MUST throw a NotImplementedError exception unless |
| 29 | # they successfully changed the config version in the config file. Exceptions |
| 30 | # are used since exec_func doesn't handle return values. |
| 31 | BBLAYERS_CONF_UPDATE_FUNCS += " \ |
| 32 | conf/bblayers.conf:LCONF_VERSION:LAYER_CONF_VERSION:oecore_update_bblayers \ |
| 33 | conf/local.conf:CONF_VERSION:LOCALCONF_VERSION:oecore_update_localconf \ |
| 34 | conf/site.conf:SCONF_VERSION:SITE_CONF_VERSION:oecore_update_siteconf \ |
| 35 | " |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 36 | |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 37 | SANITY_DIFF_TOOL ?= "meld" |
| 38 | |
| 39 | SANITY_LOCALCONF_SAMPLE ?= "${COREBASE}/meta*/conf/local.conf.sample" |
| 40 | python oecore_update_localconf() { |
| 41 | # Check we are using a valid local.conf |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 42 | current_conf = d.getVar('CONF_VERSION') |
| 43 | conf_version = d.getVar('LOCALCONF_VERSION') |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 44 | |
| 45 | failmsg = """Your version of local.conf was generated from an older/newer version of |
| 46 | local.conf.sample and there have been updates made to this file. Please compare the two |
| 47 | files and merge any changes before continuing. |
| 48 | |
| 49 | Matching the version numbers will remove this message. |
| 50 | |
| 51 | \"${SANITY_DIFF_TOOL} conf/local.conf ${SANITY_LOCALCONF_SAMPLE}\" |
| 52 | |
| 53 | is a good way to visualise the changes.""" |
| 54 | failmsg = d.expand(failmsg) |
| 55 | |
| 56 | raise NotImplementedError(failmsg) |
| 57 | } |
| 58 | |
| 59 | SANITY_SITECONF_SAMPLE ?= "${COREBASE}/meta*/conf/site.conf.sample" |
| 60 | python oecore_update_siteconf() { |
| 61 | # If we have a site.conf, check it's valid |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 62 | current_sconf = d.getVar('SCONF_VERSION') |
| 63 | sconf_version = d.getVar('SITE_CONF_VERSION') |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 64 | |
| 65 | failmsg = """Your version of site.conf was generated from an older version of |
| 66 | site.conf.sample and there have been updates made to this file. Please compare the two |
| 67 | files and merge any changes before continuing. |
| 68 | |
| 69 | Matching the version numbers will remove this message. |
| 70 | |
| 71 | \"${SANITY_DIFF_TOOL} conf/site.conf ${SANITY_SITECONF_SAMPLE}\" |
| 72 | |
| 73 | is a good way to visualise the changes.""" |
| 74 | failmsg = d.expand(failmsg) |
| 75 | |
| 76 | raise NotImplementedError(failmsg) |
| 77 | } |
| 78 | |
| 79 | SANITY_BBLAYERCONF_SAMPLE ?= "${COREBASE}/meta*/conf/bblayers.conf.sample" |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 80 | python oecore_update_bblayers() { |
| 81 | # bblayers.conf is out of date, so see if we can resolve that |
| 82 | |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 83 | current_lconf = int(d.getVar('LCONF_VERSION')) |
| 84 | lconf_version = int(d.getVar('LAYER_CONF_VERSION')) |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 85 | |
| 86 | failmsg = """Your version of bblayers.conf has the wrong LCONF_VERSION (has ${LCONF_VERSION}, expecting ${LAYER_CONF_VERSION}). |
| 87 | Please compare your file against bblayers.conf.sample and merge any changes before continuing. |
| 88 | "${SANITY_DIFF_TOOL} conf/bblayers.conf ${SANITY_BBLAYERCONF_SAMPLE}" |
| 89 | |
| 90 | is a good way to visualise the changes.""" |
| 91 | failmsg = d.expand(failmsg) |
| 92 | |
| 93 | if not current_lconf: |
| 94 | raise NotImplementedError(failmsg) |
| 95 | |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 96 | lines = [] |
| 97 | |
| 98 | if current_lconf < 4: |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 99 | raise NotImplementedError(failmsg) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 100 | |
| 101 | bblayers_fn = bblayers_conf_file(d) |
| 102 | lines = sanity_conf_read(bblayers_fn) |
| 103 | |
| 104 | if current_lconf == 4 and lconf_version > 4: |
| 105 | topdir_var = '$' + '{TOPDIR}' |
| 106 | index, bbpath_line = sanity_conf_find_line('BBPATH', lines) |
| 107 | if bbpath_line: |
| 108 | start = bbpath_line.find('"') |
| 109 | if start != -1 and (len(bbpath_line) != (start + 1)): |
| 110 | if bbpath_line[start + 1] == '"': |
| 111 | lines[index] = (bbpath_line[:start + 1] + |
| 112 | topdir_var + bbpath_line[start + 1:]) |
| 113 | else: |
| 114 | if not topdir_var in bbpath_line: |
| 115 | lines[index] = (bbpath_line[:start + 1] + |
| 116 | topdir_var + ':' + bbpath_line[start + 1:]) |
| 117 | else: |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 118 | raise NotImplementedError(failmsg) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 119 | else: |
| 120 | index, bbfiles_line = sanity_conf_find_line('BBFILES', lines) |
| 121 | if bbfiles_line: |
| 122 | lines.insert(index, 'BBPATH = "' + topdir_var + '"\n') |
| 123 | else: |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 124 | raise NotImplementedError(failmsg) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 125 | |
| 126 | current_lconf += 1 |
| 127 | sanity_conf_update(bblayers_fn, lines, 'LCONF_VERSION', current_lconf) |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 128 | bb.note("Your conf/bblayers.conf has been automatically updated.") |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 129 | return |
| 130 | |
| 131 | elif current_lconf == 5 and lconf_version > 5: |
| 132 | # Null update, to avoid issues with people switching between poky and other distros |
| 133 | current_lconf = 6 |
| 134 | sanity_conf_update(bblayers_fn, lines, 'LCONF_VERSION', current_lconf) |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 135 | bb.note("Your conf/bblayers.conf has been automatically updated.") |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 136 | return |
| 137 | |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 138 | status.addresult() |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 139 | |
| 140 | elif current_lconf == 6 and lconf_version > 6: |
| 141 | # Handle rename of meta-yocto -> meta-poky |
| 142 | # This marks the start of separate version numbers but code is needed in OE-Core |
| 143 | # for the migration, one last time. |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 144 | layers = d.getVar('BBLAYERS').split() |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 145 | layers = [ os.path.basename(path) for path in layers ] |
| 146 | if 'meta-yocto' in layers: |
| 147 | found = False |
| 148 | while True: |
| 149 | index, meta_yocto_line = sanity_conf_find_line(r'.*meta-yocto[\'"\s\n]', lines) |
| 150 | if meta_yocto_line: |
| 151 | lines[index] = meta_yocto_line.replace('meta-yocto', 'meta-poky') |
| 152 | found = True |
| 153 | else: |
| 154 | break |
| 155 | if not found: |
| 156 | raise NotImplementedError(failmsg) |
| 157 | index, meta_yocto_line = sanity_conf_find_line('LCONF_VERSION.*\n', lines) |
| 158 | if meta_yocto_line: |
| 159 | lines[index] = 'POKY_BBLAYERS_CONF_VERSION = "1"\n' |
| 160 | else: |
| 161 | raise NotImplementedError(failmsg) |
| 162 | with open(bblayers_fn, "w") as f: |
| 163 | f.write(''.join(lines)) |
| 164 | bb.note("Your conf/bblayers.conf has been automatically updated.") |
| 165 | return |
| 166 | current_lconf += 1 |
| 167 | sanity_conf_update(bblayers_fn, lines, 'LCONF_VERSION', current_lconf) |
| 168 | bb.note("Your conf/bblayers.conf has been automatically updated.") |
| 169 | return |
| 170 | |
| 171 | raise NotImplementedError(failmsg) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 172 | } |
| 173 | |
| 174 | def raise_sanity_error(msg, d, network_error=False): |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 175 | if d.getVar("SANITY_USE_EVENTS") == "1": |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 176 | try: |
| 177 | bb.event.fire(bb.event.SanityCheckFailed(msg, network_error), d) |
| 178 | except TypeError: |
| 179 | bb.event.fire(bb.event.SanityCheckFailed(msg), d) |
| 180 | return |
| 181 | |
| 182 | bb.fatal(""" OE-core's config sanity checker detected a potential misconfiguration. |
| 183 | Either fix the cause of this error or at your own risk disable the checker (see sanity.conf). |
| 184 | Following is the list of potential problems / advisories: |
| 185 | |
| 186 | %s""" % msg) |
| 187 | |
| 188 | # Check flags associated with a tuning. |
| 189 | def check_toolchain_tune_args(data, tune, multilib, errs): |
| 190 | found_errors = False |
| 191 | if check_toolchain_args_present(data, tune, multilib, errs, 'CCARGS'): |
| 192 | found_errors = True |
| 193 | if check_toolchain_args_present(data, tune, multilib, errs, 'ASARGS'): |
| 194 | found_errors = True |
| 195 | if check_toolchain_args_present(data, tune, multilib, errs, 'LDARGS'): |
| 196 | found_errors = True |
| 197 | |
| 198 | return found_errors |
| 199 | |
| 200 | def check_toolchain_args_present(data, tune, multilib, tune_errors, which): |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 201 | args_set = (data.getVar("TUNE_%s" % which) or "").split() |
| 202 | args_wanted = (data.getVar("TUNEABI_REQUIRED_%s_tune-%s" % (which, tune)) or "").split() |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 203 | args_missing = [] |
| 204 | |
| 205 | # If no args are listed/required, we are done. |
| 206 | if not args_wanted: |
| 207 | return |
| 208 | for arg in args_wanted: |
| 209 | if arg not in args_set: |
| 210 | args_missing.append(arg) |
| 211 | |
| 212 | found_errors = False |
| 213 | if args_missing: |
| 214 | found_errors = True |
| 215 | tune_errors.append("TUNEABI for %s requires '%s' in TUNE_%s (%s)." % |
| 216 | (tune, ' '.join(args_missing), which, ' '.join(args_set))) |
| 217 | return found_errors |
| 218 | |
| 219 | # Check a single tune for validity. |
| 220 | def check_toolchain_tune(data, tune, multilib): |
| 221 | tune_errors = [] |
| 222 | if not tune: |
| 223 | return "No tuning found for %s multilib." % multilib |
| 224 | localdata = bb.data.createCopy(data) |
| 225 | if multilib != "default": |
| 226 | # Apply the overrides so we can look at the details. |
| 227 | overrides = localdata.getVar("OVERRIDES", False) + ":virtclass-multilib-" + multilib |
| 228 | localdata.setVar("OVERRIDES", overrides) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 229 | bb.debug(2, "Sanity-checking tuning '%s' (%s) features:" % (tune, multilib)) |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 230 | features = (localdata.getVar("TUNE_FEATURES_tune-%s" % tune) or "").split() |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 231 | if not features: |
| 232 | return "Tuning '%s' has no defined features, and cannot be used." % tune |
| 233 | valid_tunes = localdata.getVarFlags('TUNEVALID') or {} |
| 234 | conflicts = localdata.getVarFlags('TUNECONFLICTS') or {} |
| 235 | # [doc] is the documentation for the variable, not a real feature |
| 236 | if 'doc' in valid_tunes: |
| 237 | del valid_tunes['doc'] |
| 238 | if 'doc' in conflicts: |
| 239 | del conflicts['doc'] |
| 240 | for feature in features: |
| 241 | if feature in conflicts: |
| 242 | for conflict in conflicts[feature].split(): |
| 243 | if conflict in features: |
| 244 | tune_errors.append("Feature '%s' conflicts with '%s'." % |
| 245 | (feature, conflict)) |
| 246 | if feature in valid_tunes: |
| 247 | bb.debug(2, " %s: %s" % (feature, valid_tunes[feature])) |
| 248 | else: |
| 249 | tune_errors.append("Feature '%s' is not defined." % feature) |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 250 | whitelist = localdata.getVar("TUNEABI_WHITELIST") |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 251 | if whitelist: |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 252 | tuneabi = localdata.getVar("TUNEABI_tune-%s" % tune) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 253 | if not tuneabi: |
| 254 | tuneabi = tune |
| 255 | if True not in [x in whitelist.split() for x in tuneabi.split()]: |
| 256 | tune_errors.append("Tuning '%s' (%s) cannot be used with any supported tuning/ABI." % |
| 257 | (tune, tuneabi)) |
| 258 | else: |
| 259 | if not check_toolchain_tune_args(localdata, tuneabi, multilib, tune_errors): |
| 260 | bb.debug(2, "Sanity check: Compiler args OK for %s." % tune) |
| 261 | if tune_errors: |
| 262 | return "Tuning '%s' has the following errors:\n" % tune + '\n'.join(tune_errors) |
| 263 | |
| 264 | def check_toolchain(data): |
| 265 | tune_error_set = [] |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 266 | deftune = data.getVar("DEFAULTTUNE") |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 267 | tune_errors = check_toolchain_tune(data, deftune, 'default') |
| 268 | if tune_errors: |
| 269 | tune_error_set.append(tune_errors) |
| 270 | |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 271 | multilibs = (data.getVar("MULTILIB_VARIANTS") or "").split() |
| 272 | global_multilibs = (data.getVar("MULTILIB_GLOBAL_VARIANTS") or "").split() |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 273 | |
| 274 | if multilibs: |
| 275 | seen_libs = [] |
| 276 | seen_tunes = [] |
| 277 | for lib in multilibs: |
| 278 | if lib in seen_libs: |
| 279 | tune_error_set.append("The multilib '%s' appears more than once." % lib) |
| 280 | else: |
| 281 | seen_libs.append(lib) |
| 282 | if not lib in global_multilibs: |
| 283 | tune_error_set.append("Multilib %s is not present in MULTILIB_GLOBAL_VARIANTS" % lib) |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 284 | tune = data.getVar("DEFAULTTUNE_virtclass-multilib-%s" % lib) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 285 | if tune in seen_tunes: |
| 286 | tune_error_set.append("The tuning '%s' appears in more than one multilib." % tune) |
| 287 | else: |
| 288 | seen_libs.append(tune) |
| 289 | if tune == deftune: |
| 290 | tune_error_set.append("Multilib '%s' (%s) is also the default tuning." % (lib, deftune)) |
| 291 | else: |
| 292 | tune_errors = check_toolchain_tune(data, tune, lib) |
| 293 | if tune_errors: |
| 294 | tune_error_set.append(tune_errors) |
| 295 | if tune_error_set: |
| 296 | return "Toolchain tunings invalid:\n" + '\n'.join(tune_error_set) + "\n" |
| 297 | |
| 298 | return "" |
| 299 | |
| 300 | def check_conf_exists(fn, data): |
| 301 | bbpath = [] |
| 302 | fn = data.expand(fn) |
| 303 | vbbpath = data.getVar("BBPATH", False) |
| 304 | if vbbpath: |
| 305 | bbpath += vbbpath.split(":") |
| 306 | for p in bbpath: |
| 307 | currname = os.path.join(data.expand(p), fn) |
| 308 | if os.access(currname, os.R_OK): |
| 309 | return True |
| 310 | return False |
| 311 | |
| 312 | def check_create_long_filename(filepath, pathname): |
| 313 | import string, random |
| 314 | testfile = os.path.join(filepath, ''.join(random.choice(string.ascii_letters) for x in range(200))) |
| 315 | try: |
| 316 | if not os.path.exists(filepath): |
| 317 | bb.utils.mkdirhier(filepath) |
| 318 | f = open(testfile, "w") |
| 319 | f.close() |
| 320 | os.remove(testfile) |
| 321 | except IOError as e: |
| 322 | import errno |
| 323 | err, strerror = e.args |
| 324 | if err == errno.ENAMETOOLONG: |
| 325 | return "Failed to create a file with a long name in %s. Please use a filesystem that does not unreasonably limit filename length.\n" % pathname |
| 326 | else: |
| 327 | return "Failed to create a file in %s: %s.\n" % (pathname, strerror) |
| 328 | except OSError as e: |
| 329 | errno, strerror = e.args |
| 330 | return "Failed to create %s directory in which to run long name sanity check: %s.\n" % (pathname, strerror) |
| 331 | return "" |
| 332 | |
| 333 | def check_path_length(filepath, pathname, limit): |
| 334 | if len(filepath) > limit: |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 335 | return "The length of %s is longer than %s, this would cause unexpected errors, please use a shorter path.\n" % (pathname, limit) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 336 | return "" |
| 337 | |
| 338 | def get_filesystem_id(path): |
| 339 | status, result = oe.utils.getstatusoutput("stat -f -c '%s' %s" % ("%t", path)) |
| 340 | if status == 0: |
| 341 | return result |
| 342 | else: |
| 343 | bb.warn("Can't get the filesystem id of: %s" % path) |
| 344 | return None |
| 345 | |
| 346 | # Check that the path isn't located on nfs. |
| 347 | def check_not_nfs(path, name): |
| 348 | # The nfs' filesystem id is 6969 |
| 349 | if get_filesystem_id(path) == "6969": |
| 350 | return "The %s: %s can't be located on nfs.\n" % (name, path) |
| 351 | return "" |
| 352 | |
| 353 | # Check that path isn't a broken symlink |
| 354 | def check_symlink(lnk, data): |
| 355 | if os.path.islink(lnk) and not os.path.exists(lnk): |
| 356 | raise_sanity_error("%s is a broken symlink." % lnk, data) |
| 357 | |
| 358 | def check_connectivity(d): |
| 359 | # URI's to check can be set in the CONNECTIVITY_CHECK_URIS variable |
| 360 | # using the same syntax as for SRC_URI. If the variable is not set |
| 361 | # the check is skipped |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 362 | test_uris = (d.getVar('CONNECTIVITY_CHECK_URIS') or "").split() |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 363 | retval = "" |
| 364 | |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 365 | bbn = d.getVar('BB_NO_NETWORK') |
| 366 | if bbn not in (None, '0', '1'): |
| 367 | return 'BB_NO_NETWORK should be "0" or "1", but it is "%s"' % bbn |
| 368 | |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 369 | # Only check connectivity if network enabled and the |
| 370 | # CONNECTIVITY_CHECK_URIS are set |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 371 | network_enabled = not (bbn == '1') |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 372 | check_enabled = len(test_uris) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 373 | if check_enabled and network_enabled: |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 374 | # Take a copy of the data store and unset MIRRORS and PREMIRRORS |
| 375 | data = bb.data.createCopy(d) |
| 376 | data.delVar('PREMIRRORS') |
| 377 | data.delVar('MIRRORS') |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 378 | try: |
| 379 | fetcher = bb.fetch2.Fetch(test_uris, data) |
| 380 | fetcher.checkstatus() |
| 381 | except Exception as err: |
| 382 | # Allow the message to be configured so that users can be |
| 383 | # pointed to a support mechanism. |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 384 | msg = data.getVar('CONNECTIVITY_CHECK_MSG') or "" |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 385 | if len(msg) == 0: |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 386 | msg = "%s.\n" % err |
| 387 | msg += " Please ensure your host's network is configured correctly,\n" |
| 388 | msg += " or set BB_NO_NETWORK = \"1\" to disable network access if\n" |
| 389 | msg += " all required sources are on local disk.\n" |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 390 | retval = msg |
| 391 | |
| 392 | return retval |
| 393 | |
| 394 | def check_supported_distro(sanity_data): |
| 395 | from fnmatch import fnmatch |
| 396 | |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 397 | tested_distros = sanity_data.getVar('SANITY_TESTED_DISTROS') |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 398 | if not tested_distros: |
| 399 | return |
| 400 | |
| 401 | try: |
| 402 | distro = oe.lsb.distro_identifier() |
| 403 | except Exception: |
| 404 | distro = None |
| 405 | |
| 406 | if not distro: |
| 407 | bb.warn('Host distribution could not be determined; you may possibly experience unexpected failures. It is recommended that you use a tested distribution.') |
| 408 | |
| 409 | for supported in [x.strip() for x in tested_distros.split('\\n')]: |
| 410 | if fnmatch(distro, supported): |
| 411 | return |
| 412 | |
| 413 | bb.warn('Host distribution "%s" has not been validated with this version of the build system; you may possibly experience unexpected failures. It is recommended that you use a tested distribution.' % distro) |
| 414 | |
| 415 | # Checks we should only make if MACHINE is set correctly |
| 416 | def check_sanity_validmachine(sanity_data): |
| 417 | messages = "" |
| 418 | |
| 419 | # Check TUNE_ARCH is set |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 420 | if sanity_data.getVar('TUNE_ARCH') == 'INVALID': |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 421 | messages = messages + 'TUNE_ARCH is unset. Please ensure your MACHINE configuration includes a valid tune configuration file which will set this correctly.\n' |
| 422 | |
| 423 | # Check TARGET_OS is set |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 424 | if sanity_data.getVar('TARGET_OS') == 'INVALID': |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 425 | messages = messages + 'Please set TARGET_OS directly, or choose a MACHINE or DISTRO that does so.\n' |
| 426 | |
| 427 | # Check that we don't have duplicate entries in PACKAGE_ARCHS & that TUNE_PKGARCH is in PACKAGE_ARCHS |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 428 | pkgarchs = sanity_data.getVar('PACKAGE_ARCHS') |
| 429 | tunepkg = sanity_data.getVar('TUNE_PKGARCH') |
| 430 | defaulttune = sanity_data.getVar('DEFAULTTUNE') |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 431 | tunefound = False |
| 432 | seen = {} |
| 433 | dups = [] |
| 434 | |
| 435 | for pa in pkgarchs.split(): |
| 436 | if seen.get(pa, 0) == 1: |
| 437 | dups.append(pa) |
| 438 | else: |
| 439 | seen[pa] = 1 |
| 440 | if pa == tunepkg: |
| 441 | tunefound = True |
| 442 | |
| 443 | if len(dups): |
| 444 | messages = messages + "Error, the PACKAGE_ARCHS variable contains duplicates. The following archs are listed more than once: %s" % " ".join(dups) |
| 445 | |
| 446 | if tunefound == False: |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 447 | messages = messages + "Error, the PACKAGE_ARCHS variable (%s) for DEFAULTTUNE (%s) does not contain TUNE_PKGARCH (%s)." % (pkgarchs, defaulttune, tunepkg) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 448 | |
| 449 | return messages |
| 450 | |
| 451 | # Checks if necessary to add option march to host gcc |
| 452 | def check_gcc_march(sanity_data): |
| 453 | result = True |
| 454 | message = "" |
| 455 | |
| 456 | # Check if -march not in BUILD_CFLAGS |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 457 | if sanity_data.getVar("BUILD_CFLAGS").find("-march") < 0: |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 458 | result = False |
| 459 | |
| 460 | # Construct a test file |
| 461 | f = open("gcc_test.c", "w") |
| 462 | f.write("int main (){ volatile int atomic = 2; __sync_bool_compare_and_swap (&atomic, 2, 3); return 0; }\n") |
| 463 | f.close() |
| 464 | |
| 465 | # Check if GCC could work without march |
| 466 | if not result: |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 467 | status,res = oe.utils.getstatusoutput(sanity_data.expand("${BUILD_CC} gcc_test.c -o gcc_test")) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 468 | if status == 0: |
| 469 | result = True; |
| 470 | |
| 471 | if not result: |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 472 | status,res = oe.utils.getstatusoutput(sanity_data.expand("${BUILD_CC} -march=native gcc_test.c -o gcc_test")) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 473 | if status == 0: |
| 474 | message = "BUILD_CFLAGS_append = \" -march=native\"" |
| 475 | result = True; |
| 476 | |
| 477 | if not result: |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 478 | build_arch = sanity_data.getVar('BUILD_ARCH') |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 479 | status,res = oe.utils.getstatusoutput(sanity_data.expand("${BUILD_CC} -march=%s gcc_test.c -o gcc_test" % build_arch)) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 480 | if status == 0: |
| 481 | message = "BUILD_CFLAGS_append = \" -march=%s\"" % build_arch |
| 482 | result = True; |
| 483 | |
| 484 | os.remove("gcc_test.c") |
| 485 | if os.path.exists("gcc_test"): |
| 486 | os.remove("gcc_test") |
| 487 | |
| 488 | return (result, message) |
| 489 | |
| 490 | # Unpatched versions of make 3.82 are known to be broken. See GNU Savannah Bug 30612. |
| 491 | # Use a modified reproducer from http://savannah.gnu.org/bugs/?30612 to validate. |
| 492 | def check_make_version(sanity_data): |
| 493 | from distutils.version import LooseVersion |
| 494 | status, result = oe.utils.getstatusoutput("make --version") |
| 495 | if status != 0: |
| 496 | return "Unable to execute make --version, exit code %s\n" % status |
| 497 | version = result.split()[2] |
| 498 | if LooseVersion(version) == LooseVersion("3.82"): |
| 499 | # Construct a test file |
| 500 | f = open("makefile_test", "w") |
| 501 | f.write("makefile_test.a: makefile_test_a.c makefile_test_b.c makefile_test.a( makefile_test_a.c makefile_test_b.c)\n") |
| 502 | f.write("\n") |
| 503 | f.write("makefile_test_a.c:\n") |
| 504 | f.write(" touch $@\n") |
| 505 | f.write("\n") |
| 506 | f.write("makefile_test_b.c:\n") |
| 507 | f.write(" touch $@\n") |
| 508 | f.close() |
| 509 | |
| 510 | # Check if make 3.82 has been patched |
| 511 | status,result = oe.utils.getstatusoutput("make -f makefile_test") |
| 512 | |
| 513 | os.remove("makefile_test") |
| 514 | if os.path.exists("makefile_test_a.c"): |
| 515 | os.remove("makefile_test_a.c") |
| 516 | if os.path.exists("makefile_test_b.c"): |
| 517 | os.remove("makefile_test_b.c") |
| 518 | if os.path.exists("makefile_test.a"): |
| 519 | os.remove("makefile_test.a") |
| 520 | |
| 521 | if status != 0: |
| 522 | return "Your version of make 3.82 is broken. Please revert to 3.81 or install a patched version.\n" |
| 523 | return None |
| 524 | |
| 525 | |
| 526 | # Tar version 1.24 and onwards handle overwriting symlinks correctly |
| 527 | # but earlier versions do not; this needs to work properly for sstate |
| 528 | def check_tar_version(sanity_data): |
| 529 | from distutils.version import LooseVersion |
| 530 | status, result = oe.utils.getstatusoutput("tar --version") |
| 531 | if status != 0: |
| 532 | return "Unable to execute tar --version, exit code %s\n" % status |
| 533 | version = result.split()[3] |
| 534 | if LooseVersion(version) < LooseVersion("1.24"): |
| 535 | return "Your version of tar is older than 1.24 and has bugs which will break builds. Please install a newer version of tar.\n" |
| 536 | return None |
| 537 | |
| 538 | # We use git parameters and functionality only found in 1.7.8 or later |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 539 | # The kernel tools assume git >= 1.8.3.1 (verified needed > 1.7.9.5) see #6162 |
| 540 | # The git fetcher also had workarounds for git < 1.7.9.2 which we've dropped |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 541 | def check_git_version(sanity_data): |
| 542 | from distutils.version import LooseVersion |
| 543 | status, result = oe.utils.getstatusoutput("git --version 2> /dev/null") |
| 544 | if status != 0: |
| 545 | return "Unable to execute git --version, exit code %s\n" % status |
| 546 | version = result.split()[2] |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 547 | if LooseVersion(version) < LooseVersion("1.8.3.1"): |
| 548 | return "Your version of git is older than 1.8.3.1 and has bugs which will break builds. Please install a newer version of git.\n" |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 549 | return None |
| 550 | |
| 551 | # Check the required perl modules which may not be installed by default |
| 552 | def check_perl_modules(sanity_data): |
| 553 | ret = "" |
| 554 | modules = ( "Text::ParseWords", "Thread::Queue", "Data::Dumper" ) |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 555 | errresult = '' |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 556 | for m in modules: |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 557 | status, result = oe.utils.getstatusoutput("perl -e 'use %s'" % m) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 558 | if status != 0: |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 559 | errresult += result |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 560 | ret += "%s " % m |
| 561 | if ret: |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 562 | return "Required perl module(s) not found: %s\n\n%s\n" % (ret, errresult) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 563 | return None |
| 564 | |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 565 | def sanity_check_conffiles(d): |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 566 | funcs = d.getVar('BBLAYERS_CONF_UPDATE_FUNCS').split() |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 567 | for func in funcs: |
| 568 | conffile, current_version, required_version, func = func.split(":") |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 569 | if check_conf_exists(conffile, d) and d.getVar(current_version) is not None and \ |
| 570 | d.getVar(current_version) != d.getVar(required_version): |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 571 | try: |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 572 | bb.build.exec_func(func, d, pythonexception=True) |
| 573 | except NotImplementedError as e: |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 574 | bb.fatal(str(e)) |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 575 | d.setVar("BB_INVALIDCONF", True) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 576 | |
| 577 | def sanity_handle_abichanges(status, d): |
| 578 | # |
| 579 | # Check the 'ABI' of TMPDIR |
| 580 | # |
| 581 | import subprocess |
| 582 | |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 583 | current_abi = d.getVar('OELAYOUT_ABI') |
| 584 | abifile = d.getVar('SANITY_ABIFILE') |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 585 | if os.path.exists(abifile): |
| 586 | with open(abifile, "r") as f: |
| 587 | abi = f.read().strip() |
| 588 | if not abi.isdigit(): |
| 589 | with open(abifile, "w") as f: |
| 590 | f.write(current_abi) |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 591 | elif int(abi) <= 11 and current_abi == "12": |
| 592 | status.addresult("The layout of TMPDIR changed for Recipe Specific Sysroots.\nConversion doesn't make sense and this change will rebuild everything so please delete TMPDIR (%s).\n" % d.getVar("TMPDIR")) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 593 | elif (abi != current_abi): |
| 594 | # Code to convert from one ABI to another could go here if possible. |
| 595 | status.addresult("Error, TMPDIR has changed its layout version number (%s to %s) and you need to either rebuild, revert or adjust it at your own risk.\n" % (abi, current_abi)) |
| 596 | else: |
| 597 | with open(abifile, "w") as f: |
| 598 | f.write(current_abi) |
| 599 | |
| 600 | def check_sanity_sstate_dir_change(sstate_dir, data): |
| 601 | # Sanity checks to be done when the value of SSTATE_DIR changes |
| 602 | |
| 603 | # Check that SSTATE_DIR isn't on a filesystem with limited filename length (eg. eCryptFS) |
| 604 | testmsg = "" |
| 605 | if sstate_dir != "": |
| 606 | testmsg = check_create_long_filename(sstate_dir, "SSTATE_DIR") |
| 607 | # If we don't have permissions to SSTATE_DIR, suggest the user set it as an SSTATE_MIRRORS |
| 608 | try: |
| 609 | err = testmsg.split(': ')[1].strip() |
| 610 | if err == "Permission denied.": |
| 611 | testmsg = testmsg + "You could try using %s in SSTATE_MIRRORS rather than as an SSTATE_CACHE.\n" % (sstate_dir) |
| 612 | except IndexError: |
| 613 | pass |
| 614 | return testmsg |
| 615 | |
| 616 | def check_sanity_version_change(status, d): |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 617 | # Sanity checks to be done when SANITY_VERSION or NATIVELSBSTRING changes |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 618 | # In other words, these tests run once in a given build directory and then |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 619 | # never again until the sanity version or host distrubution id/version changes. |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 620 | |
| 621 | # Check the python install is complete. glib-2.0-natives requries |
| 622 | # xml.parsers.expat |
| 623 | try: |
| 624 | import xml.parsers.expat |
| 625 | except ImportError: |
| 626 | status.addresult('Your python is not a full install. Please install the module xml.parsers.expat (python-xml on openSUSE and SUSE Linux).\n') |
| 627 | import stat |
| 628 | |
| 629 | status.addresult(check_make_version(d)) |
| 630 | status.addresult(check_tar_version(d)) |
| 631 | status.addresult(check_git_version(d)) |
| 632 | status.addresult(check_perl_modules(d)) |
| 633 | |
| 634 | missing = "" |
| 635 | |
| 636 | if not check_app_exists("${MAKE}", d): |
| 637 | missing = missing + "GNU make," |
| 638 | |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 639 | if not check_app_exists('${BUILD_CC}', d): |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 640 | missing = missing + "C Compiler (%s)," % d.getVar("BUILD_CC") |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 641 | |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 642 | if not check_app_exists('${BUILD_CXX}', d): |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 643 | missing = missing + "C++ Compiler (%s)," % d.getVar("BUILD_CXX") |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 644 | |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 645 | required_utilities = d.getVar('SANITY_REQUIRED_UTILITIES') |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 646 | |
| 647 | for util in required_utilities.split(): |
| 648 | if not check_app_exists(util, d): |
| 649 | missing = missing + "%s," % util |
| 650 | |
| 651 | if missing: |
| 652 | missing = missing.rstrip(',') |
| 653 | status.addresult("Please install the following missing utilities: %s\n" % missing) |
| 654 | |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 655 | assume_provided = d.getVar('ASSUME_PROVIDED').split() |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 656 | # Check user doesn't have ASSUME_PROVIDED = instead of += in local.conf |
| 657 | if "diffstat-native" not in assume_provided: |
| 658 | status.addresult('Please use ASSUME_PROVIDED +=, not ASSUME_PROVIDED = in your local.conf\n') |
| 659 | |
| 660 | if "qemu-native" in assume_provided: |
| 661 | if not check_app_exists("qemu-arm", d): |
| 662 | status.addresult("qemu-native was in ASSUME_PROVIDED but the QEMU binaries (qemu-arm) can't be found in PATH") |
| 663 | |
| 664 | if "libsdl-native" in assume_provided: |
| 665 | if not check_app_exists("sdl-config", d): |
| 666 | status.addresult("libsdl-native is set to be ASSUME_PROVIDED but sdl-config can't be found in PATH. Please either install it, or configure qemu not to require sdl.") |
| 667 | |
| 668 | (result, message) = check_gcc_march(d) |
| 669 | if result and message: |
| 670 | status.addresult("Your gcc version is older than 4.5, please add the following param to local.conf\n \ |
| 671 | %s\n" % message) |
| 672 | if not result: |
| 673 | status.addresult("Your gcc version is older than 4.5 or is not working properly. Please verify you can build") |
| 674 | status.addresult(" and link something that uses atomic operations, such as: \n") |
| 675 | status.addresult(" __sync_bool_compare_and_swap (&atomic, 2, 3);\n") |
| 676 | |
| 677 | # Check that TMPDIR isn't on a filesystem with limited filename length (eg. eCryptFS) |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 678 | tmpdir = d.getVar('TMPDIR') |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 679 | status.addresult(check_create_long_filename(tmpdir, "TMPDIR")) |
| 680 | tmpdirmode = os.stat(tmpdir).st_mode |
| 681 | if (tmpdirmode & stat.S_ISGID): |
| 682 | status.addresult("TMPDIR is setgid, please don't build in a setgid directory") |
| 683 | if (tmpdirmode & stat.S_ISUID): |
| 684 | status.addresult("TMPDIR is setuid, please don't build in a setuid directory") |
| 685 | |
| 686 | # Some third-party software apparently relies on chmod etc. being suid root (!!) |
| 687 | import stat |
| 688 | suid_check_bins = "chown chmod mknod".split() |
| 689 | for bin_cmd in suid_check_bins: |
| 690 | bin_path = bb.utils.which(os.environ["PATH"], bin_cmd) |
| 691 | if bin_path: |
| 692 | bin_stat = os.stat(bin_path) |
| 693 | if bin_stat.st_uid == 0 and bin_stat.st_mode & stat.S_ISUID: |
| 694 | status.addresult('%s has the setuid bit set. This interferes with pseudo and may cause other issues that break the build process.\n' % bin_path) |
| 695 | |
| 696 | # Check that we can fetch from various network transports |
| 697 | netcheck = check_connectivity(d) |
| 698 | status.addresult(netcheck) |
| 699 | if netcheck: |
| 700 | status.network_error = True |
| 701 | |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 702 | nolibs = d.getVar('NO32LIBS') |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 703 | if not nolibs: |
| 704 | lib32path = '/lib' |
| 705 | if os.path.exists('/lib64') and ( os.path.islink('/lib64') or os.path.islink('/lib') ): |
| 706 | lib32path = '/lib32' |
| 707 | |
| 708 | if os.path.exists('%s/libc.so.6' % lib32path) and not os.path.exists('/usr/include/gnu/stubs-32.h'): |
| 709 | status.addresult("You have a 32-bit libc, but no 32-bit headers. You must install the 32-bit libc headers.\n") |
| 710 | |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 711 | bbpaths = d.getVar('BBPATH').split(":") |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 712 | if ("." in bbpaths or "./" in bbpaths or "" in bbpaths): |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 713 | status.addresult("BBPATH references the current directory, either through " \ |
| 714 | "an empty entry, a './' or a '.'.\n\t This is unsafe and means your "\ |
| 715 | "layer configuration is adding empty elements to BBPATH.\n\t "\ |
| 716 | "Please check your layer.conf files and other BBPATH " \ |
| 717 | "settings to remove the current working directory " \ |
| 718 | "references.\n" \ |
| 719 | "Parsed BBPATH is" + str(bbpaths)); |
| 720 | |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 721 | oes_bb_conf = d.getVar( 'OES_BITBAKE_CONF') |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 722 | if not oes_bb_conf: |
| 723 | status.addresult('You are not using the OpenEmbedded version of conf/bitbake.conf. This means your environment is misconfigured, in particular check BBPATH.\n') |
| 724 | |
| 725 | # The length of TMPDIR can't be longer than 410 |
| 726 | status.addresult(check_path_length(tmpdir, "TMPDIR", 410)) |
| 727 | |
| 728 | # Check that TMPDIR isn't located on nfs |
| 729 | status.addresult(check_not_nfs(tmpdir, "TMPDIR")) |
| 730 | |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 731 | def sanity_check_locale(d): |
| 732 | """ |
| 733 | Currently bitbake switches locale to en_US.UTF-8 so check that this locale actually exists. |
| 734 | """ |
| 735 | import locale |
| 736 | try: |
| 737 | locale.setlocale(locale.LC_ALL, "en_US.UTF-8") |
| 738 | except locale.Error: |
| 739 | raise_sanity_error("You system needs to support the en_US.UTF-8 locale.", d) |
| 740 | |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 741 | def check_sanity_everybuild(status, d): |
| 742 | import os, stat |
| 743 | # Sanity tests which test the users environment so need to run at each build (or are so cheap |
| 744 | # it makes sense to always run them. |
| 745 | |
| 746 | if 0 == os.getuid(): |
| 747 | raise_sanity_error("Do not use Bitbake as root.", d) |
| 748 | |
| 749 | # Check the Python version, we now have a minimum of Python 2.7.3 |
| 750 | import sys |
| 751 | if sys.hexversion < 0x020703F0: |
| 752 | status.addresult('The system requires at least Python 2.7.3 to run. Please update your Python interpreter.\n') |
| 753 | |
| 754 | # Check the bitbake version meets minimum requirements |
| 755 | from distutils.version import LooseVersion |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 756 | minversion = d.getVar('BB_MIN_VERSION') |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 757 | if (LooseVersion(bb.__version__) < LooseVersion(minversion)): |
| 758 | status.addresult('Bitbake version %s is required and version %s was found\n' % (minversion, bb.__version__)) |
| 759 | |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 760 | sanity_check_locale(d) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 761 | |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 762 | paths = d.getVar('PATH').split(":") |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 763 | if "." in paths or "./" in paths or "" in paths: |
| 764 | status.addresult("PATH contains '.', './' or '' (empty element), which will break the build, please remove this.\nParsed PATH is " + str(paths) + "\n") |
| 765 | |
| 766 | # Check that the DISTRO is valid, if set |
| 767 | # need to take into account DISTRO renaming DISTRO |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 768 | distro = d.getVar('DISTRO') |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 769 | if distro and distro != "nodistro": |
| 770 | if not ( check_conf_exists("conf/distro/${DISTRO}.conf", d) or check_conf_exists("conf/distro/include/${DISTRO}.inc", d) ): |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 771 | status.addresult("DISTRO '%s' not found. Please set a valid DISTRO in your local.conf\n" % d.getVar("DISTRO")) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 772 | |
| 773 | # Check that DL_DIR is set, exists and is writable. In theory, we should never even hit the check if DL_DIR isn't |
| 774 | # set, since so much relies on it being set. |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 775 | dldir = d.getVar('DL_DIR') |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 776 | if not dldir: |
| 777 | status.addresult("DL_DIR is not set. Your environment is misconfigured, check that DL_DIR is set, and if the directory exists, that it is writable. \n") |
| 778 | if os.path.exists(dldir) and not os.access(dldir, os.W_OK): |
| 779 | status.addresult("DL_DIR: %s exists but you do not appear to have write access to it. \n" % dldir) |
| 780 | check_symlink(dldir, d) |
| 781 | |
| 782 | # Check that the MACHINE is valid, if it is set |
| 783 | machinevalid = True |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 784 | if d.getVar('MACHINE'): |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 785 | if not check_conf_exists("conf/machine/${MACHINE}.conf", d): |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 786 | status.addresult('MACHINE=%s is invalid. Please set a valid MACHINE in your local.conf, environment or other configuration file.\n' % (d.getVar('MACHINE'))) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 787 | machinevalid = False |
| 788 | else: |
| 789 | status.addresult(check_sanity_validmachine(d)) |
| 790 | else: |
| 791 | status.addresult('Please set a MACHINE in your local.conf or environment\n') |
| 792 | machinevalid = False |
| 793 | if machinevalid: |
| 794 | status.addresult(check_toolchain(d)) |
| 795 | |
| 796 | # Check that the SDKMACHINE is valid, if it is set |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 797 | if d.getVar('SDKMACHINE'): |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 798 | if not check_conf_exists("conf/machine-sdk/${SDKMACHINE}.conf", d): |
| 799 | status.addresult('Specified SDKMACHINE value is not valid\n') |
| 800 | elif d.getVar('SDK_ARCH', False) == "${BUILD_ARCH}": |
| 801 | status.addresult('SDKMACHINE is set, but SDK_ARCH has not been changed as a result - SDKMACHINE may have been set too late (e.g. in the distro configuration)\n') |
| 802 | |
| 803 | check_supported_distro(d) |
| 804 | |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 805 | omask = os.umask(0o022) |
| 806 | if omask & 0o755: |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 807 | status.addresult("Please use a umask which allows a+rx and u+rwx\n") |
| 808 | os.umask(omask) |
| 809 | |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 810 | if d.getVar('TARGET_ARCH') == "arm": |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 811 | # This path is no longer user-readable in modern (very recent) Linux |
| 812 | try: |
| 813 | if os.path.exists("/proc/sys/vm/mmap_min_addr"): |
| 814 | f = open("/proc/sys/vm/mmap_min_addr", "r") |
| 815 | try: |
| 816 | if (int(f.read().strip()) > 65536): |
| 817 | status.addresult("/proc/sys/vm/mmap_min_addr is not <= 65536. This will cause problems with qemu so please fix the value (as root).\n\nTo fix this in later reboots, set vm.mmap_min_addr = 65536 in /etc/sysctl.conf.\n") |
| 818 | finally: |
| 819 | f.close() |
| 820 | except: |
| 821 | pass |
| 822 | |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 823 | oeroot = d.getVar('COREBASE') |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 824 | if oeroot.find('+') != -1: |
| 825 | status.addresult("Error, you have an invalid character (+) in your COREBASE directory path. Please move the installation to a directory which doesn't include any + characters.") |
| 826 | if oeroot.find('@') != -1: |
| 827 | status.addresult("Error, you have an invalid character (@) in your COREBASE directory path. Please move the installation to a directory which doesn't include any @ characters.") |
| 828 | if oeroot.find(' ') != -1: |
| 829 | status.addresult("Error, you have a space in your COREBASE directory path. Please move the installation to a directory which doesn't include a space since autotools doesn't support this.") |
| 830 | |
| 831 | # Check the format of MIRRORS, PREMIRRORS and SSTATE_MIRRORS |
| 832 | import re |
| 833 | mirror_vars = ['MIRRORS', 'PREMIRRORS', 'SSTATE_MIRRORS'] |
| 834 | protocols = ['http', 'ftp', 'file', 'https', \ |
| 835 | 'git', 'gitsm', 'hg', 'osc', 'p4', 'svn', \ |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 836 | 'bzr', 'cvs', 'npm', 'sftp', 'ssh', 's3' ] |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 837 | for mirror_var in mirror_vars: |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 838 | mirrors = (d.getVar(mirror_var) or '').replace('\\n', ' ').split() |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 839 | |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 840 | # Split into pairs |
| 841 | if len(mirrors) % 2 != 0: |
| 842 | bb.warn('Invalid mirror variable value for %s: %s, should contain paired members.' % (mirror_var, mirrors.strip())) |
| 843 | continue |
| 844 | mirrors = list(zip(*[iter(mirrors)]*2)) |
| 845 | |
| 846 | for mirror_entry in mirrors: |
| 847 | pattern, mirror = mirror_entry |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 848 | |
| 849 | decoded = bb.fetch2.decodeurl(pattern) |
| 850 | try: |
| 851 | pattern_scheme = re.compile(decoded[0]) |
| 852 | except re.error as exc: |
| 853 | bb.warn('Invalid scheme regex (%s) in %s; %s' % (pattern, mirror_var, mirror_entry)) |
| 854 | continue |
| 855 | |
| 856 | if not any(pattern_scheme.match(protocol) for protocol in protocols): |
| 857 | bb.warn('Invalid protocol (%s) in %s: %s' % (decoded[0], mirror_var, mirror_entry)) |
| 858 | continue |
| 859 | |
| 860 | if not any(mirror.startswith(protocol + '://') for protocol in protocols): |
| 861 | bb.warn('Invalid protocol in %s: %s' % (mirror_var, mirror_entry)) |
| 862 | continue |
| 863 | |
| 864 | if mirror.startswith('file://'): |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 865 | import urllib |
| 866 | check_symlink(urllib.parse.urlparse(mirror).path, d) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 867 | # SSTATE_MIRROR ends with a /PATH string |
| 868 | if mirror.endswith('/PATH'): |
| 869 | # remove /PATH$ from SSTATE_MIRROR to get a working |
| 870 | # base directory path |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 871 | mirror_base = urllib.parse.urlparse(mirror[:-1*len('/PATH')]).path |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 872 | check_symlink(mirror_base, d) |
| 873 | |
| 874 | # Check that TMPDIR hasn't changed location since the last time we were run |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 875 | tmpdir = d.getVar('TMPDIR') |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 876 | checkfile = os.path.join(tmpdir, "saved_tmpdir") |
| 877 | if os.path.exists(checkfile): |
| 878 | with open(checkfile, "r") as f: |
| 879 | saved_tmpdir = f.read().strip() |
| 880 | if (saved_tmpdir != tmpdir): |
| 881 | status.addresult("Error, TMPDIR has changed location. You need to either move it back to %s or rebuild\n" % saved_tmpdir) |
| 882 | else: |
| 883 | bb.utils.mkdirhier(tmpdir) |
| 884 | # Remove setuid, setgid and sticky bits from TMPDIR |
Patrick Williams | f1e5d69 | 2016-03-30 15:21:19 -0500 | [diff] [blame] | 885 | try: |
| 886 | os.chmod(tmpdir, os.stat(tmpdir).st_mode & ~ stat.S_ISUID) |
| 887 | os.chmod(tmpdir, os.stat(tmpdir).st_mode & ~ stat.S_ISGID) |
| 888 | os.chmod(tmpdir, os.stat(tmpdir).st_mode & ~ stat.S_ISVTX) |
| 889 | except OSError as exc: |
| 890 | bb.warn("Unable to chmod TMPDIR: %s" % exc) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 891 | with open(checkfile, "w") as f: |
| 892 | f.write(tmpdir) |
| 893 | |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 894 | # If /bin/sh is a symlink, check that it points to dash or bash |
| 895 | if os.path.islink('/bin/sh'): |
| 896 | real_sh = os.path.realpath('/bin/sh') |
Brad Bishop | 37a0e4d | 2017-12-04 01:01:44 -0500 | [diff] [blame] | 897 | # Due to update-alternatives, the shell name may take various |
| 898 | # forms, such as /bin/dash, bin/bash, /bin/bash.bash ... |
| 899 | if '/dash' not in real_sh and '/bash' not in real_sh: |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 900 | status.addresult("Error, /bin/sh links to %s, must be dash or bash\n" % real_sh) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 901 | |
| 902 | def check_sanity(sanity_data): |
| 903 | class SanityStatus(object): |
| 904 | def __init__(self): |
| 905 | self.messages = "" |
| 906 | self.network_error = False |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 907 | |
| 908 | def addresult(self, message): |
| 909 | if message: |
| 910 | self.messages = self.messages + message |
| 911 | |
| 912 | status = SanityStatus() |
| 913 | |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 914 | tmpdir = sanity_data.getVar('TMPDIR') |
| 915 | sstate_dir = sanity_data.getVar('SSTATE_DIR') |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 916 | |
| 917 | check_symlink(sstate_dir, sanity_data) |
| 918 | |
| 919 | # Check saved sanity info |
| 920 | last_sanity_version = 0 |
| 921 | last_tmpdir = "" |
| 922 | last_sstate_dir = "" |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 923 | last_nativelsbstr = "" |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 924 | sanityverfile = sanity_data.expand("${TOPDIR}/conf/sanity_info") |
| 925 | if os.path.exists(sanityverfile): |
| 926 | with open(sanityverfile, 'r') as f: |
| 927 | for line in f: |
| 928 | if line.startswith('SANITY_VERSION'): |
| 929 | last_sanity_version = int(line.split()[1]) |
| 930 | if line.startswith('TMPDIR'): |
| 931 | last_tmpdir = line.split()[1] |
| 932 | if line.startswith('SSTATE_DIR'): |
| 933 | last_sstate_dir = line.split()[1] |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 934 | if line.startswith('NATIVELSBSTRING'): |
| 935 | last_nativelsbstr = line.split()[1] |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 936 | |
| 937 | check_sanity_everybuild(status, sanity_data) |
| 938 | |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame^] | 939 | sanity_version = int(sanity_data.getVar('SANITY_VERSION') or 1) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 940 | network_error = False |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 941 | # NATIVELSBSTRING var may have been overridden with "universal", so |
| 942 | # get actual host distribution id and version |
| 943 | nativelsbstr = lsb_distro_identifier(sanity_data) |
| 944 | if last_sanity_version < sanity_version or last_nativelsbstr != nativelsbstr: |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 945 | check_sanity_version_change(status, sanity_data) |
| 946 | status.addresult(check_sanity_sstate_dir_change(sstate_dir, sanity_data)) |
| 947 | else: |
| 948 | if last_sstate_dir != sstate_dir: |
| 949 | status.addresult(check_sanity_sstate_dir_change(sstate_dir, sanity_data)) |
| 950 | |
| 951 | if os.path.exists(os.path.dirname(sanityverfile)) and not status.messages: |
| 952 | with open(sanityverfile, 'w') as f: |
| 953 | f.write("SANITY_VERSION %s\n" % sanity_version) |
| 954 | f.write("TMPDIR %s\n" % tmpdir) |
| 955 | f.write("SSTATE_DIR %s\n" % sstate_dir) |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 956 | f.write("NATIVELSBSTRING %s\n" % nativelsbstr) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 957 | |
| 958 | sanity_handle_abichanges(status, sanity_data) |
| 959 | |
| 960 | if status.messages != "": |
| 961 | raise_sanity_error(sanity_data.expand(status.messages), sanity_data, status.network_error) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 962 | |
| 963 | # Create a copy of the datastore and finalise it to ensure appends and |
| 964 | # overrides are set - the datastore has yet to be finalised at ConfigParsed |
| 965 | def copy_data(e): |
| 966 | sanity_data = bb.data.createCopy(e.data) |
| 967 | sanity_data.finalize() |
| 968 | return sanity_data |
| 969 | |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 970 | addhandler config_reparse_eventhandler |
| 971 | config_reparse_eventhandler[eventmask] = "bb.event.ConfigParsed" |
| 972 | python config_reparse_eventhandler() { |
| 973 | sanity_check_conffiles(e.data) |
| 974 | } |
| 975 | |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 976 | addhandler check_sanity_eventhandler |
| 977 | check_sanity_eventhandler[eventmask] = "bb.event.SanityCheck bb.event.NetworkTest" |
| 978 | python check_sanity_eventhandler() { |
| 979 | if bb.event.getName(e) == "SanityCheck": |
| 980 | sanity_data = copy_data(e) |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 981 | check_sanity(sanity_data) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 982 | if e.generateevents: |
| 983 | sanity_data.setVar("SANITY_USE_EVENTS", "1") |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 984 | bb.event.fire(bb.event.SanityCheckPassed(), e.data) |
| 985 | elif bb.event.getName(e) == "NetworkTest": |
| 986 | sanity_data = copy_data(e) |
| 987 | if e.generateevents: |
| 988 | sanity_data.setVar("SANITY_USE_EVENTS", "1") |
| 989 | bb.event.fire(bb.event.NetworkTestFailed() if check_connectivity(sanity_data) else bb.event.NetworkTestPassed(), e.data) |
| 990 | |
| 991 | return |
| 992 | } |