#!/usr/bin/python2.6

import argparse
import ConfigParser
import hubzero.data.db
import hubzero.utilities.misc
import hubzero.utilities.user
import hubzero.config.webconfig
import os
import random
import re
import string
import distutils.dir_util
import grp
import pwd
import stat
import shutil
import platform

sourceFilesDir = "usr/lib/hubzero/cms"
hubzeroConfigFilePath = "/etc/hubzero.conf"

def checkforroot():
    uid = os.geteuid()
    if uid != 0:
        print 'Script must be run with root privileges'
        exit(1)

def generateAlphaNumPassword(length):
    pw = ''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) for x in range(length-1)) + (random.choice(string.digits))	
    return pw

def createHubzeroSecretsFile(joomlaAdminPW):

    secretsFilename = "/etc/hubzero.secrets"

    # grab what we can when its stored, everything else is stored as hash and needs to be passed in
    hubdbpw = hubzero.config.webconfig.getWebConfigDBPassword()
    ldapadminpw = hubzero.config.webconfig.getComponentParam("com_system", "ldap_managerpw")

    f = open(secretsFilename, "w")
    f.write("[DEFAULT]\n")
    #f.write("LDAP-ADMIN=" + ldapadminpw  + "\n")
    #f.write("HUBREPO=" + hubrepopw  + "\n")
    f.write("HUBDB=" + hubdbpw  + "\n")
    f.write("JOOMLA-ADMIN=" + joomlaAdminPW  + "\n")
    f.close()

    hubzero.utilities.misc.exShellCommand(['chmod', "0600", secretsFilename])


def createHubzeroConfigurationFile(hubname, docroot, uri = "", dbname = ""):
    print "creating: " + hubzeroConfigFilePath

    # For some reason, default section of the ini files can only be created via the constructor
    defaults = {'site':hubname}
    config = ConfigParser.ConfigParser(defaults)
    config.optionxform = str

    config.add_section(hubname)
    config.set(hubname, "HubName", hubname)
    config.set(hubname, "documentroot", docroot)

    if uri: config.set(hubname, "uri", uri)
    if dbname: config.set(hubname, "dbname", dbname)

    cfgfile = open(hubzeroConfigFilePath, 'w')
    config.write(cfgfile)

    hubzero.utilities.misc.exShellCommand(['chown', '/etc/hubzero.conf', '0640'])


def deleteHubFromHubconfigFile(hubname):
    parser = ConfigParser.ConfigParser()
    parser.optionxform = str
    parser.read(hubzeroConfigFilePath)

    if parser.has_option(hubname, "documentroot"):
        parser.remove_section(hubname)

        # if this was the only hub, remove the file. If the removed hub was the default, reset the default hub
        if len(parser.sections()) < 1:
            os.remove(hubzeroConfigFilePath)
        else:

            #print (parser.sections())
            if parser.get("DEFAULT", "site") == hubname:
                newDefault = parser.sections()[0]
                parser.set("DEFAULT", "site", newDefault)

            cfgfile = open(hubzeroConfigFilePath, 'w')
            parser.write(cfgfile)


def insertHubIntoHubConfigFile(hubname, docroot, uri, dbname, makeSiteDefault = False):
    """
    config file /etc/hubzero.conf, a machine wide listing of hubs with the idea
    of supporting multiple hubs someday
    """
    if not os.path.exists(hubzeroConfigFilePath):
        createHubzeroConfigurationFile(hubname, docroot, uri, dbname)
    else:		
        parser = ConfigParser.RawConfigParser()
        parser.optionxform = str

        parser.read(hubzeroConfigFilePath)

        if not parser.has_section(hubname):
            parser.add_section(hubname)

        parser.set(hubname, "HubName", hubname)
        parser.set(hubname, "documentroot", docroot)
        print "uri=" + uri
        print "dbname=" + dbname
        if uri: parser.set(hubname, "uri", uri)
        if dbname: parser.set(hubname, "dbname", dbname)

        if makeSiteDefault:
            parser.set("DEFAULT", "site", hubname)

        cfgfile = open(hubzeroConfigFilePath, 'w')
        parser.write(cfgfile)


def modifyHubConfigFile(sectionName, fieldName, fieldValue):
    """
    Change a config value in the /etc/hubzero-cms/{hubname}.conf file for the specified section and field
    """
    hubname = hubzero.config.webconfig.getDefaultSite()

    configFilename = "/etc/hubzero-cms/" + hubname + ".conf"
    parser = ConfigParser.RawConfigParser()
    parser.optionxform = str

    parser.read(configFilename)

    # make sure section exists, if not add it
    if not parser.has_section(sectionName):
        parser.add_section(sectionName)

    if (fieldValue != None):
        parser.set(sectionName, fieldName, fieldValue)	
    else:
        parser.remove_option(sectionName, fieldName)

    cfgfile = open(configFilename, 'w')
    parser.write(cfgfile)


def copyCMSFiles(src, dest, fileOwner, fileGroup):
    # Do the acutal copy
    distutils.dir_util.copy_tree(src, dest)
    # shutil.copytree(src, dest)

    # recursive set permissions
    hubzero.utilities.misc.exShellCommand(['chown', '-R', fileOwner + '.' + fileGroup, dest])


def createHubconfigurationPHPfile():
    """ Legacy, I know, but some things still use it """

    fileText = """<?php
class HubConfig {
 var $hubLDAPMasterHost = 'ldap://127.0.0.1';
 var $hubLDAPSlaveHosts = '';
 var $hubLDAPBaseDN = '%$hubLDAPBaseDN%';
 var $hubLDAPNegotiateTLS = '0';
 var $hubLDAPSearchUserDN = '%hubLDAPSearchUserDN%';
 var $hubLDAPSearchUserPW = '%hubLDAPSearchUserPW%';
 var $hubLDAPAcctMgrDN = '%hubLDAPAcctMgrDN%';
 var $hubLDAPAcctMgrPW = '%hubLDAPAcctMgrPW%';
 var $ipDBDriver = 'mysql';
 var $ipDBHost = '';
 var $ipDBPort = '';
 var $ipDBUsername = '';
 var $ipDBPassword = '';
 var $ipDBDatabase = '';
 var $ipDBPrefix = '';
 var $hubShortName = '%HUBNAME%';
 var $forgeName = '%HUBNAME% Forge';
 var $forgeURL = 'https://%HOSTNAME%';
 var $forgeRepoURL = 'https://%HOSTNAME%';
 var $svn_user = 'hubrepo';
 var $svn_password = '%FORGEPW%';
 var $hubzero_ipgeo_url = 'http://hubzero.org/ipinfo/v1';
 var $hubzero_ipgeo_key = '_HUBZERO_OPNSRC_V1_';
}
?>"""


    hubname = hubzero.config.webconfig.getDefaultSite()
    docroot = hubzero.config.hubzerositeconfig.getHubzeroConfigOption(hubname, "DocumentRoot")
    
    filePath = docroot + "/hubconfiguration.php"

    print "creating: " + filePath

    # get hubrepo password from hubzero.secrets file, if file is not there, it's blank
    hubzeroSecretsFilename = "/etc/hubzero.secrets"
    if os.path.exists(hubzeroSecretsFilename):
        secretsConfig = ConfigParser.ConfigParser()
        secretsConfig.optionxform = str
        f1 = open(hubzeroSecretsFilename, "r")
        secretsConfig.readfp(f1)
        f1.close()

        if secretsConfig.has_option("DEFAULT", "HUBREPO"):
            forgePW = secretsConfig.get("DEFAULT", "HUBREPO")
        else:
            forgePW = ""
    else:
        forgePW = ""

    hubLDAPAcctMgrDN = hubzero.config.webconfig.getComponentParam("com_system", "ldap_managerdn")
    hubLDAPAcctMgrPW = hubzero.config.webconfig.getComponentParam("com_system", "ldap_managerpw")
    hubLDAPBaseDN = hubzero.config.webconfig.getComponentParam("com_system", "ldap_basedn")	
    hubLDAPSearchUserDN = hubzero.config.webconfig.getComponentParam("com_system", "ldap_searchdn")	
    hubLDAPSearchUserPW = hubzero.config.webconfig.getComponentParam("com_system", "ldap_searchpw")	

    rc, stdOut, stdErr = hubzero.utilities.misc.exShellCommand(["hostname", "--fqdn"])
    hostname = stdOut.strip()

    fileText = fileText.replace("%$hubLDAPBaseDN%", hubLDAPBaseDN)
    fileText = fileText.replace("%hubLDAPAcctMgrDN%", hubLDAPAcctMgrDN)
    fileText = fileText.replace("%hubLDAPAcctMgrPW%", hubLDAPAcctMgrPW)
    fileText = fileText.replace("%HOSTNAME%", hostname)
    fileText = fileText.replace("%FORGEPW%", forgePW)
    fileText = fileText.replace("%HUBNAME%", hubname)
    fileText = fileText.replace("%hubLDAPSearchUserDN%", hubLDAPSearchUserDN)
    fileText = fileText.replace("%hubLDAPSearchUserPW%", hubLDAPSearchUserPW)

    f1 = open(filePath, "w")
    f1.write(fileText)

    rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["chown", "www-data.www-data", filePath])	
    if rc: print procStdErr

    rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["chmod", "0644", filePath])	
    if rc: print procStdErr



def createHubConfigFile(hubname):
    """home
    config file /etc/hubzero-cms/{hubname}.conf 
    """

    print "creating /etc/hubzero-cms/" + args.hubname + ".conf"

    createDir("/etc/hubzero-cms/", "0755", "root", "root", resetattrs=True)
    createDir("/etc/hubzero-cms/" + hubname + "/", "0755", "root", "root", resetattrs=True)

    # For some reason, DEFAULT section of the ini files can only be created via the constructor
    defaults = {}
    config = ConfigParser.ConfigParser(defaults)
    config.optionxform = str

    config.add_section("global")
    config.set("global", "name", hubname)

    config.add_section("apache-config")
    config.set("apache-config", "document_root", "/var/www/" + hubname)
    config.set("apache-config", "force_canon", "false")
    config.set("apache-config", "enable_webdav", "false")
    config.set("apache-config", "enable_filexfer", "false")
    config.set("apache-config", "enable_subversion", "false")
    config.set("apache-config", "enable_trac", "false")
    config.set("apache-config", "enable_vncproxy", "false")

    config.add_section("mw")
    config.add_section("package-config")

    filename = "/etc/hubzero-cms/" + hubname + ".conf"
    cfgfile = open(filename, 'w')
    config.write(cfgfile)

    hubzero.utilities.misc.exShellCommand(['chmod', filename, '0644'])

def deleteHubConfigFile(hubname):
    pass

def createFile(filename, mode=-1, owner=-1, group=-1, resetattrs=False, verbose=True):
    try:
        ownerUid = int(owner,0)
        if ownerUid == -1:
            owner = "-1"
        else:
            owner = pwd.getpwuid(ownerUid).pw_name
    except ValueError:
        ownerUid = pwd.getpwnam(owner).pw_uid

    try:
        ownerGid = int(group,0)
        if ownerGid == -1:
            group = "-1"
        else:
            group = grp.getgrid(ownerGid).gr_name
    except ValueError:
        ownerGid = grp.getgrnam(group).gr_gid

    try:
        nmode = int(mode,0)
    except TypeError:
        nmode = mode

    if nmode == -1:
        mode = "-1"

    if verbose:
        print "checking: " + filename

    if not os.path.exists(filename):
        if verbose:
           print "create " + filename
        open(filename,"a").close()
        resetattrs = True

    if (resetattrs):
        st = os.stat(filename)

        if ownerGid != -1 and ownerUid != -1 and ownerGid != st.st_gid and ownerUid != st.st_uid:
            if verbose:
                print "chown " +  owner + ":" + group + " " + filename
            os.chown(filename, ownerUid, ownerGid)
        elif ownerUid != -1 and ownerUid != st.st_uid:
            if verbose:
                print "chown " +  owner + " " + filename
            os.chown(filename, ownerUid, -1)
        elif ownerGid != -1 and ownerGid != st.st_gid:
            if verbose:
                print "chown " + ":" + group + " " + filename
            os.chown(filename, -1, ownerGid)

        if nmode != -1 and stat.S_IMODE(st.st_mode) != nmode:
            if verbose:
                print "chmod %#o" % nmode + " " + filename
            os.chmod(filename, nmode)


def createDir(dirName, mode=-1, owner=-1, group=-1, resetattrs=False, verbose=True):
    try:
        if isinstance(owner, (int,long)):
            ownerUid = owner
        else:
            ownerUid = int(owner,0)
        if ownerUid == -1:
            owner = "-1"
        else:
            owner = pwd.getpwuid(ownerUid).pw_name
    except ValueError:
        ownerUid = pwd.getpwnam(owner).pw_uid

    try:
        if isinstance(group, (int,long)):
            ownerGid = group
        else:
            ownerGid = int(group,0)
        if ownerGid == -1:
            group = "-1"
        else:
            group = grp.getgrgid(ownerGid).gr_name
    except ValueError:
        ownerGid = grp.getgrnam(group).gr_gid

    try:
        nmode = int(mode,0)
    except TypeError:
        nmode = mode
    
    if nmode == -1:
        mode = "-1"

    if verbose:
        print "checking: " + dirName

    if not os.path.exists(dirName):
        if verbose:
           print "mkdir " + dirName
        os.mkdir(dirName)
        resetattrs = True
    
    if (resetattrs):
        st = os.stat(dirName)

        if ownerGid != -1 and ownerUid != -1 and ownerGid != st.st_gid and ownerUid != st.st_uid:
            if verbose:
                print "chown " +  owner + ":" + group + " " + dirName
            os.chown(dirName, ownerUid, ownerGid)
        elif ownerUid != -1 and ownerUid != st.st_uid:
            if verbose:
                print "chown " +  owner + " " + dirName
            os.chown(dirName, ownerUid, -1)
        elif ownerGid != -1 and ownerGid != st.st_gid:
            if verbose:
                print "chown " + ":" + group + " " + dirName
            os.chown(dirName, -1, ownerGid)

        if nmode != -1 and stat.S_IMODE(st.st_mode) != nmode:
            if verbose:
                print "chmod %#o" % nmode + " " + dirName
            os.chmod(dirName, nmode)

def checkDirectories(docroot):
    createDir("/etc/hubzero-cms/", "0775", "root", "root", resetattrs=True)

    createDir("/var/log/hubzero-cms", "0775", "root", "www-data", resetattrs=True)
    createDir("/var/log/hubzero-cms/daily", "0770", "root", "www-data", resetattrs=True)
    createDir("/var/log/hubzero-cms/daily/imported", "0770", "root", "www-data", resetattrs=True)
    createDir("/var/log/hubzero-cms/archive", "0770", "root", "www-data", resetattrs=True)

    createDir("/var/log/apache2", "0750", "root", "adm", resetattrs=True)
    createDir("/var/log/apache2/daily", "0750", "root", "adm", resetattrs=True)
    createDir("/var/log/apache2/imported", "0750", "root", "adm", resetattrs=True)
    createDir("/var/log/apache2/archive", "0750", "root", "adm", resetattrs=True)

    createDir(docroot, "0775", "www-data", "www-data", resetattrs=True)


def m4Processing(inputFileName, outputFileName, m4ArgsArray, mode=-1, owner=-1, group=-1, resetattrs=False, verbose=True):
    try:
        ownerUid = int(owner,0)
        if ownerUid == -1:
            owner = "-1"
        else:
            owner = pwd.getpwuid(ownerUid).pw_name
    except ValueError:
        ownerUid = pwd.getpwnam(owner).pw_uid

    try:
        ownerGid = int(group,0)
        if ownerGid == -1:
            group = "-1"
        else:
            group = grp.getgrid(ownerGid).gr_name
    except ValueError:
        ownerGid = grp.getgrnam(group).gr_gid

    try:
        nmode = int(mode,0)
    except TypeError:
        nmode = mode

    if nmode == -1:
        mode = "-1"

    filename = outputFileName

    if verbose:
        print "checking " + inputFileName

    commandArgsArray = ["m4"] + m4ArgsArray + [inputFileName]
    rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(commandArgsArray)

    configtxt = ''

    if os.path.exists(filename):
        f = open(filename, 'r')
        configtxt = f.read()
        f.close()
    else:
        resetattrs = True

    if (configtxt != procStdOut):
        if (verbose):
            print "m4 " + inputFileName
        f = open(filename, 'w')
        f.write(procStdOut)
        f.close()

    if (resetattrs):
        st = os.stat(filename)

        if ownerGid != -1 and ownerUid != -1 and ownerGid != st.st_gid and ownerUid != st.st_uid:
            if verbose:
                print "chown " +  owner + ":" + group + " " + filename
            os.chown(filename, ownerUid, ownerGid)
        elif ownerUid != -1 and ownerUid != st.st_uid:
            if verbose:
                print "chown " +  owner + " " + filename
            os.chown(filename, ownerUid, -1)
        elif ownerGid != -1 and ownerGid != st.st_gid:
            if verbose:
                print "chown " + ":" + group + " " + filename
            os.chown(filename, -1, ownerGid)

        if nmode != -1 and stat.S_IMODE(st.st_mode) != nmode:
            if verbose:
                print "chmod %#o" % nmode + " " + filename
            os.chmod(filename, nmode)

