def passwd(*args): print() try: login = input("Login: "******"Password (will be echoed): ").strip() is_admin = input("Admin (yes/no): ").strip() except KeyboardInterrupt: print() logging.warning("Interrupted by user") sys.exit(0) db = DB() db.query("SELECT id FROM users WHERE login=%s", [login]) res = db.fetchall() if not res: critical_error("Unable to set password: no such user") u = User(res[0][0], db=db) if login: u["login"] = u["full_name"] = login u["is_admin"] = 1 if is_admin == "yes" else 0 u.set_password(password) u.save() print() logging.goodnews("Password changed")
def load_settings(self): self.splash_message("Loading site settings") response = api.settings() if not response: QMessageBox.critical(self.splash, "Error", response.message) critical_error("Unable to load site settings") for key in response.data: if config.get(key) and key != "site_name": if key in self.local_keys: continue config[key] = response.data[key] # Fix indices for config_group in [ "storages", "playout_channels", "ingest_channels", "folders", "views", "actions", "services", ]: ng = {} for id in config[config_group]: ng[int(id)] = config[config_group][id] config[config_group] = ng clear_cs_cache()
def listen_rabbit(self): try: import pika except ModuleNotFoundError: critical_error("'pika' module is not installed") host = config.get("rabbitmq_host", "rabbitmq") conparams = pika.ConnectionParameters(host=host) while True: try: connection = pika.BlockingConnection(conparams) channel = connection.channel() result = channel.queue_declare( queue=config["site_name"], arguments={"x-message-ttl": 1000}) queue_name = result.method.queue logging.info("Listening on", queue_name) channel.basic_consume( queue=queue_name, on_message_callback=lambda c, m, p, b: self.handle_data(b), auto_ack=True, ) channel.start_consuming() except pika.exceptions.AMQPConnectionError: logging.error("RabbitMQ connection error", handlers=[]) except Exception: log_traceback() time.sleep(2)
def __init__(self): self.connection = None self.channel = None self.queue = queue.Queue() self.lock = threading.Lock() if not has_pika: critical_error("'pika' module is not installed")
def connect(self): if config.get("cache_mode", "memcached") == "redis": pass else: if not has_pylibmc: critical_error("'pylibmc' module is not installed") self.cstring = f"{self.host}:{self.port}" self.pool = False self.conn = pylibmc.Client([self.cstring])
def __init__(self, sessions_dir, max_age, salt): self.sessions_dir = str(sessions_dir) self.max_age = max_age self.salt = salt if not os.path.isdir(self.sessions_dir): try: os.makedirs(self.sessions_dir) except Exception: critical_error( f"Unable to create sessions directory {self.sessions_dir}")
def delete(self, key): if config.get("mc_thread_safe", False): return self.threaded_delete(key) key = self.site + "-" + key for i in range(MAX_RETRIES): try: self.conn.delete(key) break except Exception: log_traceback(f"Cache delete failed ({key})") time.sleep(0.3) self.connect() else: critical_error("Memcache delete failed. This should never happen.") return True
def __init__(self, once=False): self.first_run = True self.thread = None self.is_running = False self.should_run = True try: self.on_init() except Exception: log_traceback() critical_error(f"Unable to start {self.__class__.__name__}") if once: self.main() else: self.thread = threading.Thread(target=self.run, daemon=True) self.thread.start()
def __init__(self): """Load initial config.""" super(Config, self).__init__() self["site_name"] = "Unnamed" self["user"] = "******" self["host"] = socket.gethostname() self["storages"] = {} self["rights"] = {} self["folders"] = {} self["playout_channels"] = {} self["ingest_channels"] = {} self["cs"] = {} self["views"] = {} self["meta_types"] = {} self["actions"] = {} self["services"] = {} if len(sys.argv) > 1 and os.path.exists(sys.argv[1]): local_settings_path = sys.argv[1] else: local_settings_path = "settings.json" settings_files = ["/etc/nebula.json", local_settings_path] settings = {} if "--daemon" in sys.argv: logging.file = os.devnull settings["daemon_mode"] = True for settings_file in settings_files: if os.path.exists(settings_file): try: settings.update(json.load(open(settings_file))) break except Exception: log_traceback(handlers=False) for key, value in dict(os.environ).items(): if key.lower().startswith("nebula_"): key = key.lower().replace("nebula_", "", 1) settings[key] = value if not settings: critical_error("Unable to open site settings") self.update(settings)
def threaded_save(self, key, value): if not self.pool: self.pool = pylibmc.ThreadMappedPool(self.conn) key = self.site + "-" + key with self.pool.reserve() as mc: for i in range(MAX_RETRIES): try: mc.set(str(key), str(value)) break except Exception: log_traceback(f"Cache save failed ({key})") time.sleep(0.3) self.connect() else: critical_error( "Memcache save failed. This should never happen.") self.pool.relinquish() return True
def t(*args): tools_dir = get_plugin_path("tools") if not tools_dir: return plugin_name = args[0] try: fp, pathname, description = imp.find_module(plugin_name, [tools_dir]) except ImportError: critical_error("unable to locate module: " + plugin_name) try: module = imp.load_module(plugin_name, fp, pathname, description) except Exception: log_traceback() critical_error("Unable ot open tool " + plugin_name) logging.user = plugin_name margs = args[1:] if len(args) > 1 else [] module.Plugin(*margs)
def s(*args): print() db = DB() if len(args) >= 2: try: services = tuple([int(i.strip()) for i in args[1:]]) except ValueError: critical_error("Wrong service ID") if args[0] == "start": db.query("UPDATE services SET state=2 WHERE id IN %s AND state=0", [services]) db.commit() elif args[0] == "stop": db.query("UPDATE services SET state=3 WHERE id IN %s AND state=1", [services]) db.commit() elif args[0] == "kill": db.query( "UPDATE services SET state=4 WHERE id IN %s AND state IN (1,3)", [services], ) db.commit() elif args[0] == "auto": db.query("UPDATE services SET autostart=TRUE WHERE id IN %s", [services]) db.commit() elif args[0] == "noauto": db.query("UPDATE services SET autostart=FALSE WHERE id IN %s", [services]) db.commit() else: critical_error("Unsupported command: {}".format(args[0])) time.sleep(1) show_services(db)
import sys orig_dir = os.getcwd() if orig_dir != "/opt/nebula": os.chdir("/opt/nebula") logging.user = "******" if __name__ == "__main__": command = os.path.basename(sys.argv[0]) if command.startswith("nx"): module = command[2:] args = sys.argv[1:] else: if len(sys.argv) < 2: critical_error("This command takes at least one argument") module = sys.argv[1] args = sys.argv[2:] if module not in modules: critical_error("Unknown module '{}'".format(module)) try: modules[module](*args) except SystemExit: pass except Exception: log_traceback() os.chdir(orig_dir)
def run(*args): id_service = args[0] if id_service == "hub": import hub try: hub_instance = hub.CherryAdmin(**hub.hub_config) except Exception: log_traceback() critical_error("Unhandled exception in Hub") return try: id_service = int(id_service) except ValueError: critical_error("Service ID must be integer") db = DB() db.query( """ SELECT service_type, title, host, loop_delay, settings FROM services WHERE id=%s """, [id_service], ) try: agent, title, host, loop_delay, settings = db.fetchall()[0] except IndexError: critical_error( f"Unable to start service {id_service}. No such service") config["user"] = logging.user = title if host != config["host"]: critical_error("This service should not run here.") if settings: try: settings = xml(settings) except Exception: log_traceback() logging.error("Malformed settings XML:\n", settings) db.query("UPDATE services SET autostart=0 WHERE id=%s", [id_service]) db.commit() critical_error("Unable to start service") _module = __import__("services." + agent, globals(), locals(), ["Service"]) Service = _module.Service service = Service(id_service, settings) while True: try: service.on_main() last_run = time.time() while True: time.sleep(min(loop_delay, 2)) service.heartbeat() if time.time() - last_run >= loop_delay: break except (KeyboardInterrupt): logging.warning("Keyboard interrupt") break except (SystemExit): break except Exception: log_traceback() time.sleep(2) sys.exit(1) try: if sys.argv[1] == "once": break except IndexError: pass
def load_settings(*args, **kwargs): global config # This is the first time we are connecting DB # so error handling should be here try: db = DB() except psycopg2.OperationalError: critical_error("Unable to connect nebula database") # Load from db db.query("SELECT key, value FROM settings") for key, value in db.fetchall(): config[key] = value db.query("SELECT id, settings FROM storages") config["storages"] = {} for id, settings in db.fetchall(): if id in config.get("storages_blacklist", []): continue config["storages"][id] = settings config["playout_channels"] = {} config["ingest_channels"] = {} db.query("SELECT id, channel_type, settings FROM channels") for id, channel_type, settings in db.fetchall(): if channel_type == 0: config["playout_channels"][id] = settings elif channel_type == 1: config["ingest_channels"][id] = settings config["folders"] = {} db.query("SELECT id, settings FROM folders") for id, settings in db.fetchall(): config["folders"][id] = settings config["meta_types"] = {} db.query("SELECT key, settings FROM meta_types") for key, settings in db.fetchall(): config["meta_types"][key] = settings config["cs"] = {} db.query("SELECT cs, value, settings FROM cs") for cst, value, settings in db.fetchall(): if cst not in config["cs"]: config["cs"][cst] = [] config["cs"][cst].append([value, settings]) clear_cs_cache() config["views"] = {} db.query("SELECT id, settings FROM views") for id, settings in db.fetchall(): config["views"][id] = settings config["actions"] = {} db.query("SELECT id, service_type, title FROM actions") for id, service_type, title in db.fetchall(): config["actions"][id] = { "title": title, "service_type": service_type, } config["services"] = {} db.query("SELECT id, service_type, host, title FROM services") for id, service_type, host, title in db.fetchall(): config["services"][id] = { "service_type": service_type, "host": host, "title": title, } # # Init all # messaging.configure() def seismic_log(**kwargs): messaging.send("log", **kwargs) logging.add_handler(seismic_log) cache.configure() load_common_scripts() if logging.user == "hub": messaging.send("config_changed") return True
__all__ = ["DB"] from nxtools import log_traceback, critical_error from nx.core.common import config try: import psycopg2 except ImportError: log_traceback("Import error") critical_error("Unable to import psycopg2") class DB(object): def __init__(self, **kwargs): self.pmap = { "host": "db_host", "user": "******", "password": "******", "database": "db_name", } self.settings = { key: kwargs.get(self.pmap[key], config[self.pmap[key]]) for key in self.pmap } self.conn = psycopg2.connect(**self.settings) self.cur = self.conn.cursor() def lastid(self): self.query("SELECT LASTVAL()") return self.fetchall()[0][0]
def shutdown(agents): logging.info("Shutting down agents") for agent in agents: agent.shutdown() while are_running(agents): time.sleep(0.5) agents = [] for Agent in [StorageMonitor, ServiceMonitor, SystemMonitor]: try: agents.append(Agent()) except Exception: log_traceback() shutdown(agents) critical_error(f"Unable to start {Agent.__name__}") # Main loop while True: try: sync_cron() or del_cron() time.sleep(10) except KeyboardInterrupt: break except Exception: log_traceback() time.sleep(10) # Shutdown (CTRL+C)