def __init__(self): self._recipe_actions = {} self._recipe_resources = {} self._recipes = {} reg = ComponentRegistry() for name, action in reg.load_extensions('iotile.recipe_action', product_name='build_step'): self._recipe_actions[name] = action for name, resource in reg.load_extensions('iotile.recipe_resource'): self._recipe_resources[name] = resource
def FindByName(cls, name): """Find a specific installed auth provider by name.""" reg = ComponentRegistry() for _, entry in reg.load_extensions('iotile.auth_provider', name_filter=name): return entry
def require(builder_name): """Find an advertised autobuilder and return it This function searches through all installed distributions to find if any advertise an entry point with group 'iotile.autobuild' and name equal to builder_name. The first one that is found is returned. This function raises a BuildError if it cannot find the required autobuild function Args: builder_name (string): The name of the builder to find Returns: callable: the autobuilder function found in the search """ reg = ComponentRegistry() for _name, autobuild_func in reg.load_extensions('iotile.autobuild', name_filter=builder_name): return autobuild_func raise BuildError( 'Cannot find required autobuilder, make sure the distribution providing it is installed', name=builder_name)
def FindByName(cls, name): """Find an installed VirtualTile by name. This function searches for installed virtual tiles using the pkg_resources entry_point `iotile.virtual_tile`. If name is a path ending in .py, it is assumed to point to a module on disk and loaded directly rather than using pkg_resources. Args: name (str): The name of the tile to search for. Returns: VirtualTile class: A virtual tile subclass that can be instantiated to create a virtual tile. """ if name.endswith('.py'): return cls.LoadFromFile(name) reg = ComponentRegistry() for _name, tile in reg.load_extensions('iotile.virtual_tile', name_filter=name, class_filter=BaseVirtualTile): return tile raise ArgumentError("VirtualTile could not be found by name", name=name)
def LoadPlugins(cls): """Load all registered iotile.update_record plugins.""" if cls.PLUGINS_LOADED: return reg = ComponentRegistry() for _, record in reg.load_extensions('iotile.update_record'): cls.RegisterRecordType(record) cls.PLUGINS_LOADED = True
def _load_device(self, name, config): """Load a device either from a script or from an installed module""" if config is None: config_dict = {} elif isinstance(config, dict): config_dict = config elif config[0] == '#': # Allow passing base64 encoded json directly in the port string to ease testing. import base64 config_str = str(base64.b64decode(config[1:]), 'utf-8') config_dict = json.loads(config_str) else: try: with open(config, "r") as conf: data = json.load(conf) except IOError as exc: raise ArgumentError("Could not open config file", error=str(exc), path=config) if 'device' not in data: raise ArgumentError( "Invalid configuration file passed to VirtualDeviceAdapter", device_name=name, config_path=config, missing_key='device') config_dict = data['device'] reg = ComponentRegistry() if name.endswith('.py'): _name, device_factory = reg.load_extension( name, class_filter=BaseVirtualDevice, unique=True) return _instantiate_virtual_device(device_factory, config_dict, self._loop) seen_names = [] for device_name, device_factory in reg.load_extensions( 'iotile.virtual_device', class_filter=BaseVirtualDevice, product_name="virtual_device"): if device_name == name: return _instantiate_virtual_device(device_factory, config_dict, self._loop) seen_names.append(device_name) raise ArgumentError("Could not find virtual_device by name", name=name, known_names=seen_names)
def __init__(self, settings_file=None): self.rules = [] logger = logging.getLogger('iotile.build.warnings') logger.addHandler(logging.NullHandler) #FIXME: Load settings_file #Find all registered default builders and load them in priority order #Each default resolver should be a 4-tuple with (priority, matching_regex, factory, default args) reg = ComponentRegistry() for name, resolver_entry in reg.load_extensions( 'iotile.build.default_depresolver'): try: priority, regex, factory, settings = resolver_entry except TypeError: logger.warn( 'Invalid default resolver entry %s that was not a 4-tuple: %s', name, str(resolver_entry)) continue self.rules.append((priority, (regex, factory, settings))) self.rules.sort(key=lambda x: x[0]) self._known_resolvers = {} for _, factory in reg.load_extensions('iotile.build.depresolver'): name = factory.__name__ if name in self._known_resolvers: raise ExternalError( "The same dependency resolver class name is provided by more than one entry point", name=name) self._known_resolvers[name] = factory
def __init__(self, args=None): super(ChainedAuthProvider, self).__init__(args) # FIXME: Allow overwriting default providers via args self._load_installed_providers() reg = ComponentRegistry() sub_providers = [] for _, (priority, provider, provider_args ) in reg.load_extensions('iotile.default_auth_providers'): if provider not in self._auth_factories: raise ExternalError( "Default authentication provider list references unknown auth provider", provider_name=provider, known_providers=self._auth_factories.keys()) configured = self._auth_factories[provider](provider_args) sub_providers.append((priority, configured)) sub_providers.sort(key=lambda x: x[0]) self.providers = sub_providers
def instantiate_interface(virtual_iface, config): """Find a virtual interface by name and instantiate it Args: virtual_iface (string): The name of the pkg_resources entry point corresponding to the interface. It should be in group iotile.virtual_interface config (dict): A dictionary with a 'interface' key with the config info for configuring this virtual interface. This is optional. Returns: VirtualInterface: The instantiated subclass of VirtualInterface """ # Allow the null virtual interface for testing if virtual_iface == 'null': return VirtualIOTileInterface() conf = {} if 'interface' in config: conf = config['interface'] try: reg = ComponentRegistry() if virtual_iface.endswith('.py'): _name, iface = reg.load_extension( virtual_iface, class_filter=VirtualIOTileInterface, unique=True) else: _name, iface = reg.load_extensions( 'iotile.virtual_interface', name_filter=virtual_iface, class_filter=VirtualIOTileInterface, unique=True) return iface(conf) except ArgumentError as err: print("ERROR: Could not load virtual interface (%s): %s" % (virtual_iface, err.msg)) sys.exit(1)
def instantiate_device(virtual_dev, config, loop): """Find a virtual device by name and instantiate it Args: virtual_dev (string): The name of the pkg_resources entry point corresponding to the device. It should be in group iotile.virtual_device. If virtual_dev ends in .py, it is interpreted as a python script and loaded directly from the script. config (dict): A dictionary with a 'device' key with the config info for configuring this virtual device. This is optional. Returns: BaseVirtualDevice: The instantiated subclass of BaseVirtualDevice """ conf = {} if 'device' in config: conf = config['device'] # If we're given a path to a script, try to load and use that rather than search for an installed module try: reg = ComponentRegistry() if virtual_dev.endswith('.py'): _name, dev = reg.load_extension(virtual_dev, class_filter=BaseVirtualDevice, unique=True) else: _name, dev = reg.load_extensions('iotile.virtual_device', name_filter=virtual_dev, class_filter=BaseVirtualDevice, product_name="virtual_device", unique=True) return dev(conf) except ArgumentError as err: print("ERROR: Could not load virtual device (%s): %s" % (virtual_dev, err.msg)) sys.exit(1)
def _load_installed_providers(self): self._auth_factories = {} reg = ComponentRegistry() for name, entry in reg.load_extensions('iotile.auth_provider'): self._auth_factories[name] = entry
def main(argv=None, loop=SharedLoop): """Serve access to a virtual IOTile device using a virtual iotile interface.""" if argv is None: argv = sys.argv[1:] list_parser = argparse.ArgumentParser(add_help=False) list_parser.add_argument( '-l', '--list', action='store_true', help="List all known installed interfaces and devices and then exit") list_parser.add_argument( '-v', '--verbose', action="count", default=0, help="Increase logging level (goes error, warn, info, debug)") parser = argparse.ArgumentParser( description= "Serve acess to a virtual IOTile device using a virtual IOTile interface" ) parser.add_argument('interface', help="The name of the virtual device interface to use") parser.add_argument('device', help="The name of the virtual device to create") parser.add_argument( '-c', '--config', help= "An optional JSON config file with arguments for the interface and device" ) parser.add_argument( '-l', '--list', action='store_true', help="List all known installed interfaces and devices and then exit") parser.add_argument('-n', '--scenario', help="Load a test scenario from the given file") parser.add_argument( '-s', '--state', help= "Load a given state into the device before starting to serve it. Only works with emulated devices." ) parser.add_argument( '-d', '--dump', help= "Dump the device's state when we exit the program. Only works with emulated devices." ) parser.add_argument( '-t', '--track', help= "Track all changes to the device's state. Only works with emulated devices." ) parser.add_argument( '-v', '--verbose', action="count", default=0, help="Increase logging level (goes error, warn, info, debug)") args, _rest = list_parser.parse_known_args(argv) if args.list: configure_logging(args.verbose) reg = ComponentRegistry() print("Installed Device Servers:") for name, _iface in reg.load_extensions( 'iotile.device_server', class_filter=AbstractDeviceServer): print('- {}'.format(name)) print("\nInstalled Virtual Devices:") for name, dev in reg.load_extensions('iotile.virtual_device', class_filter=BaseVirtualDevice, product_name="virtual_device"): print('- {}: {}'.format(name, one_line_desc(dev))) return 0 args = parser.parse_args(argv) configure_logging(args.verbose) config = {} if args.config is not None: with open(args.config, "r") as conf_file: config = json.load(conf_file) started = False device = None stop_immediately = args.interface == 'null' try: server = instantiate_interface(args.interface, config, loop) device = instantiate_device(args.device, config, loop) if args.state is not None: print("Loading device state from file %s" % args.state) device.load_state(args.state) if args.scenario is not None: print("Loading scenario from file %s" % args.scenario) with open(args.scenario, "r") as infile: scenario = json.load(infile) # load_metascenario expects a list of scenarios even when there is only one if isinstance(scenario, dict): scenario = [scenario] device.load_metascenario(scenario) if args.track is not None: print("Tracking all state changes to device") device.state_history.enable() adapter = VirtualDeviceAdapter(devices=[device], loop=loop) server.adapter = adapter loop.run_coroutine(adapter.start()) try: loop.run_coroutine(server.start()) except: loop.run_coroutine(adapter.stop()) adapter = None raise started = True print("Starting to serve virtual IOTile device") if stop_immediately: return 0 # We need to periodically process events that are queued up in the interface while True: time.sleep(0.5) except KeyboardInterrupt: print("Break received, cleanly exiting...") finally: if args.dump is not None and device is not None: print("Dumping final device state to %s" % args.dump) device.save_state(args.dump) if started: loop.run_coroutine(server.stop()) loop.run_coroutine(adapter.stop()) if args.track is not None and device is not None: print("Saving state history to file %s" % args.track) device.state_history.dump(args.track) return 0
def _find_release_providers(): reg = ComponentRegistry() return { name: entry for name, entry in reg.load_extensions('iotile.build.release_provider') }