def mySQLDatabaseSetup(dbName, dbPW = ""):

    if dbPW == "":
        dbPW = generateAlphaNumPassword(10)

    print "Creating mySQL databases"

    # TODO SQL native calls for these
    # TODO check to see if database is running

    # primary database
    print "Creating database: " + dbName
    rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["/usr/bin/mysql", 
                                                                        "--defaults-file=/etc/mysql/debian.cnf", 
                                                                        "-e", "CREATE DATABASE " + dbName])
    if procStdOut: print procStdOut.strip()
    if rc : print procStdErr

    # metrics database
    print "Creating database: " + dbName + "-metrics"
    rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["/usr/bin/mysql", 
                                                                        "--defaults-file=/etc/mysql/debian.cnf", 
                                                                        "-e", "CREATE DATABASE " + dbName + "_metrics;"])
    if procStdOut: print procStdOut.strip()
    if rc : print procStdErr

    # Create user with full permissions
    print "Creating database user: " + dbName
    rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["/usr/bin/mysql", 
                                                                        "--defaults-file=/etc/mysql/debian.cnf",
                                                                        "-e", "GRANT ALL PRIVILEGES ON " + dbName + ".* TO " + dbName + "@localhost"])
    if procStdOut: print procStdOut.strip()
    if rc : print procStdErr

    print "Setting database password for user: " + dbName
    rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["/usr/bin/mysql", 
                                                                        "--defaults-file=/etc/mysql/debian.cnf",
                                                                        "-e", "SET PASSWORD FOR " + dbName + "@localhost = PASSWORD('" + dbPW + "'); flush privileges;"])
    if procStdOut: print procStdOut.strip()
    if rc : print procStdErr

    # return database host, database name, database username, and database pw
    # Most of these are known before this function call, but that could change
    return 'localhost', dbName, dbName, dbPW


def generateLogRotateFiles(hubname):

    sfilename = "/usr/share/hubzero-cms/conf/logrotate-cmsdebug.m4"
    tfilename = "/etc/logrotate.d/" + hubname + "-cmsdebug"
    print sfilename + " to " + tfilename
    m4Processing(sfilename, tfilename, ["-DHUBNAME=" + hubname], 0644, "root", "root", resetattrs=True)	

    sfilename = "/usr/share/hubzero-cms/conf/logrotate-cmsauth.m4"
    tfilename = "/etc/logrotate.d/" + hubname + "-cmsauth"
    print sfilename + " to " + tfilename
    m4Processing(sfilename, tfilename, ["-DHUBNAME=" + hubname], 0644, "root", "root", resetattrs=True)	

    sfilename = "/usr/share/hubzero-cms/conf/logrotate-hub-access.m4"
    tfilename = "/etc/logrotate.d/" + hubname + "-access"
    print sfilename + " to " + tfilename
    m4Processing(sfilename, tfilename, ["-DHUBNAME=" + hubname], 0644, "root", "root", resetattrs=True)	

    sfilename = "/usr/share/hubzero-cms/conf/logrotate-hub-error.m4"
    tfilename = "/etc/logrotate.d/" + hubname + "-error"
    print sfilename + " to " + tfilename
    m4Processing(sfilename, tfilename, ["-DHUBNAME=" + hubname], 0644, "root", "root", resetattrs=True)	

    try:
        pattern1 = r'(?im)^\s*/var/log/apache2/\*.log\s+{\s*$'
        repl1 = r'/var/log/apache2/access.log /var/log/apache2/ssl_access.log /var/log/apache2/error.log /var/log/apache2/other_vhosts_access.log {'

        apache2lr = "/etc/logrotate.d/apache2"
        apache2lrfh = open(apache2lr,'r+')
        apache2lrtxt = apache2lrfh.read()
        txt = re.sub(pattern1, repl1, apache2lrtxt)
        if (txt != apache2lrtxt):
            apache2lrfh.seek(0)
            apache2lrfh.write(txt)
            apache2lrfh.close()
            print "Patched file: " + apache2lr
    except:
        print "Failed to patch file: " + apache2lr
        pass

def generateApacheConfFiles(hubname):

    if not os.path.exists("/etc/apache2/sites-m4"):
        print "Creating /etc/apache2/sites-m4"
        createDir("/etc/apache2/sites-m4", "0755", "root", "root", resetattrs=True)

    # copy over the base template files
    print "Copying /usr/share/hubzero-cms/conf/hub.m4 to /etc/apache2/sites-m4/" + hubname + ".m4"
    hubzero.utilities.misc.exShellCommand(["cp", "/usr/share/hubzero-cms/conf/hub.m4", "/etc/apache2/sites-m4/" + hubname + ".m4"])
    hubzero.utilities.misc.exShellCommand(['chmod', "'", "/etc/apache2/sites-m4/" + hubname + ".m4"])
    hubzero.utilities.misc.exShellCommand(['chown', "root.root", "/etc/apache2/sites-m4/" + hubname + ".m4"])

    print "Copying /usr/share/hubzero-cms/conf/hub-ssl.m4 to /etc/apache2/sites-m4/" + hubname + "-ssl.m4"
    hubzero.utilities.misc.exShellCommand(["cp", "/usr/share/hubzero-cms/conf/hub-ssl.m4", "/etc/apache2/sites-m4/" + hubname + "-ssl.m4"])
    hubzero.utilities.misc.exShellCommand(['chmod', "0644", "/etc/apache2/sites-m4/" + hubname + "-ssl.m4"])
    hubzero.utilities.misc.exShellCommand(['chown', "root.root", "/etc/apache2/sites-m4/" + hubname + "-ssl.m4"])

    # do the M4 processing
    generateApacheM4config(hubname)


def generateApacheM4config(hubname):

    # Read the options from the /etc/hubzero-cms/{HUBNAME}.conf file to see what to enable in our apache config
    hubzeroCMSConfig = ConfigParser.ConfigParser()
    hubzeroCMSConfig.optionxform = str
    hubzeroCMSConfig.readfp(open("/etc/hubzero-cms/" + hubname + ".conf"))

    m4ApacheConfigOptions = []

    rc, stdOut, stdErr = hubzero.utilities.misc.exShellCommand(["hostname", "--fqdn"])
    fqdn = stdOut.strip()
    m4ApacheConfigOptions.append("-DFQDN=" + fqdn)

    m4ApacheConfigOptions.append("-DHUBNAME=" + hubname)

    if hubzeroCMSConfig.get("apache-config", "force_canon").lower() == "true":
        m4ApacheConfigOptions.append("-DUSE_CANONICAL_HOSTNAME")

    if hubzeroCMSConfig.get("apache-config", "enable_webdav").lower() == "true":
        m4ApacheConfigOptions.append("-DUSE_WEBDAV")

    if hubzeroCMSConfig.get("apache-config", "enable_filexfer").lower() == "true":
        m4ApacheConfigOptions.append("-DUSE_FILEXFER")

    if hubzeroCMSConfig.get("apache-config", "enable_subversion").lower() == "true":
        m4ApacheConfigOptions.append("-DUSE_SUBVERSION")

    if hubzeroCMSConfig.get("apache-config", "enable_trac").lower() == "true":
        m4ApacheConfigOptions.append("-DUSE_TRAC")

    if hubzeroCMSConfig.get("apache-config", "enable_vncproxy").lower() == "true":

        dbPW = hubzero.config.webconfig.getWebConfigDBPassword()
        dbUserName = hubzero.config.webconfig.getWebConfigDBUsername()
        dbName = hubzero.config.webconfig.getWebConfigDBName()
        dbHost = hubzero.config.webconfig.getWebConfigOption("host")

        if dbHost: m4ApacheConfigOptions.append("-DDBHOST=" + dbHost)
        if dbUserName: m4ApacheConfigOptions.append("-DDBUSER=" + dbUserName)
        if dbPW: m4ApacheConfigOptions.append("-DDBPASS=" + dbPW)
        if dbName: m4ApacheConfigOptions.append("-DDBNAME=" + dbName)

        m4ApacheConfigOptions.append("-DUSE_VNCPROXY")

    basedn = hubLDAPBaseDN = hubzero.config.webconfig.getComponentParam("com_system", "ldap_basedn")
    if basedn: m4ApacheConfigOptions.append("-DBASEDN=" + basedn)

    ldap_searchdn = hubLDAPBaseDN = hubzero.config.webconfig.getComponentParam("com_system", "ldap_searchdn")
    if ldap_searchdn : m4ApacheConfigOptions.append("-DSEARCHDN=" + ldap_searchdn)

    ldap_searchpw = hubLDAPBaseDN = hubzero.config.webconfig.getComponentParam("com_system", "ldap_searchpw")
    if ldap_searchpw: m4ApacheConfigOptions.append("-DSEARCHPW=" + ldap_searchpw)

    if not os.path.exists("/etc/apache2/sites-m4"):
        print "/etc/apache2/sites-m4 doesn't exist, skipping m4 reconfiguration"	
    else:
        m4Processing("/etc/apache2/sites-m4/" + hubname + ".m4", 
                     "/etc/apache2/sites-available/" + hubname, 
                     m4ApacheConfigOptions, 
                     0644, "root", "root", resetattrs=True)

        m4Processing("/etc/apache2/sites-m4/" + hubname + "-ssl.m4", 
                     "/etc/apache2/sites-available/" + hubname + "-ssl", 
                     m4ApacheConfigOptions, 
                     0644, "root", "root", resetattrs=True)


def loadSQLSchema(hubname, dbHost, dbName, dbUserName, dbPW, dbTablePrefix = 'jos_'):
    """
    Load the hubzero schema sql and execute. Logic parses the file into individual statements
    """

    dbsqlfile = open("/usr/share/hubzero-cms/cms/installation/sql/mysql/hubzero.sql", "r")
    dbsql = dbsqlfile.read()

    # split file into individual statementsstatements
    dbsql = re.sub("\n\#[^\n]*", "", "\n" + dbsql)

    sqlSplitter = re.compile("\n\n", re.MULTILINE)
    sqlStatements = sqlSplitter.split(dbsql)

    # execute each statement separately
    db = hubzero.data.db.MySQLConnection(dbHost, dbName, dbUserName, dbPW)	
    for sqlStatement in sqlStatements:
        if sqlStatement.strip() != "" :
            sqlStatement = string.replace(sqlStatement, "#__", dbTablePrefix)
            db.query_rowcount(sqlStatement, None)	


def loadSQLTableData(hubname, dbHost, dbName, dbUserName, dbPW, dbTablePrefix = 'jos_'):
    """
    Load the hubzero sample data
    """
    dbsqldatafile = open("/usr/share/hubzero-cms/cms/installation/sql/mysql/hz_sample_data.sql", "r")
    sql = dbsqldatafile.read()

    # replace the table prefixes
    sql = string.replace(sql, "#__", dbTablePrefix)

    db = hubzero.data.db.MySQLConnection(dbHost, dbName, dbUserName, dbPW)	
    db.query_rowcount(sql, None)


def createPHPConfigurationFile(hubname, docroot, dbName, dbPW, dbTablePrefix, siteAdminEmail, siteAdminName, mailFrom, installKey, fileOwner, fileGroup):
    """
    Take the template and do all the needed replacements and write file to disk
    """

    if not os.path.exists("/usr/share/hubzero-cms/cms/installation/template/tmpl/configuration.html"):
        print "cannot find /usr/share/hubzero-cms/cms/installation/template/tmpl/configuration.html"
        return 1

    configfile = open("/usr/share/hubzero-cms/cms/installation/template/tmpl/configuration.html", "r")
    configfileText =  configfile.read()
    configfile.close()

    # do all the replacements and substitutions
    configfileText = re.sub(re.compile("<jtmpl:comment>.*</jtmpl:comment>\n\n", re.MULTILINE | re.DOTALL), "", configfileText)
    configfileText = configfileText.replace('<jtmpl:tmpl name="configuration">', '')	
    configfileText = configfileText.replace('</jtmpl:tmpl>', "")	

    configfileText = configfileText.replace("{VAR_OFFLINE|addslashes}", "This site is down for maintenance. Please check back again soon.")
    configfileText = configfileText.replace("{VAR_SITENAME|addslashes}", hubname) # note this currently does TWO separate replacements
    configfileText = configfileText.replace("{VAR_DBTYPE|addslashes}", "mysql")
    configfileText = configfileText.replace("{VAR_DBHOSTNAME|addslashes}", "localhost")
    configfileText = configfileText.replace("{VAR_DBPASSWORD|addslashes}", dbPW)
    configfileText = configfileText.replace("{VAR_DBNAME|addslashes}", dbName)
    configfileText = configfileText.replace("{VAR_DBUSERNAME|addslashes}", hubname)
    configfileText = configfileText.replace("{VAR_DBPREFIX|addslashes}", dbTablePrefix)
    configfileText = configfileText.replace("{VAR_SECRET|addslashes}", generateAlphaNumPassword(10))
    configfileText = configfileText.replace("{VAR_HELPURL|addslashes}", "http://help.joomla.org")
    configfileText = configfileText.replace("{VAR_FTPHOST|addslashes}", "127.0.0.1")
    configfileText = configfileText.replace("{VAR_FTPPORT|addslashes}", "21")
    configfileText = configfileText.replace("{VAR_FTPUSER|addslashes}", "")
    configfileText = configfileText.replace("{VAR_FTPPASSWORD|addslashes}", "")
    configfileText = configfileText.replace("{VAR_FTPROOT|addslashes}", "")
    configfileText = configfileText.replace("{VAR_FTPENABLE|intval}", "0")
    configfileText = configfileText.replace("{VAR_ADMINEMAIL|addslashes}", mailFrom)
    configfileText = configfileText.replace("{VAR_METADESC|addslashes}", "Joomla! - the dynamic portal engine and content management system")
    configfileText = configfileText.replace("{VAR_METAKEYS|addslashes}", "joomla, Joomla")
    configfileText = configfileText.replace("{VAR_LOG_PATH|addslashes}", docroot + "/logs")
    configfileText = configfileText.replace("{VAR_TMP_PATH|addslashes}", docroot + "/tmp")

    configFilePath = docroot + "/configuration.php"

    configfile = open(configFilePath, 'w')
    configfile.write(configfileText)
    configfile.close()

    hubzero.utilities.misc.exShellCommand(['chmod', "0664", configFilePath])
    hubzero.utilities.misc.exShellCommand(['chown', fileOwner + "." + fileGroup, configFilePath])	


def reconfigureHub(args):
    print "Reconfigure " + args.hubname
    generateApacheM4config(args.hubname)
    generateLogRotateFiles(args.hubname)


