def ensure_npm(config, basepath, fixed_setup=False, check_exists=True): """ Ensure that npm is available and either build it or show a reasonable error message """ if check_exists: tinfoil = setup_tinfoil(config_only=False, basepath=basepath) try: rd = tinfoil.parse_recipe('nodejs-native') nativepath = rd.getVar('STAGING_BINDIR_NATIVE') finally: tinfoil.shutdown() npmpath = os.path.join(nativepath, 'npm') build_npm = not os.path.exists(npmpath) else: build_npm = True if build_npm: logger.info('Building nodejs-native') try: exec_build_env_command(config.init_path, basepath, 'bitbake -q nodejs-native -c addto_recipe_sysroot', watch=True) except bb.process.ExecutionError as e: if "Nothing PROVIDES 'nodejs-native'" in e.stdout: if fixed_setup: msg = 'nodejs-native is required for npm but is not available within this SDK' else: msg = 'nodejs-native is required for npm but is not available - you will likely need to add a layer that provides nodejs' raise DevtoolError(msg) else: raise
def setup_tinfoil(config_only=False, basepath=None, tracking=False): """Initialize tinfoil api from bitbake""" import scriptpath orig_cwd = os.path.abspath(os.curdir) try: if basepath: os.chdir(basepath) bitbakepath = scriptpath.add_bitbake_lib_path() if not bitbakepath: logger.error("Unable to find bitbake by searching parent directory of this script or PATH") sys.exit(1) import bb.tinfoil tinfoil = bb.tinfoil.Tinfoil(tracking=tracking) try: tinfoil.logger.setLevel(logger.getEffectiveLevel()) tinfoil.prepare(config_only) except bb.tinfoil.TinfoilUIException: tinfoil.shutdown() raise DevtoolError('Failed to start bitbake environment') except: tinfoil.shutdown() raise finally: os.chdir(orig_cwd) return tinfoil
def ensure_npm(config, basepath, fixed_setup=False, check_exists=True): """ Ensure that npm is available and either build it or show a reasonable error message """ if check_exists: tinfoil = setup_tinfoil(config_only=False, basepath=basepath) try: rd = tinfoil.parse_recipe('nodejs-native') nativepath = rd.getVar('STAGING_BINDIR_NATIVE') finally: tinfoil.shutdown() npmpath = os.path.join(nativepath, 'npm') build_npm = not os.path.exists(npmpath) else: build_npm = True if build_npm: logger.info('Building nodejs-native') try: exec_build_env_command( config.init_path, basepath, 'bitbake -q nodejs-native -c addto_recipe_sysroot', watch=True) except bb.process.ExecutionError as e: if "Nothing PROVIDES 'nodejs-native'" in e.stdout: if fixed_setup: msg = 'nodejs-native is required for npm but is not available within this SDK' else: msg = 'nodejs-native is required for npm but is not available - you will likely need to add a layer that provides nodejs' raise DevtoolError(msg) else: raise
def setup_tinfoil(config_only=False, basepath=None, tracking=False): """Initialize tinfoil api from bitbake""" import scriptpath orig_cwd = os.path.abspath(os.curdir) try: if basepath: os.chdir(basepath) bitbakepath = scriptpath.add_bitbake_lib_path() if not bitbakepath: logger.error("Unable to find bitbake by searching parent directory of this script or PATH") sys.exit(1) import bb.tinfoil tinfoil = bb.tinfoil.Tinfoil(tracking=tracking) try: tinfoil.prepare(config_only) tinfoil.logger.setLevel(logger.getEffectiveLevel()) except bb.tinfoil.TinfoilUIException: tinfoil.shutdown() raise DevtoolError('Failed to start bitbake environment') except: tinfoil.shutdown() raise finally: os.chdir(orig_cwd) return tinfoil
def ensure_npm(config, basepath, fixed_setup=False): """ Ensure that npm is available and either build it or show a reasonable error message """ tinfoil = setup_tinfoil(config_only=True, basepath=basepath) try: nativepath = tinfoil.config_data.getVar('STAGING_BINDIR_NATIVE') finally: tinfoil.shutdown() npmpath = os.path.join(nativepath, 'npm') if not os.path.exists(npmpath): logger.info('Building nodejs-native') try: exec_build_env_command(config.init_path, basepath, 'bitbake -q nodejs-native', watch=True) except bb.process.ExecutionError as e: if "Nothing PROVIDES 'nodejs-native'" in e.stdout: if fixed_setup: msg = 'nodejs-native is required for npm but is not available within this SDK' else: msg = 'nodejs-native is required for npm but is not available - you will likely need to add a layer that provides nodejs' raise DevtoolError(msg) else: raise if not os.path.exists(npmpath): raise DevtoolError('Built nodejs-native but npm binary still could not be found at %s' % npmpath)
def ensure_npm(config, basepath, fixed_setup=False): """ Ensure that npm is available and either build it or show a reasonable error message """ tinfoil = setup_tinfoil(config_only=True, basepath=basepath) try: nativepath = tinfoil.config_data.getVar('STAGING_BINDIR_NATIVE', True) finally: tinfoil.shutdown() npmpath = os.path.join(nativepath, 'npm') if not os.path.exists(npmpath): logger.info('Building nodejs-native') try: exec_build_env_command(config.init_path, basepath, 'bitbake -q nodejs-native', watch=True) except bb.process.ExecutionError as e: if "Nothing PROVIDES 'nodejs-native'" in e.stdout: if fixed_setup: msg = 'nodejs-native is required for npm but is not available within this SDK' else: msg = 'nodejs-native is required for npm but is not available - you will likely need to add a layer that provides nodejs' raise DevtoolError(msg) else: raise if not os.path.exists(npmpath): raise DevtoolError('Built nodejs-native but npm binary still could not be found at %s' % npmpath)
def runqemu(pn, ssh=True, runqemuparams='', image_fstype=None, launch_cmd=None, qemuparams=None, overrides={}, discard_writes=True): """ launch_cmd means directly run the command, don't need set rootfs or env vars. """ import bb.tinfoil import bb.build # Need a non-'BitBake' logger to capture the runner output targetlogger = logging.getLogger('TargetRunner') targetlogger.setLevel(logging.DEBUG) handler = logging.StreamHandler(sys.stdout) targetlogger.addHandler(handler) tinfoil = bb.tinfoil.Tinfoil() tinfoil.prepare(config_only=False, quiet=True) try: tinfoil.logger.setLevel(logging.WARNING) import oeqa.targetcontrol tinfoil.config_data.setVar("TEST_LOG_DIR", "${WORKDIR}/testimage") tinfoil.config_data.setVar("TEST_QEMUBOOT_TIMEOUT", "1000") # Tell QemuTarget() whether need find rootfs/kernel or not if launch_cmd: tinfoil.config_data.setVar("FIND_ROOTFS", '0') else: tinfoil.config_data.setVar("FIND_ROOTFS", '1') recipedata = tinfoil.parse_recipe(pn) for key, value in overrides.items(): recipedata.setVar(key, value) logdir = recipedata.getVar("TEST_LOG_DIR") qemu = oeqa.targetcontrol.QemuTarget(recipedata, targetlogger, image_fstype) finally: # We need to shut down tinfoil early here in case we actually want # to run tinfoil-using utilities with the running QEMU instance. # Luckily QemuTarget doesn't need it after the constructor. tinfoil.shutdown() try: qemu.deploy() try: qemu.start(params=qemuparams, ssh=ssh, runqemuparams=runqemuparams, launch_cmd=launch_cmd, discard_writes=discard_writes) except bb.build.FuncFailed: msg = 'Failed to start QEMU - see the logs in %s' % logdir if os.path.exists(qemu.qemurunnerlog): with open(qemu.qemurunnerlog, 'r') as f: msg = msg + "Qemurunner log output from %s:\n%s" % (qemu.qemurunnerlog, f.read()) raise Exception(msg) yield qemu finally: targetlogger.removeHandler(handler) try: qemu.stop() except: pass
def runqemu(pn, ssh=True): import bb.tinfoil import bb.build tinfoil = bb.tinfoil.Tinfoil() tinfoil.prepare(False) try: tinfoil.logger.setLevel(logging.WARNING) import oeqa.targetcontrol tinfoil.config_data.setVar("TEST_LOG_DIR", "${WORKDIR}/testimage") tinfoil.config_data.setVar("TEST_QEMUBOOT_TIMEOUT", "1000") import oe.recipeutils recipefile = oe.recipeutils.pn_to_recipe(tinfoil.cooker, pn) recipedata = oe.recipeutils.parse_recipe(recipefile, [], tinfoil.config_data) # The QemuRunner log is saved out, but we need to ensure it is at the right # log level (and then ensure that since it's a child of the BitBake logger, # we disable propagation so we don't then see the log events on the console) logger = logging.getLogger('BitBake.QemuRunner') logger.setLevel(logging.DEBUG) logger.propagate = False logdir = recipedata.getVar("TEST_LOG_DIR", True) qemu = oeqa.targetcontrol.QemuTarget(recipedata) finally: # We need to shut down tinfoil early here in case we actually want # to run tinfoil-using utilities with the running QEMU instance. # Luckily QemuTarget doesn't need it after the constructor. tinfoil.shutdown() # Setup bitbake logger as console handler is removed by tinfoil.shutdown bblogger = logging.getLogger('BitBake') bblogger.setLevel(logging.INFO) console = logging.StreamHandler(sys.stdout) bbformat = bb.msg.BBLogFormatter("%(levelname)s: %(message)s") if sys.stdout.isatty(): bbformat.enable_color() console.setFormatter(bbformat) bblogger.addHandler(console) try: qemu.deploy() try: qemu.start(ssh=ssh) except bb.build.FuncFailed: raise Exception('Failed to start QEMU - see the logs in %s' % logdir) yield qemu finally: try: qemu.stop() except: pass
def runqemu(pn, ssh=True): import bb.tinfoil import bb.build tinfoil = bb.tinfoil.Tinfoil() tinfoil.prepare(False) try: tinfoil.logger.setLevel(logging.WARNING) import oeqa.targetcontrol tinfoil.config_data.setVar("TEST_LOG_DIR", "${WORKDIR}/testimage") tinfoil.config_data.setVar("TEST_QEMUBOOT_TIMEOUT", "1000") import oe.recipeutils recipefile = oe.recipeutils.pn_to_recipe(tinfoil.cooker, pn) recipedata = oe.recipeutils.parse_recipe(recipefile, [], tinfoil.config_data) # The QemuRunner log is saved out, but we need to ensure it is at the right # log level (and then ensure that since it's a child of the BitBake logger, # we disable propagation so we don't then see the log events on the console) logger = logging.getLogger("BitBake.QemuRunner") logger.setLevel(logging.DEBUG) logger.propagate = False logdir = recipedata.getVar("TEST_LOG_DIR", True) qemu = oeqa.targetcontrol.QemuTarget(recipedata) finally: # We need to shut down tinfoil early here in case we actually want # to run tinfoil-using utilities with the running QEMU instance. # Luckily QemuTarget doesn't need it after the constructor. tinfoil.shutdown() # Setup bitbake logger as console handler is removed by tinfoil.shutdown bblogger = logging.getLogger("BitBake") bblogger.setLevel(logging.INFO) console = logging.StreamHandler(sys.stdout) bbformat = bb.msg.BBLogFormatter("%(levelname)s: %(message)s") if sys.stdout.isatty(): bbformat.enable_color() console.setFormatter(bbformat) bblogger.addHandler(console) try: qemu.deploy() try: qemu.start(ssh=ssh) except bb.build.FuncFailed: raise Exception("Failed to start QEMU - see the logs in %s" % logdir) yield qemu finally: try: qemu.stop() except: pass
def runqemu(pn, test): import bb.tinfoil import bb.build tinfoil = bb.tinfoil.Tinfoil() tinfoil.prepare(False) try: tinfoil.logger.setLevel(logging.WARNING) import oeqa.targetcontrol tinfoil.config_data.setVar("TEST_LOG_DIR", "${WORKDIR}/testimage") tinfoil.config_data.setVar("TEST_QEMUBOOT_TIMEOUT", "90") import oe.recipeutils recipefile = oe.recipeutils.pn_to_recipe(tinfoil.cooker, pn) recipedata = oe.recipeutils.parse_recipe(recipefile, [], tinfoil.config_data) # The QemuRunner log is saved out, but we need to ensure it is at the right # log level (and then ensure that since it's a child of the BitBake logger, # we disable propagation so we don't then see the log events on the console) logger = logging.getLogger('BitBake.QemuRunner') logger.setLevel(logging.DEBUG) logger.propagate = False logdir = recipedata.getVar("TEST_LOG_DIR", True) qemu = oeqa.targetcontrol.QemuTarget(recipedata) finally: # We need to shut down tinfoil early here in case we actually want # to run tinfoil-using utilities with the running QEMU instance. # Luckily QemuTarget doesn't need it after the constructor. tinfoil.shutdown() try: qemu.deploy() try: qemu.start() except bb.build.FuncFailed: raise Exception('Failed to start QEMU - see the logs in %s' % logdir) yield qemu finally: try: qemu.stop() except: pass
def setup_tinfoil(cls, config_only=False): """Initialize tinfoil api from bitbake""" # import relevant libraries try: scripts_path = os.path.join(pti.repodir, 'scripts', 'lib') if scripts_path not in sys.path: sys.path.insert(0, scripts_path) import scriptpath scriptpath.add_bitbake_lib_path() import bb.tinfoil except ImportError: raise PatchtestOEError('Could not import tinfoil module') orig_cwd = os.path.abspath(os.curdir) # Load tinfoil tinfoil = None try: builddir = os.environ.get('BUILDDIR') if not builddir: logger.warn('Bitbake environment not loaded?') return tinfoil os.chdir(builddir) tinfoil = bb.tinfoil.Tinfoil() tinfoil.prepare(config_only=config_only) except bb.tinfoil.TinfoilUIException as te: if tinfoil: tinfoil.shutdown() raise PatchtestOEError( 'Could not prepare properly tinfoil (TinfoilUIException)') except Exception as e: if tinfoil: tinfoil.shutdown() raise e finally: os.chdir(orig_cwd) return tinfoil
def runqemu(pn, ssh=True, runqemuparams='', image_fstype=None, launch_cmd=None, qemuparams=None, overrides={}, discard_writes=True): """ launch_cmd means directly run the command, don't need set rootfs or env vars. """ import bb.tinfoil import bb.build tinfoil = bb.tinfoil.Tinfoil() tinfoil.prepare(config_only=False, quiet=True) try: tinfoil.logger.setLevel(logging.WARNING) import oeqa.targetcontrol tinfoil.config_data.setVar("TEST_LOG_DIR", "${WORKDIR}/testimage") tinfoil.config_data.setVar("TEST_QEMUBOOT_TIMEOUT", "1000") # Tell QemuTarget() whether need find rootfs/kernel or not if launch_cmd: tinfoil.config_data.setVar("FIND_ROOTFS", '0') else: tinfoil.config_data.setVar("FIND_ROOTFS", '1') recipedata = tinfoil.parse_recipe(pn) for key, value in overrides.items(): recipedata.setVar(key, value) # The QemuRunner log is saved out, but we need to ensure it is at the right # log level (and then ensure that since it's a child of the BitBake logger, # we disable propagation so we don't then see the log events on the console) logger = logging.getLogger('BitBake.QemuRunner') logger.setLevel(logging.DEBUG) logger.propagate = False logdir = recipedata.getVar("TEST_LOG_DIR") qemu = oeqa.targetcontrol.QemuTarget(recipedata, image_fstype) finally: # We need to shut down tinfoil early here in case we actually want # to run tinfoil-using utilities with the running QEMU instance. # Luckily QemuTarget doesn't need it after the constructor. tinfoil.shutdown() # Setup bitbake logger as console handler is removed by tinfoil.shutdown bblogger = logging.getLogger('BitBake') bblogger.setLevel(logging.INFO) console = logging.StreamHandler(sys.stdout) bbformat = bb.msg.BBLogFormatter("%(levelname)s: %(message)s") if sys.stdout.isatty(): bbformat.enable_color() console.setFormatter(bbformat) bblogger.addHandler(console) try: qemu.deploy() try: qemu.start(params=qemuparams, ssh=ssh, runqemuparams=runqemuparams, launch_cmd=launch_cmd, discard_writes=discard_writes) except bb.build.FuncFailed: raise Exception('Failed to start QEMU - see the logs in %s' % logdir) yield qemu finally: try: qemu.stop() except: pass
def main(): # Get access to our Django model newpath = os.path.abspath( os.path.dirname(os.path.abspath(sys.argv[0])) + '/..') sys.path.append(newpath) os.environ['DJANGO_SETTINGS_MODULE'] = 'settings' from django.core.management import setup_environ from django.conf import settings from layerindex.models import LayerItem, Recipe from django.db import transaction import settings setup_environ(settings) # Set path to bitbake lib dir basepath = os.path.abspath(sys.argv[1]) bitbakedir_env = os.environ.get('BITBAKEDIR', '') if bitbakedir_env and os.path.exists(bitbakedir_env + '/lib/bb'): bitbakepath = bitbakedir_env elif os.path.exists(basepath + '/bitbake/lib/bb'): bitbakepath = basepath + '/bitbake' elif os.path.exists(basepath + '/../bitbake/lib/bb'): bitbakepath = os.path.abspath(basepath + '/../bitbake') else: # look for bitbake/bin dir in PATH bitbakepath = None for pth in os.environ['PATH'].split(':'): if os.path.exists(os.path.join(pth, '../lib/bb')): bitbakepath = os.path.abspath(os.path.join(pth, '..')) break if not bitbakepath: print( "Unable to find bitbake by searching BITBAKEDIR, specified path '%s' or its parent, or PATH" % basepath) sys.exit(1) # Skip sanity checks os.environ['BB_ENV_EXTRAWHITE'] = 'DISABLE_SANITY_CHECKS' os.environ['DISABLE_SANITY_CHECKS'] = '1' sys.path.extend([bitbakepath + '/lib']) import bb.tinfoil tinfoil = bb.tinfoil.Tinfoil() tinfoil.prepare(config_only=True) logger = logging.getLogger('BitBake') fetchdir = settings.LAYER_FETCH_DIR if not fetchdir: logger.error("Please set LAYER_FETCH_DIR in settings.py") sys.exit(1) for layer in LayerItem.objects.filter(status='P'): urldir = sanitise_path(layer.vcs_url) repodir = os.path.join(fetchdir, urldir) layerrecipes = Recipe.objects.filter(layer=layer) for recipe in layerrecipes: fullpath = str( os.path.join(repodir, layer.vcs_subdir, recipe.filepath, recipe.filename)) print(fullpath) try: envdata = bb.cache.Cache.loadDataFull(fullpath, [], tinfoil.config_data) print("DESCRIPTION = \"%s\"" % envdata.getVar("DESCRIPTION", True)) except Exception as e: logger.info("Unable to read %s: %s", fullpath, str(e)) tinfoil.shutdown() sys.exit(0)
def tearDownModule(): tinfoil.shutdown()
def select_recipes(args): import bb.tinfoil tinfoil = bb.tinfoil.Tinfoil() tinfoil.prepare(False) pkg_pn = tinfoil.cooker.recipecache.pkg_pn (latest_versions, preferred_versions) = bb.providers.findProviders(tinfoil.config_data, tinfoil.cooker.recipecache, pkg_pn) skip_classes = args.skip_classes.split(',') recipelist = [] for pn in sorted(pkg_pn): pref = preferred_versions[pn] inherits = [os.path.splitext(os.path.basename(f))[0] for f in tinfoil.cooker.recipecache.inherits[pref[1]]] for cls in skip_classes: if cls in inherits: break else: recipelist.append(pn) tinfoil.shutdown() resume_from = args.resume_from if resume_from: if not resume_from in recipelist: print('%s is not a testable recipe' % resume_from) return 1 if args.only: only = args.only.split(',') for onlyitem in only: for pn in recipelist: if fnmatch.fnmatch(pn, onlyitem): break else: print('%s does not match any testable recipe' % onlyitem) return 1 else: only = None if args.skip: skip = args.skip.split(',') else: skip = [] recipes = [] for pn in recipelist: if resume_from: if pn == resume_from: resume_from = None else: continue if args.only: for item in only: if fnmatch.fnmatch(pn, item): break else: continue skipit = False for item in skip: if fnmatch.fnmatch(pn, item): skipit = True if skipit: continue recipes.append(pn) return recipes