def start(self): if self.running: gevent.signal(signal.SIGINT, self.sig_handler) gevent.signal(signal.SIGTERM, self.sig_handler) self.mdns.start() self.httpServer = HttpServer(AggregatorAPI, SERVICE_PORT, '0.0.0.0', api_args=[self.logger, self.config]) self.httpServer.start() while not self.httpServer.started.is_set(): print 'Waiting for httpserver to start...' self.httpServer.started.wait() if self.httpServer.failed is not None: raise self.httpServer.failed print "Running on port: {}".format(self.httpServer.port) priority = self.config["priority"] if not str(priority).isdigit() or priority < 100: priority = 0 self.mdns.register('registration_' + str(HOST), '_nmos-registration._tcp', DNS_SD_PORT, {"pri": priority, "api_ver": "v1.0,v1.1,v1.2", "api_proto": "http"})
def __init__(self, logger=None): self.running = False self.logger = Logger("regquery") self.logger.writeDebug('Running QueryService') self.config = {"priority": 0} self._load_config() self.mdns = MDNSEngine() self.httpServer = HttpServer(QueryServiceAPI, WS_PORT, '0.0.0.0', api_args=[self.logger])
def __init__(self, logger=None): self.running = False from nmoscommon.logger import Logger from nmosnode.facade import Facade self.logger = Logger("conmanage") self.logger.writeWarning("Could not find ipppython facade") self.facade = Facade("{}/{}".format(CONN_APINAME, CONN_APIVERSIONS[-1]), address="ipc:///tmp/ips-nodefacade", logger=self.logger) self.logger.writeDebug("Running Connection Management Service") self.httpServer = HttpServer(ConnectionManagementAPI, WS_PORT, '0.0.0.0', api_args=[self.logger])
def __init__(self, logger=None): self.running = False self.logger = Logger("regquery") self.logger.writeDebug('Running QueryService') # HTTPS under test only at present # enabled = Use HTTPS only in all URLs and mDNS adverts # disabled = Use HTTP only in all URLs and mDNS adverts # mixed = Use HTTP in all URLs, but additionally advertise an HTTPS endpoint for discovery of this API only self.config = {"priority": 100, "https_mode": "disabled"} self._load_config() self.mdns = MDNSEngine() self.httpServer = HttpServer(QueryServiceAPI, WS_PORT, '0.0.0.0', api_args=[self.logger, self.config])
def start(self): if self.running: signal.signal(signal.SIGINT, self.sig_handler) self.http_server = HttpServer(ProxyListingAPI, PORT, HOST) self.http_server.start() while not self.http_server.started.is_set(): print "Waiting for httpserver to start..." self.http_server.started.wait() if self.http_server.failed is not None: raise self.http_server.failed print "Running on port: {}".format(self.http_server.port)
class mDNSBridgeService(object): def __init__(self, domain=None): self.running = False self.registered = False self.facade = Facade("{}/{}".format(APINAME, APIVERSION)) self.domain = domain def start(self): if self.running: gevent.signal(signal.SIGINT, self.sig_handler) gevent.signal(signal.SIGTERM, self.sig_handler) self.mdns_bridge = mDNSBridge(domain=self.domain) self.http_server = HttpServer(mDNSBridgeAPI, PORT, HOST, api_args=[self.mdns_bridge]) self.http_server.start() while not self.http_server.started.is_set(): print "Waiting for httpserver to start..." self.http_server.started.wait() if self.http_server.failed is not None: raise self.http_server.failed print "Running on port: {}".format(self.http_server.port) def run(self): self.running = True self.start() self.facade.register_service("http://" + HOST + ":" + str(PORT), "{}/{}/{}/".format(APINAMESPACE, APINAME, APIVERSION)) daemon.notify("READY=1") itercount = 0 while self.running: itercount += 1 gevent.sleep(1) if itercount == 5: #5 seconds self.facade.heartbeat_service() itercount = 0 self.facade.unregister_service() self._cleanup() def stop(self): self.running = False def _cleanup(self): self.http_server.stop() self.mdns_bridge.stop() print "Stopped main()" def sig_handler(self): print "Pressed ctrl+c" self.stop()
def start(self): if self.running: gevent.signal(signal.SIGINT, self.sig_handler) gevent.signal(signal.SIGTERM, self.sig_handler) self.mdns_bridge = mDNSBridge(domain=self.domain) self.http_server = HttpServer(mDNSBridgeAPI, PORT, HOST, api_args=[self.mdns_bridge]) self.http_server.start() while not self.http_server.started.is_set(): print "Waiting for httpserver to start..." self.http_server.started.wait() if self.http_server.failed is not None: raise self.http_server.failed print "Running on port: {}".format(self.http_server.port)
def setUpClass(cls): """Runs before each test""" cls.logger = Logger("conmanage") cls.mockApi = MockSenderAPI() cls.mockReceiver = MockSenderAPI() cls.activator = MockActivator() cls.sdpManager = cls.mockReceiver.transportManagers[0] cls.httpServer = HttpServer(ConnectionManagementAPI, SENDER_WS_PORT, '0.0.0.0', api_args=[cls.logger]) cls.httpServer.start() while not cls.httpServer.started.is_set(): cls.httpServer.started.wait() cls.dut = cls.httpServer.api cls.senderUUID = "8358af5c-6d82-4ef8-b992-13ed40a7246d" cls.receiverUUID = "076f7e9d-8a93-42cc-9506-fd57505ccc89" cls.dut.addSender(cls.mockApi, cls.senderUUID) cls.dut.addReceiver(cls.mockReceiver, cls.receiverUUID) cls.baseUrl = "http://127.0.0.1:" + str(SENDER_WS_PORT) cls.deviceRoot = cls.baseUrl + '/' + DEVICE_ROOT cls.senderRoot = cls.deviceRoot + "single/senders/" + cls.senderUUID cls.receiverRoot = cls.deviceRoot + "single/receivers/" + cls.receiverUUID cls.maxDiff = None
def _start(self): gevent.signal(signal.SIGINT, self._sig_handler) gevent.signal(signal.SIGTERM, self._sig_handler) self.httpServer = HttpServer(GroupingAPI, PORT, '0.0.0.0', ssl=self.config.get("ssl")) self.httpServer.start() while not self.httpServer.started.is_set(): self.logger.writeInfo('Waiting for httpserver to start...') self.httpServer.started.wait() if self.httpServer.failed is not None: raise self.httpServer.failed self.httpServer.api.app.config.update(self.config) db_mongo.init_app(self.httpServer.api.app, logger=self.logger) self.logger.writeInfo("Running on port: {}".format( self.httpServer.port))
def __init__(self, manager, logger, facade): # Start the web server used to show the interface self.logger = logger self.facade = facade self.httpServer = HttpServer(NmosDriverWebApi, WS_PORT, '0.0.0.0', api_args=[logger, manager, facade]) self.httpServer.start() while not self.httpServer.started.is_set(): self.logger.writeDebug('Waiting for httpserver to start...') self.httpServer.started.wait() if self.httpServer.failed is not None: raise self.httpServer.failed self.logger.writeDebug( "Mock driver interface running on port: {}".format( self.httpServer.port))
class ProxyListingService(object): def __init__(self): self.running = False def start(self): if self.running: signal.signal(signal.SIGINT, self.sig_handler) self.http_server = HttpServer(ProxyListingAPI, PORT, HOST) self.http_server.start() while not self.http_server.started.is_set(): print "Waiting for httpserver to start..." self.http_server.started.wait() if self.http_server.failed is not None: raise self.http_server.failed print "Running on port: {}".format(self.http_server.port) def run(self): self.running = True self.start() while self.running: time.sleep(1) self.stop() def stop(self): if self.running: self.running = False else: self.http_server.stop() print "Stopped main()" def sig_handler(self, sig, frame): print "Pressed ctrl+c" self.stop()
class RegistryAggregatorService(object): def __init__(self, logger=None, interactive=False): self.config = {"priority": 0} self._load_config() self.running = False self.httpServer = None self.interactive = interactive self.mdns = MDNSEngine() self.logger = Logger("aggregation", logger) def _load_config(self): try: config_file = "/etc/nmos-registration/config.json" if os.path.isfile(config_file): f = open(config_file, 'r') extra_config = json.loads(f.read()) self.config.update(extra_config) except Exception as e: print "Exception loading config: {}".format(e) def start(self): if self.running: gevent.signal(signal.SIGINT, self.sig_handler) gevent.signal(signal.SIGTERM, self.sig_handler) self.mdns.start() self.httpServer = HttpServer(AggregatorAPI, SERVICE_PORT, '0.0.0.0', api_args=[self.logger, self.config]) self.httpServer.start() while not self.httpServer.started.is_set(): print 'Waiting for httpserver to start...' self.httpServer.started.wait() if self.httpServer.failed is not None: raise self.httpServer.failed print "Running on port: {}".format(self.httpServer.port) priority = self.config["priority"] if not str(priority).isdigit() or priority < 100: priority = 0 self.mdns.register('registration_' + str(HOST), '_nmos-registration._tcp', DNS_SD_PORT, {"pri": priority, "api_ver": "v1.0,v1.1,v1.2", "api_proto": "http"}) def run(self): self.running = True self.start() while self.running: time.sleep(1) self._cleanup() def _cleanup(self): self.mdns.stop() self.mdns.close() self.httpServer.stop() print "Stopped main()" def stop(self): self.running = False def sig_handler(self): print 'Pressed ctrl+c' self.stop()
class QueryService: def __init__(self, logger=None): self.running = False self.logger = Logger("regquery") self.logger.writeDebug('Running QueryService') # HTTPS under test only at present # enabled = Use HTTPS only in all URLs and mDNS adverts # disabled = Use HTTP only in all URLs and mDNS adverts # mixed = Use HTTP in all URLs, but additionally advertise an HTTPS endpoint for discovery of this API only self.config = {"priority": 100, "https_mode": "disabled"} self._load_config() self.mdns = MDNSEngine() self.httpServer = HttpServer(QueryServiceAPI, WS_PORT, '0.0.0.0', api_args=[self.logger, self.config]) def start(self): if self.running: gevent.signal(signal.SIGINT, self.sig_handler) gevent.signal(signal.SIGTERM, self.sig_handler) self.running = True self.mdns.start() self.logger.writeDebug('Running web socket server on %i' % WS_PORT) self.httpServer.start() while not self.httpServer.started.is_set(): self.logger.writeDebug('Waiting for httpserver to start...') self.httpServer.started.wait() if self.httpServer.failed is not None: raise self.httpServer.failed self.logger.writeDebug("Running on port: {}".format(self.httpServer.port)) priority = self.config["priority"] if not str(priority).isdigit() or priority < 100: priority = 0 if self.config["https_mode"] != "enabled": self.mdns.register(DNS_SD_NAME + "_http", DNS_SD_TYPE, DNS_SD_HTTP_PORT, {"pri": priority, "api_ver": ",".join(API_VERSIONS), "api_proto": "http"}) if self.config["https_mode"] != "disabled": self.mdns.register(DNS_SD_NAME + "_https", DNS_SD_TYPE, DNS_SD_HTTPS_PORT, {"pri": priority, "api_ver": ",".join(API_VERSIONS), "api_proto": "https"}) def run(self): self.running = True self.start() while self.running: time.sleep(1) self._cleanup() def _cleanup(self): self.mdns.stop() self.mdns.close() self.httpServer.stop() def sig_handler(self): self.stop() def stop(self): self.running = False def _load_config(self): try: config_file = "/etc/ips-regquery/config.json" if os.path.isfile(config_file): f = open(config_file, 'r') extra_config = json.loads(f.read()) self.config.update(extra_config) except Exception as e: self.logger.writeDebug("Exception loading config: {}".format(e))
class NodeFacadeService: def __init__(self, interactive=False): self.logger = Logger("facade", None) if HOST == "": self.logger.writeFatal( "Unable to start facade due to lack of connectivity") sys.exit(1) self.running = False self.httpServer = None self.interface = None self.interactive = interactive self.registry = None self.registry_cleaner = None self.node_id = None self.mdns = MDNSEngine() self.mdnsname_suffix = '_' + str(HOSTNAME) + "_" + str(getpid()) self.mappings = { "device": "ver_dvc", "flow": "ver_flw", "source": "ver_src", "sender": "ver_snd", "receiver": "ver_rcv", "self": "ver_slf" } self.mdns_updater = MDNSUpdater(self.mdns, "_nmos-node._tcp", "node" + self.mdnsname_suffix, self.mappings, PORT, self.logger, txt_recs={ "api_ver": "v1.0,v1.1,v1.2", "api_proto": "http" }) self.aggregator = Aggregator(self.logger, self.mdns_updater) def sig_handler(self): print 'Pressed ctrl+c' self.stop() def sig_hup_handler(self): if getLocalIP() != "": global HOST HOST = updateHost() self.registry.modify_node(href=self.generate_href(), host=HOST, api={ "versions": NODE_APIVERSIONS, "endpoints": self.generate_endpoints() }, interfaces=self.list_interfaces()) def generate_endpoints(self): endpoints = [] if HTTPS_MODE != "enabled": endpoints.append({ "host": HOST, "port": 80, #Everything should go via apache proxy "protocol": "http" }) if HTTPS_MODE != "disabled": endpoints.append({ "host": HOST, "port": 443, #Everything should go via apache proxy "protocol": "https" }) return endpoints def generate_href(self): if HTTPS_MODE == "enabled": return "https://{}/".format(HOST) else: return "http://{}/".format(HOST) def list_interfaces(self): interfaces = {} # Initially populate interfaces from known-good location net_path = "/sys/class/net/" if os.path.exists(net_path): for interface_name in os.listdir(net_path): if interface_name != "lo": address_path = net_path + interface_name + "/address" if os.path.exists(address_path): address = open(address_path, "r").readline() interfaces[interface_name] = { "name": interface_name, "chassis_id": None, "port_id": address.lower().strip("\n").replace(":", "-") } # Attempt to source proper LLDP data for interfaces if os.path.exists("/usr/sbin/lldpcli"): try: chassis_data = json.loads( check_output( ["/usr/sbin/lldpcli", "show", "chassis", "-f", "json"])) chassis_id = chassis_data["local-chassis"]['chassis'].values( )[0]["id"]["value"] if chassis_data["local-chassis"]['chassis'].values( )[0]["id"]["type"] == "mac": chassis_id = chassis_id.lower().replace(":", "-") interface_data = json.loads( check_output([ "/usr/sbin/lldpcli", "show", "statistics", "-f", "json" ])) if isinstance(interface_data["lldp"]["interface"], dict): for interface_name in interface_data["lldp"][ "interface"].keys(): if interface_name in interfaces: # Only correct the Chassis ID. Port ID MUST be a MAC address interfaces[interface_name][ "chassis_id"] = chassis_id else: for interface_block in interface_data["lldp"]["interface"]: interface_name = interface_block.keys()[0] if interface_name in interfaces: # Only correct the Chassis ID. Port ID MUST be a MAC address interfaces[interface_name][ "chassis_id"] = chassis_id except Exception: pass return interfaces.values() def start(self): if self.running: gevent.signal(signal.SIGINT, self.sig_handler) gevent.signal(signal.SIGTERM, self.sig_handler) gevent.signal(signal.SIGHUP, self.sig_hup_handler) self.mdns.start() self.node_id = get_node_id() node_version = str(ptptime.ptp_detail()[0]) + ":" + str( ptptime.ptp_detail()[1]) node_data = { "id": self.node_id, "label": nmoscommonconfig.config.get('node_label', FQDN), "description": nmoscommonconfig.config.get('node_description', "Node on {}".format(FQDN)), "tags": nmoscommonconfig.config.get('node_tags', {}), "href": self.generate_href(), "host": HOST, "services": [], "hostname": HOSTNAME, "caps": {}, "version": node_version, "api": { "versions": NODE_APIVERSIONS, "endpoints": self.generate_endpoints(), }, "clocks": [ { "name": "clk0", "ref_type": "internal", }, { "name": "clk1", "ref_type": "ptp", "version": "IEEE1588-2008", "traceable": False, "gmid": "00-00-00-00-00-00-00-00", "locked": False, }, # Extra values will be filled in as needed at point of checking ], "interfaces": self.list_interfaces() } self.registry = FacadeRegistry(self.mappings.keys(), self.aggregator, self.mdns_updater, self.node_id, node_data, self.logger) self.registry_cleaner = FacadeRegistryCleaner(self.registry) self.registry_cleaner.start() self.httpServer = HttpServer(FacadeAPI, PORT, '0.0.0.0', api_args=[self.registry]) self.httpServer.start() while not self.httpServer.started.is_set(): self.logger.writeInfo('Waiting for httpserver to start...') self.httpServer.started.wait() if self.httpServer.failed is not None: raise self.httpServer.failed self.logger.writeInfo("Running on port: {}".format( self.httpServer.port)) try: self.logger.writeInfo("Registering as {}...".format(self.node_id)) self.aggregator.register( 'node', self.node_id, **legalise_resource(node_data, "node", NODE_REGVERSION)) except Exception as e: self.logger.writeWarning("Could not register: {}".format( e.__repr__())) self.interface = FacadeInterface(self.registry, self.logger) self.interface.start() def run(self): self.running = True pidfile = "/tmp/ips-nodefacade.pid" file(pidfile, 'w').write(str(getpid())) self.start() daemon.notify("READY=1") while self.running: self.registry.update_ptp() time.sleep(1) os.unlink(pidfile) self._cleanup() def _cleanup(self): try: self.logger.writeDebug("cleanup: unregister facade " + self.node_id) self.aggregator.unregister('node', self.node_id) except Exception as e: self.logger.writeWarning("Could not unregister: {}".format(e)) if self.mdns: try: self.mdns.stop() except Exception as e: self.logger.writeWarning("Could not stop mdns: {}".format(e)) self.registry_cleaner.stop() self.interface.stop() self.httpServer.stop() self.aggregator.stop() self.logger.writeInfo("Stopped main()") def stop(self): self.running = False
def start(self): if self.running: gevent.signal(signal.SIGINT, self.sig_handler) gevent.signal(signal.SIGTERM, self.sig_handler) gevent.signal(signal.SIGHUP, self.sig_hup_handler) self.mdns.start() self.node_id = get_node_id() node_version = str(ptptime.ptp_detail()[0]) + ":" + str( ptptime.ptp_detail()[1]) node_data = { "id": self.node_id, "label": nmoscommonconfig.config.get('node_label', FQDN), "description": nmoscommonconfig.config.get('node_description', "Node on {}".format(FQDN)), "tags": nmoscommonconfig.config.get('node_tags', {}), "href": self.generate_href(), "host": HOST, "services": [], "hostname": HOSTNAME, "caps": {}, "version": node_version, "api": { "versions": NODE_APIVERSIONS, "endpoints": self.generate_endpoints(), }, "clocks": [ { "name": "clk0", "ref_type": "internal", }, { "name": "clk1", "ref_type": "ptp", "version": "IEEE1588-2008", "traceable": False, "gmid": "00-00-00-00-00-00-00-00", "locked": False, }, # Extra values will be filled in as needed at point of checking ], "interfaces": self.list_interfaces() } self.registry = FacadeRegistry(self.mappings.keys(), self.aggregator, self.mdns_updater, self.node_id, node_data, self.logger) self.registry_cleaner = FacadeRegistryCleaner(self.registry) self.registry_cleaner.start() self.httpServer = HttpServer(FacadeAPI, PORT, '0.0.0.0', api_args=[self.registry]) self.httpServer.start() while not self.httpServer.started.is_set(): self.logger.writeInfo('Waiting for httpserver to start...') self.httpServer.started.wait() if self.httpServer.failed is not None: raise self.httpServer.failed self.logger.writeInfo("Running on port: {}".format( self.httpServer.port)) try: self.logger.writeInfo("Registering as {}...".format(self.node_id)) self.aggregator.register( 'node', self.node_id, **legalise_resource(node_data, "node", NODE_REGVERSION)) except Exception as e: self.logger.writeWarning("Could not register: {}".format( e.__repr__())) self.interface = FacadeInterface(self.registry, self.logger) self.interface.start()
class GroupingService: def __init__(self, interactive=False): self.facades = {} for version in APIVERSIONS: self.facades[version] = Facade("{}/{}".format(APINAME, version)) self.logger = Logger("grouping", None) self.running = False self.httpServer = None with open(CONFIG_PATH) as config_fp: self.config = json.load(config_fp) def _sig_handler(self): self.logger.writeInfo("Stopping...") self._stop() def _start(self): gevent.signal(signal.SIGINT, self._sig_handler) gevent.signal(signal.SIGTERM, self._sig_handler) self.httpServer = HttpServer(GroupingAPI, PORT, '0.0.0.0', ssl=self.config.get("ssl")) self.httpServer.start() while not self.httpServer.started.is_set(): self.logger.writeInfo('Waiting for httpserver to start...') self.httpServer.started.wait() if self.httpServer.failed is not None: raise self.httpServer.failed self.httpServer.api.app.config.update(self.config) db_mongo.init_app(self.httpServer.api.app, logger=self.logger) self.logger.writeInfo("Running on port: {}".format( self.httpServer.port)) def run(self): self.running = True self._start() for version in APIVERSIONS: self.facades[version].register_service( "http://127.0.0.1:" + str(PORT), "{}/{}/{}/".format(APINAMESPACE, APINAME, version)) itercount = 0 while self.running: if itercount % 5 == 0: for facade in self.facades: self.facades[facade].heartbeat_service() gevent.sleep(1) itercount += 1 if itercount == 10: itercount = 0 for facade in self.facades: self.facades[facade].unregister_service() self._cleanup() def _cleanup(self): self.httpServer.stop() self.logger.writeInfo("Stopped") def _stop(self): self.running = False
class ConnectionManagementService: def __init__(self, logger=None): self.running = False from nmoscommon.logger import Logger from nmosnode.facade import Facade self.logger = Logger("conmanage") self.logger.writeWarning("Could not find ipppython facade") self.facade = Facade("{}/{}".format(CONN_APINAME, CONN_APIVERSIONS[-1]), address="ipc:///tmp/ips-nodefacade", logger=self.logger) self.logger.writeDebug("Running Connection Management Service") self.httpServer = HttpServer(ConnectionManagementAPI, WS_PORT, '0.0.0.0', api_args=[self.logger]) def start(self): '''Call this to run the API without blocking''' if self.running: gevent.signal_handler(signal.SIGINT, self.sig_handler) gevent.signal_handler(signal.SIGTERM, self.sig_handler) self.running = True self.httpServer.start() while not self.httpServer.started.is_set(): self.logger.writeDebug('Waiting for httpserver to start...') self.httpServer.started.wait() if self.httpServer.failed is not None: raise self.httpServer.failed self.logger.writeDebug("Running on port: {}" .format(self.httpServer.port)) self.facade.register_service("http://127.0.0.1:{}".format(self.httpServer.port), "{}{}/".format(CONN_ROOT[1:], CONN_APIVERSIONS[-1])) try: from nmosconnectiondriver.httpIpstudioDriver import httpIpstudioDriver self.logger.writeInfo("Using ipstudio driver") # Start the IPStudio driver self.driver = httpIpstudioDriver( self.httpServer.api, self.logger, self.facade ) except ImportError: # Start the mock driver self.driver = NmosDriver( self.httpServer.api, self.logger, self.facade ) def run(self): '''Call this to run the API in keep-alive (blocking) mode''' self.running = True self.start() itercount = 0 while self.running: gevent.sleep(1) itercount += 1 if itercount == 5: self.facade.heartbeat_service() itercount = 0 self._cleanup() def _cleanup(self): self.httpServer.stop() self.facade.unregister_service() def sig_handler(self): self.stop() def stop(self): '''Gracefully shut down the API''' self._cleanup() self.running = False
class QueryService: def __init__(self, logger=None): self.running = False self.logger = Logger("regquery") self.logger.writeDebug('Running QueryService') self.config = {"priority": 0} self._load_config() self.mdns = MDNSEngine() self.httpServer = HttpServer(QueryServiceAPI, WS_PORT, '0.0.0.0', api_args=[self.logger]) def start(self): if self.running: gevent.signal(signal.SIGINT, self.sig_handler) gevent.signal(signal.SIGTERM, self.sig_handler) self.running = True self.mdns.start() HOST = getLocalIP() self.logger.writeDebug('Running web socket server on %i' % WS_PORT) self.httpServer.start() while not self.httpServer.started.is_set(): self.logger.writeDebug('Waiting for httpserver to start...') self.httpServer.started.wait() if self.httpServer.failed is not None: raise self.httpServer.failed self.logger.writeDebug("Running on port: {}".format( self.httpServer.port)) priority = self.config["priority"] if not str(priority).isdigit() or priority < 100: priority = 0 self.mdns.register('query_' + str(HOST), '_nmos-query._tcp', DNS_SD_PORT, { "pri": priority, "api_ver": "v1.0,v1.1,v1.2", "api_proto": "http" }) def run(self): self.running = True self.start() while self.running: time.sleep(1) self._cleanup() def _cleanup(self): self.mdns.stop() self.mdns.close() self.httpServer.stop() def sig_handler(self): self.stop() def stop(self): self.running = False def _load_config(self): try: config_file = "/etc/nmos-query/config.json" if os.path.isfile(config_file): f = open(config_file, 'r') extra_config = json.loads(f.read()) self.config.update(extra_config) except Exception as e: self.logger.writeDebug("Exception loading config: {}".format(e))
class NodeFacadeService: def __init__(self, interactive=False): self.logger = Logger("facade", None) if HOST == "": self.logger.writeFatal( "Unable to start facade due to lack of connectivity") sys.exit(1) self.running = False self.httpServer = None self.interface = None self.interactive = interactive self.registry = None self.registry_cleaner = None self.node_id = None self.mdns = MDNSEngine() self.mappings = { "device": "ver_dvc", "flow": "ver_flw", "source": "ver_src", "sender": "ver_snd", "receiver": "ver_rcv", "self": "ver_slf" } self.mdns_updater = None self.auth_registry = AuthRegistry(app=None, scope=ALLOWED_SCOPE) self.protocol = PROTOCOL if PROTOCOL == "https": self.dns_sd_port = DNS_SD_HTTPS_PORT else: self.dns_sd_port = DNS_SD_HTTP_PORT if ENABLE_P2P: self.mdns_updater = MDNSUpdater(self.mdns, DNS_SD_TYPE, DNS_SD_NAME, self.mappings, self.dns_sd_port, self.logger, txt_recs=self._mdns_txt( NODE_APIVERSIONS, self.protocol, OAUTH_MODE)) self.aggregator = Aggregator(self.logger, self.mdns_updater, self.auth_registry) def _mdns_txt(self, versions, protocol, oauth_mode): return { "api_ver": ",".join(versions), "api_proto": protocol, "api_auth": str(oauth_mode).lower() } def sig_handler(self): print('Pressed ctrl+c') self.stop() def sig_hup_handler(self): if getLocalIP() != "": global HOST HOST = updateHost() self.registry.modify_node(href=self.generate_href(), host=HOST, api={ "versions": NODE_APIVERSIONS, "endpoints": self.generate_endpoints() }, interfaces=self.list_interfaces()) def generate_endpoints(self): endpoints = [] endpoints.append({ "host": HOST, "port": self.dns_sd_port, # Everything should go via apache proxy "protocol": self.protocol, "authorization": OAUTH_MODE }) return endpoints def generate_href(self): return "{}://{}/".format(PROTOCOL, HOST) def list_interfaces(self): interfaces = {} # Initially populate interfaces from known-good location net_path = "/sys/class/net/" if os.path.exists(net_path): for interface_name in os.listdir(net_path): address_path = net_path + interface_name + "/address" if os.path.exists(address_path) and interface_name != 'lo': with open(address_path, 'r') as address_file: address = address_file.readline().strip('\n') if address: interfaces[interface_name] = { "name": interface_name, "chassis_id": None, "port_id": address.lower().replace(":", "-") } # Attempt to source proper LLDP data for interfaces if os.path.exists("/usr/sbin/lldpcli"): try: chassis_data = json.loads( check_output( ["/usr/sbin/lldpcli", "show", "chassis", "-f", "json"])) chassis_id = chassis_data["local-chassis"]['chassis'].values( )[0]["id"]["value"] if chassis_data["local-chassis"]['chassis'].values( )[0]["id"]["type"] == "mac": chassis_id = chassis_id.lower().replace(":", "-") interface_data = json.loads( check_output([ "/usr/sbin/lldpcli", "show", "statistics", "-f", "json" ])) if isinstance(interface_data["lldp"]["interface"], dict): for interface_name in interface_data["lldp"][ "interface"].keys(): if interface_name in interfaces: # Only correct the Chassis ID. Port ID MUST be a MAC address interfaces[interface_name][ "chassis_id"] = chassis_id else: for interface_block in interface_data["lldp"]["interface"]: interface_name = interface_block.keys()[0] if interface_name in interfaces: # Only correct the Chassis ID. Port ID MUST be a MAC address interfaces[interface_name][ "chassis_id"] = chassis_id except Exception: pass return list(itervalues(interfaces)) def start(self): if self.running: gevent.signal_handler(signal.SIGINT, self.sig_handler) gevent.signal_handler(signal.SIGTERM, self.sig_handler) gevent.signal_handler(signal.SIGHUP, self.sig_hup_handler) self.mdns.start() self.node_id = get_node_id() node_version = str(ptptime.ptp_detail()[0]) + ":" + str( ptptime.ptp_detail()[1]) node_data = { "id": self.node_id, "label": _config.get('node_label', FQDN), "description": _config.get('node_description', "Node on {}".format(FQDN)), "tags": _config.get('node_tags', {}), "href": self.generate_href(), "host": HOST, "services": [], "hostname": HOSTNAME, "caps": {}, "version": node_version, "api": { "versions": NODE_APIVERSIONS, "endpoints": self.generate_endpoints(), }, "clocks": [], "interfaces": self.list_interfaces() } self.registry = FacadeRegistry(self.mappings.keys(), self.aggregator, self.mdns_updater, self.node_id, node_data, self.logger) self.registry_cleaner = FacadeRegistryCleaner(self.registry) self.registry_cleaner.start() self.httpServer = HttpServer( FacadeAPI, PORT, '0.0.0.0', api_args=[self.registry, self.auth_registry]) self.httpServer.start() while not self.httpServer.started.is_set(): self.logger.writeInfo('Waiting for httpserver to start...') self.httpServer.started.wait() if self.httpServer.failed is not None: raise self.httpServer.failed self.logger.writeInfo("Running on port: {}".format( self.httpServer.port)) try: self.logger.writeInfo("Registering as {}...".format(self.node_id)) self.aggregator.register( 'node', self.node_id, **translate_api_version(node_data, "node", NODE_REGVERSION)) except Exception as e: self.logger.writeWarning("Could not register: {}".format( e.__repr__())) self.interface = FacadeInterface(self.registry, self.logger) self.interface.start() def run(self): self.running = True pidfile = "/tmp/ips-nodefacade.pid" with open(pidfile, 'w') as f: f.write(str(getpid())) self.start() daemon.notify(SYSTEMD_READY) while self.running: self.registry.update_ptp() time.sleep(1) os.unlink(pidfile) def _cleanup(self): try: self.logger.writeDebug("cleanup: unregister facade " + self.node_id) self.aggregator.unregister('node', self.node_id) except Exception as e: self.logger.writeWarning("Could not unregister: {}".format(e)) if self.mdns: try: self.mdns.stop() except Exception as e: self.logger.writeWarning("Could not stop mdns: {}".format(e)) self.registry_cleaner.stop() self.interface.stop() self.httpServer.stop() self.aggregator.stop() self.mdns_updater.stop() self.logger.writeInfo("Stopped main()") def stop(self): self._cleanup() self.running = False