def installHub(args):

    if validateArgs(args) != 0:
        return 1

    hubname = args.hubname

    # we'll need the hostname in a couple of spots
    rc, stdOut, stdErr = hubzero.utilities.misc.exShellCommand(["hostname", "--fqdn"])
    hostname = stdOut.strip()

    # docroot is where the www directory will go
    if not os.path.exists(args.docroot):
        print "ERROR - docroot (" + docroot + ") does not exist"
        return 1

    docroot = args.docroot + "/" + hubname

    if os.path.exists(docroot):
        print "ERROR - install location (" + docroot + ") already exists"
        return 1

    # if install key was provided, validate
    if args.installkey:
        p = re.compile("^[a-zA-Z0-9]+$")
        m = p.match(args.installkey)

        if not m:
            print "install key invalid - must be alphanumeric"
            return(1)
        else:
            if len(args.installkey) < 8 :
                print "installkey must have length of at least 8"
                return(1)
            else:
                print "installkey key ok"

    # Debian or RH?
    if hubzero.utilities.misc.isDebian():
        print "Debain install"
        wwwOwner = 'www-data'
        wwwGroup = 'www-data'

    if hubzero.utilities.misc.isRHEL():
        print "RHEL install"
        wwwOwner = 'apache'

    # Todo, offer upgrade functionality, for now, exit the install if the secrets file alread exists
    if os.path.exists('/etc/hubzero.secrets'):
        print 'looks like this is not a fresh install, /etc/hubzero.secrets file present'
        return(1)

    print "Copying CMS files from /usr/share/hubzero-cms/cms/ to " + docroot
    copyCMSFiles("/usr/share/hubzero-cms/cms/", docroot, wwwOwner, wwwGroup)

    print "Creating /etc/hubzero.conf entry"
    if (args.uri == None):
        uri = "http://" + hostname
    else:
        uri = args.uri

    if (args.dbname == None):
        dbname = hubname
    else:
        dbname = args.dbname

    insertHubIntoHubConfigFile(hubname, docroot, uri, dbname, True)

    # check various installation directories and create if necessary
    checkDirectories(docroot)

    # do substitutions for the configuraiton.php file from the template and write out
    print "creating: configuration.php"
    dbPW = generateAlphaNumPassword(10)
    installKey = generateAlphaNumPassword(10)

    if args.mailfrom == "":
        args.mailfrom = "webmaster@" + hostname

    createPHPConfigurationFile(hubname, 
                               docroot, 
                               hubname, 
                               dbPW, 
                               args.dbprefix, 
                               args.siteadminemail, 
                               args.siteadminfirstname + ' ' + args.siteadminlastname,
                               args.mailfrom,
                               installKey,
                               "www-data",
                               "www-data")	

    createHubConfigFile(hubname)

    generateLogRotateFiles(hubname)

    # setup the databases
    print "Setting up the databases"
    dbHost, dbName, dbUserName, dbPW = mySQLDatabaseSetup(hubname, dbPW)

    print "Creating database schema"
    loadSQLSchema(hubname, "localhost", dbName, dbUserName, dbPW, args.dbprefix)

    print "Loading default data into database"
    loadSQLTableData(hubname, "localhost", dbName, dbUserName, dbPW, args.dbprefix)	

    # config apache
    print "enabling apache mod rewrite"
    rc, stdOut, stdErr = hubzero.utilities.misc.exShellCommand(["a2enmod", "rewrite"])
    print stdOut.strip()
    if rc: print stdErr

    print "enabling apache mod ssl"
    rc, stdOut, stdErr  = hubzero.utilities.misc.exShellCommand(["a2enmod", "ssl"])
    print stdOut.strip()
    if rc: print stdErr

    generateApacheConfFiles(hubname)

    # add joomla admin user
    if not args.promptsiteadminpw:
        adminpw = generateAlphaNumPassword(10)
    else:
        adminpw = pw = raw_input("Enter an password for your website admin user")

    # create home directory for the hub
    hubHomeDir = "/home/" + hubname
    print "creating " + hubHomeDir
    rc, stdOut, stdErr = hubzero.utilities.misc.exShellCommand(["mkdir", hubHomeDir])
    if stdOut: print stdOut.strip()
    if rc: print stdErr

    # create apache conf.d directory for the hub
    confDir = "/etc/apache2/" + hubname + ".conf.d"
    print "creating " + confDir
    rc, stdOut, stdErr = hubzero.utilities.misc.exShellCommand(["mkdir", confDir])
    if stdOut: print stdOut.strip()
    if rc: print stdErr
    rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["chown", "root:root", confDir])	
    if rc: 
        print procStdErr
    rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["chmod", "0755", confDir])	
    if rc: 
        print procStdErr

    # create hub admin account
    print "Adding site admin account"

    hubzero.utilities.user.addhubuser(args.hubname,
                                      'admin', 
                                      'webmaster@' + hostname,
                                      adminpw,
                                      gecos="CMS Manager",
                                      joomlagidNumber=25,
                                      uidNumber=1000, 
                                      skipCreateLDAPUser = True,
                                      skipCreateGroup = True)	

    #create /srv/hubname (www-data:www-data 0770)
    createDir("/srv/" + args.hubname, '0770', 'www-data', 'www-data', resetattrs=True)

    #create /srv/hubname/projects (www-data:www-data 0770)
    createDir("/srv/" + args.hubname + "/projects", '0770', 'www-data', 'www-data', resetattrs=True)	

    #set the webpath parameter in params in the com_projects component entry to '/srv/hubname/projects'	
    hubzero.config.webconfig.addComponentParam('com_projects', 'webpath', '/srv/' + args.hubname + '/projects')

    print "restarting web server"
    rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["/etc/init.d/apache2", "restart"])	
    if rc: print procStdErr

    if args.createsecretsfile:
        createHubzeroSecretsFile(adminpw)

    # usr/bin/textifier exists enable textifier
    if os.path.exists("/usr/bin/textifier"):
        print "enabling textifier"
        textifierConfigure(True)

    # if mailgateway installed, enable mailgateway 
    if os.path.exists("/usr/lib/hubzero/bin/mailproc/mailproc.py"):
        print "enabling mailgateway"
        mailgateway(True)

    # Summary messages at end of install
    print "\nInstallation Complete"
    print "Your web docroot is: " + docroot
    print "Your database host is: " + dbHost
    print "Your database name is: " + dbName
    print "Your database username is: " + dbUserName
    print "Your database password is: " + dbPW
    print "Your installation key is: " + installKey
    print "Your web admin password is " + adminpw

    return(0)


def configHubFile(args):
    configFilename = "/etc/hubzero-cms/" + args.hubname + ".conf"

    if not os.path.exists(configFilename):
        print "Cannot find config file " + configFilename
        return(1)

    config = ConfigParser.RawConfigParser()
    config.optionxform = str
    config.read(configFilename)

    # = means we are setting, otherwise we're retrieving 
    if "=" in args.option:
        option, value = args.option.split("=")
        config.set(args.section, option, value)

        with open(configFilename, 'wb') as configfile:
            config.write(configfile)
    else:
        rv = config.get(args.section, args.option)
        print rv


def uninstallHub(args):
    hubname = args.hubname


    # reconcile /etc/hubzero.conf (remove hubname section, reassign default if it was set to value hubname)
    deleteHubFromHubconfigFile(hubname)

    if os.path.exists("/etc/hubzero-cms/" + hubname + ".conf"): os.remove("/etc/hubzero-cms/" + hubname + ".conf")
    if os.path.exists("/etc/logrotate.d/" + hubname + "-cmsauth"): os.remove("/etc/logrotate.d/" + hubname + "-cmsauth")
    if os.path.exists("/etc/logrotate.d/" + hubname + "-cmsdebug"): os.remove("/etc/logrotate.d/" + hubname + "-cmsdebug")
    if os.path.exists("/etc/logrotate.d/" + hubname + "-access"): os.remove("/etc/logrotate.d/" + hubname + "-access")
    if os.path.exists("/etc/logrotate.d/" + hubname + "-error"): os.remove("/etc/logrotate.d/" + hubname + "-error")
    if os.path.exists("/etc/apache2/sites-m4/" + hubname + ".m4"): os.remove("/etc/apache2/sites-m4/" + hubname + ".m4") 
    if os.path.exists("/etc/apache2/sites-available/" + hubname): os.remove("/etc/apache2/sites-available/" + hubname) 
    if os.path.exists("/etc/apache2/sites-m4/" + hubname + "-ssl.m4"): os.remove("/etc/apache2/sites-m4/" + hubname + "-ssl.m4")
    if os.path.exists("/etc/apache2/sites-available/" + hubname + "-ssl"): os.remove("/etc/apache2/sites-available/" + hubname + "-ssl")

    if os.path.exists("/etc/apache2/sites-enabled/" + hubname + "-ssl"):
        os.remove("/etc/apache2/sites-enabled/" + hubname + "-ssl")

    if os.path.exists("/etc/apache2/sites-enabled/" + hubname):
        os.remove("/etc/apache2/sites-enabled/" + hubname)

    print "You must manually delete /var/www/" + hubname
    print "You must manually delete /var/log/hubzero-cms/" + hubname + "-cmsdebug.log"
    print "You must manually delete /var/log/hubzero-cms/" + hubname + "-cmsauth.log"
    print "You must manually delete /var/log/apache2/" + hubname + "-access.log"
    print "You must manually delete /var/log/apache2/" + hubname + "-error.log"
    print "You must manually delete /home/" + hubname 
    print "You must manually delete /etc/apache2/" + hubname + ".conf.d/" 

    # remove database user
    print "Removing database user: " + hubname
    rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["/usr/bin/mysql", 
                                                                        "--defaults-file=/etc/mysql/debian.cnf",
                                                                        "-e", "DROP USER " + hubname + '@localhost'])
    if procStdOut: print procStdOut.strip()
    if rc : print procStdErr

    # remove databases
    print "Removing database: " + hubname
    rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["/usr/bin/mysql", 
                                                                        "--defaults-file=/etc/mysql/debian.cnf",
                                                                        "-e", "DROP DATABASE " + hubname])
    if procStdOut: print procStdOut.strip()
    if rc : print procStdErr

    print "Removing database: " + hubname + "_metrics"
    rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["/usr/bin/mysql", 
                                                                        "--defaults-file=/etc/mysql/debian.cnf",
                                                                        "-e", "DROP DATABASE " + hubname + "_metrics"])		
    print procStdOut
    if procStdOut: print procStdOut.strip()
    if rc : print procStdErr


def _ldapConfigure(args):
    ldapConfigure(args.enable)

def ldapConfigure(enable):
    print "ldap configure"

    if enable:
        print "Enabling ldap support"
        hubzero.config.webconfig.setPluginEnabled('user', 'ldap', True)
        pw = pwd.getpwnam('admin')
        if pw:
            createDir(pw.pw_dir, '0750', pw.pw_uid, pw.pw_gid, resetattrs=True)    
        modifyHubConfigFile("package-config", 'ldap', 'true')        
    else:
        print "Disabling ldap support"
        hubzero.config.webconfig.setPluginEnabled('user', 'ldap', False)
        modifyHubConfigFile("package-config", 'ldap', 'false')        



def _webdavConfigure(args):
    webdavConfigure(args.enable)

def webdavConfigure(enable):

    hubname = hubzero.config.webconfig.getDefaultSite()	
    filename = '/etc/auto.master'
    filename2 =  '/etc/auto.webdav'

    if enable:
        print "Enabling WebDAV"
        modifyHubConfigFile('apache-config', 'enable_webdav', 'true')

        print "checking /etc/auto.master"
        print "regenerating /etc/auto.master"
        # add line to /etc/auto.master, remove any pre existing line similar to the one below (commented out or not) and add

        if not os.path.exists(filename):
            f1 = open(filename, 'w')
            f1.write("/webdav/home /etc/auto.webdav --timeout=60\n")
            f1.close()			
        else:
            f1 = open(filename, 'r')
            filetext = f1.read()
            f1.close()
            filetext = re.sub("^.*/webdav/home /etc/auto.webdav --timeout=60\n.*$", "", filetext, re.MULTILINE | re.DOTALL)
            filetext += "/webdav/home /etc/auto.webdav --timeout=60\n"
           
            f1 = open(filename, 'w')
            f1.write(filetext)
            f1.close()	

        print "checking /etc/auto.webdav"
        print "rewriting /etc/auto.webdav"
        f2 = open(filename2, 'w')
        f2.write("*  -fstype=usermap,user=www-data,source_user=&,allow_other :/home/" + hubname + "/&")
        f2.close()

        print "checking /etc/modules"
        try:
            modulesfn = "/etc/modules"
            modulesfh = open(modulesfn,"r+")
            modulestxt = modulesfh.read()

            txt = re.sub(r'(?m)^\s*#\s*fuse($|\s+.*$)',r'fuse\1',modulestxt)

            if txt.find('fuse') == -1:
                txt = txt.rstrip() + "\nfuse"

            txt = txt.rstrip() + "\n"
            
            if (txt != modulestxt):
                modulesfh.seek(0)
                modulesfh.write(txt)
                modulesfh.close()
                print "patched " + modulesfn
                    
                print "/sbin/modprobe fuse"
                rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["/sbin/modprobe", "fuse"])  
                print procStdOut
                if rc: print procStdErr 

        except:
            print "Failed to patch file " + modulesfn
            pass

        modifyHubConfigFile("package-config", 'webdav', 'true')        

    else:
        print "Disabling WebDAV"
        modifyHubConfigFile('apache-config', 'enable_webdav', 'false')

        print "checking /etc/auto.master"
        print "regenerating /etc/auto.master"
        f1 = open(filename, 'r')
        filetext = f1.read()
        f1.close()

        filetext = re.sub('^.*/webdav/home /etc/auto.webdav --timeout=60\n.*$', '', filetext)

        f1 = open(filename, 'w')
        f1.write(filetext)
        f1.close()

        print "checking /etc/auto.webdav"
        if os.path.exists("/etc/auto.webdav"):
            print "removing /etc/auto.webdav"
            os.remove(filename2)

        # This would undo /etc/modules, but we leave it unchanged in case something 
        # other than WebDAV also needs it.
        #
        #print "checking /etc/modules"
        #try:
        #    modulesfn = "/etc/modules"
        #    modulesfh = open(modulesfn,"r+")
        #    modulestxt = modulesfh.read()
        #
        #   txt = re.sub(r'(?m)^\s*fuse($|\s+.*$)',r'#fuse\1',modulestxt)
        #   
        #    if (txt != modulestxt):
        #        modulesfh.seek(0)
        #        modulesfh.write(txt)
        #        modulesfh.close()
        #        print "patched " + modulesfn
        #except:
        #    print "Failed to patch file " + modulesfn
        #    pass

                    
    # regenerate the apache config files to use the new option setting
    generateApacheM4config(hubname)

    rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["/etc/init.d/apache2", "restart"])	
    print procStdOut
    if rc: print procStdErr	

    if os.path.exists("/etc/init.d/autofs"):
        rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["/etc/init.d/autofs", "restart"])	
        print procStdOut
        if rc: print procStdErr	
    else:
        print "[ERROR] autofs init.d script missing (autofs not installed?)"

    modifyHubConfigFile("package-config", 'webdav', 'false')

def _tracConfigure(args):
    tracConfigure(args.enable)

def tracConfigure(enable):
    hubname = hubzero.config.webconfig.getDefaultSite()	

    if enable:
        print "Enabling trac"
        modifyHubConfigFile('apache-config', 'enable_trac', 'true')
        createDir("/opt", "0750", "root", "root", resetattrs=True)
        createDir("/opt/trac", "0770", "www-data", "www-data", resetattrs=True)
        createDir("/opt/trac/tools", "0770", "www-data", "www-data", resetattrs=True)		

    else:
        print "Disabling trac"
        modifyHubConfigFile('apache-config', 'enable_trac', 'false')

    # regenerate the apache config files to use the new option setting
    generateApacheM4config(hubname)

    print "/etc/init.d/apache2 restart"
    rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["/etc/init.d/apache2", "restart"])	
    print procStdOut
    if rc: print procStdErr	


def _filexferConfigure(args):
    filexferConfigure(args.enable)

def filexferConfigure(enable):
    hubname = hubzero.config.webconfig.getDefaultSite()	

    if enable:
        print "Enabling filexfer"
        modifyHubConfigFile('apache-config', 'enable_filexfer', 'true')
    else:
        print "Disabling filexfer"
        modifyHubConfigFile('apache-config', 'enable_filexfer', 'false')

    # regenerate the apache config files to use the new option setting
    generateApacheM4config(hubname)

    print "/etc/init.d/apache2 restart"
    rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["/etc/init.d/apache2", "restart"])	
    print procStdOut
    if rc: print procStdErr		


def _forcecanonConfigure(args):
    forcecanonConfigure(args.enable)

def forcecanonConfigure(args):
    hubname = hubzero.config.webconfig.getDefaultSite()	

    if args.enable:
        print "Enabling force_canon"
        modifyHubConfigFile('apache-config', 'force_canon', 'true')
    else:
        print "Disabling force_canon"
        modifyHubConfigFile('apache-config', 'force_canon', 'false')

    # regenerate the apache config files to use the new option setting
    generateApacheM4config(hubname)

    print "restarting web server"

    rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["/etc/init.d/apache2", "restart"])	
    print procStdOut
    if rc: print procStdErr	

def _forgeConfigure(args):
    forgeConfigure(args.enable)

