#!/usr/bin/python

import os
import subprocess
import argparse
import sys
import signal
import time
import ConfigParser
import pprint

###############################################################################
#
# Arguments
#
# Arguments can be specified directly, or via config file. 
# TODO -- Make this a separate reusable class
#
################################################################################
gBasename = "ovs-ctl"

gConfigParser = argparse.ArgumentParser(description=gBasename, add_help=False)

gConfigParser.add_argument('-cf', '--config-file', 
                     help="Load settings from the given config file", 
                     nargs='+', metavar="FILE", 
                     default=os.path.expanduser("~/."+gBasename))

gConfigParser.add_argument('-c', '--config', 
                     help="Use the specified configuration section", 
                     default=None)

gConfigParser.add_argument('-d', '--default-config-file', 
                     help="Location of the local default config file", 
                     metavar="FILE", 
                     default="/opt/ovs/%s-default.conf" % (gBasename))

gConfigParser.add_argument('-nd', '--no-default', 
                     help="Do not load the default config file", 
                     action='store_true', default=False)
gConfigParser.add_argument('--dump-config',
                     help="Dump the loaded configuration settings", 
                     action='store_true', default=False)

#
# Parse the config files first, then parse remaining command line arguments
#
gConfig = ConfigParser.SafeConfigParser()
configArgs, remainingArgs = gConfigParser.parse_known_args()

if not configArgs.no_default:
    gConfig.read([configArgs.default_config_file])

if isinstance(configArgs.config_file, str):
    configFiles = [ configArgs.config_file]
else:
    configFiles = configArgs.config_file

configFiles = [ os.path.expanduser(x) if x.startswith('~') else x 
                for x in configFiles ]

gConfig.read(configFiles)

# Dump loaded config if requested
if configArgs.dump_config:
    for section in gConfig.sections():
        print section
        for option in gConfig.options(section):
            print " ", option, "=", gConfig.get(section, option)
    sys.exit()



#
# Functional arguments go here
#

#
# OVS target binaries -- these can all be specified individually. 
# If not specified, they are determined by the base directory settings
#
gParser = argparse.ArgumentParser(parents=[gConfigParser])

gParser.add_argument('--ovs-vswitchd-schema', 
                     help="""Path to the vswitchd.ovsschema file""")
gParser.add_argument('--ovs-vswitchd-log', 
                     help="""Path to the vswitchd log file""")
gParser.add_argument('--ovs-vswitchd', 
                     help="""Path to the target ovs-vswitchd binary""")
gParser.add_argument('--ovs-vsctl', 
                     help="""Path to the target ovs-vsctl binary""")
gParser.add_argument('--ovs-ofctl', 
                     help="""Path to the target ovs-ofctl binary""")
gParser.add_argument('--ovsdb-tool', 
                     help="""Path to the target ovsdb-tool binary""")
gParser.add_argument('--ovsdb-server', 
                     help="""Path to the target ovsdb-server binary""")
gParser.add_argument('--ovs-kmod', 
                     help="""Path to the OVS kernel module""")
gParser.add_argument('--ovs-src-dir',
                     help="""Directory for the OVS Source Files""")

gParser.add_argument('--ovs-log-dir',
                     help="""Directory for the OVS Runtime Log Files""")

gParser.add_argument('--ovs-version')

gParser.add_argument("--ovs-base-dir", help="OVS Base Installation Directory")

gParser.add_argument("--ovs-runtime-dir", 
                     help="OVS Runtime Directory", 
                     default="/var/run/ovs")

gParser.add_argument('--ovs-db-sock', 
                     help="Domain Socket Location")
                     
gParser.add_argument('--ovs-db-file', 
                     help="Location for the OVS database file")


#
# Logging/Debugging/Testing options
#
gParser.add_argument('--dry', 
                     help="""Dry run only. Don't actually do anything""", 
                     action='store_true',  default=False)

gParser.add_argument('--log', 
                     help='Enable logging', 
                     action='store_true', default=False)

gParser.add_argument('--verbose', 
                     help='Enable verbose output information', 
                     action='store_true', default=False)

