#!/usr/bin/python
# @package      hubzero-python
# @file         hzcms
# @author       David Benham <dbenham@purdue.edu>
# @author       Nicholas J. Kisseberth <nkissebe@purdue.edu>
# @copyright    Copyright (c) 2013-2014 HUBzero Foundation, LLC.
# @license      http://www.gnu.org/licenses/lgpl-3.0.html LGPLv3
#
# Copyright (c) 2013-2014 HUBzero Foundation, LLC.
#
# This file is part of: The HUBzero(R) Platform for Scientific Collaboration
#
# The HUBzero(R) Platform for Scientific Collaboration (HUBzero) is free
# software: you can redistribute it and/or modify it under the terms of
# the GNU Lesser General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# HUBzero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# HUBzero is a registered trademark of HUBzero Foundation, LLC.
#

import argparse
import ConfigParser
import errno
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
import subprocess
import sys
import time
import MySQLdb
from distutils.version import LooseVersion, StrictVersion

sourceFilesDir = "usr/lib/hubzero/cms"
hubzeroConfigFilePath = "/etc/hubzero.conf"
hubzero.utilities.misc.JOOMLA_25 = False
HUBZERO_CMS_DIR = "/usr/share/hubzero-cms"

# distribution constants
DIST_DEB = 1
DIST_RH = 2

# default password length for autogenerated passwords
autoGenPWLength = 14

# set some global versioning and distribution variables
if os.path.exists("/usr/share/hubzero-cms-1.3.0/cms/index.php"):
    HUBZERO_CMS_DIR = "/usr/share/hubzero-cms-1.3.0"
    hubzero.utilities.misc.JOOMLA_25 = True
elif os.path.exists("/usr/share/hubzero-cms-1.2.2/cms/index.php"):
    HUBZERO_CMS_DIR = "/usr/share/hubzero-cms-1.2.2"
    hubzero.utilities.misc.JOOMLA_25 = True
elif os.path.exists("/usr/share/hubzero-cms-1.2.1/cms/index.php"):
    HUBZERO_CMS_DIR = "/usr/share/hubzero-cms-1.2.1"
    hubzero.utilities.misc.JOOMLA_25 = True
elif os.path.exists("/usr/share/hubzero-cms-1.2.0/cms/index.php"):
    HUBZERO_CMS_DIR = "/usr/share/hubzero-cms-1.2.0"
    hubzero.utilities.misc.JOOMLA_25 = True
elif os.path.exists("/usr/share/hubzero-cms-1.1.0/cms/index.php"):
    HUBZERO_CMS_DIR = "/usr/share/hubzero-cms-1.1.0"
elif os.path.exists("/usr/share/hubzero-cms/cms/index.php"):
    HUBZERO_CMS_DIR = "/usr/share/hubzero-cms"

# I know, shame on me, using a global
if hubzero.utilities.misc.isRHEL():
	dist = DIST_RH
elif hubzero.utilities.misc.isDebian():
	dist = DIST_DEB
else:
	print "unknown distribution"
	exit(1)


def blockTillMySQLRunning(connAttemptsMax = 10, sleepInterval = 1):
    waitLoop = False
    connAttempt = 1

    while(1):
        if connAttempt > connAttemptsMax:
            print ""
            # if we wait too long, we throw an exception    
            raise Exception("timed out testing for MySQL running check")
        try:
            connAttempt+=1
            time.sleep(sleepInterval)

            # we're just looking to see if the MySQL is running, a failed login attempt
            # will return a different error and we don't care about it
            db = MySQLdb.connect(host="localhost", user="XX~XX", passwd="XX~XX",  db="XX~XX")

        except MySQLdb.OperationalError as e:
            if e.args[0] == 2002: # when mysql is not running
                sys.stdout.write('.')
                sys.stdout.flush()
                waitLoop = True
                continue
        break

    if waitLoop : print ""


def restartWebServer():
# figure we do this enough for a function
	if hubzero.utilities.misc.isRHEL():
		serviceInit('httpd','restart')
	elif hubzero.utilities.misc.isDebian():
		serviceInit('apache2','restart')

# return the user and group for the web user
def webGroup():
    if hubzero.utilities.misc.isRHEL():
        return "apache"
    elif hubzero.utilities.misc.isDebian():
        return "www-data"

# return the user and group for the web user
def webUser():
    if hubzero.utilities.misc.isRHEL():
        return "apache"
    elif hubzero.utilities.misc.isDebian():
        return "www-data"

# return the apache config directory 
def apacheConfigDir():
    if hubzero.utilities.misc.isRHEL():
        return "/etc/httpd/"
    elif hubzero.utilities.misc.isDebian():
        return "/etc/apache2/"


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


def serviceInit(service, action = 'start'):

    serviceScript = '/etc/init.d/' + service

    print "checking " + serviceScript

    if not os.path.exists(serviceScript):
        print "missing " + serviceScript

    print serviceScript + " " + action

    try:
        rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand([serviceScript, action])
    except:
        print serviceScript + " " + action + " failed"
        return -1
    
    if rc : print procStdErr
    
    return rc


def generateAlphaNumPassword(length):
    # we removed I, i, L, l, O, o, and 1 and 0 to avoid ambiguity in generated passwords
    pw = ''.join(random.choice("ABCDEFGHJKMNPQRSTUVWXYZ" + "abcdefghjkmnpqrstuvwxyz" + "23456789") for x in range(length-1)) + (random.choice("23456789"));	
    return pw