def forgeConfigure(enable):

    hubname = hubzero.config.webconfig.getDefaultSite()	

    if enable:
        print "Enabling hubzero-forge"

        print "checking: user 'apps'"

        if not hubzero.utilities.user.userExists('apps',hubname):
            print "creating: user 'apps'"

            hubzero.utilities.user.addhubuser(hubname,
                                      username = 'apps',
                                      email = 'apps@' + hostname,
                                      grouptype = 0,
                                      pw = '*',
                                      pwdisabled = True,
                                      gecos = 'Applications Manager', 
                                      loginShell = '/bin/bash')

        print "checking: user 'hubrepo'"

        if not hubzero.utilities.user.userExists('hubrepo',hubname):
            print "creating: user 'hubrepo'"

            hubzero.utilities.user.addhubuser(hubname,
                                      username = 'hubrepo', 
                                      email = 'hubrepo@' + hostname,
                                      grouptype = 0,
                                      gecos = 'Repository Manager', 
                                      pw = '*',
                                      loginShell = '/bin/bash',
                                      homeDir = '/home/'+hubname+'/hubrepo')

        # add group 'apps'
        print "checking: 'apps' group"
        if not hubzero.utilities.group.groupExists("apps"):
            print "adding 'apps' group"
            hubzero.utilities.group.addhubgroup("apps", "apps")

        # apps should be in the apps group
        print "checking: 'apps' user in 'apps' group"
        if not hubzero.utilities.group.userInGroup("apps","apps"):
            print "adding 'apps' user to 'apps' group"
            hubzero.utilities.group.addUserToGroup("apps","apps")

        # hubrepo should be in the apps group
        print "checking: 'hubrepo' user in 'apps' group"
        if not hubzero.utilities.group.userInGroup("hubrepo","apps"):
            print "adding 'hubrepo' user to 'apps' group"
            hubzero.utilities.group.addUserToGroup("hubrepo","apps")

        # subversion needs to be enabled for this to work
        print "checking: hubzero-subversion configuration"
        if hubzero.config.webconfig.getHubSiteConfig(hubname, "apache-config", "enable_subversion").lower() != 'true':
            subversionConfigure(True)

        # trac need to be enabled for this to work
        print "checking: hubzero-trac configuration"
        if hubzero.config.webconfig.getHubSiteConfig(hubname, "apache-config", "enable_trac").lower() != 'true':
            tracConfigure(True)

        createDir("/apps", "2775", "apps", "apps", resetattrs=True)

        print "checking: /etc/sudoers.d/hubzero-forge"
        filename = "/etc/sudoers.d/hubzero-forge"
        if not os.path.exists(filename):
            if not os.path.exists("/etc/sudoers.d"):
                os.makedirs("/etc/sudoers.d")

            print "creating: /etc/sudoers.d/hubzero-forge"
            f1 = open(filename, 'w')
            f1.write("www-data\tALL=(apps)NOPASSWD:/usr/bin/finalizetool\n")
            f1.write("www-data\tALL=(apps)NOPASSWD:/usr/bin/installtool\n")
            f1.write("www-data\tALL=(apps)NOPASSWD:/usr/bin/licensetool\n")
            f1.write("www-data\tALL=(root)NOPASSWD:/etc/init.d/apache2\n")	
            f1.close()			
        else:
            f1 = open(filename, 'r')
            filetext = f1.read()
            f1.close()

            print "patching: /etc/sudoers.d/hubzero-forge"
            # remove any possibly commented out lines then add the new lines
            filetext = re.sub(".*www-data\\s+ALL=\\(apps\\)NOPASSWD:/usr/bin/finalizetool\n", "", filetext, re.MULTILINE | re.DOTALL)
            filetext += "www-data\tALL=(apps)NOPASSWD:/usr/bin/finalizetool\n"

            filetext = re.sub(".*www-data\\s+ALL=\\(apps\\)NOPASSWD:/usr/bin/installtool\n", "", filetext, re.MULTILINE | re.DOTALL)
            filetext += "www-data\tALL=(apps)NOPASSWD:/usr/bin/installtool\n"

            filetext = re.sub(".*www-data\\s+ALL=\\(apps\\)NOPASSWD:/usr/bin/licensetool\n", "", filetext, re.MULTILINE | re.DOTALL)
            filetext += "www-data\tALL=(apps)NOPASSWD:/usr/bin/licensetool\n"

            filetext = re.sub(".*www-data\\s+ALL=\\(root\\)NOPASSWD:/etc/init.d/apache2\n", "", filetext, re.MULTILINE | re.DOTALL)
            filetext += "www-data\tALL=(root)NOPASSWD:/etc/init.d/apache2\n"

            f1 = open(filename, 'w')
            f1.write(filetext)
            f1.close()	

        rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["chmod", "0440", "-R", filename])	
        if rc: print procStdErr

        # add hubrepo password to hubzero.secrets file, if file is not there, not sure what to do, just skip for now
        hubzeroSecretsFilename = "/etc/hubzero.secrets"
        repoPW = dbPW = generateAlphaNumPassword(10)

        if os.path.exists(hubzeroSecretsFilename):
            secretsConfig = ConfigParser.ConfigParser()
            secretsConfig.optionxform = str
            f1 = open(hubzeroSecretsFilename, "rw")
            secretsConfig.readfp(f1)
            secretsConfig.set("DEFAULT", "HUBREPO", repoPW)
            f2 = open(hubzeroSecretsFilename, "w")
            secretsConfig.write(f2)
            f1.close()
            f2.close()

        # update hubrepo user passwords
        if hubzero.utilities.user.userExists('hubrepo'):
            print "changing: user 'hubrepo' password"
            hubzero.utilities.user.updateUserPW('hubrepo', repoPW)
        else:
            print "[ERROR] no hubrepo user present, not changing password"

        # create the hubconfiguration.php file
        createHubconfigurationPHPfile()

        modifyHubConfigFile('apache-config', 'enable_forge', 'true')

    else:
        print "Disabling hubzero-forge"
        modifyHubConfigFile('apache-config', 'enable_forge', 'false')

    # TODO	
    # error out if no ldap configured

    # regenerate the apache config files to use the new option setting
    generateApacheM4config(hubname)


def _subversionConfigure(args):
    subversionConfigure(args.enable)

def subversionConfigure(enable):
    hubname = hubzero.config.webconfig.getDefaultSite()	

    if enable:
        print "Enabling subversion"
        modifyHubConfigFile('apache-config', 'enable_subversion', 'true')
        createDir("/opt", "0750", "root", "root", resetattrs=True)
        createDir("/opt/svn", "0770", "www-data", "www-data", resetattrs=True)
        createDir("/opt/svn/tools", "0770", "www-data", "www-data", resetattrs=True)
        createDir("/etc/apache2/" + hubname + ".conf.d", "0755", "root", "root", resetattrs=True)
        createDir("/etc/apache2/" + hubname + ".conf.d/svn", "0700", "www-data", "www-data", resetattrs=True)

    else:
        print "Disabling subversion for hub"
        modifyHubConfigFile('apache-config', 'enable_subversion', 'false')

    if os.path.exists("/etc/apache2/svn.conf"):
        print "Upgrading subversion for hub"
        print "Moving svn.conf to new /etc/apache2/" + hubname + ".conf.d/svn"
        createDir("/etc/apache2/" + hubname + ".conf.d", "0755", "root", "root", resetattrs=True)
        createDir("/etc/apache2/" + hubname + ".conf.d/svn", "0700", "www-data", "www-data", resetattrs=True)
        os.rename("/etc/apache2/svn.conf", "/etc/apache2/" + hubname + ".conf.d/svn/svn.conf")
    if os.path.exists("/etc/apache2/svn.bak"):
        print "Upgrading subversion for hub"
        print "Moving svn.bak to new /etc/apache2/" + hubname + ".conf.d/svn"
        createDir("/etc/apache2/" + hubname + ".conf.d", "0755", "root", "root", resetattrs=True)
        createDir("/etc/apache2/" + hubname + ".conf.d/svn", "0700", "www-data", "www-data", resetattrs=True)
        os.rename("/etc/apache2/svn.bak", "/etc/apache2/" + hubname + ".conf.d/svn/svn.bak")

    # regenerate the apache config files to use the new option setting
    generateApacheM4config(hubname)	

    print "restarting web server"
    rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["/etc/init.d/apache2", "restart"])	
    print procStdOut
    if rc: print procStdErr		


def _vncProxyConfigure(args):
    vncProxyConfigure(args.enable)

def vncProxyConfigure(enable):
    hubname = hubzero.config.webconfig.getDefaultSite()	

    if args.enable:
        print "Enabling vncproxy"
        print "checking: user 'vncproxy'"

        try:
            pwd.getpwnam('vncproxy').pw_uid
        except:
            print "creating: user 'vncproxy'"
            rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["/usr/sbin/useradd","-r",
                "-d","/var/lib/vncproxy","-g","nogroup",'-m',"-s","/bin/false","vncproxy"])  
            print procStdOut
            if rc: print procStdErr 
    
        createDir("/var/log/vncproxy", "0750", "www-data", "adm", resetattrs=True)
        createDir("/var/log/vncproxyd", "0750", "vncproxy", "adm", resetattrs=True)
        modifyHubConfigFile('apache-config', 'enable_vncproxy', 'true')
    else:
        print "Disabling vncproxy"
        modifyHubConfigFile('apache-config', 'enable_vncproxy', 'false')

    # regenerate the apache config files to use the new option setting
    generateApacheM4config(hubname)	

    print "restarting web server"
    rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["/etc/init.d/apache2", "restart"])	
    print procStdOut
    if rc: print procStdErr	

def _mwServiceConfigure(args):
    mwServiceConfigure(args.enable)

def mwServiceConfigure(enable):
    hubname = hubzero.config.webconfig.getDefaultSite()	

    if enable:
        print "Enabling mw-service"
        # turn off disk quota
        vzConfFile = "/etc/vz/vz.conf"	
        if os.path.exists(vzConfFile):
            changed = False
            with open(vzConfFile, "r") as f1:
                vzConfFileText = f1.read()

                # add or replace our needed config option
                if "DISK_QUOTA=yes" in vzConfFileText:
                    vzConfFileText = vzConfFileText.replace("DISK_QUOTA=yes", "DISK_QUOTA=no")
                    changed = True
                else:
                    if not "DISK_QUOTA=no" in vzConfFileText:
                        vzConfFileText += "DISK_QUOTA=no\n"
                        changed = True
            if changed:
                with open(vzConfFile, "w") as f1:
                    print "Turning off disk quota in " + vzConfFile
                    f1.write(vzConfFileText)
        else:
            print vzConfFile + " not found"

        # generate /etc/mw-service/mw-service.conf	
        # @TODO: set_quotas needs this, it should be rewritten to
        # to loop through user list from database and lookup homedirs
        # per user instead of looping through directory.
        confFileName = "/etc/mw-service/mw-service.conf"

        if not os.path.exists(confFileName):
            maxwellConfFileText = (
                "hub_name = \"" + hubname + "\"\n"
                "hub_homedir = \"/home/" + hubname + "\"\n" )

            # write the file
            print "creating " + confFileName
            f3 = open(confFileName, "w")
            f3.write(maxwellConfFileText)
            f3.close()

            rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["chown", "root.www-data", confFileName])	
            if rc: 
                print procStdErr

            rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["chmod", "0640", confFileName])	
            if rc: 
                print procStdErr
        else:
            # @TODO Should use a regex check to find these variables more accurately
            changed = False
            with open(confFileName, "r") as f1:
                maxwellConfFileText = f1.read().rstrip()

                if "hub_name" not in maxwellConfFileText:
                    maxwellConfFileText += "\nhub_name = \"" + hubname + "\""
                    changed = True
                if "hub_homedir" not in maxwellConfFileText:
                    maxwellConfFileText += "\nhub_homedir = \"/home/" + hubname + "\""
                    changed = True

            if changed:
                print "updating " + confFileName
                with open(confFileName, "w") as f1:
                    f1.write(maxwellConfFileText+"\n")

        # some db work	
        # @TODO Should probably use proper fqdn rather than localhost
        dbPW = hubzero.config.webconfig.getWebConfigDBPassword()
        dbUserName = hubzero.config.webconfig.getWebConfigDBUsername()
        dbName = hubzero.config.webconfig.getWebConfigDBName()
        db =  hubzero.data.db.MySQLConnection("localhost", dbName, dbUserName, dbPW)		

        print "Doing mw database configuration"

        sql = "INSERT IGNORE INTO `host` (`hostname`,`provisions`,`status`,`uses`,`portbase`) VALUE ('localhost',14,'down',0,0);"
        db.query_rowcount(sql, None)	

        sql = "UPDATE `host` SET status='up' WHERE hostname='localhost';"
        db.query_rowcount(sql, None)	

        # add group 'network'
        if not hubzero.utilities.group.groupExists("network"):
            print "adding 'network' group"
            hubzero.utilities.group.addhubgroup("network", "network")
        else:
            print "'network' group already exists"

        modifyHubConfigFile("package-config", 'mw-service', 'true')		
    else:
        print "Disabling mw-service"
        # some db work	
        # @TODO Should probably use proper fqdn rather than localhost
        dbPW = hubzero.config.webconfig.getWebConfigDBPassword()
        dbUserName = hubzero.config.webconfig.getWebConfigDBUsername()
        dbName = hubzero.config.webconfig.getWebConfigDBName()
        db =  hubzero.data.db.MySQLConnection("localhost", dbName, dbUserName, dbPW)		

        print "Doing mw database configuration"
        sql = "UPDATE `host` SET status='down' WHERE hostname='localhost';"
        db.query_rowcount(sql, None)	
        modifyHubConfigFile("package-config", 'mw-service', 'false')		
        pass


def _mwClientConfigure(args):
    mwClientConfigure(args.enable)

def mwClientConfigure(enable):
    hubname = hubzero.config.webconfig.getDefaultSite()	

    if enable:
        print "Enabling mw-client"

        modifyHubConfigFile("package-config", 'mw-client', 'true')		

        rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["mkdir", "-p", "/root/.ssh"])	
        if rc: print procStdErr

        # put key in root's authorized keys
        # cat /etc/mw-client/maxwell.key.pub >>  /root/.ssh/authorized_keys

        keyfile = "/etc/mw-client/maxwell.key.pub"
        authkeysfile = "/root/.ssh/authorized_keys"

        f1 = open(keyfile, 'r')
        key = f1.read()
        f1.close()

        # add to file
        if os.path.exists(authkeysfile):

            f2 = open(authkeysfile, 'r')
            keyfileTextOriginal = f2.read()
            f2.close()

            if not key in keyfileTextOriginal:
                print "adding /etc/mw-client/maxwell.key.pub to /root/.ssh/authorized_keys"
                keyfile = open("/root/.ssh/authorized_keys", "a")
                keyfile.write(key)
                keyfile.close()
            else:
                print "key already in /root/.ssh/authorized_keys"

        else: # create file
            print "adding /etc/mw-client/maxwell.key.pub to newly created /root/.ssh/authorized_keys file"
            keyfile = open("/root/.ssh/authorized_keys", "w")
            keyfile.write(key)
            keyfile.close()			

        # generate /etc/mw-client/mw-client.conf	
        dbPW = hubzero.config.webconfig.getWebConfigDBPassword()
        dbUserName = hubzero.config.webconfig.getWebConfigDBUsername()
        dbName = hubzero.config.webconfig.getWebConfigDBName()

        uri = hubzero.config.hubzerositeconfig.getHubzeroConfigOption(hubname, "uri")
        if uri == '':
            uri = "http://" + hostname

        # do /etc/mw-client/mw-clienta.conf file replacements
        # get hostname
        rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["hostname", "--fqdn"])	
        if rc: 
            print procStdErr
            hostname = 'unknown'
        else: 
            hostname  = procStdOut.strip()

        maxwellConfFileText = (
            "mysql_host = \"localhost\"\n"
            "mysql_user=\"" + dbUserName + "\"\n"
            "mysql_password=\"" + dbPW + "\"\n"
            "mysql_db=\"" + dbName + "\"\n"
            "hub_name=\"" + hubname + "\"\n"
            "hub_url=\"" + uri + "\"\n"
            "hub_homedir=\"/home/" + hubname + "\"\n")


        confFileName = "/etc/mw-client/mw-client.conf"
        # write the file
        print "creating " + confFileName
        f3 = open(confFileName, "w")
        f3.write(maxwellConfFileText)
        f3.close()

        rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["chown", "root.www-data", confFileName])	
        if rc: 
            print procStdErr

        rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["chmod", "0640", confFileName])	
        if rc: 
            print procStdErr

        #restart /etc/init.d/expire-sessions
        if os.path.exists("/etc/init.d/expire-sessions"):
            rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["/etc/init.d/expire-sessions", "restart"])
            if rc: print procStdErr
        else:
            print "/etc/init.d/expire-sessions not restarted, file not found"

    else:
        print "Disabling mw for hub"
        modifyHubConfigFile("package-config", 'mw-client', 'false')		



def _textifierConfigure(args):
    textifierConfigure(args.enable)