gParser.add_argument("--kill", help="Kill running OVS", 
                     default=False, action='store_true')

gParser.add_argument("--keep-veths", 
                     help="""By default, all existing veths will be destroyed and
the veth module removed before initializing. If you don't want the veth module
removed, specify this argument. Your mileage may vary if you use this.""", 
                     default=False, action='store_true')

gParser.add_argument("--no-kmod", 
                     help="""Do not attempt to insert or remove the OVS kernel module. 
Your mileage may vary.""", 
                     default=False, action='store_true')

gParser.add_argument("--vlog", 
                     help="""Tail the running vswitch.log file in a new xterm""", 
                     default=False, action='store_true')

#
# Runtime and setup arguments
#
gParser.add_argument('-p', '--port-count', type=int, 
                     help="Number of veth ports to connect.", 
                     default='4')


gParser.add_argument("--bridge", help="Name of OF OVS Bridge", 
                     default="ofbr0")

gParser.add_argument("--cip", help="Controller Connection", 
                     default="127.0.0.1")

gParser.add_argument("--cport", type=int, help="Controller Port", 
                     default=6633)

gParser.add_argument("--max_backoff", help="VSwitchD max backoff value", 
                     default=1000, type=int)


gParser.add_argument("--keep-db", 
                     help="""By default, a new database is initialized at each
execution. If you want to keep and use the old database (if it exists), 
use this option""", 
                     action='store_true', default=False)

gParser.add_argument('-lb', '--loopback',
                     help="Create a loopback pair.  The port numbers are port_count+1 and port_count+2.", 
                     default=False, action='store_true')


gParser.add_argument("--cli", 
                     help="Run the ovs-ctl cli after initialization", 
                     action='store_true', default=False)

gParser.add_argument("--teardown", 
                     help="Kill OVS instance after CLI exits", 
                     action='store_true', default=False)

#
# Reset defaults based on config files and override
#
# Anything in the "Defaults" section gets slurped first:
defaults = {}
if gConfig.has_section('Defaults'):
    defaults = dict(gConfig.items('Defaults'))
    gParser.set_defaults(**defaults)

#
# The configuration to execute might be specified in on the command line, or in the Defaults section(s)
# of the config files. 
#
# If its specified on the command line, it will be present in configArgs.config
# If its specified in the section, it will only be present in the defaults dict. 
# Need to check both. Command line takes precedence. 
#
gConfigSection = None
if configArgs.config != None:
    gConfigSection = configArgs.config
elif defaults.has_key('config'):
    gConfigSection = defaults['config']


if gConfigSection != None:
    if gConfig.has_section(gConfigSection):
        section = dict(gConfig.items(gConfigSection))
        gParser.set_defaults(**section)
    else:
        print >>sys.stderr, "Requestion configuration '%s' does not exist" % (configArgs.config)
        sys.exit()


###############################################################################
# 
# Done with argument setup. Parser remaining arguments
#
###############################################################################
gArgs = gParser.parse_args(remainingArgs)


#
# At the end of all of this, we need the following things to be defined
# or derived:
#
gRequiredOptions = [
    [ 'ovs_vswitchd_schema', 'ovs_src_dir',     '/vswitchd/vswitch.ovsschema', True,  True  ], 
    [ 'ovs_vswitchd',        'ovs_base_dir',    '/sbin/ovs-vswitchd',          True,  True  ], 
    [ 'ovs_vsctl',           'ovs_base_dir',    '/bin/ovs-vsctl',              True,  True  ], 
    [ 'ovs_ofctl',           'ovs_base_dir',    '/bin/ovs-ofctl',              True,  True  ], 
    [ 'ovsdb_tool',          'ovs_base_dir',    '/bin/ovsdb-tool',             True,  True, ], 
    [ 'ovsdb_server',        'ovs_base_dir',    '/sbin/ovsdb-server',          True,  True, ], 
    [ 'ovs_db_file',          'ovs_base_dir',    '/ovs.db',                    False, True, ], 
    [ 'ovs_db_sock',         'ovs_runtime_dir', '/db.sock',                    False, True, ], 
    [ 'ovs_kmod',            'ovs_base_dir',    '/sbin/openvswitch_mod.ko',    True,  not gArgs.no_kmod ], 
]

