def __init__(self, output=sys.stdout, tracking=False): # Needed to avoid deprecation warnings with python 2.6 warnings.filterwarnings("ignore", category=DeprecationWarning) # Set up logging self.logger = logging.getLogger('BitBake') console = logging.StreamHandler(output) bb.msg.addDefaultlogFilter(console) format = bb.msg.BBLogFormatter("%(levelname)s: %(message)s") if output.isatty(): format.enable_color() console.setFormatter(format) self.logger.addHandler(console) self.config = CookerConfiguration() configparams = TinfoilConfigParameters(parse_only=True) self.config.setConfigParameters(configparams) self.config.setServerRegIdleCallback(self.register_idle_function) features = [] if tracking: features.append(CookerFeatures.BASEDATASTORE_TRACKING) self.cooker = BBCooker(self.config, features) self.config_data = self.cooker.data bb.providers.logger.setLevel(logging.ERROR) self.cooker_data = None
class Tinfoil: def __init__(self, output=sys.stdout, tracking=False): # Needed to avoid deprecation warnings with python 2.6 warnings.filterwarnings("ignore", category=DeprecationWarning) # Set up logging self.logger = logging.getLogger('BitBake') self._log_hdlr = logging.StreamHandler(output) bb.msg.addDefaultlogFilter(self._log_hdlr) format = bb.msg.BBLogFormatter("%(levelname)s: %(message)s") if output.isatty(): format.enable_color() self._log_hdlr.setFormatter(format) self.logger.addHandler(self._log_hdlr) self.config = CookerConfiguration() configparams = TinfoilConfigParameters(parse_only=True) self.config.setConfigParameters(configparams) self.config.setServerRegIdleCallback(self.register_idle_function) features = [] if tracking: features.append(CookerFeatures.BASEDATASTORE_TRACKING) self.cooker = BBCooker(self.config, features) self.config_data = self.cooker.data bb.providers.logger.setLevel(logging.ERROR) self.cooker_data = None def register_idle_function(self, function, data): pass def parseRecipes(self): sys.stderr.write("Parsing recipes..") self.logger.setLevel(logging.WARNING) try: while self.cooker.state in (state.initial, state.parsing): self.cooker.updateCache() except KeyboardInterrupt: self.cooker.shutdown() self.cooker.updateCache() sys.exit(2) self.logger.setLevel(logging.INFO) sys.stderr.write("done.\n") self.cooker_data = self.cooker.recipecache def prepare(self, config_only=False): if not self.cooker_data: if config_only: self.cooker.parseConfiguration() self.cooker_data = self.cooker.recipecache else: self.parseRecipes() def shutdown(self): self.cooker.shutdown(force=True) self.cooker.post_serve() self.cooker.unlockBitbake() self.logger.removeHandler(self._log_hdlr)
class Tinfoil: def __init__(self, output=sys.stdout, tracking=False): # Needed to avoid deprecation warnings with python 2.6 warnings.filterwarnings("ignore", category=DeprecationWarning) # Set up logging self.logger = logging.getLogger("BitBake") self._log_hdlr = logging.StreamHandler(output) bb.msg.addDefaultlogFilter(self._log_hdlr) format = bb.msg.BBLogFormatter("%(levelname)s: %(message)s") if output.isatty(): format.enable_color() self._log_hdlr.setFormatter(format) self.logger.addHandler(self._log_hdlr) self.config = CookerConfiguration() configparams = TinfoilConfigParameters(parse_only=True) self.config.setConfigParameters(configparams) self.config.setServerRegIdleCallback(self.register_idle_function) features = [] if tracking: features.append(CookerFeatures.BASEDATASTORE_TRACKING) self.cooker = BBCooker(self.config, features) self.config_data = self.cooker.data bb.providers.logger.setLevel(logging.ERROR) self.cooker_data = None def register_idle_function(self, function, data): pass def parseRecipes(self): sys.stderr.write("Parsing recipes..") self.logger.setLevel(logging.WARNING) try: while self.cooker.state in (state.initial, state.parsing): self.cooker.updateCache() except KeyboardInterrupt: self.cooker.shutdown() self.cooker.updateCache() sys.exit(2) self.logger.setLevel(logging.INFO) sys.stderr.write("done.\n") self.cooker_data = self.cooker.recipecaches[""] def prepare(self, config_only=False): if not self.cooker_data: if config_only: self.cooker.parseConfiguration() self.cooker_data = self.cooker.recipecaches[""] else: self.parseRecipes() def shutdown(self): self.cooker.shutdown(force=True) self.cooker.post_serve() self.cooker.unlockBitbake() self.logger.removeHandler(self._log_hdlr)
def prepare(self, config_only=False, config_params=None, quiet=0): if self.tracking: extrafeatures = [bb.cooker.CookerFeatures.BASEDATASTORE_TRACKING] else: extrafeatures = [] if not config_params: config_params = TinfoilConfigParameters(config_only=config_only, quiet=quiet) cookerconfig = CookerConfiguration() cookerconfig.setConfigParameters(config_params) server, self.server_connection, ui_module = setup_bitbake(config_params, cookerconfig, extrafeatures) self.ui_module = ui_module if self.server_connection: _server_connections.append(self.server_connection) if config_only: config_params.updateToServer(self.server_connection.connection, os.environ.copy()) self.run_command('parseConfiguration') else: self.run_actions(config_params) self.config_data = bb.data.init() connector = TinfoilDataStoreConnector(self, None) self.config_data.setVar('_remote_data', connector) self.cooker = TinfoilCookerAdapter(self) self.cooker_data = self.cooker.recipecaches[''] else: raise Exception('Failed to start bitbake server')
def prepare(self, config_only=False, config_params=None, quiet=0, extra_features=None): if self.tracking: extrafeatures = [bb.cooker.CookerFeatures.BASEDATASTORE_TRACKING] else: extrafeatures = [] if extra_features: extrafeatures += extra_features if not config_params: config_params = TinfoilConfigParameters(config_only=config_only, quiet=quiet) cookerconfig = CookerConfiguration() cookerconfig.setConfigParameters(config_params) server, self.server_connection, ui_module = setup_bitbake( config_params, cookerconfig, extrafeatures, setup_logging=False) self.ui_module = ui_module # Ensure the path to bitbake's bin directory is in PATH so that things like # bitbake-worker can be run (usually this is the case, but it doesn't have to be) path = os.getenv('PATH').split(':') bitbakebinpath = os.path.abspath( os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '..', 'bin')) for entry in path: if entry.endswith(os.sep): entry = entry[:-1] if os.path.abspath(entry) == bitbakebinpath: break else: path.insert(0, bitbakebinpath) os.environ['PATH'] = ':'.join(path) if self.server_connection: _server_connections.append(self.server_connection) if config_only: config_params.updateToServer(self.server_connection.connection, os.environ.copy()) self.run_command('parseConfiguration') else: self.run_actions(config_params) self.config_data = bb.data.init() connector = TinfoilDataStoreConnector(self, None) self.config_data.setVar('_remote_data', connector) self.cooker = TinfoilCookerAdapter(self) self.cooker_data = self.cooker.recipecaches[''] else: raise Exception('Failed to start bitbake server')
def prepare(self, config_only=False, config_params=None, quiet=0): if self.tracking: extrafeatures = [bb.cooker.CookerFeatures.BASEDATASTORE_TRACKING] else: extrafeatures = [] if not config_params: config_params = TinfoilConfigParameters(config_only=config_only, quiet=quiet) cookerconfig = CookerConfiguration() cookerconfig.setConfigParameters(config_params) server, self.server_connection, ui_module = setup_bitbake(config_params, cookerconfig, extrafeatures) self.ui_module = ui_module # Ensure the path to bitbake's bin directory is in PATH so that things like # bitbake-worker can be run (usually this is the case, but it doesn't have to be) path = os.getenv('PATH').split(':') bitbakebinpath = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '..', 'bin')) for entry in path: if entry.endswith(os.sep): entry = entry[:-1] if os.path.abspath(entry) == bitbakebinpath: break else: path.insert(0, bitbakebinpath) os.environ['PATH'] = ':'.join(path) if self.server_connection: _server_connections.append(self.server_connection) if config_only: config_params.updateToServer(self.server_connection.connection, os.environ.copy()) self.run_command('parseConfiguration') else: self.run_actions(config_params) self.config_data = bb.data.init() connector = TinfoilDataStoreConnector(self, None) self.config_data.setVar('_remote_data', connector) self.cooker = TinfoilCookerAdapter(self) self.cooker_data = self.cooker.recipecaches[''] else: raise Exception('Failed to start bitbake server')
def __init__(self, output=sys.stdout): # Needed to avoid deprecation warnings with python 2.6 warnings.filterwarnings("ignore", category=DeprecationWarning) # Set up logging self.logger = logging.getLogger('BitBake') if output is not None: setup_log_handler(self.logger, output) self.config = self.config = CookerConfiguration() configparams = bb.tinfoil.TinfoilConfigParameters(parse_only=True) self.config.setConfigParameters(configparams) self.config.setServerRegIdleCallback(self.register_idle_function) self.cooker = bb.cooker.BBCooker(self.config) self.config_data = self.cooker.data bb.providers.logger.setLevel(logging.ERROR) bb.taskdata.logger.setLevel(logging.CRITICAL) self.cooker_data = None self.taskdata = None self.localdata = bb.data.createCopy(self.config_data) self.localdata.finalize() # TODO: why isn't expandKeys a method of DataSmart? bb.data.expandKeys(self.localdata)
def prepare(self, config_only=False, config_params=None, quiet=0, extra_features=None): """ Prepares the underlying BitBake system to be used via tinfoil. This function must be called prior to calling any of the other functions in the API. NOTE: if you call prepare() you must absolutely call shutdown() before your code terminates. You can use a "with" block to ensure this happens e.g. with bb.tinfoil.Tinfoil() as tinfoil: tinfoil.prepare() ... Parameters: config_only: True to read only the configuration and not load the cache / parse recipes. This is useful if you just want to query the value of a variable at the global level or you want to do anything else that doesn't involve knowing anything about the recipes in the current configuration. False loads the cache / parses recipes. config_params: optionally specify your own configuration parameters. If not specified an instance of TinfoilConfigParameters will be created internally. quiet: quiet level controlling console output - equivalent to bitbake's -q/--quiet option. Default of 0 gives the same output level as normal bitbake execution. extra_features: extra features to be added to the feature set requested from the server. See CookerFeatures._feature_list for possible features. """ self.quiet = quiet if self.tracking: extrafeatures = [bb.cooker.CookerFeatures.BASEDATASTORE_TRACKING] else: extrafeatures = [] if extra_features: extrafeatures += extra_features if not config_params: config_params = TinfoilConfigParameters(config_only=config_only, quiet=quiet) cookerconfig = CookerConfiguration() cookerconfig.setConfigParameters(config_params) if not config_only: # Disable local loggers because the UI module is going to set up its own for handler in self.localhandlers: self.logger.handlers.remove(handler) self.localhandlers = [] self.server_connection, ui_module = setup_bitbake( config_params, cookerconfig, extrafeatures) self.ui_module = ui_module # Ensure the path to bitbake's bin directory is in PATH so that things like # bitbake-worker can be run (usually this is the case, but it doesn't have to be) path = os.getenv('PATH').split(':') bitbakebinpath = os.path.abspath( os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '..', 'bin')) for entry in path: if entry.endswith(os.sep): entry = entry[:-1] if os.path.abspath(entry) == bitbakebinpath: break else: path.insert(0, bitbakebinpath) os.environ['PATH'] = ':'.join(path) if self.server_connection: _server_connections.append(self.server_connection) if config_only: config_params.updateToServer(self.server_connection.connection, os.environ.copy()) self.run_command('parseConfiguration') else: self.run_actions(config_params) self.recipes_parsed = True self.config_data = TinfoilDataStoreConnector(self, 0) self.cooker = TinfoilCookerAdapter(self) self.cooker_data = self.cooker.recipecaches[''] else: raise Exception('Failed to start bitbake server')
def prepare(self, config_only=False, config_params=None, quiet=0, extra_features=None): """ Prepares the underlying BitBake system to be used via tinfoil. This function must be called prior to calling any of the other functions in the API. NOTE: if you call prepare() you must absolutely call shutdown() before your code terminates. You can use a "with" block to ensure this happens e.g. with bb.tinfoil.Tinfoil() as tinfoil: tinfoil.prepare() ... Parameters: config_only: True to read only the configuration and not load the cache / parse recipes. This is useful if you just want to query the value of a variable at the global level or you want to do anything else that doesn't involve knowing anything about the recipes in the current configuration. False loads the cache / parses recipes. config_params: optionally specify your own configuration parameters. If not specified an instance of TinfoilConfigParameters will be created internally. quiet: quiet level controlling console output - equivalent to bitbake's -q/--quiet option. Default of 0 gives the same output level as normal bitbake execution. extra_features: extra features to be added to the feature set requested from the server. See CookerFeatures._feature_list for possible features. """ self.quiet = quiet if self.tracking: extrafeatures = [bb.cooker.CookerFeatures.BASEDATASTORE_TRACKING] else: extrafeatures = [] if extra_features: extrafeatures += extra_features if not config_params: config_params = TinfoilConfigParameters(config_only=config_only, quiet=quiet) cookerconfig = CookerConfiguration() cookerconfig.setConfigParameters(config_params) if not config_only: # Disable local loggers because the UI module is going to set up its own for handler in self.localhandlers: self.logger.handlers.remove(handler) self.localhandlers = [] self.server_connection, ui_module = setup_bitbake(config_params, cookerconfig, extrafeatures) self.ui_module = ui_module # Ensure the path to bitbake's bin directory is in PATH so that things like # bitbake-worker can be run (usually this is the case, but it doesn't have to be) path = os.getenv('PATH').split(':') bitbakebinpath = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '..', 'bin')) for entry in path: if entry.endswith(os.sep): entry = entry[:-1] if os.path.abspath(entry) == bitbakebinpath: break else: path.insert(0, bitbakebinpath) os.environ['PATH'] = ':'.join(path) if self.server_connection: _server_connections.append(self.server_connection) if config_only: config_params.updateToServer(self.server_connection.connection, os.environ.copy()) self.run_command('parseConfiguration') else: self.run_actions(config_params) self.recipes_parsed = True self.config_data = bb.data.init() connector = TinfoilDataStoreConnector(self, None) self.config_data.setVar('_remote_data', connector) self.cooker = TinfoilCookerAdapter(self) self.cooker_data = self.cooker.recipecaches[''] else: raise Exception('Failed to start bitbake server')
class Tinfoil: def __init__(self, output=sys.stdout, tracking=False): # Needed to avoid deprecation warnings with python 2.6 warnings.filterwarnings("ignore", category=DeprecationWarning) # Set up logging self.logger = logging.getLogger('BitBake') self._log_hdlr = logging.StreamHandler(output) bb.msg.addDefaultlogFilter(self._log_hdlr) format = bb.msg.BBLogFormatter("%(levelname)s: %(message)s") if output.isatty(): format.enable_color() self._log_hdlr.setFormatter(format) self.logger.addHandler(self._log_hdlr) self.config = CookerConfiguration() configparams = TinfoilConfigParameters(parse_only=True) self.config.setConfigParameters(configparams) self.config.setServerRegIdleCallback(self.register_idle_function) features = [] if tracking: features.append(CookerFeatures.BASEDATASTORE_TRACKING) self.cooker = BBCooker(self.config, features) self.config_data = self.cooker.data bb.providers.logger.setLevel(logging.ERROR) self.cooker_data = None def register_idle_function(self, function, data): pass def __enter__(self): return self def __exit__(self, type, value, traceback): self.shutdown() def parseRecipes(self): sys.stderr.write("Parsing recipes..") self.logger.setLevel(logging.WARNING) try: while self.cooker.state in (state.initial, state.parsing): self.cooker.updateCache() except KeyboardInterrupt: self.cooker.shutdown() self.cooker.updateCache() sys.exit(2) self.logger.setLevel(logging.INFO) sys.stderr.write("done.\n") self.cooker_data = self.cooker.recipecaches[''] def prepare(self, config_only=False): if not self.cooker_data: if config_only: self.cooker.parseConfiguration() self.cooker_data = self.cooker.recipecaches[''] else: self.parseRecipes() def parse_recipe_file(self, fn, appends=True, appendlist=None, config_data=None): """ Parse the specified recipe file (with or without bbappends) and return a datastore object representing the environment for the recipe. Parameters: fn: recipe file to parse - can be a file path or virtual specification appends: True to apply bbappends, False otherwise appendlist: optional list of bbappend files to apply, if you want to filter them config_data: custom config datastore to use. NOTE: if you specify config_data then you cannot use a virtual specification for fn. """ if appends and appendlist == []: appends = False if appends: if appendlist: appendfiles = appendlist else: if not hasattr(self.cooker, 'collection'): raise Exception( 'You must call tinfoil.prepare() with config_only=False in order to get bbappends' ) appendfiles = self.cooker.collection.get_file_appends(fn) else: appendfiles = None if config_data: # We have to use a different function here if we're passing in a datastore localdata = bb.data.createCopy(config_data) envdata = bb.cache.parse_recipe(localdata, fn, appendfiles)[''] else: # Use the standard path parser = bb.cache.NoCache(self.cooker.databuilder) envdata = parser.loadDataFull(fn, appendfiles) return envdata def shutdown(self): self.cooker.shutdown(force=True) self.cooker.post_serve() self.cooker.unlockBitbake() self.logger.removeHandler(self._log_hdlr)
class Tinfoil: def __init__(self, output=sys.stdout, tracking=False): # Needed to avoid deprecation warnings with python 2.6 warnings.filterwarnings("ignore", category=DeprecationWarning) # Set up logging self.logger = logging.getLogger('BitBake') self._log_hdlr = logging.StreamHandler(output) bb.msg.addDefaultlogFilter(self._log_hdlr) format = bb.msg.BBLogFormatter("%(levelname)s: %(message)s") if output.isatty(): format.enable_color() self._log_hdlr.setFormatter(format) self.logger.addHandler(self._log_hdlr) self.config = CookerConfiguration() configparams = TinfoilConfigParameters(parse_only=True) self.config.setConfigParameters(configparams) self.config.setServerRegIdleCallback(self.register_idle_function) features = [] if tracking: features.append(CookerFeatures.BASEDATASTORE_TRACKING) self.cooker = BBCooker(self.config, features) self.config_data = self.cooker.data bb.providers.logger.setLevel(logging.ERROR) self.cooker_data = None def register_idle_function(self, function, data): pass def __enter__(self): return self def __exit__(self, type, value, traceback): self.shutdown() def parseRecipes(self): sys.stderr.write("Parsing recipes..") self.logger.setLevel(logging.WARNING) try: while self.cooker.state in (state.initial, state.parsing): self.cooker.updateCache() except KeyboardInterrupt: self.cooker.shutdown() self.cooker.updateCache() sys.exit(2) self.logger.setLevel(logging.INFO) sys.stderr.write("done.\n") self.cooker_data = self.cooker.recipecaches[''] def prepare(self, config_only = False): if not self.cooker_data: if config_only: self.cooker.parseConfiguration() self.cooker_data = self.cooker.recipecaches[''] else: self.parseRecipes() def parse_recipe_file(self, fn, appends=True, appendlist=None, config_data=None): """ Parse the specified recipe file (with or without bbappends) and return a datastore object representing the environment for the recipe. Parameters: fn: recipe file to parse - can be a file path or virtual specification appends: True to apply bbappends, False otherwise appendlist: optional list of bbappend files to apply, if you want to filter them config_data: custom config datastore to use. NOTE: if you specify config_data then you cannot use a virtual specification for fn. """ if appends and appendlist == []: appends = False if appends: if appendlist: appendfiles = appendlist else: if not hasattr(self.cooker, 'collection'): raise Exception('You must call tinfoil.prepare() with config_only=False in order to get bbappends') appendfiles = self.cooker.collection.get_file_appends(fn) else: appendfiles = None if config_data: # We have to use a different function here if we're passing in a datastore localdata = bb.data.createCopy(config_data) envdata = bb.cache.parse_recipe(localdata, fn, appendfiles)[''] else: # Use the standard path parser = bb.cache.NoCache(self.cooker.databuilder) envdata = parser.loadDataFull(fn, appendfiles) return envdata def shutdown(self): self.cooker.shutdown(force=True) self.cooker.post_serve() self.cooker.unlockBitbake() self.logger.removeHandler(self._log_hdlr)