def textifierConfigure(enable):

    confFileText = """host: localhost
db: %db
user: %user
password: %password
insert: INSERT INTO jos_document_text_data(hash, body) VALUES (%0q,%1q) ON DUPLICATE KEY UPDATE body = %1q
"""	
    if enable:
        dbPW = hubzero.config.webconfig.getWebConfigDBPassword()
        dbUserName = hubzero.config.webconfig.getWebConfigDBUsername()
        dbName = hubzero.config.webconfig.getWebConfigDBName()

        confFileText = confFileText.replace("%db", dbName)
        confFileText = confFileText.replace("%user", dbUserName)
        confFileText = confFileText.replace("%password", dbPW)

        # create /etc/textifier.conf
        textifierConfFile = "/etc/textifier.conf"

        file1 = open(textifierConfFile, "w")
        file1.write(confFileText)	
        os.chmod(textifierConfFile, 0640)

        hubzero.utilities.misc.exShellCommand(['chown', 'www-data.www-data', textifierConfFile])

def _mwMetrics(args):
    mwMetrics(args.enable)

def mwMetrics(enable):
    if enable:
        # some db work

        dbPW = hubzero.config.webconfig.getWebConfigDBPassword()
        dbUserName = hubzero.config.webconfig.getWebConfigDBUsername()
        dbName = hubzero.config.webconfig.getWebConfigDBName()
        db =  hubzero.data.db.MySQLConnection("localhost", dbName, dbUserName, dbPW)		

        print "Doing metrics database configuration"

        sql = 'UPDATE jos_plugins SET published = 0 WHERE folder = "usage";'
        db.query_rowcount(sql, None)	

        sql = 'UPDATE jos_plugins SET published = 1 WHERE folder = "usage" AND element IN ("overview","maps")'
        db.query_rowcount(sql, None)			

        sql = 'UPDATE jos_plugins SET params = "period=14 nchart_path=/site/stats/chart_resources/ nmap_path=/site/stats/resource_maps/" WHERE folder = "resources" AND element = "usage";'
        db.query_rowcount(sql, None)			

        sql = 'UPDATE jos_resource_types SET params="plg_citations=1nplg_questions=1nplg_recommendations=1nplg_related=1nplg_reviews=1nplg_usage=1nplg_versions=1nplg_favorite=1nplg_share=1nplg_wishlist=1nplg_supportingdocs=1" WHERE type="Tools"'
        db.query_rowcount(sql, None)			

    else:
        pass


def _mailgateway(args):
    mailgateway(args.enable)

def mailgateway(enable):

    if enable:
        print "Enabling Mail Gateway"
        pwSalt = generateAlphaNumPassword(16)
        pw = generateAlphaNumPassword(16)
        dbPW = hubzero.config.webconfig.getWebConfigDBPassword()
        dbUserName = hubzero.config.webconfig.getWebConfigDBUsername()
        dbName = hubzero.config.webconfig.getWebConfigDBName()
        confFileName = "/etc/hubmail_gw.conf"
        hubname = hubzero.config.webconfig.getDefaultSite()

        rc, stdOut, stdErr = hubzero.utilities.misc.exShellCommand(["hostname", "--fqdn"])
        hostname = stdOut.strip()

        fileText = """<?php
class HubmailConfig {
 public $user = '%DBUSER%';
 public $password = '%DBPW%';
 public $db = '%DBNAME%';
 public $host = 'localhost';
 public $fromname = '%HUBNAME% Support Team';
 public $mailfrom = 'support@%HOSTNAME%';
 public $sitename = '%HUBNAME%';
 public $email_token_current_version = '1';
 public $email_token_encryption_info_v1 = '%SALT%,%PW%';
 public $hubShortURL = '%HOSTNAME%';
 public $hubLongURL = 'http://%HOSTNAME%';
}
"""
        fileText = fileText.replace("%DBUSER%", dbUserName)
        fileText = fileText.replace("%DBPW%", dbPW)
        fileText = fileText.replace("%DBNAME%", dbName)
        fileText = fileText.replace("%HUBNAME%", hubname)
        fileText = fileText.replace("%HOSTNAME%", hostname)
        fileText = fileText.replace("%SALT%", pwSalt)
        fileText = fileText.replace("%PW%", pw)

        with open(confFileName, "w") as f1:
            f1.write(fileText)

        rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["chown", "www-data.Debian-exim", confFileName])	
        if rc: 
            print procStdErr

        rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["chmod", "0640", confFileName])	
        if rc: 
            print procStdErr
      
        filename = '/etc/default/spamassassin'
        
        print "checking " + filename
        
        if os.path.exists(filename):
            try:
                fh = open(filename, 'r+')
                configtxt = fh.read()
                (txt, count) = re.subn(r'(?im)^\s*ENABLED\s*=\s*.*$', "ENABLED=1", configtxt)

                txt = txt.rstrip() + "\n"

                if (count == 0):
                    txt = txt + "ENABLED=1\n"                

                if (txt != configtxt):
                    fh.seek(0)
                    fh.write(txt)
                    fh.truncate()
                    print "patched file " + filename
                    print "/etc/init.d/spamassassin restart"
                    rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["/etc/init.d/spamassassin", "restart"])
                    print procStdOut
                    if rc: print procStdErr

                fh.close()
            except:
                print "Failed to patch file " + filename
                raise

        else:
            print "/etc/default/spamassassin not found, unable to patch"
            raise

        modifyHubConfigFile("package-config", 'mailgateway', 'true')

    else:
        print "Disabling Mail Gateway"

        # Disable spamassisin, leave on instead in case something else wanted it
        #filename = '/etc/defaults/spamassassin'
        #
        #if os.path.exists(filename):
        #    fh = open(filename, 'r+')
        #    configtxt = fh.read()
        #    (txt, count) = re.subn(r'(?im)^\s*ENABLED\s*=\s*(.*$)', "ENABLED=0", configtxt)
        #
        #    txt = txt.rstrip() + "\n"
        #
        #    if (txt != configtxt):
        #        fh.seek(0)
        #        fh.write(txt)
        #        fh.truncate()
        #        print "patched file " + filename
        #
        #    fh.close()

        modifyHubConfigFile("package-config", 'mailgateway', 'false')      
        pass


def _submitserverConfigure(args):
    submitserverConfigure(args.enable)

def submitserverConfigure(enable):

    confFileName = "/etc/submit/submit-server.conf"

    fileText = """# WARNING: this file is auto-generated.

listenURIs = tcp://:830

mysqlHost = localhost
mysqlUser = %DBUSERNAME%
mysqlPassword = %DBPW%
mysqlDB = %DBNAME%

ldapHosts = ldap://localhost
ldapBaseDN = %hubLDAPBaseDN%
ldapUserDN = uid=%s,ou=users,%hubLDAPBaseDN%

loadLimit = 510         # cumulative load must not exceed 510
loadHalflife = 3600     # static load is divided in half ever 3600 sec
loadHorizon = 86400     # forget about jobs started earlier than 1 day ago
"""

    if enable:
        dbPW = hubzero.config.webconfig.getWebConfigDBPassword()
        dbUserName = hubzero.config.webconfig.getWebConfigDBUsername()
        dbName = hubzero.config.webconfig.getWebConfigDBName()
        hubname = hubzero.config.webconfig.getDefaultSite()
        hubLDAPAcctMgrDN = hubzero.config.webconfig.getComponentParam("com_system", "ldap_managerdn")
        hubLDAPAcctMgrPW = hubzero.config.webconfig.getComponentParam("com_system", "ldap_managerpw")
        hubLDAPBaseDN = hubzero.config.webconfig.getComponentParam("com_system", "ldap_basedn")	

        rc, stdOut, stdErr = hubzero.utilities.misc.exShellCommand(["hostname", "--fqdn"])
        hostname = stdOut.strip()

        if not hubzero.utilities.group.groupExists("submit"):
            print "adding 'submit' group"
            hubzero.utilities.group.addhubgroup("submit", "submit")
        else:
            print "'submit' group already exists"

        fileText = fileText.replace("%DBUSERNAME%", dbUserName)
        fileText = fileText.replace("%DBPW%", dbPW)
        fileText = fileText.replace("%DBNAME%", dbName)
        fileText = fileText.replace("%hubLDAPBaseDN%", hubLDAPBaseDN)
        fileText = fileText.replace("%hubLDAPAcctMgrDN%", hubLDAPAcctMgrDN)
        fileText = fileText.replace("%hubLDAPBaseDN%", hubLDAPBaseDN)


        if not os.path.exists("/etc/submit/"):
            os.makedirs("/etc/submit/")
        with open(confFileName, "w") as f1:
            f1.write(fileText)

        #rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["chown", "XXX.XXX", confFileName])	
        #if rc: 
        #	print procStdErr

        rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["chmod", "0640", confFileName])	
        if rc: 
            print procStdErr

def reconfigureSshdConfig(enable_sftp, enable_ssh, enable_mwvirtualssh):

    print "checking: /etc/ssh/sshd_config"

    if os.path.exists("/etc/ssh/sshd_config"):
        fh = open("/etc/ssh/sshd_config",'r+')
        configtxt = fh.read()

        pattern1 = r'(?ims)^\n*#\s*hubzero-mw-virtualssh\s*--\s*DO\s*NOT\s*REMOVE\s*THIS\s*LINE\s*\n.*?^#\s*hubzero-mw-virtualssh\s*--\s*DO\s*NOT\s*REMOVE\s*THIS\s*LINE\s*(\n+|$)'
        pattern2 = r'(?ims)^\n*#\s*hubzero-ssh\s*--\s*DO\s*NOT\s*REMOVE\s*THIS\s*LINE\s*\n.*?^#\s*hubzero-ssh\s*--\s*DO\s*NOT\s*REMOVE\s*THIS\s*LINE\s*(\n+|$)'
        pattern3 = r'(?ims)^\n*#\s*hubzero-sftp\s*--\s*DO\s*NOT\s*REMOVE\s*THIS\s*LINE\s*\n.*?^#\s*hubzero-sftp\s*--\s*DO\s*NOT\s*REMOVE\s*THIS\s*LINE\s*(\n+|$)'

        txt = re.sub(pattern1, "", configtxt)
        txt = re.sub(pattern2, "", txt)
        txt = re.sub(pattern3, "", txt)

        #   virtualssh    ssh    sftp
        #       0          0       0    --  GOOD
        #       0          0       1    --  GOOD
        #       0          1       0    --  GOOD
        #       0          1       1    --  GOOD
        #       1          0       0    --  GOOD
        #       1          0       1    --  GOOD
        #       1          1       0    --  GOOD
        #       1          1       1    --  GOOD

        # possibly simpler to just directly define all 8 combinations
        newtxt  = ""
        
        if enable_mwvirtualssh:
            newtxt += "\n"
            newtxt += "# hubzero-mw-virtualssh -- DO NOT REMOVE THIS LINE\n"
            newtxt += "XAuthLocation /usr/share/hubzero-mw-client/xauth-incoming\n"
            newtxt += "\n"

            if enable_ssh:
               newtxt += "Match Group !tunnelers,!root,!staff,!adm,!hnusers,ctusers User *,!www-data\n"
            else:
               newtxt += "Match Group !root,!staff,!adm,ctusers User *,!www-data\n"
            
            newtxt += "    AllowTcpForwarding no\n"
            newtxt += "    ForceCommand /usr/share/hubzero-mw-client/virtualssh\n"

            if enable_ssh:
                newtxt += "\n"
                newtxt += "Match Group tunnelers,!root,!staff,!adm,!hnusers,ctusers User *,!www-data\n"
                newtxt += "    AllowTcpForwarding yes\n"
                newtxt += "    ForceCommand /usr/share/hubzero-mw-client/virtualssh\n"
            elif not enable_sftp:
                newtxt += "\n"
                newtxt += "Match Group *,!root,!staff,!adm User *,!www-data\n"
                newtxt += "    AllowTcpForwarding no\n"
                newtxt += "    ForceCommand /bin/false\n"
            
            newtxt += "# hubzero-mw-virtualssh -- DO NOT REMOVE THIS LINE\n"

        if enable_ssh:
            newtxt += "\n"
            newtxt += "# hubzero-ssh -- DO NOT REMOVE THIS LINE\n"
            if not enable_sftp:
                if enable_mwvirtualssh:
                    newtxt += "Match Group tunnelers,!root,!staff,!adm,!hnusers,!ctusers User *,!www-data\n"
                else:
                    newtxt += "Match Group tunnelers,!root,!staff,!adm,!hnusers User *,!www-data\n"
                newtxt += "    AllowTcpForwarding yes\n"
                newtxt += "    ForceCommand /bin/false\n"
                newtxt += "\n"

                if enable_mwvirtualssh:
                    newtxt += "Match Group *,!tunnelers,!root,!staff,!adm,!hnusers,!ctusers User *,!www-data\n"
                else:
                    newtxt += "Match Group *,!tunnelers,!root,!staff,!adm,!hnusers User *,!www-data\n"
                newtxt += "    AllowTcpForwarding no\n"
                newtxt += "    ForceCommand /bin/false\n"
            newtxt += "# hubzero-ssh -- DO NOT REMOVE THIS LINE\n"

        if enable_sftp:
            newtxt += "\n"
            newtxt += "# hubzero-sftp -- DO NOT REMOVE THIS LINE\n"
            if enable_mwvirtualssh and enable_ssh:
                newtxt += "Match Group *,!tunnelers,!root,!staff,!adm,!hnusers,!ctusers User *,!www-data\n"
            elif enable_ssh:
                newtxt += "Match Group *,!tunnelers,!root,!staff,!adm,!hnusers User *,!www-data\n"
            elif enable_mwvirtualssh:
                newtxt += "Match Group *,!root,!staff,!adm,!ctusers User *,!www-data\n"
            else:
                newtxt += "Match Group *,!root,!staff,!adm User *,!www-data\n"
            newtxt += "    X11Forwarding no\n"
            newtxt += "    AllowTcpForwarding no\n"
            newtxt += "    ForceCommand internal-sftp\n"
            newtxt += "    ChrootDirectory /sftp\n"
            
            if enable_ssh: 
                newtxt += "\n"
                if enable_mwvirtualssh:
                    newtxt += "Match Group tunnelers,!root,!staff,!adm,!hnusers,!ctusers User *,!www-data\n"
                else:
                    newtxt += "Match Group tunnelers,!root,!staff,!adm,!hnusers User *,!www-data\n"
                newtxt += "    X11Forwarding no\n"
                newtxt += "    AllowTcpForwarding yes\n"
                newtxt += "    ForceCommand internal-sftp\n"
                newtxt += "    ChrootDirectory /sftp\n"

            newtxt += "# hubzero-sftp -- DO NOT REMOVE THIS LINE\n"

        txt = txt.rstrip() + "\n" + newtxt

        if (txt != configtxt):
            print "Reconfigure: /etc/ssh/sshd_config"
            fh.seek(0)
            fh.write(txt)
            fh.truncate()
            print "Patched file: " + "/etc/ssh/sshd_config"
            print "Restarting ssh"
            rc, procOutput, procError = hubzero.utilities.misc.exShellCommand(['service', 'ssh', 'restart'])
            if rc: 
                print procOutput 
                print procError

        fh.close()

def groupExists(name):
    try:
        (name, passwd, gid, mem) = grp.getgrnam(name)
    except:
        return False

    return True

def createSshGroups():
    print "checking: hnusers group"
    if not groupExists("hnusers"):
        print "adding 'hnusers' group"
        rc, stdOut, stdErr = hubzero.utilities.misc.exShellCommand(["groupadd", "--system", "hnusers"])

    print "checking: tunnelers group"
    if not groupExists("tunnelers"):
        print "adding 'tunnelers' group"
        rc, stdOut, stdErr = hubzero.utilities.misc.exShellCommand(["groupadd", "--system", "tunnelers"])