def __require_option(key, basedir, path, exists=True):
    value = getattr(gArgs, key)
    if value is None:
        # Unspecified -- try to default based on given path
        value = getattr(gArgs, basedir)

        if value is None:
            return False

        value += path

    if exists and not os.path.exists(value):
        return False

    if gArgs.verbose:
        print '--v-- option: %s @ %s' % (key, value)

    setattr(gArgs, key, value)


Validated = True
# Try to validate as many things as we can
for option in gRequiredOptions:
    if option[4]:
        if __require_option(option[0], option[1], option[2], option[3]) == False:
            Validated = False

# If any of them failed, try to be as helpful as possible
if Validated == False:
    print >>sys.stdout, "\nConfiguration problem. One or more required settings are missing or could not be derived:\n"
    for option in gRequiredOptions:
        if option[4] is False:
            continue

        value = getattr(gArgs, option[0])
        if value:
            print >>sys.stdout, " %s: %s" % (option[0], value), 
            if option[3] and not os.path.exists(value):
                print >>sys.stdout, "-- does not exist"
            else:
                print "(OK)"
        else:
            print >>sys.stdout, " %s: Unknown. " % (option[0]), 
            base = getattr(gArgs, option[1])
            if base:
                print >>sys.stdout, "Search path was '%s'." % (base + option[2])
            else:
                print >>sys.stdout, "Could not derive path because '%s' was also unspecified." % (option[1])
    print >>sys.stdout
    sys.exit()




#
# If we aren't in a dry run, you must execute as root to accompish anything
#
if not os.geteuid() == 0 and gArgs.dry == False:
    print >>sys.stderr, "Must run as root to accomplish any of this."
    sys.exit()


###############################################################################
#
# Helpers 
#
###############################################################################

def createVeths(count):
    for idx in range(0, count):
        lcall(["/sbin/ip", "link", "add", "type", "veth"])

def vethsUp(count):
    for idx in range(0, count*2):
        lcall(["/sbin/ifconfig", 'veth%s' % (idx), "up"])

def lcall(cmd, log=gArgs.log, dry=gArgs.dry, popen=False, 
          pidFile=None):
    
    if log or gArgs.verbose:
        print "%s: %s" % ('popen' if popen else 'call', cmd)
    
    if not dry:
        if not popen:
            subprocess.call(cmd)
        else:
            p = subprocess.Popen(cmd)
            if pidFile != None:
                pidf = open(pidFile, "w"); 
                print >>pidf, p.pid
                pidf.close()

    

def vsctl(argsList):
    argsList.insert(0, "--db=unix:%s" % (gArgs.ovs_db_sock))
    argsList.insert(0, gArgs.ovs_vsctl)
    lcall(argsList)

def ofctl(argsList):
    argsList.insert(0, gArgs.ovs_ofctl)
    lcall(argsList)

def killpid(pid):
    try:
        os.kill(pid, signal.SIGTERM)
        return False
    except OSError, e:
        return True


def killp(pidfile):
    if os.path.exists(pidfile):
        pid=int(open(pidfile).read())
        print "Killing %s, pid=%s..." % (pidfile, pid),
        if not gArgs.dry:
            while not killpid(pid):
                time.sleep(1)
                pass
        print "dead"


###############################################################################
#
# main
#
###############################################################################

gServerPid = gArgs.ovs_runtime_dir + "/ovsdb-server.pid"
gSwitchPid = gArgs.ovs_runtime_dir + "/ovs-vswitchd.pid"
gLogPid=     gArgs.ovs_runtime_dir + "/ovs-vswitchd-tail.pid"

# Kill previous execution based on contents of the runtime dir
if os.path.exists(gServerPid):
    print gServerPid
    vsctl(["del-br", gArgs.bridge])


