Beispiel #1
0
    def init(self, db, env):
        """Initialize the application without loading it into the database.
           db: a ravel.db.RavelDb instance to be passed to the application's
           sub-shell
           env: a ravel.env.Environment instance of the CLI's executing
           environment to be passed to the application's sub-shell"""
        if not self.pyfile:
            return

        # discover sql components (tables, views, functions)
        if self.sqlfile is not None:
            with open(self.sqlfile) as f:
                self.components = discoverComponents(f.read())

        logger.debug("discovered {0} components: {1}"
                     .format(self.name, self.components))

        # if needed, add path
        filepath = os.path.dirname(self.pyfile)
        ravel.util.append_path(filepath)

        try:
            self.module = importlib.import_module(self.name)
            self.console =  self.module.console(db, env, self.components)

            # force module prompt to app name
            self.console.prompt = self.name + "> "
            self.console.doc_header = self.name + \
                                      " commands (type help <topic>):"
        except BaseException, e:
            errstr = "{0}: {1}".format(type(e).__name__, str(e))
            logger.warning("error loading %s console: %s",
                           self.name, e)
Beispiel #2
0
    def init(self, db, env):
        """Initialize the application without loading it into the database.
           db: a ravel.db.RavelDb instance to be passed to the application's
           sub-shell
           env: a ravel.env.Environment instance of the CLI's executing
           environment to be passed to the application's sub-shell"""
        if not self.pyfile:
            return

        # discover sql components (tables, views, functions)
        if self.sqlfile is not None:
            with open(self.sqlfile) as f:
                self.components = discoverComponents(f.read())

        logger.debug("discovered {0} components: {1}".format(
            self.name, self.components))

        # if needed, add path
        filepath = os.path.dirname(self.pyfile)
        ravel.util.append_path(filepath)

        try:
            self.module = importlib.import_module(self.name)
            self.console = self.module.console(db, env, self.components)

            # force module prompt to app name
            self.console.prompt = self.name + "> "
            self.console.doc_header = self.name + \
                                      " commands (type help <topic>):"
        except BaseException, e:
            errstr = "{0}: {1}".format(type(e).__name__, str(e))
            logger.warning("error loading %s console: %s", self.name, e)
Beispiel #3
0
    def _delFlowByName(self, src, dst):
        hostnames = self.env.provider.cache_name

        if src not in hostnames:
            print "Unknown host", src
            return

        if dst not in hostnames:
            print "Unknown host", dst
            return

        src = hostnames[src]
        dst = hostnames[dst]
        self.db.cursor.execute("SELECT fid FROM rm WHERE src={0} and dst={1};"
                               .format(src, dst))
        result = self.db.cursor.fetchall()

        if len(result) == 0:
            logger.warning("no flow installed for hosts {0},{1}".format(src, dst))
            return None

        fids = [res[0] for res in result]
        for fid in fids:
            self._delFlowById(fid)

        return fids
Beispiel #4
0
def clear_queue(queue_id):
    try:
        mq = sysv_ipc.MessageQueue(queue_id, sysv_ipc.IPC_CREAT, mode=0777)
        mq.remove()
    except sysv_ipc.PermissionsError:
        logger.warning(
            "could not clear clear message queue {0}".format(queue_id))
Beispiel #5
0
    def _delFlowByName(self, src, dst):
        hostnames = self.env.provider.cache_name

        if src not in hostnames:
            print "Unknown host", src
            return

        if dst not in hostnames:
            print "Unknown host", dst
            return

        src = hostnames[src]
        dst = hostnames[dst]
        self.db.cursor.execute("SELECT fid FROM my_rm WHERE src={0} and dst={1};"
                               .format(src, dst))
        result = self.db.cursor.fetchall()

        if len(result) == 0:
            logger.warning("no flow installed for hosts {0},{1}".format(src, dst))
            return None

        fids = [res[0] for res in result]
        for fid in fids:
            self._delFlowById(fid)

        return fids
Beispiel #6
0
def is_profiled():
    "Check if profiling is enabled"
    try:
        shm = sysv_ipc.SharedMemory(ProfileQueueId)
        return shm.read().strip("\0") == ProfileOn
    except sysv_ipc.ExistentialError, e:
        logger.warning("profile queue doesn't exist: %", e)
        return False