def reconfigureNslcdConfig(useGroups):

    print "checking: /etc/nslcd.conf"

    if os.path.exists("/etc/nslcd.conf"):
        fh = open("/etc/nslcd.conf", 'r+')
        configtxt = fh.read()

        if useGroups:
            # filter shadow (&(objectClass=posixAccount)(host=web))
            # pam_authz_search (&(objectClass=posixAccount)(uid=$username)(host=web))

            pattern1 = r'(?im)(^\s*filter\s+shadow\s+)\(\s*\&\s*(\(\s*objectClass\s*=\s*posixAccount\s*\))\s*\(\s*host\s*=\s*web\s*\s*\)\s*\)(.*$)'
            pattern2 = r'(?im)(^\s*pam_authz_search\s+\(\s*\&\s*\(\s*objectClass\s*=\s*posixAccount\s*\)\s*\(\s*uid\s*=\s*\$username\s*\)\s*)\(\s*host\s*=\s*web\s*\)(\s*\).*$)'
        
            (txt, count) = re.subn(pattern1, r'\1\2\3', configtxt)
            (txt, count) = re.subn(pattern2, r'\1\2', txt)
        else:
            # filter shadow (objectClass=posixAccount)
            # pam_authz_search (&(objectClass=posixAccount)(uid=$username))

            pattern1 = r'(?im)(^\s*filter\s+shadow\s+)(\s*\(objectClass\s*=\s*posixAccount\s*\))(.*$)'
            pattern2 = r'(?im)(^\s*pam_authz_search\s+\(\s*\&\s*\(\s*objectClass\s*=\s*posixAccount\s*\)\s*\(\s*uid\s*=\s*\$username\s*\))(\s*\).*$)'
            (txt, count) = re.subn(pattern1,r'\1(&\2(host=web))\3',configtxt)
            (txt, count) = re.subn(pattern2,r'\1(host=web)\2',txt)

        if txt != "" and txt[-1] != "\n":
            txt = txt + "\n"

        if (txt != configtxt):
            print "Reconfigure: /etc/nslcd.conf"
            fh.seek(0)
            fh.write(txt)
            fh.truncate()
            print "Patched file: " + "/etc/nslcd.conf"
            print "Restarting nslcd"

            rc, procOutput, procError = hubzero.utilities.misc.exShellCommand(['service', 'nslcd', 'restart'])
            if rc: 
                print procOutput 
                print procError

        fh.close()

    else:
        print "/etc/nslcd.conf missing, can't reconfigure it"

def _mwVirtualsshConfigure(args):
    mwVirtualsshConfigure(args.enable)

def mwVirtualsshConfigure(enable):

    hubname = hubzero.config.webconfig.getDefaultSite()

    enable_mwvirtualssh = enable
    enable_sftp = hubzero.config.webconfig.getHubSiteConfig(hubname, "package-config", "sftp") == 'true'
    enable_ssh = hubzero.config.webconfig.getHubSiteConfig(hubname, "package-config", "ssh") == 'true'

    if enable:
        createSshGroups()

        print "checking: ctusers group"
        if not groupExists("ctusers"):
            print "adding 'ctusers' group"
            rc, stdOut, stdErr = hubzero.utilities.misc.exShellCommand(["groupadd", "--system", "ctusers"])

        reconfigureSshdConfig(enable_sftp, enable_ssh, enable_mwvirtualssh)
        reconfigureNslcdConfig(True if enable_sftp or enable_ssh or enable_mwvirtualssh else False)
        modifyHubConfigFile("package-config", 'mw-virtualssh', 'true')

    else:
        reconfigureNslcdConfig(True if enable_sftp or enable_ssh or enable_mwvirtualssh else False)
        reconfigureSshdConfig(enable_sftp, enable_ssh, enable_mwvirtualssh)
        modifyHubConfigFile("package-config", 'mw-virtualssh', 'false')      

def _sshConfigure(args):
    sshConfigure(args.enable) 

def sshConfigure(enable):

    hubname = hubzero.config.webconfig.getDefaultSite()

    enable_mwvirtualssh = hubzero.config.webconfig.getHubSiteConfig(hubname, "package-config", "mw-virtualssh") == 'true'
    enable_sftp = hubzero.config.webconfig.getHubSiteConfig(hubname, "package-config", "sftp") == 'true'
    enable_ssh = enable

    if enable:
        reconfigureSshdConfig(enable_sftp, enable_ssh, enable_mwvirtualssh)
        reconfigureNslcdConfig(True if enable_sftp or enable_ssh or enable_mwvirtualssh else False)
        modifyHubConfigFile("package-config", 'ssh', 'true')
    else:
        reconfigureNslcdConfig(True if enable_sftp or enable_ssh or enable_mwvirtualssh else False)
        reconfigureSshdConfig(enable_sftp, enable_ssh, enable_mwvirtualssh)
        modifyHubConfigFile("package-config", 'ssh', 'false')


def _sftpConfigure(args):
    if (args.enable):
        sftpEnable()
    else:
        sftpDisable()

def sftpDisable():
    hubname = hubzero.config.webconfig.getDefaultSite()	
    enable_mwvirtualssh = hubzero.config.webconfig.getHubSiteConfig(hubname, "package-config", "mw-virtualssh") == 'true'
    enable_sftp = False
    enable_ssh = hubzero.config.webconfig.getHubSiteConfig(hubname, "package-config", "ssh") == 'true'
    restart_autofs = False

    # @TODO try to delete these directories
    # removeDirIfEmpty("/sftp/home")
    # removeDirIfEmpty("/sftp")
    # maybe try to umount

    filename = '/etc/auto.master'

    if os.path.exists(filename):
        fh = open(filename, 'r+')
        configtxt = fh.read()
        (txt, count) = re.subn(r'(?im)^\n*^.*?/sftp/home\s*/etc/auto.home\n.*(\n+|$)', "", configtxt)

        if txt != "" and txt[-1] != "\n":
            txt = txt + "\n"

        if (txt != configtxt):
            fh.seek(0)
            fh.write(txt)
            fh.truncate()
            print "Patched file: " + filename
            restart_autofs = True

        fh.close()

    filename = '/etc/auto.home'

    if os.path.exists(filename):
        fh = open(filename, 'r+')
        configtxt = fh.read()
        (txt, count) = re.subn(r'(?im)^\n*^.*?' + hubname + r'\s*-rw,hard,bg,tcp\s*:/home/' + hubname + r'.*?(\n+|$)', "", configtxt)

        if txt != '' and txt[-1] != "\n":
            txt = txt + "\n"

        if (txt != configtxt):
            fh.seek(0)
            fh.write(txt)
            fh.truncate()
            print "Patched file: " + filename
            restart_autofs = True

        fh.close()

    reconfigureSshdConfig(enable_sftp, enable_ssh, enable_mwvirtualssh)
    reconfigureNslcdConfig(True if enable_sftp or enable_ssh or enable_mwvirtualssh else False)

    if restart_autofs:
        rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["/etc/init.d/autofs", "restart"])	
        if rc: print procStdErr

    modifyHubConfigFile("package-config", 'sftp', 'false')
    
def sftpEnable():
    hubname = hubzero.config.webconfig.getDefaultSite()	

    enable_mwvirtualssh = hubzero.config.webconfig.getHubSiteConfig(hubname, "package-config", "mw-virtualssh") == 'true'
    enable_sftp = True
    enable_ssh = hubzero.config.webconfig.getHubSiteConfig(hubname, "package-config", "ssh") == 'true'

    restart_autofs = False

    createSshGroups()

    createDir("/sftp", "0755", "root", "root", resetattrs=True)
    createDir("/sftp/home", "0755", "root", "root", resetattrs=True)

    fileText = "\n/sftp/home		/etc/auto.home\n"
    filename = '/etc/auto.master'

    if not os.path.exists(filename):
        fh = open(filename, 'w')
        configtxt = ''
        txt = fileText
    else:
        fh = open(filename, 'r+')
    
        configtxt = fh.read()
        (txt, count) = re.subn(r'(?im)^\n*^.*?/sftp/home\s*/etc/auto.home\n.*?(\n+|$)', "/sftp/home		/etc/auto.home\n", configtxt)
        if count < 1:
           txt = configtxt.rstrip("\n \t\r") + fileText

    if txt != '' and txt[-1] != "\n":
        txt = txt + "\n"

    if (txt != configtxt):
        fh.seek(0)
        fh.write(txt)
        fh.truncate()
        print "Patched file: " + filename
        restart_autofs = True

    fh.close()

    fileText = "\n" + hubname + "    -rw,hard,bg,tcp    :/home/" + hubname + "\n"
    filename = '/etc/auto.home'

    if not os.path.exists(filename):
        fh = open(filename, 'w')
        configtxt = ''
        txt = fileText
    else:
        fh = open(filename, 'r+')
        configtxt = fh.read()
        (txt, count) = re.subn(r'(?im)^\n*^.*?' + hubname + r'\s*-rw,hard,bg,tcp\s*:/home/' + hubname + '.*?(\n+|$)', fileText, configtxt)
        if count < 1:
            txt = configtxt.rstrip("\n \t\r") + fileText

    if txt != '' and txt[-1] != "\n":
        txt = txt + "\n"

    if (txt != configtxt):
        fh.seek(0)
        fh.write(txt)
        fh.truncate()
        print "Patched file: " + filename
        restart_autofs = True

    fh.close()

    reconfigureNslcdConfig(True if enable_sftp or enable_ssh or enable_mwvirtualssh else False)
    reconfigureSshdConfig(enable_sftp, enable_ssh, enable_mwvirtualssh)

    if restart_autofs:
        print "restarting autofs"
        rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["/etc/init.d/autofs", "restart"])	
        if rc: print procStdErr

    modifyHubConfigFile("package-config", 'sftp', 'true')

def _openvzConfigure(args):
    if (args.enable):
        openvzEnable()
    else:
        openvzDisable()

def openvzEnable():

    print "Enabling OpenVZ kernel"

    hubname = hubzero.config.webconfig.getDefaultSite() 

    (sysname, nodename, release, version, machine) = os.uname()
    
    if (machine == 'x86_64'):
        arch = 'amd64'
    elif (machine == 'i686'):
        arch = '686'
    else:
        print "hzcms doesn't recognize this machine type: " + machine
        return

    if hubzero.utilities.misc.isRHEL():        
        kernelstring = 'stab'
        print "hzcms doesn't know how to configure openvz on RedHat"
        return

    if not hubzero.utilities.misc.isDebian():
        kernelstring = 'unknown'
        print "hzcms doesn't know how to configure openvz on this unknown Linux distribution"
        return

    (distname, version, id) = platform.linux_distribution('debian','debian')
    
    if version.startswith('6.') or version.startswith('5.'):
        kernelstring = 'openvz'
    elif version.startswith('7.') or version.stratswith('4.'):
        kernelstring = 'stab'
    else:
        print "hzcms doesn't know to configure openvz on this version of Debian GNU/Linux: " + version
        return

    grubfn = "/boot/grub/grub.cfg"
    grubfh = open(grubfn,'r')
    grubtxt = grubfh.read()
    grubfh.close()

    menuentries = re.findall(r'(?m)^.*/boot/vmlinuz-.*\s', grubtxt)
    entry = 0
    vzrelease = ''

    for menuentry in menuentries:
        if menuentry.find(kernelstring) != -1 and menuentry.find(' single') == -1:
            m = re.search(r'vmlinuz-(.*?)\s',menuentry)
            if m:
                vzrelease = m.group(1)
            break
        entry = entry + 1
    
    if entry > len(menuentries):
        print "hzcms didn't find an openvz kernel in the grub menu list."
        return

    print "checking: /etc/default/grub"
    try:
        grubfn = "/etc/default/grub"
        grubfh = open(grubfn,'r+')
        grubtxt = grubfh.read()

        txt = re.sub(r'(?m)^\s*GRUB_DEFAULT\s*=.*$','GRUB_DEFAULT='+str(entry),grubtxt)
        if (txt != grubtxt):
            grubfh.seek(0)
            grubfh.write(txt)
            grubfh.close()
            print "patched file: " + grubfn
            print "/usr/sbin/update-grub"
            rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["/usr/sbin/update-grub"]) 
            if rc: print procStdErr
    except:
        print "Failed to patch file: " + grubfn
        raise
    
    
    if hubzero.utilities.misc.isDebian() and kernelstring == 'stab':
        print "checking: /etc/modules"
        try:
            modulesfn = "/etc/modules"
            modulesfh = open(modulesfn,"r+")
            modulestxt = modulesfh.read()

            txt = re.sub(r'(?m)^\s*loop($|\s+.*$)',r'#loop\1',modulestxt)
            if (txt != modulestxt):
                modulesfh.seek(0)
                modulesfh.write(txt)
                modulesfh.close()
                print "patched: " + modulesfn
        except:
            print "Failed to patch file: " + modulesfn
            pass

    print "checking: /etc/sysctl.conf"
    try:
        sysctlfn = "/etc/sysctl.conf"
        sysctlfh = open(sysctlfn,"r+")
        sysctltxt = sysctlfh.read()

        txt = re.sub(r'(?m)^\s*#\s*net.ipv4.ip_forward\s*=.*$','net.ipv4.ip_forward=1',sysctltxt)
        if (txt != sysctltxt):
            sysctlfh.seek(0)
            sysctlfh.write(txt)
            sysctlfh.close()
            print "patched: " + sysctlfn
    except:
        print "Failed to patch file: " + sysctlfn
        pass

    print "checking: /proc/sys/net/ipv4/ip_forward"
    try:
        ipffn = "/proc/sys/net/ipv4/ip_forward"
        ipffh = open(ipffn,"r+")
        ipfftxt = ipffh.read()

        if ipfftxt != '1\n':
            ipffh.seek(0)
            ipffh.write('1\n')
            ipffh.close()
            print "patched: " + ipffn
    except:
        print "Failed to patch file: " + ipffn
        pass

    if release.find(kernelstring) == -1:
        print "\nOpenVZ is configured. Please restart to boot into the OpenVZ kernel"
    else:
        print "\nOpenVZ is configured and running."

    modifyHubConfigFile("package-config", 'openvz', 'true')

def openvzDisable():

    print "Disabling OpenVZ kernel"

    hubname = hubzero.config.webconfig.getDefaultSite() 

    (sysname, nodename, release, version, machine) = os.uname()
    
    if (machine == 'x86_64'):
        arch = 'amd64'
    elif (machine == 'i686'):
        arch = '686'
    else:
        print "hzcms doesn't recognize this machine type: " + machine
        return

    if hubzero.utilities.misc.isRHEL():        
        kernelstring = 'stab'
        print "hzcms doesn't know how to unconfigure openvz on RedHat"
        return

    if not hubzero.utilities.misc.isDebian():
        kernelstring = 'unknown'
        print "hzcms doesn't know how to unconfigure openvz on this unknown Linux distribution"
        return

    (distname, version, id) = platform.linux_distribution('debian','debian')
    
    if version.startswith('6.') or version.startswith('5.'):
        kernelstring = 'openvz'
    elif version.startswith('7.'):
        kernelstring = 'stab'
    else:
        print "hzcms doesn't know to unconfigure openvz on this version of Debian GNU/Linux: " + version
        return

    grubfn = "/boot/grub/grub.cfg"
    grubfh = open(grubfn,'r')
    grubtxt = grubfh.read()
    grubfh.close()

    menuentries = re.findall(r'(?m)^.*/boot/vmlinuz-.*\s', grubtxt)
    entry = 0
    vzrelease = ''

    for menuentry in menuentries:
        if menuentry.find(kernelstring) == -1 and menuentry.find(' single') == -1:
            m = re.search(r'vmlinuz-(.*?)\s',menuentry)
            if m:
                vzrelease = m.group(1)
            break
        entry = entry + 1
    
    if entry > len(menuentries):
        print "hzcms didn't find a non-openvz kernel in the grub menu list."
        return

        print "checking: /etc/default/grub"
        try:
            grubfn = "/etc/default/grub"
            grubfh = open(grubfn,'r+')
            grubtxt = grubfh.read()

            txt = re.sub(r'(?m)^\s*GRUB_DEFAULT\s*=.*$','GRUB_DEFAULT='+str(entry),grubtxt)
            if (txt != grubtxt):
                grubfh.seek(0)
                grubfh.write(txt)
                grubfh.close()
                print "patched: " + grubfn
                print "/usr/sbin/update-grub"
                rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["/usr/sbin/update-grub"]) 
                if rc: print procStdErr
        except:
            print "Failed to patch file: " + grubfn
            raise
    
    if hubzero.utilities.misc.isDebian() and kernelstring == 'stab':
        print "checking: /etc/modules"
        try:
            modulesfn = "/etc/modules"
            modulesfh = open(modulesfn,"r+")
            modulestxt = modulesfh.read()

            txt = re.sub(r'(?m)^\s*#\s*loop($|\s+.*$)',r'loop\1',modulestxt)
            if (txt != modulestxt):
                modulesfh.seek(0)
                modulesfh.write(txt)
                modulesfh.close()
                print "Patched file: " + modulesfn
        except:
            print "Failed to patch file: " + modulesfn
            pass
              
    print "\nYou may want to turn off ipv4_ipforward in /etc/sysctl.conf"
    print "You may want to disable IP forwarding in /proc/sys/net/ipv4/ip_forward"

    if release.find(kernelstring) != -1:
        print "The OpenVZ kernel is now unconfigured but it still running."
        print "Please reboot into a non-OpenVZ kernel"
    else:
        print "The OpenVZ is unconfigured and not running."

    modifyHubConfigFile("package-config", 'openvz', 'false')