def killall():
    # Kill existing DB/vswitchd
    killp(gSwitchPid)
    killp(gServerPid)
    killp(gLogPid)

    # Remove old logpid file, since this does not happen automagically
    if os.path.exists(gLogPid):
        os.remove(gLogPid)

    if gArgs.keep_veths == False:
        lcall(['/sbin/rmmod', 'veth'])
        lcall(['/sbin/modprobe', 'veth'])

    # Remove kmod
    lcall(['/sbin/rmmod', gArgs.ovs_kmod])


killall()
if gArgs.kill == True:
    # Don't do anything else
    sys.exit()


# Remove bridge module
lcall(['/sbin/rmmod', 'bridge'])
# Insert openvswitch module
lcall(['/sbin/insmod', gArgs.ovs_kmod])

port_count = gArgs.port_count
if gArgs.loopback:
    port_count += 1
createVeths(port_count)
vethsUp(port_count)

if not os.path.exists(gArgs.ovs_db_file) or gArgs.keep_db == False:
    print "Initializing DB @ %s" % (gArgs.ovs_db_file)
    if os.path.exists(gArgs.ovs_db_file) and not gArgs.dry:
        os.remove(gArgs.ovs_db_file)

    lcall([gArgs.ovsdb_tool, "create", gArgs.ovs_db_file, 
           gArgs.ovs_vswitchd_schema])
else:
    print "Keeping existing DB @ %s" % (gArgs.ovs_db_file)


if not os.path.exists(gArgs.ovs_runtime_dir):
    os.makedirs(gArgs.ovs_runtime_dir)

# Start dbserver
lcall([gArgs.ovsdb_server, gArgs.ovs_db_file, 
       "--remote=punix:%s" % (gArgs.ovs_db_sock), 
       "--detach", "--pidfile=%s" % (gServerPid)])

# Init db
vsctl(["--no-wait", "init"])

# Start vswitchd
startV = [ gArgs.ovs_vswitchd, 
          "unix:%s" % (gArgs.ovs_db_sock), 
          "--verbose", "--detach",
          "--pidfile=%s" % (gSwitchPid) ]

if gArgs.ovs_vswitchd_log:
    startV.append("--log-file=%s" % (gArgs.ovs_vswitchd_log))

lcall(startV)

if gArgs.vlog:
    lcall(["xterm", "-T", "vswitchd-log", "-e", "tail", "-f", 
           gArgs.ovs_vswitchd_log], 
          popen=True, pidFile=gLogPid)


# Add a bridge
vsctl(["add-br", gArgs.bridge])
ofctl(["show", gArgs.bridge])

# Add Veths to bridge
for idx in range(0, gArgs.port_count):
    vsctl(["add-port", gArgs.bridge, "veth%s" % (idx*2)])

# Check if loopback port added
if gArgs.loopback:
    lb_idx = gArgs.port_count * 2
    vsctl(["add-port", gArgs.bridge, "veth%d" % (lb_idx)])
    vsctl(["add-port", gArgs.bridge, "veth%d" % (lb_idx+1)])

# Set controller
vsctl(["set-controller", gArgs.bridge, "tcp:%s:%s" % (
        gArgs.cip, gArgs.cport)])

# Minimize default backoff for controller connections
vsctl(["set", "Controller", gArgs.bridge, 
       "max_backoff=%s" % (gArgs.max_backoff)])


ofctl(["show", gArgs.bridge])


if gArgs.cli:
    while True:
        cmd = raw_input("[%s] ovs-ctl> " % gConfigSection)
        if cmd and cmd != "":
            args = cmd.split(" ")
            if args[0] == "vsctl" or args[0] == "ovs-vsctl":
                vsctl(args[1:])
            elif args[0] == "ofctl" or args[0] == "ovs-ofctl":
                ofctl(args[1:])
            elif args[0] == "exit" or args[0] == "quit":
                break; 
            elif args[0] == "kill":
                gArgs.teardown = True
                break
            else:
                print "unknown command '%s'" % args[0]
            

if gArgs.teardown:
    print "Killing OVS"
    killall()




                        
            