Beispiel #7
0
def is_profiled():
    "Check if profiling is enabled"
    try:
        shm = sysv_ipc.SharedMemory(ProfileQueueId)
        return shm.read().strip("\0") == ProfileOn
    except sysv_ipc.ExistentialError, e:
        logger.warning("profile queue doesn't exist: %", e)
        return False
Beispiel #8
0
 def load_schema(self, script):
     """Load the specified schema into the database"
        script: path to a SQL script"""
     try:
         s = open(script, "r").read()
         logger.debug("loaded schema %s", script)
         self.cursor.execute(s)
     except psycopg2.DatabaseError, e:
         logger.warning("error loading schema: %s", self.fmt_errmsg(e))
Beispiel #9
0
def clear_queue(queue_id):
    try:
        mq = sysv_ipc.MessageQueue(queue_id,
                                   sysv_ipc.IPC_CREAT,
                                   mode=0777)
        mq.remove()
    except sysv_ipc.PermissionsError:
        logger.warning("could not clear clear message queue {0}"
                       .format(queue_id))
Beispiel #10
0
def RavelCLI(opts):
    """Start a RavelConsole instance given a list of command line options
       opts: parsed OptionParser object"""
    if opts.custom:
        ravel.mndeps.custom(opts.custom)

    topo = ravel.mndeps.build(opts.topo)
    if topo is None:
        print "Invalid mininet topology", opts.topo
        return

    if opts.script is not None and not os.path.isfile(opts.script):
        print "{0}: no such script file".format(opts.script)
        return

    passwd = None
    if opts.password:
        passwd = getpass.getpass("Enter password: "******"Pox instance is already running.  Please shut down " \
                "existing controller first (or run ravel.py --clean)."
            return

        controller = PoxInstance("ravel.controller.poxmgr")

    from ravel.network import MininetProvider, EmptyNetProvider
    if opts.onlydb:
        net = EmptyNetProvider(raveldb, topo)
    else:
        net = MininetProvider(raveldb, topo, controller)

    if net is None:
        print "Cannot start network"

    env = Environment(raveldb, net, Config.AppDirs, opts)
    env.start()

    while True:
        try:
            if opts.script is not None:
                RavelConsole(env).do_exec(opts.script)

                if opts.exit:
                    break

            RavelConsole(env, quiet=opts.script).cmdloop()
            break
        except Exception, e:
            logger.warning("console crashed: %s", e)
Beispiel #11
0
    def load_topo(self, provider):
        """Load a topology from the specified network provider
           provider: a ravel.network.NetworkProvider instance"""
        topo = provider.topo
        try:
            node_count = 0
            nodes = {}
            for sw in topo.switches():
                node_count += 1
                dpid = provider.getNodeByName(sw).dpid
                ip = provider.getNodeByName(sw).IP()
                mac = provider.getNodeByName(sw).MAC()
                nodes[sw] = node_count
                self.cursor.execute("INSERT INTO switches (sid, dpid, ip, mac, name) "
                                    "VALUES ({0}, '{1}', '{2}', '{3}', '{4}');"
                                    .format(node_count, dpid, ip, mac, sw))

            for host in topo.hosts():
                node_count += 1
                ip = provider.getNodeByName(host).IP()
                mac = provider.getNodeByName(host).MAC()
                nodes[host] = node_count
                self.cursor.execute("INSERT INTO hosts (hid, ip, mac, name) "
                                    "VALUES ({0}, '{1}', '{2}', '{3}');"
                                    .format(node_count, ip, mac, host))

            for link in topo.links():
                h1,h2 = link
                if h1 in topo.switches() and h2 in topo.switches():
                    ishost = 0
                else:
                    ishost = 1

                sid = nodes[h1]
                nid = nodes[h2]
                self.cursor.execute("INSERT INTO tp(sid, nid, ishost, isactive) "
                                    "VALUES ({0}, {1}, {2}, {3});"
                                    .format(sid, nid, ishost, 1))

                # bidirectional edges
                self.cursor.execute("INSERT INTO tp(sid, nid, ishost, isactive) "
                                    "VALUES ({1}, {0}, {2}, {3});"
                                    .format(sid, nid, ishost, 1))

                self.cursor.execute("INSERT INTO ports(sid, nid, port) "
                                    "VALUES ({0}, {1}, {2}), ({1}, {0}, {3});"
                                    .format(sid, nid,
                                            topo.port(h1, h2)[0],
                                            topo.port(h1, h2)[1]))

        except psycopg2.DatabaseError, e:
            logger.warning("error loading topology: %s", self.fmt_errmsg(e))
Beispiel #12
0
    def num_connections(self):
        """Returns the number of existing connections to the database.  If
           there are >1 connections, a new Ravel base implementation cannot be
           loaded into the database.
           returns: the number of existing connections to the database"""
        try:
            self.cursor.execute("SELECT * FROM pg_stat_activity WHERE "
                                "datname='{0}'".format(self.name))

            # ignore cursor connection
            return len(self.cursor.fetchall()) - 1
        except psycopg2.DatabaseError, e:
            logger.warning("error loading schema: %s", self.fmt_errmsg(e))
Beispiel #13
0
 def __init__(self, queue_id):
     "queue_id: the integer id of the queue to be used"
     self.queue_id = queue_id
     pc = ravel.profiling.PerfCounter("mq_connect")
     pc.start()
     try:
         self.mq = sysv_ipc.MessageQueue(self.queue_id, mode=0777)
     except sysv_ipc.ExistentialError, e:
         logger.warning("queue {0} does not exist: {1}".format(
             self.queue_id, e))
         self.mq = sysv_ipc.MessageQueue(self.queue_id,
                                         sysv_ipc.IPC_CREAT,
                                         mode=0777)
Beispiel #14
0
    def truncate(self):
        """Clean the database of any state Ravel components, except for 
           topology tables.  This rolls back the database to the state after
           the topology is first loaded"""
        try:
            tables = ["cf", "clock", "p_spv", "spatial_ref_sys", "spv_tb_del",
                      "spv_tb_ins", "rm", "rm_delta", "urm"]

            self.cursor.execute("truncate %s;" % ", ".join(tables))
            logger.debug("truncated tables")
            self.cursor.execute("INSERT INTO clock values (0);")
        except psycopg2.DatabaseError, e:
            logger.warning("error truncating databases: %s", self.fmt_errmsg(e))
Beispiel #15
0
    def _delFlowById(self, fid):
        try:
            # does the flow exist?
            self.db.cursor.execute("SELECT fid FROM my_rm WHERE fid={0}".format(fid))
            if len(self.db.cursor.fetchall()) == 0:
                logger.warning("no flow installed with fid %s", fid)
                return None

            self.db.cursor.execute("DELETE FROM my_rm WHERE fid={0}".format(fid))
            return fid
        except Exception, e:
            print e
            return None
Beispiel #16
0
    def _delFlowById(self, fid):
        try:
            # does the flow exist?
            self.db.cursor.execute("SELECT fid FROM rm WHERE fid={0}".format(fid))
            if len(self.db.cursor.fetchall()) == 0:
                logger.warning("no flow installed with fid %s", fid)
                return None

            self.db.cursor.execute("DELETE FROM rm WHERE fid={0}".format(fid))
            return fid
        except Exception, e:
            print e
            return None
Beispiel #17
0
 def __init__(self, queue_id):
     "queue_id: the integer id of the queue to be used"
     self.queue_id = queue_id
     pc = ravel.profiling.PerfCounter("mq_connect")
     pc.start()
     try:
         self.mq = sysv_ipc.MessageQueue(self.queue_id,
                                         mode=0777)
     except sysv_ipc.ExistentialError, e:
         logger.warning("queue {0} does not exist: {1}"
                        .format(self.queue_id, e))
         self.mq = sysv_ipc.MessageQueue(self.queue_id,
                                         sysv_ipc.IPC_CREAT,
                                         mode=0777)
Beispiel #18
0
    def clean(self):
        """Clean the database of any existing Ravel components"""
        # close existing connections
        self.conn.close()

        conn = None
        try:
            conn = psycopg2.connect(database="postgres",
                                    user=self.user,
                                    password=self.passwd)
            conn.set_isolation_level(ISOLEVEL)
            cursor = conn.cursor()
            cursor.execute("drop database %s" % self.name)
        except psycopg2.DatabaseError, e:
            logger.warning("error cleaning database: %s", self.fmt_errmsg(e))
Beispiel #19
0
    def unload_app(self, appname):
        """Unload an application from the environment
           appname: the application to load"""

        # don't unload coreapps
        if appname in self.coreapps:
            logger.warning("cannot unload core apps {0}".format(self.coreapps))
            return

        app = self.apps[appname]
        app.unload(self.db)

        if app.name in self.loaded:
            del self.loaded[app.name]

        if app.shortcut is not None and app.shortcut in self.loaded:
            del self.loaded[app.shortcut]
Beispiel #20
0
    def unload_app(self, appname):
        """Unload an application from the environment
           appname: the application to load"""

        # don't unload coreapps
        if appname in self.coreapps:
            logger.warning("cannot unload core apps {0}".format(self.coreapps))
            return

        app = self.apps[appname]
        app.unload(self.db)

        if app.name in self.loaded:
            del self.loaded[app.name]

        if app.shortcut is not None and app.shortcut in self.loaded:
            del self.loaded[app.shortcut]
Beispiel #21
0
    def add_extensions(self):
        """If not already added, add extensions required by Ravel (plpythonu,
           postgis, pgrouting)"""
        try:
            self.cursor.execute("SELECT 1 FROM pg_catalog.pg_namespace n JOIN " +
                                "pg_catalog.pg_proc p ON pronamespace = n.oid " +
                                "WHERE proname = 'pgr_dijkstra';")
            fetch = self.cursor.fetchall()

            if fetch == []:
                self.cursor.execute("CREATE EXTENSION IF NOT EXISTS plpythonu;")
                self.cursor.execute("CREATE EXTENSION IF NOT EXISTS postgis;")
                self.cursor.execute("CREATE EXTENSION IF NOT EXISTS pgrouting;")
                self.cursor.execute("CREATE EXTENSION plsh;")
                logger.debug("created extensions")
        except psycopg2.DatabaseError, e:
            logger.warning("error loading extensions: %s", self.fmt_errmsg(e))
Beispiel #22
0
def update_trigger_path(filename, path):
    """Update PYTHONPATH within a Python-based trigger implemented within the
       SQL file specified in filename.
       filename: the file containing the SQL trigger implementation
       path: the path to append to PYTHONPATH"""
    path = os.path.expanduser(path)
    if not os.path.isfile(filename):
        logger.warning("cannot find sql file %s", filename)
        return

    with open(filename, "r") as f:
        lines = []
        content = f.read()

    newstr = 'sys.path.append("{0}")'.format(path)
    pattern = re.compile(r"sys.path.append\(\S+\)")
    content = re.sub(pattern, newstr, content)

    open(filename, "w").write(content)
Beispiel #23
0
def update_trigger_path(filename, path):
    """Update PYTHONPATH within a Python-based trigger implemented within the
       SQL file specified in filename.
       filename: the file containing the SQL trigger implementation
       path: the path to append to PYTHONPATH"""
    path = os.path.expanduser(path)
    if not os.path.isfile(filename):
        logger.warning("cannot find sql file %s", filename)
        return

    with open(filename, "r") as f:
        lines = []
        content = f.read()

    newstr = 'sys.path.append("{0}")'.format(path)
    pattern = re.compile(r"sys.path.append\(\S+\)")
    content = re.sub(pattern, newstr, content)

    open(filename, "w").write(content)
Beispiel #24
0
    def load_app(self, appname):
        """Load an application in the environment
           appname: the application to unload"""
        if appname in self.loaded:
            return

        # look for newly-added applications
        self.discover()

        if appname in self.apps:
            app = self.apps[appname]
            app.load(self.db)
            if app.is_loadable():
                self.loaded[app.name] = app
                if app.shortcut is not None and app.shortcut != app.name:
                    if app.shortcut in self.loaded:
                        logger.warning("shortcut {0} for {1} already in use"
                                       .format(app.shortcut, app.name))
                    else:
                        self.loaded[app.shortcut] = app
Beispiel #25
0
 def create(self):
     """If not created, create a database with the name specified in
        the constructor"""
     conn = None
     try:
         conn = psycopg2.connect(database="postgres",
                                 user=self.user,
                                 password=self.passwd)
         conn.set_isolation_level(ISOLEVEL)
         cursor = conn.cursor()
         cursor.execute("SELECT datname FROM pg_database WHERE " +
                        "datistemplate = false;")
         fetch = cursor.fetchall()
         
         dblist = [fetch[i][0] for i in range(len(fetch))]
         if self.name not in dblist:
             cursor.execute("CREATE DATABASE %s;" % self.name)
             logger.debug("created databse %s", self.name)
     except psycopg2.DatabaseError, e:
         logger.warning("error creating database: %s", self.fmt_errmsg(e))
Beispiel #26
0
    def load_app(self, appname):
        """Load an application in the environment
           appname: the application to unload"""
        if appname in self.loaded:
            return

        # look for newly-added applications
        self.discover()

        if appname in self.apps:
            app = self.apps[appname]
            app.load(self.db)
            if app.is_loadable():
                self.loaded[app.name] = app
                if app.shortcut is not None and app.shortcut != app.name:
                    if app.shortcut in self.loaded:
                        logger.warning(
                            "shortcut {0} for {1} already in use".format(
                                app.shortcut, app.name))
                    else:
                        self.loaded[app.shortcut] = app
Beispiel #27
0
    def __init__(self, name, user, base, passwd=None, reconnect=False):
        """name: the name of the database to connect to
           user: the username to use to connect
           base: a file containing the SQL implementation for Ravel's base
           passwd: the password to connect to the database
           reconnect: true to connect to an existing database setup, false
           to load a new instance of Ravel's base into the database"""
        self.name = name
        self.user = user
        self.passwd = passwd
        self.base = base
        self.cleaned = not reconnect
        self._cursor = None
        self._conn = None

        if not reconnect and self.num_connections() > 0:
            logger.warning("existing connections to database, skipping reinit")
            self.cleaned = False
        elif not reconnect:
            self.init()
            self.cleaned = True
Beispiel #28
0
 def cli(self, cmd):
     "EmptyNetProvider has no CLI, raises warning"
     logger.warning("no CLI available for db-only mode")
Beispiel #29
0
def RavelCLI(opts):
    """Start a RavelConsole instance given a list of command line options
		opts: parsed OptionParser object"""
    if opts.custom:
        ravel.mndeps.custom(opts.custom)

    topo = ravel.mndeps.build(opts.topo)
    if topo is None:
        print "Invalid mininet topology", opts.topo
        return

    if opts.script is not None and not os.path.isfile(opts.script):
        print "{0}: no such script file".format(opts.script)
        return

    passwd = None
    if opts.password:
        passwd = getpass.getpass("Enter password: "******"Pox instance is already running.  Please shut down " \
              "existing controller first (or run ravel.py --clean)."
            return

        controller = PoxInstance("ravel.controller.poxmgr")

    from ravel.network import MininetProvider, EmptyNetProvider
    if opts.onlydb:
        net = EmptyNetProvider(raveldb, topo)
    else:
        net = MininetProvider(raveldb, topo, controller)

    if net is None:
        print "Cannot start network"

    env = Environment(raveldb, net, Config.AppDirs, opts)
    env.start()

    # ---------------------------------------------------------------
    # Sarah's additions
    # ---------------------------------------------------------------
    with open("/home/ravel/ravel/ep/resource_logs/boottime.txt",
              "a") as bootTimeLog:
        if opts.restore:
            RavelConsole(env).do_exec("scripts/wipeSchema.sql")
            os.system(
                "sudo -u ravel psql ravel < /home/ravel/ravel/ep/backup.sql")
            bootMode = "restored"
        else:
            bootMode = "launched"

        # this is the last thing we do before launching the CLI... add time to log
        bootTimeLog.write("{0} - Ravel {1}. Ready for CLI.\n".format(
            datetime.datetime.now(), bootMode))
    # ---------------------------------------------------------------

    while True:
        try:
            if opts.script is not None:
                RavelConsole(env).do_exec(opts.script)
                if opts.exit:
                    break
            RavelConsole(env, quiet=opts.script).cmdloop()
            break
        except Exception, e:
            logger.warning("console crashed: %s", e)
Beispiel #30
0
 def cli(self, cmd):
     "EmptyNetProvider has no CLI, raises warning"
     logger.warning("no CLI available for db-only mode")