def _cronConfigure(args):
    if (args.enable):
        cronEnable()
    else:
        cronDisable()

def cronEnable():
    hubname = hubzero.config.webconfig.getDefaultSite() 

    createDir("/etc/hubzero-cms/" + hubname + "/", "0755", "root", "root", resetattrs=True)
    createDir("/var/log/hubzero-cms/", 0770, "www-data",  "www-data", resetattrs=True)
    createDir("/var/log/hubzero-cms/daily", 0770, "www-data",  "www-data", resetattrs=True)
    createDir("/var/log/hubzero-cms/daily/cron", 0770, "www-data",  "www-data", resetattrs=True)
    createFile("/var/log/hubzero-cms/" + hubname + "-cmscron.log", 0640, "www-data", "www-data", resetattrs=True)
    usrfilename = "/usr/share/hubzero-cms/conf/cron-cmscron.m4"
    etcfilename = "/etc/hubzero-cms/" + hubname + "/cron-cmscron.m4"
    cronfilename = "/etc/cron.d/" + hubname + "-cmscron"

    if not os.path.exists(etcfilename):
        # copy over the base template files
        print "copy2 " + usrfilename + " to " + etcfilename
        shutil.copy2(usrfilename,etcfilename)

    m4Processing(etcfilename, cronfilename, ["-DHUBNAME=" + hubname], 0644, "root", "root", resetattrs=True) 

    usrfilename = "/usr/share/hubzero-cms/conf/logrotate-cmscron.m4"
    etcfilename = "/etc/hubzero-cms/" + hubname + "/logrotate-cmscron.m4"
    logrotatefilename = "/etc/logrotate.d/" + hubname + "-cmscron"

    if not os.path.exists(etcfilename):
        # copy over the base template files
        print "copy2 " + usrfilename + " to " + etcfilename
        shutil.copy2(usrfilename, etcfilename)

    m4Processing(etcfilename, logrotatefilename, ["-DHUBNAME=" + hubname], 0644, "root", "root", resetattrs=True)    

    #reload /etc/init.d/cron
    if os.path.exists("/etc/init.d/cron"):
        rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["/etc/init.d/cron", "reload"])
        if rc: print procStdErr
    else:
        print "/etc/init.d/cron not reloaded, file not found"

def cronDisable():
    hubname = hubzero.config.webconfig.getDefaultSite() 

    cronfilename = "/etc/cron.d/" + hubname + "-cmscron"

    if os.path.exists(cronfilename):
        print "remove " + cronfilename
        os.remove(cronfilename)

    logrotatefilename = "/etc/logrotate.d/" + hubname + "-cmscron"

    if os.path.exists(logrotatefilename):
        print "remove " + logrotatefilename
        os.remove(logrotatefilename)

    #reload /etc/init.d/cron
    if os.path.exists("/etc/init.d/cron"):
        rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["/etc/init.d/cron", "reload"])
        if rc: print procStdErr
    else:
        print "/etc/init.d/cron not reloaded, file not found"



def _createDHCPExitHookFile(args):
    fileName = "/etc/dhcp/dhclient-exit-hooks.d/dhcpleaseupdate"
    fileText = """# our custom change is delimited by #.# ... #.#
# just delete this and replace it every time
sed -i "/\#\.\#/,/\#\.\#/d" /etc/hosts

hn=$(hostname)
fqdn=$(hostname -f)
date=`date`

line="$new_ip_address $fqdn $hn"
t="#.# Do not edit. Auto inserted section by /etc/dhcp/dhclient-exit-hooks.d/dhcpleaseupdate script on $date \\n$line\\n#.#"

sed -i "1i $t" /etc/hosts"""

    if args.enable:
        with open(fileName, "w") as f1:
            f1.write(fileText)

        rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["chmod", "0644", fileName])	
        if rc: print procStdErr

    else:
        if os.path.exists(fileName):
            os.remove(fileName)


def updateHub(args):

    # Debian or RH?
    if hubzero.utilities.misc.isDebian():
        wwwOwner = 'www-data'
        wwwGroup = 'www-data'

    if hubzero.utilities.misc.isRHEL():
        wwwOwner = 'apache'

    hubname = hubzero.config.webconfig.getDefaultSite()
    docroot = hubzero.config.hubzerositeconfig.getHubzeroConfigOption(hubname, "DocumentRoot")
    dbname = hubzero.config.hubzerositeconfig.getHubzeroConfigOption(hubname, "dbname")
    uri = hubzero.config.hubzerositeconfig.getHubzeroConfigOption(hubname, "uri")

    rc, stdOut, stdErr = hubzero.utilities.misc.exShellCommand(["hostname", "--fqdn"])
    hostname = stdOut.strip()

    if uri == None:
        uri = "http://" + hostname

    if dbname == None:
        dbname = hubname

    # Copy fresh code
    if not os.path.exists(docroot + "/.git"):
        print "Copying CMS files from /usr/share/hubzero-cms/cms/ to " + docroot
        copyCMSFiles("/usr/share/hubzero-cms/cms/", docroot, wwwOwner, wwwGroup)
    else:
        print "Leaving git controlled CMS files alone"

    # @TODO someday put database migrations here

    # Fix various problems with apache configuration problems
    if os.path.exists("/etc/apache2/sites-m4"):

        pattern1 = r'(?im)^(\s*)(AddType\s+text/plain\s+.*\.php(\s+.*\n|\n))((?!^\s*php_admin_value\s+engine\s+Off))'
        repl1 = r'\1\2\1php_admin_value engine Off\n'
        pattern2 = r'(?im)^(\s*)(Include\s+/etc/apache2/)(svn.con\[f].*\n)'
        repl2 = r'\1\2HUBNAME.conf.d/svn/\3'
        pattern3 = r'(?im)^(\s*)(Include\s+/etc/apache2/HUBNAME\.conf\.d/)(svn.con\[f].*\n)'
        repl3 = r'\1\2svn/\3'
        pattern4 = r'(?im)^(\s*)(RewriteRule\s+\^filexfer/\(\.\*\)\s+\${)(xlate.*\n)'
        repl4 = r'\1\2filexfer-\3'
  
        svn_line = r'RewriteRule\s+\^\(\.\*/\)\?\(\\\.svn\|\\\.git\|\\\.hg\)/\s+-\s+\[R=404,L\]'
        wl_line  = r'RewriteRule\s+\^/site/wishlist/\(\.\*\)\(\\\.htm\|\\\.html\)\$\s+\-\s+\[R=404,L,NC\]'
        
        pattern5 = r'(?im)(^\s*)(' + svn_line + r')\s*\n+(?!\s*' + wl_line + r'\s*\n)'
        repl5 = r'\1\2\n\1RewriteRule ^/site/wishlist/(.*)(\.htm|\.html)$ - [R=404,L,NC]\n\n'

        try:
            hubm4 = "/etc/apache2/sites-m4/" + hubname + ".m4"
            hubm4fh = open(hubm4,'r+')
            hubm4txt = hubm4fh.read()
            txt = re.sub(pattern1, repl1, hubm4txt)
            txt = re.sub(pattern2, repl2, txt)
            txt = re.sub(pattern3, repl3, txt)
            txt = re.sub(pattern4, repl4, txt)
            txt = re.sub(pattern5, repl5, txt)
            if (txt != hubm4txt):
                hubm4fh.seek(0)
                hubm4fh.write(txt)
                hubm4fh.close()
                print "Patched file: " + hubm4
        except:
            print "Failed to patch file: " + hubm4
            pass

        try:
            hubsslm4 = "/etc/apache2/sites-m4/" + hubname + "-ssl.m4"
            hubsslm4fh = open(hubsslm4,'r+')
            hubsslm4txt = hubsslm4fh.read()
            txt = re.sub(pattern1, repl1, hubsslm4txt)
            txt = re.sub(pattern2, repl2, txt)
            txt = re.sub(pattern3, repl3, txt)
            txt = re.sub(pattern4, repl4, txt)
            txt = re.sub(pattern5, repl5, txt)
            if (txt != hubsslm4txt):
                hubsslm4fh.seek(0)
                hubsslm4fh.write(txt)
                hubsslm4fh.close()
                print "Patched file: " + hubsslm4
        except:
            print "Failed to patch file: " + hubsslm4
            pass

    # fix apache access log rotation scripts
    if os.path.exists("/etc/logrotate.d/" + hubname + "-access"):
        print "checking /etc/logrotate.d/" + hubname + "-access"
        pattern1 = r'(?im)^(\s*if\s+)(-f\s*"`\.\s+/etc/apache2/envvars\s*;\s*echo\s+\${APACHE_PID_FILE:-/var/run/apache2\.pid}`")(\s*;\s*then\s*)'
        repl1 = r'\1[ \2 ]\3'
        try:
            tfilename = "/etc/logrotate.d/" + hubname + "-access"
            tfileh = open(tfilename,'r+')
            tfiletxt = tfileh.read()
            txt = re.sub(pattern1, repl1, tfiletxt)
            if (txt != tfiletxt):
                tfileh.seek(0)
                tfileh.write(txt)
                tfileh.close()
                print "patched " + tfilename
        except:
            print "Failed to patch " + tfilename
            pass

    # Add new uri and dbname options to hub configuration file
    print "Updating hub configuration file for hub " + hubname
    insertHubIntoHubConfigFile(hubname, docroot, uri, dbname)

    # fix mw-client.conf, remove hub_template
    if os.path.exists("/etc/mw-client/mw-client.conf"):
        print "checking /etc/mw-client/mw-client.conf"
        try:
            mwfilename = "/etc/mw-client/mw-client.conf"
            mwfh = open(mwfilename,'r+')
            mwtxt = mwfh.read()
            txt = re.sub(r'(?im)^\s*hub_template\s*=.*$','',mwtxt)
            if (txt != mwtxt):
                mwfh.seek(0)
                mwfh.write(txt)
                mwfh.close()
                print "patched " + mwfilename
        except:
            print "Failed tp patch " + mwfilename

    # Update database schema to match commits broguht in since original release
    # @TODO migrations will replace this segment one day
    dbPW = hubzero.config.webconfig.getWebConfigDBPassword()
    dbUserName = hubzero.config.webconfig.getWebConfigDBUsername()
    dbName = hubzero.config.webconfig.getWebConfigDBName()
    db =  hubzero.data.db.MySQLConnection("localhost", dbName, dbUserName, dbPW)

    print "Database schema updates"

    sql = """
UPDATE `jos_plugins` SET element='wiki' WHERE element='topics';
CREATE TABLE IF NOT EXISTS `jos_venue` ( `id` int(11) NOT NULL AUTO_INCREMENT, `venue` varchar(40), `network` varchar(40), PRIMARY KEY (`id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `jos_venue_countries` ( `id` int(11) NOT NULL AUTO_INCREMENT, `countrySHORT` varchar(40), PRIMARY KEY (`id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE FULLTEXT INDEX jos_citations_search_ftidx ON jos_citations (title,isbn,doi,abstract,author,publisher);
ALTER TABLE `jos_wiki_page` ADD `modified` DATETIME  NOT NULL  DEFAULT '0000-00-00 00:00:00'  AFTER `state`;
ALTER TABLE `jos_wiki_page` ADD `version_id` INT(11)  NOT NULL  DEFAULT '0'  AFTER `modified`;
ALTER TABLE `jos_wiki_version` ADD `length` INT(11)  NOT NULL  DEFAULT '0'  AFTER `summary`;
ALTER TABLE `jos_citations` MODIFY `type` varchar(30) DEFAULT NULL AFTER `uid`;
ALTER TABLE `jos_citations` ADD `language` varchar(100) DEFAULT NULL;
ALTER TABLE `jos_citations` ADD `accession_number` varchar(100) DEFAULT NULL;
ALTER TABLE `jos_citations` ADD `short_title` varchar(250) DEFAULT NULL;
ALTER TABLE `jos_citations` ADD `author_address` text;
ALTER TABLE `jos_citations` ADD `keywords` text;
ALTER TABLE `jos_citations` ADD `abstract` text;
ALTER TABLE `jos_citations` ADD `call_number` varchar(100) DEFAULT NULL;
ALTER TABLE `jos_citations` ADD `label` varchar(100) DEFAULT NULL;
ALTER TABLE `jos_citations` ADD `research_notes` text;
ALTER TABLE `jos_citations` ADD `params` text;
ALTER TABLE `jos_forum_sections` CHANGE `group_id` `scope_id` INT(11)  NOT NULL  DEFAULT '0';
ALTER TABLE `jos_forum_sections` ADD `scope` VARCHAR(100)  NOT NULL  DEFAULT 'site'  AFTER `state`;
ALTER TABLE `jos_forum_categories` CHANGE `group_id` `scope_id` INT(11)  NOT NULL  DEFAULT '0';
ALTER TABLE `jos_forum_categories` ADD `scope` VARCHAR(100)  NOT NULL  DEFAULT 'site'  AFTER `state`;
ALTER TABLE `jos_forum_posts` CHANGE `group_id` `scope_id` INT(11)  NOT NULL  DEFAULT '0';
ALTER TABLE `jos_forum_posts` ADD `scope` VARCHAR(100)  NOT NULL  DEFAULT 'site'  AFTER `hits`;
UPDATE `jos_forum_sections` SET scope=CASE WHEN scope IN ('', 'group') THEN 'group' ELSE 'course' END WHERE scope_id>0;
UPDATE `jos_forum_sections` SET scope='site' WHERE scope_id=0;
UPDATE `jos_forum_categories` SET scope=CASE WHEN scope IN ('', 'group') THEN 'group' ELSE 'course' END WHERE scope_id>0;
UPDATE `jos_forum_categories` SET scope='site' WHERE scope_id=0;
UPDATE `jos_forum_posts` SET scope=CASE WHEN scope IN ('', 'group') THEN 'group' ELSE 'course' END WHERE scope_id>0;
UPDATE `jos_forum_posts` SET scope='site' WHERE scope_id=0;
ALTER TABLE `jos_forum_sections` ADD `object_id` INT(11)  NOT NULL  DEFAULT '0'  AFTER `asset_id`;
ALTER TABLE `jos_forum_categories` ADD `object_id` INT(11)  NOT NULL  DEFAULT '0'  AFTER `asset_id`;
ALTER TABLE `jos_forum_posts` ADD `object_id` INT(11)  NOT NULL  DEFAULT '0'  AFTER `asset_id`;
RENAME TABLE `jos_venue` TO `venue`;
ALTER TABLE `venue` CHANGE `venue` `venue` VARCHAR(40) DEFAULT NULL;
ALTER TABLE `venue` DROP  COLUMN `network`;
ALTER TABLE `venue` ADD COLUMN `state` VARCHAR(15) DEFAULT NULL AFTER `venue`;
ALTER TABLE `venue` ADD COLUMN `type` VARCHAR(10) DEFAULT NULL AFTER `state`;
ALTER TABLE `venue` ADD COLUMN `mw_version` VARCHAR(3) DEFAULT NULL AFTER `type`;
ALTER TABLE `venue` ADD COLUMN `ssh_key_path` VARCHAR(200) DEFAULT NULL AFTER `mw_version`;
ALTER TABLE `venue` ADD COLUMN `latitude` DOUBLE DEFAULT NULL AFTER `ssh_key_path`;
ALTER TABLE `venue` ADD COLUMN `longitude` DOUBLE DEFAULT NULL AFTER `latitude`;
ALTER TABLE `venue` ADD COLUMN `master` VARCHAR(255) DEFAULT NULL AFTER `longitude`;
RENAME TABLE `jos_venue_countries` TO `venue_countries`;
ALTER TABLE `venue_countries` ADD COLUMN `id` INT(11) PRIMARY KEY NOT NULL AUTO_INCREMENT FIRST;
ALTER TABLE `venue_countries` ADD COLUMN `venue_id` INT(11) NOT NULL AFTER `id`;
ALTER TABLE `venue_countries` DROP COLUMN `venue`;
ALTER TABLE `host` ADD COLUMN `venue_id` INT(11)  AFTER `portbase`;
ALTER TABLE jos_xgroups DROP access;
ALTER TABLE jos_xgroups CHANGE privacy discoverability TINYINT(3);
ALTER TABLE jos_xgroups ADD COLUMN approved TINYINT(3) DEFAULT 1 AFTER published;
UPDATE `jos_xgroups` SET type=0, published=1 WHERE cn IN ('apps','network','submit');
"""

    for s in sql.splitlines():
        if s == "":
            continue
        try:
            db.query_rowcount(s, None)
        except:
            pass

    # Fix subversion if it's configured
    if hubzero.config.webconfig.getHubSiteConfig(hubname, "apache-config", "enable_subversion").lower() == 'true':
        subversionConfigure(True)
    else:
        subversionConfigure(False)

    # Use enable_mw_service and enable_mw_client seperate flags instead of enable_mw
    enable_mw_service = hubzero.config.webconfig.getHubSiteConfig(hubname, "package-config", "mw-service")
    enable_mw_client = hubzero.config.webconfig.getHubSiteConfig(hubname, "package-config", "mw-client")
    enable_mw = hubzero.config.webconfig.getHubSiteConfig(hubname, "mw", "enable_mw")

    if (enable_mw_client == ''):
        enable_mw_client = enable_mw
        if (enable_mw_client != ''):
            modifyHubConfigFile("package-config", 'mw-client', enable_mw_client)		
        else:
            modifyHubConfigFile("package-config", 'mw-client', 'false')		

    if (enable_mw_service == ''):
        enable_mw_service = enable_mw
        if (enable_mw_service != ''):
            modifyHubConfigFile("package-config", 'mw-service', enable_mw_service)		
        else:
            modifyHubConfigFile("package-config", 'mw-service', 'false')		

    if (enable_mw != ''):
        modifyHubConfigFile('mw', 'enable_mw', None)		

    # Make sure /etc/mw-service/mw-service.conf got written, we missed it originally
    # @TODO It would be slightly better to look for the host entry to determine
    # if this needs to be fixed or left alone.
    if (enable_mw_service.lower() == 'true'):
        mwServiceConfigure(True)

    # Fix permissions on /etc/apache2/hubname.conf.d
    if os.path.exists("/etc/apache2/" + hubname + ".conf.d"):
        hubzero.utilities.misc.exShellCommand(['chmod', "0755", "/etc/apache2/" + hubname + ".conf.d"])
        hubzero.utilities.misc.exShellCommand(['chown', "root:root", "/etc/apache2/" + hubname + ".conf.d"])

    # Fix permissions on /etc/apache2/hubname.conf.d/svn
    if os.path.exists("/etc/apache2/" + hubname + ".conf.d/svn"):
        hubzero.utilities.misc.exShellCommand(['chmod', "0700", "/etc/apache2/" + hubname + ".conf.d/svn"])
        hubzero.utilities.misc.exShellCommand(['chown', "www-data:www-data", "/etc/apache2/" + hubname + ".conf.d/svn"])

    # Fix permissions to /etc/nsswitch.conf which we initially got wrong
    filename = "/etc/nsswitch.conf"
    hubzero.utilities.misc.exShellCommand(['chmod', '0644', filename])
    hubzero.utilities.misc.exShellCommand(['chown', 'root:root', filename])

    # Regenerate logrotate files to fix some issues with original generation
    generateLogRotateFiles(hubname)

    # Fix missing closing brace on hubconfiguration.php file
    if os.path.exists(docroot + "/hubconfiguration.php"):
        f = open(docroot + "/hubconfiguration.php","r+")
        configtxt = f.read()
        txt = re.sub(r'([^\s}])\s*\?>\s*$',r'\1\n}\n?>\n',configtxt)
        if configtxt != txt:
            f.seek(0)
            f.write(txt)
            f.close()
            print "patched: " + docroot + "/hubconfiguration.php"


    # Should follow ldap sync on/off setting for the follow two fixes

    # 1) Remove inadvertently created admin group

    # Group should be cn=admin, probably gid=1000, probably one group member 'admin'
    # group name 'admin group',type = hub, not published
    #gidNumber = hubzero.utilities.group.groupNumberLookup('admin')
    #if (gidNumber = 1000):
    #    hubzero.utilities.group.delhubgroup('admin')

    # 2) Make sure gid for admin user is 'users' 



