Пример #1
0
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")
Пример #2
0
    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()
Пример #3
0
    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)
Пример #4
0
 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")
Пример #5
0
 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])
Пример #6
0
    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}")
Пример #7
0
 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
Пример #8
0
 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()
Пример #9
0
    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)
Пример #10
0
 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
Пример #11
0
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)
Пример #12
0
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)
Пример #13
0
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)
Пример #14
0
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
Пример #15
0
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
Пример #16
0
__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]
Пример #17
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)