def createHubzeroSecretsFile(joomlaAdminPW, mySQLRootPW):

    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.write("MYSQL-ROOT=" + mySQLRootPW  + "\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
    """

    changed = False

    print "checking " + hubzeroConfigFilePath

    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):
            changed = True
            parser.add_section(hubname)

        if not parser.has_option(hubname,'HubName') or parser.get(hubname,'HubName') != hubname:
            changed = True
            parser.set(hubname, "HubName", hubname)
        
        if not parser.has_option(hubname,'documentroot') or parser.get(hubname,'documentroot') != docroot:
            changed = True
            parser.set(hubname, "documentroot", docroot)

        if uri: 
            if not parser.has_option(hubname,'uri') or parser.get(hubname,'uri') != uri:
                changed = True
                parser.set(hubname, "uri", uri)

        if dbname: 
            if not parser.has_option(hubname,'dbname') or parser.get(hubname,'dbname') != dbname:
                changed = True
                parser.set(hubname, "dbname", dbname)

        if makeSiteDefault:
            if not parser.has_option("DEFAULT", 'site') or parser.get("DEFAULT",'site') != hubname:
                changed = True
                parser.set("DEFAULT", "site", hubname)

        if changed:
            print "updating " + hubzeroConfigFilePath
            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):
    print "copy_tree " + src + " " +  dest
    # 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])
    hubzero.utilities.misc.exShellCommand(['chmod', '-R', 'g+rw', dest])


def _setMySQLPW(args):
    setMySQLPW(args.username, args.pw, dist)


def setMySQLPW(username, pw, dist):
    print "setting MYSQL pw for user: " + username

    if dist == DIST_DEB:
            mysql_service = "/etc/init.d/mysql"
    else:
            mysql_service = "/etc/init.d/mysqld"

    if os.path.exists('/var/run/mysqld/mysqld.pid'):
        os.system(mysql_service + " stop")

        # wait for mysql to stop
        while os.path.exists('/var/run/mysqld/mysqld.pid'): pass
    else:
        # this could be first mysql start, if so we need a normal start to create the mysql database
        os.system(mysql_service + " start")
        while not os.path.exists('/var/run/mysqld/mysqld.pid'): pass

        # wait for mysql to stop
        os.system(mysql_service + " stop")
        while os.path.exists('/var/run/mysqld/mysqld.pid'): pass

    # use subprocess to keep process around after it starts, use mysqld_safe to bypass security checks,
    # allows for password changes (especially for root) without having to know root's password
    subprocess.Popen(["/usr/bin/mysqld_safe", "--skip-grant-tables" , "--skip-networking"])

    # wait for mysql server to restart
    print "waiting for mysql to restart"

    while not os.path.exists('/var/run/mysqld/mysqld.pid'): pass

    blockTillMySQLRunning()

    # change password
    print "changing mysql password for " + username

    sql =  'use mysql; '
    sql += 'update user set password=PASSWORD("' + pw + '") where User="' + username + ' "; ';
    sql += 'flush privileges; '
    os.system('mysql -u root -e ' + "'" + sql + "'")

    # restart normal mysql server
    os.system(mysql_service + " stop")
    while os.path.exists('/var/run/mysqld/mysqld.pid'): pass
    os.system(mysql_service + " start")
    while not os.path.exists('/var/run/mysqld/mysqld.pid'): pass

    blockTillMySQLRunning()



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")	

    hostname = gethostname()

    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", webUser() + ":" + webGroup(), 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

    if isinstance(mode,basestring):
        if mode.startswith('0'):

            nmode = int(mode,0)
        else:
            nmode = int(mode,8)
    else:
        nmode = mode

    if verbose:
        print "checking " + filename

    if not os.path.exists(filename):
        if verbose:
           print "creating " + 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

    if isinstance(mode,basestring):
        if mode.startswith('0'):
            nmode = int(mode,0)
        else:
            nmode = int(mode,8)
    else:
        nmode = mode

    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 initPhpErrorLog(logfile = '/var/log/php/error.log', forceChange = False):

    filename = '/etc/php5/apache2/php.ini'
    configtxt = ''

    if os.path.exists(filename):
        fh = open(filename, 'r+')
        configtxt = fh.read()
    else:
        return True

    if (not forceChange):
        m = re.search(r'(?im)^\s*error_log\s*=\s*(.*)\s*$', configtxt)

        if (m != None):
            logfile = m.group(1)

    (txt, n) = re.subn(r'(?im)^\s*error_log\s*=\s*(.*)\s*$', 'error_log = ' + logfile + "\n", configtxt)

    if (n == 0):
        (txt, n) = re.subn(r'(?im)^\s*;\s*error_log\s*=\s*(.*)\s*$', 'error_log = ' + logfile + "\n", configtxt, 1)

    if (n == 0):
        txt = configtxt.rstrip() + "\n" + "error_log = " + logfile + "\n"

    if (txt != configtxt):
        fh.seek(0)
        fh.write(txt)
        fh.truncate()
        print "patched " + filename
        serviceInit('apache2','restart')

    fh.close()

    createDir(os.path.dirname(logfile), "0750", "root", webGroup(), resetattrs=True)
    createFile(logfile, "0750", webUser(), webGroup(), resetattrs=True)

    return True

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

    createDir("/var/log/hubzero-cms", "0775", "root", webServerGroup, resetattrs=True)
    createDir("/var/log/hubzero-cms/daily", "0770", "root", webServerGroup, resetattrs=True)
    createDir("/var/log/hubzero-cms/daily/imported", "0770", "root", webServerGroup, resetattrs=True)
    createDir("/var/log/hubzero-cms/archive", "0770", "root", webServerGroup, 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", webServerUser, webServerGroup, resetattrs=True)

def checkConfigurationPhp(docroot, verbose=True):

    filename = docroot + "/configuration.php"

    if verbose:
        print "checking " + filename

    st = os.stat(filename)

    if (st.st_mode & stat.S_IROTH):
        if verbose:
            print "chmod %#o" % (st.st_mode & ~stat.S_IROTH) + " " + filename

        os.chmod(filename,st.st_mode&~stat.S_IROTH)


def m4Processing(inputFileName, outputFileName, m4ArgsArray, mode=-1, owner=-1, group=-1, resetattrs=False, verbose=True):
    rc = False

    try:
        ownerUid = int(owner)
        if ownerUid == -1:
            owner = "-1"
        else:
            owner = pwd.getpwuid(ownerUid).pw_name
    except ValueError:
        ownerUid = pwd.getpwnam(owner).pw_uid

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

    if isinstance(mode,basestring):
        if mode.startswith('0'):
            nmode = int(mode,0)
        else:
            nmode = int(mode,8)
    else:
        nmode = mode

    filename = outputFileName

    if verbose:
        print "checking " + outputFileName

    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()
        rc = 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)

    return rc


def _mySQLDatabaseSetup(args):

    dbPW, mysqlRootPW = mySQLDatabaseSetup(args.dbname, 'localhost', dist)

    loadSQLSchema(args.dbname, "localhost", args.dbname, args.dbname, dbPW, "jos_")
    loadSQLTableData(args.dbname, "localhost", args.dbname, args.dbname, dbPW, "jos_")


def mySQLDatabaseSetup(dbName, host, dist, dbPW = '', dbRootPW=''):
    """
    dbName - name of new database
    host - database host
    dbRootPW - pw for the DB root user
    Dist - distribution - Deb/RH

    """
    if not dbPW:
        dbPW = generateAlphaNumPassword(14)

    print "creating mySQL databases"

    if dist == DIST_DEB:

        # Creating 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

        # Set that user's password
        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

    elif dist == DIST_RH:

        # create hub database
        rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(
            ["/usr/bin/mysql",
            "-u", "root", "-p" + dbRootPW,
            "-e", "CREATE DATABASE " + dbName])

        if procStdOut: print procStdOut.strip()
        if rc : print procStdErr

        # metrics database
        print "creating database: " + dbName + "-metrics"
        if dist == DIST_DEB:
            rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(
                ["/usr/bin/mysql",
                "-u", "root", "-p" + dbRootPW,
                "-e", "CREATE DATABASE " + dbName + "_metrics"])

        if procStdOut: print procStdOut.strip()
        if rc : print procStdErr

        # Create db user with full permissions over the new database
        # Note: user name matches database name
        print "creating database user: " + dbName
        rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand([
            "/usr/bin/mysql",
            "-u", "root", "-p" + dbRootPW,
            "-e", "GRANT ALL PRIVILEGES ON " + dbName + ".* TO " + dbName + "@localhost"])

        if procStdOut: print procStdOut.strip()
        if rc : print procStdErr

        # Set that user's password
        print "setting database password for user: " + dbName
        rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(
            ["/usr/bin/mysql",
            "-u", "root", "-p" + dbRootPW,
            "-e", "SET PASSWORD FOR " + dbName + "@localhost = PASSWORD('" + dbPW + "'); flush privileges;"])

        if procStdOut: print procStdOut.strip()
        if rc : print procStdErr

    else:
        raise Exception("mySQLDatabaseSetup error, unknown dist: " + dist)

    return dbPW


def generateLogRotateFiles(hubname):

    sfilename = HUBZERO_CMS_DIR + "/conf/logrotate-cmsdebug.m4"

    if os.path.exists(sfilename):
        tfilename = "/etc/logrotate.d/" + hubname + "-cmsdebug"
        m4Processing(sfilename, tfilename, ["-DHUBNAME=" + hubname], 0644, "root", "root", resetattrs=True, verbose=True)	

    sfilename = HUBZERO_CMS_DIR + "/conf/logrotate-cmsauth.m4"

    if os.path.exists(sfilename):
        tfilename = "/etc/logrotate.d/" + hubname + "-cmsauth"
        m4Processing(sfilename, tfilename, ["-DHUBNAME=" + hubname], 0644, "root", "root", resetattrs=True, verbose=True)	

    sfilename = HUBZERO_CMS_DIR + "/conf/logrotate-cmsprofile.m4"

    if os.path.exists(sfilename):
        tfilename = "/etc/logrotate.d/" + hubname + "-cmsprofile"
        m4Processing(sfilename, tfilename, ["-DHUBNAME=" + hubname], 0644, "root", "root", resetattrs=True, verbose=True)	

    sfilename = HUBZERO_CMS_DIR + "/conf/logrotate-hub-access.m4"

    if os.path.exists(sfilename):
        tfilename = "/etc/logrotate.d/" + hubname + "-access"
        m4Processing(sfilename, tfilename, ["-DHUBNAME=" + hubname], 0644, "root", "root", resetattrs=True, verbose=True)	

    sfilename = HUBZERO_CMS_DIR + "/conf/logrotate-hub-error.m4"

    if os.path.exists(sfilename):
        tfilename = "/etc/logrotate.d/" + hubname + "-error"
        m4Processing(sfilename, tfilename, ["-DHUBNAME=" + hubname], 0644, "root", "root", resetattrs=True, verbose=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"
        print "checking " + apache2lr
        apache2lrfh = open(apache2lr,'r+')
        apache2lrtxt = apache2lrfh.read()
        txt = re.sub(pattern1, repl1, apache2lrtxt)
        if (txt != apache2lrtxt):
            apache2lrfh.seek(0)
            apache2lrfh.write(txt)
            apache2lrfh.truncate()
            print "patched " + apache2lr
        apache2lrfh.close()
    except:
        print "Failed to patch file " + apache2lr
        pass

def generateApacheConfFiles(hubname, dist):

    if dist == DIST_DEB:
		m4dir = "/etc/apache2/sites-m4/"
    elif dist == DIST_RH:
		m4dir = "/etc/httpd/sites-m4/"
    else:
		print "generateApacheConfFiles error, unknown disttirbution" + dist
		return 1

    print "m4 processing to " + m4dir

    if not os.path.exists(m4dir):
            print "creating " + m4dir
            createDir(m4dir, "0755", "root", "root")

    print "cp /usr/share/hubzero-cms/conf/hub.m4 " + m4dir + hubname + ".m4"
    hubzero.utilities.misc.exShellCommand(["cp", HUBZERO_CMS_DIR + "/conf/hub.m4", m4dir + hubname + ".m4"])
    hubzero.utilities.misc.exShellCommand(['chmod', "'", m4dir + hubname + ".m4"])
    hubzero.utilities.misc.exShellCommand(['chown', "root.root", m4dir + hubname + ".m4"])

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

    # do the M4 processing
    generateApacheM4config(hubname)

    if dist == DIST_RH and os.path.exists("/etc/httpd/conf.d/ssl.conf"):
        os.remove("/etc/httpd/conf.d/ssl.conf")


def generateApacheM4config(hubname):

    generatedM4File = False

    # 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 = []

    fqdn = gethostname()
    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 hubzero.utilities.misc.isDebian():

        # log file location in debian
        m4ApacheConfigOptions.append("-DWEBLOGFILEROOT=${APACHE_LOG_DIR}")

        m4ApacheConfigOptions.append("-DSSLCERTFILE=/etc/ssl/certs/ssl-cert-snakeoil.pem")
        m4ApacheConfigOptions.append("-DSSLCERTKEYFILE=/etc/ssl/private/ssl-cert-snakeoil.key")
        m4ApacheConfigOptions.append("-DTRACROOT=/usr/share/pyshared/")
        m4ApacheConfigOptions.append("-DAPACHE_HOME=apache2")
        m4ApacheConfigOptions.append("-DDISTDEB=1")

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

            #print "processing /etc/apache2/sites-m4/" + hubname + "-ssl.m4 to /etc/apache2/sites-available/" + hubname + "-ssl"
            m4Processing("/etc/apache2/sites-m4/" + hubname + "-ssl.m4",
                         "/etc/apache2/sites-available/" + hubname + "-ssl",
                         m4ApacheConfigOptions,
                         0644, "root", "root")

            generatedM4File = True

    elif hubzero.utilities.misc.isRHEL():

        # log file location in rh, logs is a symbolic link to /var/log/httpd
        m4ApacheConfigOptions.append("-DWEBLOGFILEROOT=logs")

        m4ApacheConfigOptions.append("-DSSLCERTFILE=/etc/ssl/certs/opensourcehub-selfsignedcert.crt")
        m4ApacheConfigOptions.append("-DSSLCERTKEYFILE=/etc/ssl/certs/private/opensourcehub-selfsignedcert.key")
        m4ApacheConfigOptions.append("-DTRACROOT=/usr/lib/python%d.%d/site-packages/" % (sys.version_info[0], sys.version_info[1]))
        m4ApacheConfigOptions.append("-DAPACHE_HOME=httpd")
        m4ApacheConfigOptions.append("-DDISTRH=1")

        if not os.path.exists("/etc/httpd/sites-m4"):
            print "/etc/httpd/sites-m4 doesn't exist, skipping m4 reconfiguration"
        else:
            #print "processing /etc/httpd/sites-m4/" + hubname + ".m4 to /etc/httpd/conf.d/" + hubname + ".conf"
            m4Processing("/etc/httpd/sites-m4/" + hubname + ".m4",
                         "/etc/httpd/conf.d/" + hubname + ".conf",
                         m4ApacheConfigOptions,
                         0644, "root", "root")

            #print "processing /etc/httpd/sites-m4/" + hubname + "-ssl.m4 to /etc/httpd/conf.d/" + hubname + "-ssl.conf"
            m4Processing("/etc/httpd/sites-m4/" + hubname + "-ssl.m4",
                         "/etc/httpd/conf.d/" + hubname + "-ssl.conf",
                         m4ApacheConfigOptions,
                         0644, "root", "root")

            generatedM4File = True

    else:
        print "generateApacheM4config error, unrecognized Linux distribution "

    return generatedM4File


def replacePrefix(sql, prefix = '#__', tablePrefix = 'jos_'):
    # Initialize variables.
    escaped = False
    startPos = 0
    quoteChar = ''
    literal = ''

    sql = sql.strip()
    n = len(sql)

    while (startPos < n):
        ip = sql.find(prefix, startPos)

        if (ip == -1):
            break
    
        j = sql.find("'", startPos)

        k = sql.find('"', startPos)

        if ((k != -1) and ((k < j) or (j == -1))):
            quoteChar = '"'
            j = k
        else:
            quoteChar = "'"

        if (j == -1):
            j = n

        sub = sql[startPos:j]

        literal += sub.replace(prefix, tablePrefix)

        startPos = j

        j = startPos + 1

        if (j >= n):
            break

        # quote comes first, find end of quote
        while (True):
            k = sql.find(quoteChar, j)

            escaped = False

            if (k == -1):
                break

            l = k - 1

            while (l >= 0 and sql[l] == '\\'):
                l = l - 1
                escaped = not escaped

            if (escaped):
                j = k + 1
                continue

            break

        if (k == -1):
            # error in the query - no end quote; ignore it
            break

        sub = sql[startPos:(k+1)]
        literal += sub
        startPos = k + 1

    if (startPos < n):
        sub = sql[startPos:n]
        literal += sub
    
    return literal

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

    if hubzero.utilities.misc.JOOMLA_25:
        dbsqlfile = open(HUBZERO_CMS_DIR + "/cms/installation/sql/mysql/joomla.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)
                sqlStatement = replacePrefix(sqlStatement, "#__", dbTablePrefix)
                db.query_rowcount(sqlStatement, None)

    dbsqlfile = open(HUBZERO_CMS_DIR+"/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:

        try:
                if sqlStatement.strip() != "" :
                    #sqlStatement = string.replace(sqlStatement, "#__", dbTablePrefix)
                    sqlStatement = replacePrefix(sqlStatement, "#__", dbTablePrefix)
                    db.query_rowcount(sqlStatement, None)
        except Exception as e:
                # print out the problem, but don't stop
                print "SQL schema import exception" + str(e)


def loadSQLTableData(hubname, dbHost, dbName, dbUserName, dbPW, dbTablePrefix = 'jos_'):
    """
    Load the hubzero sample data
    """

    dbsqlfile = open(HUBZERO_CMS_DIR + "/cms/installation/sql/mysql/hz_sample_data.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)
            sqlStatement = replacePrefix(sqlStatement, "#__", dbTablePrefix)
            db.query_rowcount(sqlStatement, 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(HUBZERO_CMS_DIR+"/cms/installation/template/tmpl/configuration.html"):
        print "cannot find " + HUBZERO_CMS_DIR + "/cms/installation/template/tmpl/configuration.html"
        return 1

    configfile = open(HUBZERO_CMS_DIR+"/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")
    configfileText = configfileText.replace("{VAR_ENV|addslashes}", "production")

    configFilePath = docroot + "/configuration.php"

    print "creating " + configFilePath

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

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


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


def createSSLCerts():

    # create the private subdir of the certs directory
    if not os.path.exists("/etc/ssl/certs/private"):
        os.makedirs("/etc/ssl/certs/private")

    p = subprocess.Popen(["/usr/bin/openssl",
        "req", "-newkey", "rsa:2048",
        "-keyout", "/etc/ssl/certs/private/opensourcehub-selfsignedcert.key",
        "-nodes", "-x509", "-days", "3650",
        "-out", "/etc/ssl/certs/opensourcehub-selfsignedcert.crt"],
        stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

    p.stdin.write('--\nsomestate\nsomecity\nsomeorg\nsomeou\nlocalhost.localdomain\nroot@localhost.localdomain\n')

    #for line in p.stdout:
    #    print line

    #for line in p.stderr:
    #    print line


def deleteHub(args):

    hubname = args.hubname

    parser = ConfigParser.ConfigParser()
    parser.optionxform = str
    parser.read(hubzeroConfigFilePath)
    if parser.has_option(hubname, "documentroot"):
        docroot = parser.get(hubname, "documentroot")
    else:
        print "no documentroot in /etc/hubzero.conf for " + args.hubname
        exit()

    # get root pw
    if os.path.exists("/root/.my.cnf"):
        config = ConfigParser.RawConfigParser()
        config.read("/root/.my.cnf")
        newRootPW = config.get("client", "password")
    else:
        # just blow it away
        newRootPW = generateAlphaNumPassword(10)
        setMySQLPW('root', newRootPW, dist)

        with open('/root/.my.cnf', 'w') as f:
            f.write("[client]\nuser=root\npassword=" + newRootPW + "\n")
        
    # delete the database
    print "deleting database " + hubname
    rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand([
        "/usr/bin/mysql",
         "-u", "root", 
         "-p" + newRootPW,
         "-e", "DROP DATABASE " + hubname])

    # delete the web root
    print "removing " + docroot
    if os.path.isdir(docroot):
        distutils.dir_util.remove_tree(docroot)

    # delete /etc/hubzero.secrets
    try:
        os.remove("/etc/hubzero.secrets")
    except OSError as e:
        if e.errno != errno.ENOENT:
            raise


def availableCMSVersions():
    files = glob.glob("/usr/share/hubzero-cms-*/cms")

    versions = []

    for file in files:
        file = file.strip()

        if not os.path.isdir(file):
            continue

        m = re.match(r'^/usr/share/hubzero-cms-(\d.*)/cms$', file)

        if m:
            versions.append([m.group(1),file])

    if os.path.isdir("/usr/share/hubzero-cms/cms/libraries/Hubzero/Oauth"):
        versions.append(["1.1.0","/usr/share/hubzero-cms"])
    elif os.path.isdir("/usr/share/hubzero-cms/cms/libraries/Hubzero/Session"):
        versions.append(["1.0.0","/usr/share/hubzero-cms"])
    elif os.path.isdir("/usr/share/hubzero-cms/cms/libraries/Hubzero"):
        versions.append(["0.8.0","/usr/share/hubzero-cms"])

    return versions


def installHub(args):

    # Debian or RH?
    if hubzero.utilities.misc.isDebian():
        print "Debian install"
        return installHubDebian(args)
    elif hubzero.utilities.misc.isRHEL():
        print "RHEL install"
        return installHubRH(args)
    else:
	print "Error: unknown distribution"
        return 1

def a2enmod(name):
    print "enabling apache mod '" + name + "'"
    rc, stdOut, stdErr = hubzero.utilities.misc.exShellCommand(["a2enmod", name])
    for s in stdOut.split("\n"):
	if "Enabling module" in s:
            continue
        if "to activate new configuration" in s:
            continue
        if "on how to configure SSL" in s:
            continue
        if "already enabled" in s:
            continue
        if "To activate the new configuration" in s:
            continue
        if "service apache2 restart" in s:
            continue
        if s.strip() == "":
            continue

        print s.strip()
    if rc: print stdErr

def installHubDebian(args):

    if validateArgs(args) != 0:
        return 1

    wwwOwner = webUser()
    wwwGroup = webGroup()

    hubname = args.hubname
    hostname = gethostname()

    # 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"

    initPhpErrorLog()

    # 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)

    copyCMSFiles(HUBZERO_CMS_DIR + "/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, wwwOwner, wwwGroup)

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

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

    # setup the databases
    print "setting up the databases"
    dbName = hubname
    dbUserName = hubname
    mySQLDatabaseSetup(hubname, "localhost", dist, dbPW)

    createPHPConfigurationFile(
        hubname, 
        docroot, 
        hubname, 
        dbPW, 
        args.dbprefix, 
        args.siteadminemail, 
        args.siteadminfirstname + ' ' + args.siteadminlastname,
        args.mailfrom,
        installKey,
        webUser(),
        webGroup())	

    createHubConfigFile(hubname)

    generateLogRotateFiles(hubname)

    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)	

    a2enmod("rewrite")
    a2enmod("ssl")
   
    # generate the apache web config files
    if not apacheOgreManaged():
        generateApacheConfFiles(hubname, DIST_DEB)

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


    if not os.path.exists("/root/.my.cnf"):
        rootmysqlpw = generateAlphaNumPassword(autoGenPWLength)
        setMySQLPW('root', rootmysqlpw, DIST_DEB)

        with open('/root/.my.cnf', 'w') as f:
            f.write("[client]\nuser=root\npassword=" + rootmysqlpw + "\n")
    else:
        config = ConfigParser.RawConfigParser()
        config.read("/root/.my.cnf")
        rootmysqlpw = config.get("client", "password")

    updateTimezoneDatabase(True, rootmysqlpw)

    # create home directory for the hub
    hubHomeDir = "/home/" + hubname
    if not os.path.exists(hubHomeDir):
        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
    if not apacheOgreManaged():
        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 (webUser()+":"+webGroup() 0770)
    createDir("/srv/" + args.hubname, '0770', webUser(), webGroup(), resetattrs=True)

    #create /srv/hubname/projects (webUser()+":"+webGroup() 0770)
    createDir("/srv/" + args.hubname + "/projects", '0770', webUser(), webGroup(), 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')

    serviceInit('apache2','restart')

    if args.createsecretsfile:
        createHubzeroSecretsFile(adminpw, rootmysqlpw)

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

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

    dataviewerConfigure(True)
    cronEnable()

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

    return(0)


def apacheOgreManaged():
    # gonna assume if ogre owns this file, then it owns all apache
    return OgreManaged("/etc/httpd/conf/httpd.conf")


def installHubRH(args):

    hubname = args.hubname
    wwwOwner = 'apache'
    wwwGroup = 'apache'

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

    # check the hubname
    p = re.compile("^[a-zA-Z][a-zA-Z0-9]+$")
    m = p.match(hubname)
    if not m:
        print "ERROR - hubname must be alphanumeric and start with a letter"
        return(1)

    docroot = args.docroot + "/" + hubname

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

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

    # 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"

    # 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)

    copyCMSFiles(HUBZERO_CMS_DIR + "/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, wwwOwner, wwwGroup)

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

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

    createPHPConfigurationFile(hubname,
                               docroot,
                               hubname,
                               dbPW,
                               args.dbprefix,
                               args.siteadminemail,
                               args.siteadminfirstname + ' ' + args.siteadminlastname,
                               args.mailfrom,
                               installKey,
                               webUser(),
                               webGroup())

    createHubConfigFile(hubname)

    generateLogRotateFiles(hubname)

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

    if not os.path.exists("/root/.my.cnf"):
        rootmysqlpw = generateAlphaNumPassword(autoGenPWLength)
        setMySQLPW('root', rootmysqlpw, DIST_RH)

        with open('/root/.my.cnf', 'w') as f:
            f.write("[client]\nuser=root\npassword=" + rootmysqlpw + "\n")
    else:
        config = ConfigParser.RawConfigParser()
        config.read("/root/.my.cnf")
        rootmysqlpw = config.get("client", "password")

    updateTimezoneDatabase(True, rootmysqlpw)

    # setup the databases, pw of the new database owner is passed back
    print "setting up the databases"
    dbName = hubname
    dbPW = mySQLDatabaseSetup(hubname, "localhost", DIST_RH, dbPW, rootmysqlpw)

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

    print "loading default data into database"
    loadSQLTableData(hubname, "localhost", dbName, 'root', rootmysqlpw, args.dbprefix)

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

    # see if apache orge files are OGRE managed
    if not apacheOgreManaged():
        generateApacheConfFiles(hubname, DIST_RH)

    # create apache conf.d directory for the hub
    # Todo, check to see if conf.d is zero length file, delete if present.
    if not OgreManaged("/etc/httpd/conf/httpd.conf"):
        confDir = "/etc/httpd/" + 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 (apache:apache 0770)
    createDir("/srv/" + args.hubname, '0770', 'apache', 'apache')

    #create /srv/hubname/projects (apache:apache 0770)
    createDir("/srv/" + args.hubname + "/projects", '0770', 'apache', 'apache')

    #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')

    # create /etc/hubzero.secrets file
    if args.createsecretsfile:
        createHubzeroSecretsFile(adminpw, rootmysqlpw)

    # create certs
    print "creating self signed SSL certificates for website"
    createSSLCerts()

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

    # 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)

    dataviewerConfigure(True)
    cronEnable()

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

    return(0)


def OgreManaged(filename):
    if not os.path.exists(filename):
        return False
    else:
        with open(filename, 'r') as f:
            ftxt = f.read()

            if "### WARNING Ogre Managed ###" in ftxt:
                return True
            else:
                return False

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 serviceInit(service, action = 'start'):

    serviceScript = '/etc/init.d/' + service

    print "checking " + serviceScript

    if not os.path.exists(serviceScript):
        print "missing " + serviceScript

    print serviceScript + " " + action

    try:
        rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand([serviceScript, action])
    except:
        print serviceScript + " " + action + " failed"
        return -1
    
    if rc : print procStdErr
    
    return rc


def nscdInvalidate(passwords = True, groups = True):

    print "checking /etc/init.d/nscd status"
    try:
        rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["/etc/init.d/nscd", "status"])
    except:
        print "/etc/init.d/nscd status check failed"
        return

    if rc == 0:
        if passwords:
            print "invalidating nscd password cache"
            print "/usr/sbin/nscd -i passwd"
            rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["/usr/sbin/nscd", "-i", "passwd"])
            if rc : print procStdErr
        if groups:
            print "invalidating nscd group cache"
            print "/usr/sbin/nscd -i group"
            rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["/usr/sbin/nscd", "-i", "group"])
            if rc : print procStdErr
    else:
        print "nscd not running, can't invalidate cache(s)"
  

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

def ldapConfigure(enable):

    if enable:
        print "enabling LDAP support"
        hubzero.config.webconfig.setPluginEnabled('user', 'ldap', True)
        hubzero.utilities.group.syncgroups(verbose=True)
        hubzero.utilities.user.syncusers(verbose=True)
        nscdInvalidate()
        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"
        nscdInvalidate()
        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 not os.path.exists("/etc/modules"):
        print "creating /etc/modules file"
        with open('/etc/modules', 'a'):
            os.utime('/etc/modules', None)


    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.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')

        if dist == DIST_DEB:
            f2.write("*  -fstype=usermap,user=www-data,source_user=&,allow_other :/home/" + hubname + "/&")
        else:
            f2.write("*  -fstype=usermap,user=apache,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.truncate()
                print "patched " + modulesfn
                    
                print "/sbin/modprobe fuse"
                rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["/sbin/modprobe", "fuse"])  
                print procStdOut
                if rc: print procStdErr 

            modulesfh.close()

        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.truncate()
        #        print "patched " + modulesfn
        #    modulesfh.close()
        #except:
        #    print "Failed to patch file " + modulesfn
        #    pass

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

    serviceInit('autofs','restart')

    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", "0755", "root", "root", resetattrs=True)
        createDir("/opt/trac", "0755",  webUser(),  webGroup(), resetattrs=True)
        createDir("/opt/trac/tools", "0770",  webUser(),  webGroup(), resetattrs=True)		

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

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

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
    if generateApacheM4config(hubname):
        restartWebServer()

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


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

    if 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
    if generateApacheM4config(hubname):
        restartWebServer()


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")

        # apps should be in the web user group (!)
        print "checking 'apps' user in '" + webGroup() + "' group"
        group = grp.getgrnam(webGroup())
        if ('apps' not in group.gr_mem):
            print "usermod -a -G %s apps" % webGroup()
            hubzero.utilities.misc.exShellCommand(["usermod","-a","-G",webGroup(),"apps"])

        # admin should be in the apps group
        print "checking 'admin' user in 'apps' group"
        if not hubzero.utilities.group.userInGroup("admin","apps"):
            print "adding 'admin' user to 'apps' group"
            hubzero.utilities.group.addUserToGroup("admin","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(webUser() + "\tALL=(apps)NOPASSWD:/usr/bin/finalizetool\n")
            f1.write(webUser() + "\tALL=(apps)NOPASSWD:/usr/bin/installtool\n")
            f1.write(webUser() + "\tALL=(apps)NOPASSWD:/usr/bin/licensetool\n")
            f1.write(webUser() + "\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(".*"+ webUser() +"\\s+ALL=\\(apps\\)NOPASSWD:/usr/bin/finalizetool\n", "", filetext, re.MULTILINE | re.DOTALL)
            filetext += webUser() + "\tALL=(apps)NOPASSWD:/usr/bin/finalizetool\n"

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

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

            filetext = re.sub(".*"+ webUser() +"\\s+ALL=\\(root\\)NOPASSWD:/etc/init.d/apache2\n", "", filetext, re.MULTILINE | re.DOTALL)
            filetext += webUser() + "\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(autoGenPWLength)

        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
    if generateApacheM4config(hubname):
        restartWebServer()


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", "0755", "root", "root", resetattrs=True)
        createDir("/opt/svn", "0750", webUser(), webGroup(), resetattrs=True)
        createDir("/opt/svn/tools", "0750", webUser(), webGroup(), resetattrs=True)
        createDir(apacheConfigDir() + hubname + ".conf.d", "0755", "root", "root", resetattrs=True)
        createDir(apacheConfigDir() + hubname + ".conf.d/svn", "0700", webUser(), webGroup(), resetattrs=True)

    else:
        print "disabling subversion"
        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 " + apacheConfigDir + " " + hubname + ".conf.d/svn"
        createDir(apacheConfigDir() + hubname + ".conf.d", "0755", "root", "root", resetattrs=True)
        createDir(apacheConfigDir() + hubname + ".conf.d/svn", "0700", webUser(), webGroup(), resetattrs=True)
        os.rename(apacheConfigDir() + "svn.conf", apacheConfigDir() + hubname + ".conf.d/svn/svn.conf")

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

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

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","nobody" if dist== DIST_RH else "nogroup",'-m',"-s","/bin/false","vncproxy"])  
            print procStdOut
            if rc: print procStdErr 
    
        createDir("/var/log/vncproxy", "0750", webUser(), "adm", resetattrs=True)
        createDir("/var/log/vncproxyd", "0750", "vncproxy", "adm", resetattrs=True)
        modifyHubConfigFile('apache-config', 'enable_vncproxy', 'true')

        # add the load module for the vncproxy to the end of the LoadModule lines in /etc/httpd/conf/httpd.conf
        if dist == DIST_RH:
            filename = "/etc/httpd/conf/httpd.conf"
            f = open(filename, "r+")
            configtxt = f.read()
            txt = re.sub(re.compile(r'(LoadModule.*)(\n){2,}'), r'\1\nLoadModule vncproxy_module modules/mod_vncproxy.so\n\n', configtxt)

            if configtxt != txt:
                f.seek(0)
                f.write(txt)
                f.truncate()
                print "patched " + filename
            f.close()

    else:
        print "disabling vncproxy"
        modifyHubConfigFile('apache-config', 'enable_vncproxy', 'false')

        # comment out all vncProxy lines in in /etc/httpd/conf/httpd.conf
        if dist == DIST_RH:
            filename = "/etc/httpd/conf/httpd.conf"
            f = open(filename, "r+")
            configtxt = f.read()
            txt = re.sub(re.compile(r'^(LoadModule vncproxy_module.*)$', re.MULTILINE), r'#\1', configtxt)

            if configtxt != txt:
                f.seek(0)
                f.write(txt)
                f.truncate()
                print "patched " + filename
                f.close()


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


def _dataviewerConfigure(args):
    dataviewerConfigure(args.enable)


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

    if enable:
        print "enabling dataviewer"

        db_host = hubzero.config.webconfig.getPluginParam("projects","databases","db_host")
        db_user = hubzero.config.webconfig.getPluginParam("projects","databases","db_user")
        db_password = hubzero.config.webconfig.getPluginParam("projects","databases","db_password")
        db_ro_user = hubzero.config.webconfig.getPluginParam("projects","databases","db_ro_user")
        db_ro_password = hubzero.config.webconfig.getPluginParam("projects","databases","db_ro_password")

        if (db_password == 'datawriter_pw') or (db_password == '') or (db_password == None):
          	rwPW = generateAlphaNumPassword(autoGenPWLength)
        else:
            rwPW = db_password

        if (db_ro_password == 'dataviewer_pw') or (db_ro_password == '') or (db_ro_password == None):
            roPW = generateAlphaNumPassword(autoGenPWLength)
        else:
            roPW = db_ro_password

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

        print "creating database user: dataviewer, password = " + roPW

        rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["/usr/bin/mysql", 
                                                                        "--defaults-file=/etc/mysql/debian.cnf",
                                                                        "-e", "GRANT SELECT ON `prj\_db\_%`.* TO 'dataviewer'@'localhost' IDENTIFIED BY '" + roPW + "'"])
        if procStdOut: print procStdOut.strip()
        if rc : print procStdErr

        print "creating database user: datawriter, password = " + rwPW

        rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["/usr/bin/mysql", 
                                                                        "--defaults-file=/etc/mysql/debian.cnf",
                                                                        "-e", "GRANT CREATE,DROP,SELECT,INSERT,UPDATE,DELETE ON `prj\_db\_%`.* TO 'datawriter'@'localhost' IDENTIFIED BY '" + rwPW + "'"])
        if procStdOut: print procStdOut.strip()
        if rc : print procStdErr

        hubzero.config.webconfig.addPluginParam("projects","databases","db_password",rwPW)
        hubzero.config.webconfig.addPluginParam("projects","databases","db_host","localhost")
        hubzero.config.webconfig.addPluginParam("projects","databases","db_user","datawriter")
        hubzero.config.webconfig.addPluginParam("projects","databases","db_ro_user","dataviewer")
        hubzero.config.webconfig.addPluginParam("projects","databases","db_ro_password",roPW)
    else:
        print "disabling dataviewer [THIS DOESN'T ACTUALLY CHANGE ANYTHING YET]"


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


def mwServiceConfigure(enable):
    hubname = hubzero.config.webconfig.getDefaultSite()	
    enable_mw_service = hubzero.config.webconfig.getHubSiteConfig(hubname, "package-config", "mw-service")
    
    if enable:
            
        if enable_mw_service.lower() != 'true':
            print "enabling mw-service"

        # turn off disk quota
        print "checking /etc/vz/vz.conf"
        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"

        if os.path.exists("/var/lib/vz/template/debian-7.0-amd64-maxwell"):
            ovz_session = "7.0-amd64"
        elif os.path.exists("/var/lib/vz/template/debian-7.0-i386-maxwell"):
            ovz_session = "7.0-i386"
        elif os.path.exists("/var/lib/vz/template/debian-6.0-amd64-maxwell"):
            ovz_session = "6.0-amd64"
        elif os.path.exists("/var/lib/vz/template/debian-6.0-i386-maxwell"):
            ovz_session = "6.0-i386"
        elif os.path.exists("/var/lib/vz/template/debian-5.0-amd64-maxwell"):
            ovz_session = "5.0-amd64"
        elif os.path.exists("/var/lib/vz/template/debian-5.0-i386-maxwell"):
            ovz_session = "5.0-i386"
        elif os.path.exists("/var/lib/vz/template/debian-4.0-amd64-maxwell"):
            ovz_session = "4.0-amd64"
        elif os.path.exists("/var/lib/vz/template/debian-4.0-i386-maxwell"):
            ovz_session = "4.0-i386"

        # 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"

        print "checking " + confFileName

        if not os.path.exists(confFileName):
            maxwellConfFileText = (
                "submit_server = \"" + hostname + "\"\n"
                "hub_name = \"" + hubname + "\"\n"
                "hub_homedir = \"/home/" + hubname + "\"\n" 
                "ovz_session_conf = \"hub-session-" + ovz_session + ".conf\"\n"
                "ovz_session_mount = \"hub-session-" + ovz_session + ".mount\"\n"
                "ovz_session_umount = \"hub-session-" + ovz_session + ".umount\"\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." + webGroup()  , 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 "ovz_session_conf" not in maxwellConfFileText:
                    maxwellConfFileText += "\novz_session_conf = \"hub-session-" + ovz_session + ".conf\""
                    changed = True
                if "ovz_session_mount" not in maxwellConfFileText:
                    maxwellConfFileText += "\novz_session_mount = \"hub-session-" + ovz_session + ".mount\""
                    changed = True
                if "ovz_session_umount" not in maxwellConfFileText:
                    maxwellConfFileText += "\novz_session_umount = \"hub-session-" + ovz_session + ".umount\""
                    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)		

        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'
        print "checking group 'network'"
        if not hubzero.utilities.group.groupExists("network"):
            print "adding group 'network'"
            hubzero.utilities.group.addhubgroup("network", "network")

        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()
        db =  hubzero.data.db.MySQLConnection("localhost", dbName, dbUserName, dbPW)

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

        # do /etc/mw-client/mw-clienta.conf file replacements
        # get hostname
        hostname = gethostname()

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

        if hubzero.utilities.misc.JOOMLA_25:
            sql = 'select template from `jos_template_styles` where client_id=0 and home=1'
        else:
            sql = 'select template from `jos_templates_menu` where menuid = 0 and client_id=0'

        template = db.query_selectscalar(sql, None)
        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"
            "hub_template=\"" + template + "\"\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:" + webGroup(), confFileName])	
        if rc: 
            print procStdErr

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

	## Todo, permissions on the /etc/mw-client directory needs more open read
        ##rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["chmod", "0640", /etc/mw-client/])	
        ##if rc: 
        ##    print procStdErr

        serviceInit('expire-sessions','restart')

    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:
        print "enabling textifier"
        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', webUser() + ":" + webGroup(), textifierConfFile])
    else:
        print "disabling textifier"


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"
        if hubzero.utilities.misc.JOOMLA_25:
            sql = 'UPDATE jos_extensions SET enabled = 0 WHERE type = "plugin" AND folder = "usage";'
        else:
            sql = 'UPDATE jos_plugins SET published = 0 WHERE folder = "usage";'
        db.query_rowcount(sql, None)	

        if hubzero.utilities.misc.JOOMLA_25:
            sql = 'UPDATE jos_extensions SET enabled = 1 WHERE type = "plugin" AND folder = "usage" AND element IN ("overview","maps");'
        else:
            sql = 'UPDATE jos_plugins SET published = 1 WHERE folder = "usage" AND element IN ("overview","maps")'
        db.query_rowcount(sql, None)			

        if hubzero.utilities.misc.JOOMLA_25:
            sql = 'UPDATE jos_extensions SET params = \'{"period":"14","chart_path":"/site/stats/chart_resources/","map_path":"/site/stats/resource_maps/"}\' WHERE type="plugin" AND folder = "resources" AND element = "usage";'
        else:
            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)			

        if hubzero.utilities.misc.JOOMLA_25:
            sql = 'UPDATE jos_resource_types SET params="plg_citations=1\nplg_questions=1\nplg_recommendations=1\nplg_related=1\nplg_reviews=1\nplg_usage=1\nplg_versions=1\nplg_favorite=1\nplg_share=1\nplg_wishlist=1\nplg_supportingdocs=1" WHERE type="Tools"'
        else:
            sql = 'UPDATE jos_resource_types SET params="plg_citations=1\nplg_questions=1\nplg_recommendations=1\nplg_related=1\nplg_reviews=1\nplg_usage=1\nplg_versions=1\nplg_favorite=1\nplg_share=1\nplg_wishlist=1\nplg_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 mailgateway"
        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()

        hostname = gethostname()

        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", webUser()+":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 " + filename
                    serviceInit('spamassassin','restart')

                fh.close()
            except:
                print "Failed to patch " + 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 " + 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.
[server]
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")	

        hostname = gethostname()

        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):
            fh.seek(0)
            fh.write(txt)
            fh.truncate()
            print "patched " + "/etc/ssh/sshd_config"
            serviceInit('ssh','restart')

        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):
            fh.seek(0)
            fh.write(txt)
            fh.truncate()
            print "patched " + "/etc/nslcd.conf"
            serviceInit('nslcd','restart')

        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 " + 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 " + 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:
        serviceInit('autofs','restart')

    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 " + 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 " + 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:
        serviceInit('autofs','restart')

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

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

def openvzEnable():

    print "enabling openvz"

    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.truncate()
            print "patched " + grubfn
            print "/usr/sbin/update-grub"
            rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["/usr/sbin/update-grub"]) 
            if rc: print procStdErr

        grubfh.close()
    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.truncate()
                print "patched " + modulesfn
            modulesfh.close()
        except:
            print "Failed to patch " + 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)
            print "patched " + sysctlfn
        
        sysctlfh.close()
    except:
        print "Failed to patch " + 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')
            print "patched " + ipffn
        ipffh.close()
    except:
        print "Failed to patch " + 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.truncate()
                print "patched " + grubfn
                print "/usr/sbin/update-grub"
                rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["/usr/sbin/update-grub"]) 
                if rc: print procStdErr
            grubfh.close()
        except:
            print "Failed to patch " + 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.truncate()
                print "patched " + modulesfn
            modulesfh.close()
        except:
            print "Failed to patch " + 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, webUser(),  webGroup(), resetattrs=True)
    createDir("/var/log/hubzero-cms/daily", 0770, webUser(),  webGroup(), resetattrs=True)
    createDir("/var/log/hubzero-cms/daily/cron", 0770, webUser(),  webGroup(), resetattrs=True)
    createFile("/var/log/hubzero-cms/" + hubname + "-cmscron.log", 0640, webUser(), webGroup(), resetattrs=True)
    usrfilename = "/usr/share/hubzero-cli/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-cli/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)    

    serviceInit('cron','reload')

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)

    serviceInit('cron','reload')


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 updateDatabaseSchema(document_root = None):

    print "checking database schema"

    if document_root == None:    
        hubname = hubzero.config.webconfig.getDefaultSite()
        document_root = hubzero.config.hubzerositeconfig.getHubzeroConfigOption(hubname, "DocumentRoot")
    
    if not os.path.isdir(document_root):
        print "document root does not exist"
        return False

    schemaUpdateFilename = document_root + "/installation/sql/mysql/updates.sql"

    if os.path.exists(schemaUpdateFilename):
        print "updating database schema"

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

        #if hubzero.utilities.misc.JOOMLA_25:
        #    sql = """
        #UPDATE `jos_xgroups` SET type=0, published=1 WHERE cn IN ('apps','network','submit');
        #"""
    
        with open(schemaUpdateFilename) as f:
            print "updating database schema by applying " + schemaUpdateFilename
            for line in f:
                if line == "":
                    continue
                try:
                    #print s
                    db.query_rowcount(line, None)
                except Exception as e:
                    #print e
                    pass

    if os.path.exists(document_root + "/cli/muse.php"):
        output, err = subprocess.Popen(["/usr/bin/php", document_root+"/cli/muse.php", "migration", "-i"],stdout=subprocess.PIPE,stderr=subprocess.PIPE).communicate()
        for s in output.split("\n"):
            if "Would run" in s:
                print "/usr/bin/php " + document_root + "/cli/muse Migration -i -f"
                output, err = subprocess.Popen(["/usr/bin/php", document_root+"/cli/muse.php", "migration", "-i", "-f"],stdout=subprocess.PIPE,stderr=subprocess.PIPE).communicate()
                if err:
                    print err
                for s in output.split("\n"):
                    s = s.strip()

                    if s == '':
                        continue

                    if "Ignoring up()" in s:
                        continue

                    if "Ignore dates: all eligible" in s:
                        continue

                    print s
                break
    elif os.path.exists(document_root + "/bin/migration.php"):
        output, err = subprocess.Popen(["/usr/bin/php", document_root+"/bin/migration.php", "-i"],stdout=subprocess.PIPE,stderr=subprocess.PIPE).communicate()
        for s in output.split("\n"):
            if "Would run" in s:
                print "/usr/bin/php " + document_root + "/bin/migration.php -i -f"
                output, err = subprocess.Popen(["/usr/bin/php", document_root+"/bin/migration.php", "-i", "-f"],stdout=subprocess.PIPE,stderr=subprocess.PIPE).communicate()
                if err:
                    print err
                for s in output.split("\n"):
                    s = s.strip()

                    if s == '':
                        continue

                    if "Ignoring up()" in s:
                        continue
                    if "Ignore dates: all eligible" in s:
                        continue

                    print s
                break

# To regenerate this file:
#
# git log --summary --reverse | sed -e '/ delete mode ...... /!d;s/ .\{19\}/\.\//' | xargs -I {} sh -c "[ ! -f '{}' ]  && echo {}" > deleted-files.txt
#
# When processing this list a script should:
#
# * ignore any line not starting with "./"
# * normalize path to remove any attempts escape the document root
# * ignore any result that does not resolve to a file or symbolic link
# * remove containing directory if empty after removing result
#
# gitcheck = false apply even if document root is "git" controlled
# dryrun = true, print what would be done, but don't do it
# quiet = true, don't print errors
# 

def updateDeletedFiles(document_root = None, gitcheck = True, dryrun = True, quiet = False, verbose = False):

    print "checking for files to delete"

    if document_root == None:    
        hubname = hubzero.config.webconfig.getDefaultSite()
        document_root = hubzero.config.hubzerositeconfig.getHubzeroConfigOption(hubname, "DocumentRoot")
    
    if not os.path.isdir(document_root):
        return True

    if os.path.isdir(document_root + "/.git") and gitcheck:
        return True

    deletedFilesFilename = document_root + "/installation/deleted-files.txt"

    if not os.path.exists(deletedFilesFilename):
        return True

    with open(deletedFilesFilename, "r") as f:
        for line in f:
            filename = line.strip()

            if filename.startswith("./"):
                filename = os.path.normpath(filename)
                if os.path.isfile(document_root + "/" + filename):
                    os.remove(document_root + "/" + filename)
                    print "rm " + document_root + "/" + filename

                    directory_name = os.path.dirname(document_root + "/" + filename)
                    file_list = os.listdir( directory_name )
                    if not file_list:
                        os.rmdir(directory_name)
                        print "rmdir " + directory_name

                continue
            elif filename.startswith("#"):
                continue
            elif filename == "":
                continue
            
            print "Remove deleted files [skipping invalid filename " + filename + "]"


def updateTimezoneDatabase(restart_on_update = False, rootpw = None):
    
    print "checking for timezone database updates"

    my_mtime = 0
    my_filename = None

    for root, dirs, files in os.walk('/usr/share/zoneinfo', topdown=False):
        for name in files:
            name = os.path.join(root,name)
            if os.path.isfile(name):
                file_mtime = os.path.getmtime(name)
                if file_mtime > my_mtime:
                        my_mtime = file_mtime
                        my_filename = name

    createDir("/etc/hubzero", "0755", "root", "root", resetattrs=True)

    with open("/etc/hubzero/timezone.dat", "a+") as f:
        content = f.readlines()
        last_mtime = 0

        if content:
            last_mtime = content[0]

    if (last_mtime >= my_mtime):
        return False

    if rootpw == None:
        rootpw = hubzero.config.passwords.getMySqlPW()

    if not rootpw:
        print "unable to load timezone data [MySQL root password unknown]"
        return False
    
    db =  hubzero.data.db.MySQLConnection("localhost", "mysql", "root", rootpw)

    print "/usr/bin/mysql_tzinfo_to_sql /usr/share/zoneinfo"

    output, err = subprocess.Popen(["/usr/bin/mysql_tzinfo_to_sql","/usr/share/zoneinfo"],stdout=subprocess.PIPE,stderr=subprocess.PIPE).communicate()

    for s in err.split("\n"):
        s = s.strip()

        if s == '':
            continue

        if "Riyadh" in s:
            continue

        if "zone.tab" in s:
            continue

        if "iso3166.tab" in s:
            continue

        print "STDERR: " + s

    sql = output.split(';')

    print "executing " + str(len(sql)) + " SQL statements"

    for s in sql:
        s = s.strip()

        if s == '':
            continue

        if 'Local time zone must be set' in s:
            continue

        try:
            #print "string ["+s+"]"
            db.query_rowcount(s, None)
        except Exception as e:
            print s
            print "Got Exception"
            print e
            pass

    
    with open("/etc/hubzero/timezone.dat", "w+") as f:
        f.write(str(my_mtime)+"\n")
        f.write(time.ctime(my_mtime)+"\n")
        f.write(my_filename+"\n")

    if restart_on_update:
        serviceInit('mysql','restart')

        blockTillMySQLRunning()

    return True

def updateHub(args):

    # Debian or RH?
    wwwOwner = webUser()
    wwwGroup = webGroup()

    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")

    hostname = gethostname()

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

    if dbname == None:
        dbname = hubname

    # Copy fresh code
    if os.path.exists(docroot + "/.git"):
        print "checking " + docroot + " [git]"
    else:
        print "checking " + docroot
        copyCMSFiles(HUBZERO_CMS_DIR+"/cms/", docroot, wwwOwner, wwwGroup)
        updateDeletedFiles()

    updateTimezoneDatabase(True)

    updateDatabaseSchema()

    initPhpErrorLog()

    # 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'

        # @TODO add rule to remove site wishlist rewrite rule 
        # for versions >= 1.2.0 as it is just a patch for 
        # version < 1.2.0 
        try:
            hubm4 = "/etc/apache2/sites-m4/" + hubname + ".m4"
            print "checking " + hubm4
            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)
            version = hubzero.config.webconfig.getCMSversion(docroot)
            if StrictVersion(version) < StrictVersion("1.2.0"):
                txt = re.sub(pattern5, repl5, txt)
            if (txt != hubm4txt):
                hubm4fh.seek(0)
                hubm4fh.write(txt)
                hubm4fh.truncate()
                print "patched " + hubm4
            hubm4fh.close()
        except:
            print "Failed to patch " + hubm4
            pass

        try:
            hubsslm4 = "/etc/apache2/sites-m4/" + hubname + "-ssl.m4"
            print "checking " + hubsslm4
            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)
            version = hubzero.config.webconfig.getCMSversion(docroot)
            if StrictVersion(version) < StrictVersion("1.2.0"):
                txt = re.sub(pattern5, repl5, txt)
            if (txt != hubsslm4txt):
                hubsslm4fh.seek(0)
                hubsslm4fh.write(txt)
                hubsslm4fh.truncate()
                print "patched " + hubsslm4
            hubsslm4fh.close()
        except:
            print "Failed to patch " + 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.truncate()
                print "patched " + tfilename
            tfileh.close()
        except:
            print "Failed to patch " + tfilename
            pass

    checkConfigurationPhp(docroot)

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

    # Add new uri and dbname options to hub configuration file
    insertHubIntoHubConfigFile(hubname, docroot, uri, dbname)

    # fix mw-client.conf
    # if hub_template is set, update it
    print "checking /etc/mw-client/mw-client.conf"
    if os.path.exists("/etc/mw-client/mw-client.conf"):
 
        if hubzero.utilities.misc.JOOMLA_25:
            sql = 'select template from `jos_template_styles` where client_id=0 and home=1'
        else:
            sql = 'select template from `jos_templates_menu` where menuid = 0 and client_id=0'

        template = db.query_selectscalar(sql, None)

        try:
            mwfilename = "/etc/mw-client/mw-client.conf"
            mwfh = open(mwfilename,'r+')
            mwtxt = mwfh.read()
            txt, count = re.subn(r'(?im)(^\s*hub_template\s*=).*$',r'\1'+'"'+template+'"',mwtxt)

            #if count < 1:
            #    txt = txt.rstrip()
            #    txt = txt + "\nhub_template=\"" + template + "\""

            if (txt != mwtxt):
                mwfh.seek(0)
                mwfh.write(txt)
                mwfh.truncate()
                print "patched " + mwfilename

        except:
            print "Failed tp patch " + mwfilename

        mwfh.close()

    # Eventually we need a container template fixer, but it will need to be more
    # flexible then what we have commented out below

    #template = "/var/lib/vz/template/debian-6.0-amd64-maxwell"
    #print "checking " + template
    #if os.path.exists(template):
    #    print "apt-get update " + template
    #    rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["/usr/sbin/chroot", template, "apt-get", "update"]) 
    #    if rc: print procStdErr
    #
    #    print "apt-get install -y hubzero-filexfer " + template
    #    rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["/usr/sbin/chroot", template, "apt-get", "install", "-y", "hubzero-filexfer"]) 
    #    if rc: print procStdErr

    #template = "/var/lib/vz/template/debian-7.0-amd64-maxwell"
    #print "checking " + template
    #if os.path.exists(template):
    #    print "apt-get update " + template
    #    rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["/usr/sbin/chroot", template, "apt-get", "update"]) 
    #    if rc: print procStdErr

    #    print "apt-get install -y hubzero-filexfer " + template
    #    rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["/usr/sbin/chroot", template, "apt-get", "install", "-y", "hubzero-filexfer"]) 
    #    if rc: print procStdErr

    # Update database schema to match commits broguht in since original release
    # @TODO migrations will replace this segment one day

    # Fix trac if it's configured
    if hubzero.config.webconfig.getHubSiteConfig(hubname, "apache-config", "enable_trac").lower() == 'true':
        createDir("/opt", "0755", "root", "root", resetattrs=True)
        createDir("/opt/trac", "0750", webUser(), webGroup(), resetattrs=True)
        createDir("/opt/trac/tools", "0750", webUser(), webGroup(), resetattrs=True)

    # Fix subversion if it's configured
    if hubzero.config.webconfig.getHubSiteConfig(hubname, "apache-config", "enable_subversion").lower() == 'true':
        createDir("/opt", "0755", "root", "root", resetattrs=True)
        createDir("/opt/svn", "0750", webUser(), webGroup(), resetattrs=True)
        createDir("/opt/svn/tools", "0750", webUser(), webGroup(), resetattrs=True)
        createDir("/etc/apache2/" + hubname + ".conf.d", "0755", "root", "root", resetattrs=True)
        createDir("/etc/apache2/" + hubname + ".conf.d/svn", "0700", webUser(), webGroup(), resetattrs=True)

        if os.path.exists("/etc/apache2/svn.conf"):
            print "rename /etc/apache2/svn.conf /etc/apache2/" + hubname + ".conf.d/svn/svn.conf"
            os.rename("/etc/apache2/svn.conf", "/etc/apache2/" + hubname + ".conf.d/svn/svn.conf")

        if os.path.exists("/etc/apache2/svn.bak"):
            print "rename /etc/apache2/svn.bak /etc/apache2/" + hubname + ".conf.d/svn/svn.bak"
            os.rename("/etc/apache2/svn.bak", "/etc/apache2/" + hubname + ".conf.d/svn/svn.bak")

    # 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', webUser()+":"+webGroup(), "/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
    print "checking " + docroot + "/hubconfiguration.php"
    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 txt.find('hubShortName') == -1:
            txt = re.sub(r'(?im)^(\s*)(var\s*\$forgeName\s*=)',r'\1var $hubShortName = ' + "'" + hubname + "'" + r';\n\1\2',txt)

        if configtxt != txt:
            f.seek(0)
            f.write(txt)
            f.truncate()
            print "patched " + docroot + "/hubconfiguration.php"
        f.close()

    if hubzero.config.webconfig.getPluginEnabled('user','ldap'):
        syncLdap = True
    else:
        syncLdap = False

    # Fix admin user/group
    # At some point hzcms created 'admin' user with a 
    # corresponding 'admin' group instead of using the 'users' group (100).
    # We can check for those conditions and fix the group with a fair
    # confidence we aren't squashing an intentionally created group
    # with the same name
    print "checking user 'admin'"
    cn = db.query_selectscalar("SELECT cn FROM jos_xgroups AS xg, jos_xprofiles AS xp WHERE xg.cn='admin' AND xp.username='admin' AND xp.gidNumber=xg.gidNumber;", None)
    if cn == 'admin':
        print "repairing user 'admin'"
        db.query_rowcount("UPDATE jos_xprofiles SET gidNumber=100 WHERE username='admin' AND gidNumber NOT IN (100,3000)", None)
        print "deleting group 'admin' from database"
        db.query_rowcount("DELETE xgm FROM jos_xgroups_members AS xgm, jos_xgroups AS xg WHERE xgm.gidNumber=xg.gidNumber AND xg.cn='admin';", None)
        db.query_rowcount("DELETE FROM jos_xgroups WHERE cn='admin';", None)
        if syncLdap:
            hubzero.utilities.group.syncgroup('admin',verbose=True)
            hubzero.utilities.user.syncuser('admin',verbose=True)

    # Fix apps user/group
    # At some point hzcms or hubzero-fogrge created 'apps' user with a 
    # primary corresponding 'apps' group instead of using the 'users' 
    # group (100). We can check for those conditions and fix 
    # the group with a fair confidence we aren't squashing an intentional 
    # change.
    print "checking user 'apps'"
    cn = db.query_selectscalar("SELECT cn FROM jos_xgroups AS xg, jos_xprofiles AS xp WHERE xg.cn='apps' AND xp.username='apps' AND xp.gidNumber=xg.gidNumber;", None)
    if cn == 'apps':
        print "repairing user 'apps'"
        db.query_rowcount("UPDATE jos_xprofiles SET gidNumber=100 WHERE username='apps' AND gidNumber NOT IN (100,3000)", None)
        db.query_rowcount("UPDATE jos_xgroups SET type='0', published='1', approved='1', description='apps' WHERE cn='apps'", None)
        if syncLdap:
            hubzero.utilities.user.syncuser('apps',verbose=True)
            hubzero.utilities.group.syncgroup('apps',verbose=True)

    # Fix hubrepo user/group
    # At some point hzcms or hubzero-fogrge created 'hubrepo' user with a 
    # corresponding 'hubrepo' group instead of using the 'users' group (100).
    # We can check for those conditions and fix the group with a fair
    # confidence we aren't squashing an intentionally created group
    # with the same name.
    print "checking user 'hubrepo'"
    cn = db.query_selectscalar("SELECT cn FROM jos_xgroups AS xg, jos_xprofiles AS xp WHERE xg.cn='hubrepo' AND xp.username='hubrepo' AND xp.gidNumber=xg.gidNumber;", None)
    if cn == 'hubrepo':
        print "repairing user 'hubrepo'"
        db.query_rowcount("UPDATE jos_xprofiles SET gidNumber=100 WHERE username='hubrepo' AND gidNumber NOT IN (100,3000)", None)
        print "deleting group 'hubrepo' from database"
        db.query_rowcount("DELETE xgm FROM jos_xgroups_members AS xgm, jos_xgroups AS xg WHERE xgm.gidNumber=xg.gidNumber AND xg.cn='hubrepo';", None)
        db.query_rowcount("DELETE FROM jos_xgroups WHERE cn='hubrepo';", None)
        if syncLdap:
            hubzero.utilities.group.syncgroup('hubrepo',verbose=True)
            hubzero.utilities.user.syncuser('hubrepo',verbose=True)

    # Fix fuse module loading if webdav is configured
    if hubzero.config.webconfig.getHubSiteConfig(hubname, "apache-config", "enable_trac").lower() == 'true':
        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.truncate()
                print "patched " + modulesfn
                    
                print "/sbin/modprobe fuse"
                rc, procStdOut, procStdErr = hubzero.utilities.misc.exShellCommand(["/sbin/modprobe", "fuse"])  
                if rc: print procStdErr 

                serviceInit("autofs","restart")

            modulesfh.close()

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

    # Fix admin in apps group if forge is configured
    if hubzero.config.webconfig.getHubSiteConfig(hubname, "apache-config", "enable_forge").lower() == 'true':
        if hubzero.utilities.group.groupExists("apps"):
            print "checking 'admin' user in 'apps' group"
            if not hubzero.utilities.group.userInGroup("admin","apps"):
                print "adding 'admin' user to 'apps' group"
                hubzero.utilities.group.addUserToGroup("admin","apps")

    # Fix apps user in webGroup() group if forge is configured (so it can read configuration.php)
    if hubzero.config.webconfig.getHubSiteConfig(hubname, "apache-config", "enable_forge").lower() == 'true':
        print "checking 'apps' user in '" + webGroup() + "' group"
        group = grp.getgrnam(webGroup())
        if ('apps' not in group.gr_mem):
            print "usermod -a -G %s apps" % webGroup()
            hubzero.utilities.misc.exShellCommand(["usermod","-a","-G",webGroup(),"apps"])

    # Fix default home directory parameter
    # @FIXME: effectively disables having /home as your home directory
    # location. This will be fixed one day by putting home directory
    # in a global config file and resetting this accordingly
    # @FIXME: should also remove hubHomeDir parameter, but it should be harmless

    print "checking default home directory prefix"
    changedHomeDirs = False
    if hubzero.utilities.misc.JOOMLA_25:
        id = db.query_selectscalar("SELECT extension_id FROM jos_extensions WHERE type='component' AND (params LIKE BINARY '%\"homedir\":\"/home\"%' OR params LIKE BINARY '%\"homedir\":\"/\"%') AND `element`='com_members';",None)
    else:
        id = db.query_selectscalar("SELECT id FROM jos_components WHERE (params LIKE BINARY '%homedir=/home\n%' OR params LIKE BINARY '%homedir=\n%') AND `option`='com_members' AND parent=0;",None)

    if (id > 0):
        print "setting default home directory prefix to /home/" + hubname
        if hubzero.utilities.misc.JOOMLA_25:
            sql = "UPDATE jos_extensions SET `params` = REPLACE(`params`,'\"homedir\":\"/home\"','\"homedir\":\"/home/' + hubname + '\"') WHERE `element` = 'com_members'"
            db.query_rowcount(sql, None)
            sql = "UPDATE jos_extensions SET `params` = REPLACE(`params`,'\"homedir\":\"/\"','\"homedir\":\"/home/' + hubname + '\"') WHERE `element` = 'com_members'"
            db.query_rowcount(sql, None)
        else:
            sql = "UPDATE jos_components SET `params` = REPLACE(`params`,'homedir=/home\n','homedir=/home/" + hubname + "\n') WHERE `option` = 'com_members'"
            db.query_rowcount(sql, None)
            sql = "UPDATE jos_components SET `params` = REPLACE(`params`,'homedir=\n','homedir=/home/" + hubname + "\n') WHERE `option` = 'com_members'"
            db.query_rowcount(sql, None)

    # Fix user home directories that were incorrectly set due to the above

        print "checking user home directory prefixes"

        # grab all users from db with invalid home directory prefix
        sql = "SELECT username from jos_xprofiles WHERE homeDirectory=CONCAT('/home/',username)"

        usersFromDB = {}
        for duser in db.query(sql, None):
            usersFromDB[duser.username] = 1
            #print duser.username + " has invalid home directory prefix"

        for user in usersFromDB:
            print "fixing home directory prefix for user " + user
            sql = "UPDATE jos_xprofiles SET homeDirectory=CONCAT('/home/"+hubname+"/"+"',username) WHERE username='" + user + "'"
            if db.query_rowcount(sql,None) == 1 and syncLdap:
                print "syncing ldap entry for user " + user
                hubzero.utilities.user.syncuser(user)
                changedHomeDirs = True

        if changedHomeDirs:
            print "\n\nSOME HOME DIRECTORIES MOVED!"
            print "PLEASE MOVE HOME DIRECTORIES FROM /home TO /home/" + hubname + "\n\n"

    # Fix permissions on /apps
    if os.path.exists("/apps"):
        createDir("/apps", "2775", "apps", "apps", resetattrs=True)


    # Make sure apache config files are current with m4 template
    generateApacheM4config(hubname)
    
    # Make sure all changes made during update are reflected in running system
    restartWebServer()

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