def validateArgs(args):
    """
    For system-wide argument validation, some of the sub commands will have their
    own specific checks
    """

    # hubname length check
    if len(args.hubname) > 16 :
        print "hubname too long, must be 16 characters or less"
        return 1
 
    # other hubname checks 
    p = re.compile("^[a-zA-Z][a-zA-Z0-9]+$")
    m = p.match(args.hubname)
    if not m:
        print "install hubname must be alphanumeric and start with a letter"
        return 1

    return 0

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

# we'll need the hostname in a couple of spots
rc, stdOut, stdErr = hubzero.utilities.misc.exShellCommand(["hostname", "--fqdn"])
if rc: 
    print stdErr
hostname = stdOut	

# exit if not being run by the root user
checkforroot()

# main parser
parser = argparse.ArgumentParser(prog="hzcms")
subparsers = parser.add_subparsers()

# config subcommand
parser_config = subparsers.add_parser('confighubfile', help='get and set config values for a hub')
parser_config.add_argument('hubname', help='hubname')
parser_config.add_argument('section', help='section name')
parser_config.add_argument('option', help='option name')
parser_config.set_defaults(func=configHubFile)

# install subcommand
parser_install = subparsers.add_parser('install', help='install a new hub')
parser_install.add_argument('hubname', help='name of new hub')

parser_install.add_argument('--uri', help='uri of new hub')
parser_install.add_argument('--dbname', help='db name of new hub')

parser_install.add_argument('--dbprefix', help='prefix for web tables', default='jos_')
parser_install.add_argument('--docroot', help='root folder for the cms web files', default='/var/www')
parser_install.add_argument('--installkey', help='alphanumeric key used to run joomla install scripts, min length=8')
parser_install.add_argument('--mailfrom', help='email of the site admin', default="")
parser_install.add_argument('--promptsiteadminpw', help='prompt for a site admin password, if not provided, one will be created and output to screen', action="store_true", default=False)
parser_install.add_argument('--createsecretsfile', help='create the /etc/hubzero.secrets file', default=True, action="store_true")
parser_install.add_argument('--siteadminemail', help='email of the site admin', default='admin@myhub.org')
parser_install.add_argument('--siteadminfirstname', help='name of the site admin', default="CMS")
parser_install.add_argument('--siteadminlastname', help='name of the site admin', default="Manager")
parser_install.set_defaults(func=installHub)

# uninstall subcommand
parser_uninstall = subparsers.add_parser('uninstall', help='remove existing hub')
parser_uninstall.add_argument('hubname', help='name of hub to delete')
parser_uninstall.set_defaults(func=uninstallHub)

# update subcommand
parser_update = subparsers.add_parser('update', help='update existing hub')
parser_update.set_defaults(func=updateHub)

# reconfigure subcommand
parser_reconfigure = subparsers.add_parser('reconfigure', help='regenerate m4 configfiles for existing hub')
parser_reconfigure.add_argument('hubname', help='hubname')
parser_reconfigure.set_defaults(func=reconfigureHub)

# OK, time to make head spin by digging down two subparsers, the configure subparser will have multiple subparsers
parser_configure = subparsers.add_parser('configure', help='various configuration commands')
parser_configure_subparsers = parser_configure.add_subparsers()

# configure/ldap subcommand
parser_configure_ldap = parser_configure_subparsers.add_parser('ldap', help='configure hub ldap')
group = parser_configure_ldap.add_mutually_exclusive_group()
group.add_argument('--enable', dest='enable', help='turn on ldap plugin for hub', action="store_true", default=True)
group.add_argument('--disable', dest='enable', help='turn off ldap plugin for hub', action="store_false", default=False)
parser_configure_ldap.set_defaults(func=ldapConfigure)

# configure/webdav subcommand
parser_configure_webdav = parser_configure_subparsers.add_parser('webdav', help='configure hub webdav')
group = parser_configure_webdav.add_mutually_exclusive_group()
group.add_argument('--enable', dest='enable', help='turn on webdav functionality for hub', action="store_true", default=True)
group.add_argument('--disable', dest='enable', help='turn off webdav functionality for hub', action="store_false", default=False)
parser_configure_webdav.set_defaults(func=_webdavConfigure)

# configure/subversion
parser_configure_subversion = parser_configure_subparsers.add_parser('subversion', help='configure hub ')
group = parser_configure_subversion.add_mutually_exclusive_group()
group.add_argument('--enable', dest='enable', help='turn on subversion functionality for hub', action="store_true", default=True)
group.add_argument('--disable', dest='enable', help='turn off subversion functionality for hub', action="store_false", default=False)
parser_configure_subversion.set_defaults(func=_subversionConfigure)

# configure/filexfer
parser_configure_filexfer = parser_configure_subparsers.add_parser('filexfer', help='configure hub filexfer')
group = parser_configure_filexfer.add_mutually_exclusive_group()
group.add_argument('--enable', dest='enable', help='turn on filexfer functionality for hub', action="store_true", default=True)
group.add_argument('--disable', dest='enable', help='turn off filexfer functionality for hub', action="store_false", default=False)
parser_configure_filexfer.set_defaults(func=filexferConfigure)

# configure/forcecnanno
parser_configure_forcecanon = parser_configure_subparsers.add_parser('forcecanon', help='configure hub forcecanon')
group = parser_configure_forcecanon.add_mutually_exclusive_group()
group.add_argument('--enable', dest='enable', help='turn on forcecanon functionality for hub', action="store_true", default=True)
group.add_argument('--disable', dest='enable', help='turn off forcecanon functionality for hub', action="store_false", default=False)
parser_configure_forcecanon.set_defaults(func=forcecanonConfigure)

# configure/forge
parser_configure_forge = parser_configure_subparsers.add_parser('forge', help='configure hub forge')
group = parser_configure_forge.add_mutually_exclusive_group()
group.add_argument('--enable', dest='enable', help='turn on forge functionality for hub', action="store_true", default=True)
group.add_argument('--disable', dest='enable', help='turn off forge functionality for hub', action="store_false", default=False)
parser_configure_forge.set_defaults(func=_forgeConfigure)

# configure/hostsupdate
parser_configure_hosts = parser_configure_subparsers.add_parser('hosts', help='installs hook to auto update /etc/hosts to include hostname for host IP obtained from DHCP (only matters in VM/DHCP installs)')
group = parser_configure_hosts.add_mutually_exclusive_group()
group.add_argument('--enable', dest='enable', help='turn on forge functionality for hub', action="store_true", default=True)
group.add_argument('--disable', dest='enable', help='turn off forge functionality for hub', action="store_false", default=False)
parser_configure_hosts.set_defaults(func=_createDHCPExitHookFile)

# configure/mailgateway
parser_configure_mailgateway = parser_configure_subparsers.add_parser('mailgateway', help='configure hub metrics')
group = parser_configure_mailgateway.add_mutually_exclusive_group()
group.add_argument('--enable', dest='enable', help='turn on mailgateway functionality for hub', action="store_true", default=True)
group.add_argument('--disable', dest='enable', help='turn off mailgateway functionality for hub', action="store_false", default=False)
parser_configure_mailgateway.set_defaults(func=_mailgateway)

# configure/metrics
parser_configure_metrics = parser_configure_subparsers.add_parser('metrics', help='configure hub metrics')
group = parser_configure_metrics.add_mutually_exclusive_group()
group.add_argument('--enable', dest='enable', help='turn on metrics functionality for hub', action="store_true", default=True)
group.add_argument('--disable', dest='enable', help='turn off metrics functionality for hub', action="store_false", default=False)
parser_configure_metrics.set_defaults(func=_mwMetrics)

# configure/mw-client
parser_configure_mwclient = parser_configure_subparsers.add_parser('mw-client', help='configure hub mw-client')
group = parser_configure_mwclient.add_mutually_exclusive_group()
group.add_argument('--enable', dest='enable', help='turn on mw-client functionality for hub', action="store_true", default=True)
group.add_argument('--disable', dest='enable', help='turn off mw-client functionality for hub', action="store_false", default=False)
parser_configure_mwclient.set_defaults(func=_mwClientConfigure)

# configure/_mw-service
parser_configure_mwservice = parser_configure_subparsers.add_parser('mw-service', help='configure hub mw-service')
group = parser_configure_mwservice.add_mutually_exclusive_group()
group.add_argument('--enable', dest='enable', help='turn on mw-service functionality for hub', action="store_true", default=True)
group.add_argument('--disable', dest='enable', help='turn off mw-service functionality for hub', action="store_false", default=False)
parser_configure_mwservice.set_defaults(func=_mwServiceConfigure)

# configure/submit-server
parser_configure_submitserver = parser_configure_subparsers.add_parser('submit-server', help='configure hub submit server')
group = parser_configure_submitserver.add_mutually_exclusive_group()
group.add_argument('--enable', dest='enable', help='turn on submit server functionality for hub', action="store_true", default=True)
group.add_argument('--disable', dest='enable', help='turn off submit server functionality for hub', action="store_false", default=False)
parser_configure_submitserver.set_defaults(func=_submitserverConfigure)

# configure/ssh
parser_configure_ssh = parser_configure_subparsers.add_parser('ssh', help='configure ssh settings for hub')
group = parser_configure_ssh.add_mutually_exclusive_group()
group.add_argument('--enable', dest='enable', help='turn on ssh functionality for hub', action="store_true", default=True)
group.add_argument('--disable', dest='enable', help='turn off ssh functionality for hub', action="store_false", default=False)
parser_configure_ssh.set_defaults(func=_sshConfigure)

# configure/sftp
parser_configure_sftp = parser_configure_subparsers.add_parser('sftp', help='configure sftp setting for hub')
group = parser_configure_sftp.add_mutually_exclusive_group()
group.add_argument('--enable', dest='enable', help='turn on sftp server functionality for hub', action="store_true", default=True)
group.add_argument('--disable', dest='enable', help='turn off sftp server functionality for hub', action="store_false", default=False)
parser_configure_sftp.set_defaults(func=_sftpConfigure)

# configure/mw-virtualssh
parser_configure_mwvirtualssh = parser_configure_subparsers.add_parser('mw-virtualssh', help='configure mw-virtualssh settings for hub')
group = parser_configure_mwvirtualssh.add_mutually_exclusive_group()
group.add_argument('--enable', dest='enable', help='turn on mw-virtualssh functionality for hub', action="store_true", default=True)
group.add_argument('--disable', dest='enable', help='turn off mw-virtualssh functionality for hub', action="store_false", default=False)
parser_configure_mwvirtualssh.set_defaults(func=_mwVirtualsshConfigure)

# configure/cron
parser_configure_cron = parser_configure_subparsers.add_parser('cron', help='configure cron setting for hub')
group = parser_configure_cron.add_mutually_exclusive_group()
group.add_argument('--enable', dest='enable', help='turn on cron functionality for hub', action="store_true", default=True)
group.add_argument('--disable', dest='enable', help='turn off cron functionality for hub', action="store_false", default=False)
parser_configure_cron.set_defaults(func=_cronConfigure)

# configure/openvz
parser_configure_openvz = parser_configure_subparsers.add_parser('openvz', help='configure openvz setting for hub')
group = parser_configure_openvz.add_mutually_exclusive_group()
group.add_argument('--enable', dest='enable', help='turn on openvz functionality for hub', action="store_true", default=True)
group.add_argument('--disable', dest='enable', help='turn off openvz functionality for hub', action="store_false", default=False)
parser_configure_openvz.set_defaults(func=_openvzConfigure)

# configure/textifier
parser_configure_textifier = parser_configure_subparsers.add_parser('textifier', help='configure hub textifier')
group = parser_configure_textifier.add_mutually_exclusive_group()
group.add_argument('--enable', dest='enable', help='turn on textifier functionality for hub', action="store_true", default=True)
group.add_argument('--disable', dest='enable', help='turn off textifier functionality for hub', action="store_false", default=False)
parser_configure_textifier.set_defaults(func=_textifierConfigure)

# configure/trac
parser_configure_trac = parser_configure_subparsers.add_parser('trac', help='configure hub trac')
group = parser_configure_trac.add_mutually_exclusive_group()
group.add_argument('--enable', dest='enable', help='turn on trac functionality for hub', action="store_true", default=True)
group.add_argument('--disable', dest='enable', help='turn off trac functionality for hub', action="store_false", default=False)
parser_configure_trac.set_defaults(func=_tracConfigure)

# configure/vncproxy
parser_configure_vncproxy = parser_configure_subparsers.add_parser('vncproxy', help='configure hub vncproxy')
group = parser_configure_vncproxy.add_mutually_exclusive_group()
group.add_argument('--enable', dest='enable', help='turn on vncproxy functionality for hub', action="store_true", default=True)
group.add_argument('--disable', dest='enable', help='turn off vncproxy functionality for hub', action="store_false", default=False)
parser_configure_vncproxy.set_defaults(func=_vncProxyConfigure)

# call subcommand
args =  parser.parse_args()

args.func(args)