def gethostname():

    if hubzero.utilities.misc.isRHEL():
        rc, stdOut, stdErr = hubzero.utilities.misc.exShellCommand(["hostname"])
    elif hubzero.utilities.misc.isDebian():
        rc, stdOut, stdErr = hubzero.utilities.misc.exShellCommand(["hostname", "--fqdn"])

    if rc:
        print stdErr
    else:
       hostname = stdOut.strip()

    return hostname


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

hostname = gethostname()

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

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

# 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.add_argument('--cmsversion', help='version of HUBzero CMS to install')
parser_install.set_defaults(func=installHub)

# delete subcommand
parser_delete = subparsers.add_parser('delete', help='delete files and database of existing hub')
parser_delete.add_argument('hubname', help='name of hub to delete')
parser_delete.set_defaults(func=deleteHub)

# 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)

# configure command, configure command has a slew of it's own sub commands
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)

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

# end configure/xxx subcommands


# creathubdatabase subcommand
parser_installdb = subparsers.add_parser('createhubdatabase', help='create a new hub database in mysql')
parser_installdb.add_argument('--dbname', help='database name', required=True)
parser_installdb.set_defaults(func=_mySQLDatabaseSetup)

# confighubfile 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)

# 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)

# resetmysqlpw subcommand
parser_resetmysqlpw = subparsers.add_parser('resetmysqlpw', help='reset mysql password')
parser_resetmysqlpw.add_argument('--username', help='username', required=True)
parser_resetmysqlpw.add_argument('--pw', help='password', required=True)
parser_resetmysqlpw.set_defaults(func=_setMySQLPW)

# 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)


args =  parser.parse_args()

args.func(args)
