#!/usr/bin/env python

import os
import errno
import shutil
import glob
import sys
import tempfile
import inspect

python_names = ['python2.7', 'python2.6']
python_paths = []
python_paths += glob.glob("/opt/python-2.7.*/bin/python2.7")
python_paths += glob.glob("/opt/python-2.6.*/bin/python2.6")
python_paths += [
  os.path.join(os.sep, "opt", "python-2.6.4", "bin", "python"),
  os.path.join(os.sep, "usr", "local", "bin", "python2.6")
]

try:
    sysname, nodename, x, x, machine = os.uname()
except:
    import platform
    sysname, nodename, x, x, machine, x = platform.uname()

try:
    pathbin = os.path.dirname(__file__)
except NameError:
    # old python version do not support __file__
    pathbin = os.path.join(os.sep, 'opt', 'opensvc', 'bin')

def make_sure_path_exists(path):
    try:
        os.makedirs(path, 0755)
    except OSError, exception:
        if exception.errno != errno.EEXIST:
            raise

pathbin = os.path.realpath(pathbin)
if not pathbin.rstrip(os.sep).endswith('bin'):
    # hpux executes the postinstall from dir
    # /var/tmp/XXXXXXXXX/catalog/opensvc/commands/
    pathbin = os.path.join(os.sep, 'opt', 'opensvc', 'bin')
pathsvc = os.path.realpath(os.path.join(pathbin, '..'))
pathbin = os.path.join(pathsvc, 'bin')
pathetc = os.path.join(pathsvc, 'etc')
pathvar = os.path.join(pathsvc, 'var')
pathtmp = os.path.join(pathsvc, 'tmp')
pathlib = os.path.join(pathsvc, 'lib')
pathlog = os.path.join(pathsvc, 'log')
pathusr = os.path.join(pathsvc, 'usr')

make_sure_path_exists(pathlog)

def logit(msg):
    curframe = inspect.currentframe()
    calframe = inspect.getouterframes(curframe, 2)
    try:
        import datetime
        timestamp = str(datetime.datetime.now())
    except:
        timestamp = '?'

    osvlog = os.path.join(pathlog, 'postinstall.log')
    content = '['+calframe[1][3]+']['+timestamp+'] '+msg
    f = open(osvlog, 'a')
    f.write(content+'\n')
    f.close()

logit("Starting OpenSVC PostInstall")

SolarisRootRelocate = False
if sysname == 'SunOS' and "PKG_INSTALL_ROOT" in os.environ and os.environ['PKG_INSTALL_ROOT'] != '/':
     SolarisRootRelocate = True

variables = {"pathsvc":pathsvc, "pathbin":pathbin, "pathetc":pathetc, "pathvar":pathvar, "pathtmp":pathtmp, "pathlib":pathlib, "pathlog":pathlog, "pathusr":pathusr, "SolarisRootRelocate":SolarisRootRelocate}
for key in variables:
    logit("var %s <%s>"%(key,variables[key]))

def python_path():
    logit("Begin")
    for n in python_names:
        p = _python_path(n)
        if p is not None:
            return p
    for p in python_paths:
        if os.path.exists(p):
            return p

def _python_path(python_exe):
    logit("Begin")
    for path in os.environ["PATH"].split(os.pathsep):
        exe_file = os.path.join(path, python_exe)
        if os.path.exists(exe_file) and os.access(exe_file, os.X_OK):
            return exe_file
    return None

def install_cron():
    logit("Begin")
    if sysname == 'Windows':
        return 
    else:
        return install_cron_unix()

def install_cron_windows():
    logit("Begin")
    print "install OsvcSched service"
    schedstop()
    schedremove()
    schedinstall()
    schedstart()

def schedremove():
    logit("Begin")
    cmd = ' remove'
    schedcmd(cmd)

def schedstart():
    logit("Begin")
    cmd = ' start'
    schedcmd(cmd)

def schedstop():
    logit("Begin")
    cmd = ' stop'
    schedcmd(cmd)

def schedinstall():
    logit("Begin")
    cmd = ''
    cmd += ' --username LocalSystem'
    cmd += ' --startup auto'
    cmd += ' install\n'
    schedcmd(cmd)

def schedcmd(_cmd):
    logit("Begin")
    print _cmd
    rc = '"'+sys.executable+'" "'+os.path.join(pathlib, 'rcWinScheduler.py')+'"'
    cmd = "@echo off\n"
    cmd += rc
    cmd += _cmd
    fd, fname = tempfile.mkstemp(dir=pathtmp, suffix='.cmd')
    f = os.fdopen(fd, 'w')
    f.write(cmd)
    f.close()
    import subprocess
    subprocess.call([fname])
    os.unlink(fname)
 
def install_cron_unix():
    logit("Begin")
    """install opensvc cron jobs
    """

    agt = os.path.join(pathbin, 'perfagt.'+sysname)
    ce = [{
           'sched': "0,10,20,30,40,50 * * * *",
           'reset_sched': False,
           'user': "",
           'cmd': "[ -x /opt/opensvc/bin/svcmon ] && /opt/opensvc/bin/svcmon --updatedb --maxdelaydb 120 >/dev/null 2>&1",
           'marker': 'svcmon --updatedb',
           'ok': False
    },{
           'sched': "0,10,20,30,40,50 * * * *",
           'reset_sched': True,
           'user': "",
           'cmd': "[ -x /opt/opensvc/bin/cron/opensvc ] && /opt/opensvc/bin/cron/opensvc >/dev/null 2>&1",
           'marker': '/opt/opensvc/bin/cron/opensvc',
           'ok': False
    },{
           'sched': "0,10,20,30,40,50 * * * *",
           'reset_sched': False,
           'user': "",
           'cmd': "[ -x %s ] && %s >/dev/null 2>&1"%(agt,agt),
           'marker': agt,
           'ok': False
    }]
    remove_entries = ['bin/nodemgr compliance check']

    purge = []
    root_crontab = False

    """ order of preference
    """
    if sysname == 'SunOS' :
	if SolarisRootRelocate is True:
	    suncron = os.environ["PKG_INSTALL_ROOT"] + '/var/spool/cron/crontabs/root'
            root_crontab_locs = [
               suncron
            ]
	else:
	    root_crontab_locs = [
		'/var/spool/cron/crontabs/root'
            ]
    else:
        root_crontab_locs = [
            '/etc/cron.d/opensvc',
            '/var/spool/cron/crontabs/root',
            '/var/spool/cron/root',
            '/var/cron/tabs/root',
            '/usr/lib/cron/tabs/root',
        ]
    for loc in root_crontab_locs:
        if os.path.exists(os.path.dirname(loc)):
            if not root_crontab:
                root_crontab = loc
                if root_crontab == '/etc/cron.d/opensvc':
                    ce[0]['user'] = "root"
                    ce[1]['user'] = "root"
                    ce[2]['user'] = "root"
            elif os.path.exists(loc):
                purge.append(loc)

    if not root_crontab:
        print "no root crontab found in usual locations %s"%str(root_crontab_locs)
        return False

    ce[0]['full'] = ' '.join([ce[0]['sched'], ce[0]['user'], ce[0]['cmd']])
    ce[1]['full'] = ' '.join([ce[1]['sched'], ce[1]['user'], ce[1]['cmd']])

    if os.path.exists(agt):
        ce[2]['full'] = ' '.join([ce[2]['sched'], ce[2]['user'], ce[2]['cmd']])
    else:
        ce[2]['full'] = None

    new = False
    if os.path.exists(root_crontab):
        try:
            f = open(root_crontab, 'r')
            new = f.readlines()
            f.close()
        except:
            f.close()
            import traceback
            traceback.print_exc()

        i = -1
        for line in new:
            i += 1
            for c in ce:
                if c['full'] is None:
                    continue
                if line.find(c['marker']) != -1:
                    if line.find(c['cmd']) != -1:
                        sched = ' '.join(line.split()[:5])
                    if c['reset_sched'] and sched != c['sched']:
                        new[i] = ' '.join([c['sched'], c['user'], c['cmd']])+'\n'
                        c['ok'] = True
                    else:
                        # preserve scheduling
                        if c['reset_sched']:
                            sched = c['sched']
                        else:
                            sched = ' '.join(line.split()[:5])
                        new[i] = ' '.join([sched, c['user'], c['cmd']])+'\n'
                        c['ok'] = True
        for c in ce:
            if c['full'] is not None and not c['ok']:
                new.append(c['full']+'\n')
    else:
        new = []
        for c in ce:
            if c['full'] is not None and not c['ok']:
                new.append(c['full']+'\n')

    if not new:
        print "problem preparing the new crontab"
        return False
 
    i = -1
    for line in new:
        i += 1
        for re in remove_entries:
            if line.find(re) != -1:
                print 'delete line "%s" from %s'%(re,root_crontab)
                del new[i]

    try:
        f = open(root_crontab, 'w')
        f.write(''.join(new))
        f.close()
    except:
        f.close()
        import traceback
        traceback.print_exc()

    """ Activate changes (actually only needed on HP-UX)
    """
    if root_crontab.find('/var/spool/') != -1:
        cmd = ['crontab', root_crontab]
        ret = os.system(' '.join(cmd))

    for loc in purge:
        try:
            f = open(loc, 'r')
            new = [ line for line in f.readlines() if line.find('opensvc.daily') == -1 and line.find('svcmon --updatedb') == -1 ]
            f.close()
            f = open(loc, 'w')
            f.write(''.join(new))
            f.close()
        except:
            f.close()
            import traceback
            traceback.print_exc()

    """ Clean up old standard file locations
    """
    for f in ['/etc/cron.daily/opensvc', '/etc/cron.daily/opensvc.daily']:
        if os.path.exists(f):
            os.unlink(f)

def activate_chkconfig(svc):
    logit("Begin")
    cmd = ['chkconfig', '--add', svc]
    ret = os.system(' '.join(cmd))
    if ret > 0:
        return False
    return True

def activate_systemd(launcher):
    logit("Begin")
    systemdsvc = 'opensvc-agent.service'
    
    # populate systemd tree with opensvc unit file
    src = os.path.join(pathbin, 'systemd.opensvc-agent.service')
    dst = os.path.join('/etc/systemd/system/', systemdsvc)
    shutil.copyfile(src, dst)
    os.chmod(dst, 0644)
    
    # add symlink to resolve systemd service call
    systemd_call = '/opt/opensvc/bin/opensvc.init'
    if not os.path.islink(systemd_call):
        if os.path.exists(systemd_call):
            os.unlink(systemd_call)
        msg = "create link %s -> %s"%(systemd_call, launcher)
        logit(msg)
        try:
            os.symlink(launcher, systemd_call)
        except:
            logit("Error while trying to create opensvc.init symlink")

    # reload systemd configuration
    cmd = ['systemctl', '-q', 'daemon-reload']
    ret = os.system(' '.join(cmd))
    if ret > 0:
        logit("WARN : Problem during systemctl reload")
    
    # enable opensvc agent startup through systemd
    cmd = ['systemctl', '-q', 'enable', systemdsvc]
    ret = os.system(' '.join(cmd))
    if ret > 0:
        logit("WARN : Problem during systemctl enable")


def systemd_mgmt():
    logit("Begin")
    cmd = ['systemctl', '--version', '>>/dev/null', '2>&1']
    ret = os.system(' '.join(cmd))
    if ret > 0:
        return False
    return True

def activate_ovm(launcher):
    logit("Begin")
    activate_chkconfig('zopensvc')

def activate_redhat(launcher):
    logit("Begin")
    activate_chkconfig('opensvc')

def activate_debian(launcher):
    logit("Begin")
    cmd = ['update-rc.d', '-f', 'opensvc', 'remove']
    ret = os.system(' '.join(cmd))
    if ret > 0:
        return False
    cmd = ['update-rc.d', 'opensvc', 'defaults']
    ret = os.system(' '.join(cmd))
    if ret > 0:
        return False
    return True

def activate_hpux(launcher):
    logit("Begin")
    rc = "/sbin/init.d/opensvc"
    links = ["/sbin/rc1.d/K010opensvc", "/sbin/rc2.d/K010opensvc", "/sbin/rc3.d/S990opensvc"]
    if os.path.exists("/sbin/rc2.d/S990opensvc"):
        os.unlink("/sbin/rc2.d/S990opensvc")
    for l in links:
        if not os.path.islink(l):
            if os.path.exists(l):
                os.unlink(l)
            os.symlink(rc, l)
    try:
        f = open("/etc/rc.config.d/opensvc", "w")
        f.write("RUN_OPENSVC=1\n")
        f.close()
    except:
        f.close()
        import traceback
        traceback.print_exc()
    return True

def activate_AIX(launcher):
    logit("Begin")
    rc = "/etc/rc.d/init.d/opensvc"
    links = ["/etc/rc.d/rc2.d/S990opensvc"]
    for l in links:
        if not os.path.islink(l):
            if os.path.exists(l):
                os.unlink(l)
            print "create link %s -> %s"%(l, rc)
            os.symlink(rc, l)
    return True

def activate_OSF1(launcher):
    logit("Begin")
    rc = "/sbin/init.d/opensvc"
    links = ["/sbin/rc0.d/K010opensvc", "/sbin/rc2.d/K010opensvc", "/sbin/rc3.d/S990opensvc"]
    for l in links:
	if not os.path.islink(l):
	    if os.path.exists(l):
	        os.unlink(l)
	    os.symlink(rc, l)
    return True

def activate_SunOS(launcher):
    logit("Begin")
    if SolarisRootRelocate is True:
        rc = "/etc/init.d/opensvc"
        links = [os.environ["PKG_INSTALL_ROOT"] + "/etc/rc0.d/K00opensvc", os.environ["PKG_INSTALL_ROOT"] + "/etc/rc3.d/S99opensvc"]
    else:
	rc = "/etc/init.d/opensvc"
	links = ["/etc/rc0.d/K00opensvc", "/etc/rc3.d/S99opensvc"]
    logit("rc <%s>"%rc)
    for l in links:
        logit("link <%s>"%l)
        if not os.path.islink(l):
            if os.path.exists(l):
                os.unlink(l)
            os.symlink(rc, l)
    return True

def activate_FreeBSD(launcher):
    logit("Begin")
    return True

def activate_Darwin(launcher):
    logit("Begin")
    return True

def update_file(filename, srctext, replacetext):
    logit("Begin")
    """ replace into filename srctext by replacetext
    """
    import fileinput
    for line in fileinput.input(filename, inplace=1):
        if line.rstrip('\n') == srctext.rstrip('\n') :
            line = replacetext
        print line.rstrip('\n')
    fileinput.close()

def install_params(path2file):
    logit("Begin")
    """ install template file with tunable variables
    """
    if os.path.exists(path2file):
        return

    try:
        f = open(path2file, "w")
    except:
        import traceback
        traceback.print_exc()
    else:
        f.write("# This is the OpenSVC startup configuration file\n")
        f.write("# You may need to adapt parameters to fit your environment\n")
        f.write("# This file is not modified during software upgrades\n")
        f.write("# If empty, default settings are used in the init script\n\n\n")
        f.write("# arguments passed to the allservices boot command at system boot\n")
        f.write("#osvc_opts=\n")
        f.close()
 
def install_rc():
    logit("Begin")
    """install startup script
    """
    params = None
    copyrc = True

    if os.path.exists('/etc/debian_version'):
        rc = '/etc/init.d/opensvc'
        params = '/etc/default/opensvc'
        src = '/opt/opensvc/bin/opensvc.init.debian'
        if systemd_mgmt():
            logit("Debian with systemd")
            copyrc = False
            activate = activate_systemd
        else:
            logit("Debian with update-rc.d (rely on insserv)")
            activate = activate_debian
    elif os.path.exists('/etc/SuSE-release'):
        rc = '/etc/init.d/opensvc'
        params = '/etc/sysconfig/opensvc'
        src = '/opt/opensvc/bin/opensvc.init.suse'
        if systemd_mgmt():
            logit("SuSE with systemd")
            copyrc = False
            activate = activate_systemd
        else:
            logit("SuSE with chkconfig (rely on insserv)")
            activate = activate_redhat       
    elif os.path.exists('/etc/redhat-release'):
        params = '/etc/sysconfig/opensvc'
        src = '/opt/opensvc/bin/opensvc.init.redhat'
        try:
            f = open('/etc/redhat-release', 'r')
            buff = f.read()
            f.close()
        except:
            buff = ""
        if buff.find('Oracle VM server') != -1:
            rc = '/etc/init.d/zopensvc'
            activate = activate_ovm
        else:
            rc = '/etc/init.d/opensvc'
            if systemd_mgmt():
                logit("Red Hat with systemd")
                copyrc = False
                activate = activate_systemd
            else:
                logit("Red Hat with chkconfig (rely on insserv)")
                activate = activate_redhat    

    elif sysname == "HP-UX":
        rc = '/sbin/init.d/opensvc'
        src = '/opt/opensvc/bin/opensvc.init.hpux'
        activate = activate_hpux
    elif sysname == "SunOS":
	if SolarisRootRelocate is True:
            rc = os.environ["PKG_INSTALL_ROOT"] + '/etc/init.d/opensvc'
            params = os.environ["PKG_INSTALL_ROOT"] + '/etc/default/opensvc'
            src = os.environ["PKG_INSTALL_ROOT"] + '/opt/opensvc/bin/opensvc.init.SunOS'
        else:
            rc = '/etc/init.d/opensvc'
            params = '/etc/default/opensvc'
            src = '/opt/opensvc/bin/opensvc.init.SunOS'
        activate = activate_SunOS
    elif sysname == "OSF1":
        rc = '/sbin/init.d/opensvc'
        src = '/opt/opensvc/bin/opensvc.init.OSF1'
        activate = activate_OSF1
    elif sysname == "FreeBSD":
        rc = '/etc/rc.d/opensvc'
        params = '/etc/defaults/opensvc'
        src = '/opt/opensvc/bin/opensvc.init.FreeBSD'
        activate = activate_FreeBSD
    elif sysname == "AIX":
        rc = '/etc/rc.d/init.d/opensvc'
        src = '/opt/opensvc/bin/opensvc.init.AIX'
        activate = activate_AIX
    elif sysname == "Darwin":
        rc = '/Library/LaunchDaemons/com.opensvc.svcmgr.plist'
        params = '/etc/defaults/opensvc'
        src = '/opt/opensvc/bin/darwin.com.opensvc.svcmgr.plist'
        activate = activate_Darwin
    elif sysname == 'Windows':
        return False
    else:
        print "could not select an init script: unsupported operating system"
        return False

    if os.path.islink(rc):
        os.unlink(rc)

    if copyrc:
        logit("Copying src launcher script to rc")
        shutil.copyfile(src, rc)
        os.chmod(rc, 0755)

    if params is not None and not os.path.exists(params):
        logit("Installing default parameters file")
        install_params(params)
        
    activate(src)

def gen_keys():
    logit("Begin")
    if sysname == 'Windows':
        return
    home = os.path.expanduser("~root")
    logit("home <%s>"%home)
    if SolarisRootRelocate is True:
	home = os.environ['PKG_INSTALL_ROOT'] + os.path.expanduser("~root")
        logit("SunOS and relocatable install home is now <%s>"%home)
    sshhome = os.path.join(home, ".ssh")
    logit("gen_keys(): sshhome <%s>"%sshhome)
    if not os.path.exists(sshhome):
	print "create dir", sshhome
	os.makedirs(sshhome, 0700)
    priv = os.path.join(sshhome, "id_dsa")
    pub = os.path.join(sshhome, "id_dsa.pub")
    if os.path.exists(pub) or os.path.exists(priv):
        return
    cmd = ['ssh-keygen', '-t', 'dsa', '-b', '1024', '-P', '""', '-f', priv]
    ret = os.system(' '.join(cmd))

def missing_dir(sub):
    logit("Begin")
    pathd = os.path.join(pathsvc, sub)
    if not os.path.exists(pathd):
	print "create dir", pathd
	os.makedirs(pathd, 0755)

def missing_dirs():
    logit("Begin")
    missing_dir('log')
    missing_dir('tmp')
    missing_dir('var')

def convert_svclinks():
    logit("Begin")
    missing_dir('etc')
    svcmgr = os.path.join('..', 'bin', 'svcmgr')
    if not os.path.exists(svcmgr):
	return 1
    rcService = os.path.realpath(os.path.join(os.sep, 'opt', 'opensvc', 'bin', 'rcService'))
    if not os.path.exists(rcService):
	return 1
    for fname in os.listdir(pathetc):
        fpath = os.path.join(pathetc, fname)
        if not os.path.islink(fpath):
            continue
        rpath = os.path.realpath(fpath)
        if rpath != rcService:
            continue
        os.unlink(fpath)
        os.symlink(svcmgr, fpath)

def move_usr_to_opt():
    logit("Begin")
    linksvc = os.path.join(os.sep, 'service')
    old_pathsvc = os.path.join(os.sep, 'usr', 'local', 'opensvc')
    old_pathvar = os.path.join(old_pathsvc, 'var')
    old_pathetc = os.path.join(old_pathsvc, 'etc')

    if os.path.exists(old_pathvar):
        for f in glob.glob(old_pathvar+'/*'):
            dst = os.path.join(pathvar, os.path.basename(f))
            if os.path.exists(dst) and dst.find('host_mode') == -1:
                continue
            if os.path.isdir(f):
                shutil.copytree(f, dst, symlinks=True)
            elif os.path.islink(f):
                linkto = os.readlink(f)
                os.symlink(linkto, dst)
            else:
                shutil.copy2(f, dst)

    if os.path.exists(old_pathetc):
        for f in glob.glob(old_pathetc+'/*'):
            dst = os.path.join(pathetc, os.path.basename(f))
            if os.path.exists(dst):
                continue
            if os.path.islink(f):
                linkto = os.readlink(f)
                os.symlink(linkto, dst)
            elif os.path.isdir(f):
                shutil.copytree(f, dst, symlinks=True)
            else:
                shutil.copy2(f, dst)

    if os.path.exists(old_pathsvc):
        shutil.rmtree(old_pathsvc)

    if os.path.islink(linksvc) and os.path.realpath(linksvc) == old_pathsvc:
        os.unlink(linksvc)

def install_etc_path():
    logit("Begin")
    p = os.path.join(os.sep, 'etc', 'PATH')
    if not os.path.exists(p):
        return
    try:
        f = open(p, "r")
        buff = f.read()
        f.close()
    except:
        return
    l = buff.strip().split(":")
    n = len(l)
    for op in (pathbin, pathetc):
        if op in l:
            continue
        l.append(op)
    if len(l) == n:
        return
    try:
        f = open(p, "w")
        f.write(":".join(l)+'\n')
        f.close()
    except:
        return

def install_profile():
    logit("Begin")
    prof_d = os.path.join(os.sep, 'etc', 'profile.d')
    prof = os.path.join(prof_d, 'opensvc.sh')
    buff = "export PATH=$PATH:"+pathbin+":"+pathetc+"\n"
    if not os.path.exists(prof_d):
        return
    try:
        f = open(prof, 'w')
        f.write(buff)
        f.close()
    except:
        f.close()
        import traceback
        traceback.print_exc()

def install_bash_completion():
    logit("Begin")
    src = os.path.join(pathsvc, 'usr', 'share', 'bash_completion.d', 'opensvc')
    ds = [os.path.join(os.sep, 'etc', 'bash_completion.d'),
          os.path.join(os.sep, 'etc', 'bash', 'bash_completion.d')]
    for d in ds:
        dst = os.path.join(d, 'opensvc')
        if not os.path.exists(d):
            d = None
            continue
        else:
            break
    if d is None:
        return
    shutil.copyfile(src, dst)
    os.chmod(dst, 0644)

def install_link(source, target):
    logit("Begin")
    if source == '' or target == '':
        return False
    if os.path.realpath(source) == os.path.realpath(target):
        return True
    if os.path.islink(target) or os.path.exists(target):
        os.unlink(target)
    os.symlink(source,target)

def install_pythonlink():
    logit("Begin")
    if sysname == 'Windows':
        return install_pythonlink_windows()
    else:
        return install_pythonlink_unix()


def install_pythonlink_windows():
    logit("Begin")
    logit("Before appending pathlib to syspath")
    logit(os.environ["PATH"])
    sys.path.append(pathlib)
    logit("After appending pathlib to syspath")
    logit(os.environ["PATH"])
    from rcUtilitiesWindows import get_registry_value
    logit("Before reading installfolder in registry")
    try:
        installfolder = get_registry_value('HKEY_CURRENT_USER', 'Software\\OpenSVC', 'path')
    except:
        logit("ERROR while trying to read path into registry HKCU/Software/OpenSVC/path")
        sys.exit(1)

    installfolder = installfolder.rstrip('\\')   
    logit("installfolder = <"+installfolder+">")
    osvcenv = os.path.join(installfolder, 'osvcenv.cmd')
    content = '@echo off\nset OSVCROOT='+installfolder+'\nset OSVCPYTHONROOT=%OSVCROOT%\python\nset PYTHONPATH=%OSVCROOT%\lib\nset OSVCPYTHONEXEC=%OSVCPYTHONROOT%\python.exe\ncall inpath.cmd OSVCPYTHONROOT'
    logit(content)
    f = open(osvcenv, 'w')
    f.write(content)
    f.close()
		
def install_pythonlink_unix():
    logit("Begin")
    p = python_path()
    if p is None:
        print >>sys.stderr, "could not find a valid python installation"
        sys.exit(1)
    target = os.path.join(pathbin, 'python')
    return install_link(source=p, target=target)

def move_host_mode():
    logit("Begin")
    hm = os.path.join(pathvar, 'host_mode')
    cf = os.path.join(pathetc, 'node.conf')
    nodemgr = os.path.join(pathbin, 'nodemgr')
    if not os.path.exists(hm):
        return
    try:
        fp = open(hm, 'r')
        mode = fp.read().split()[0]
        fp.close()
    except:
        print 'failed to read old host_mode. renamed to', hm+'.old'
        shutil.move(hm, hm+'.old')
        return
    cmd = [nodemgr, 'set', '--param', 'node.host_mode', '--value', mode]
    ret = os.system(' '.join(cmd))
    if ret != 0:
        print 'failed to set host_mode in node.conf'
        return
    shutil.move(hm, hm+'.old')
 
def nodeconf_params():
    logit("Begin")
    nodeconf = os.path.join(pathetc, 'node.conf')
    dotnodeconf = os.path.join(pathetc, '.node.conf')

    # reset etc/.node.conf (autogenerated)
    if os.path.exists(dotnodeconf):
        os.unlink(dotnodeconf)

    if not os.path.exists(nodeconf):
        return

    import ConfigParser
    import copy
    try:
        config = ConfigParser.RawConfigParser()
    except AttributeError:
        return
    config.read(nodeconf)
    changed = False

    # no DEFAULT in etc/node.conf
    for o in copy.copy(config.defaults()):
        config.remove_option('DEFAULT', o)
        changed = True

    # sync section goes to etc/.node.conf
    if config.has_section('sync'):
        config.remove_section('sync')
        changed = True

    for s in config.sections():
        for o in config.options(s):
            if o in ['sync_interval', 'push_interval', 'comp_check_interval']:
                v = config.getint(s, o)
                config.remove_option(s, o)
                config.set(s, 'interval', v)
                changed = True
            if o in ['sync_days', 'push_days', 'comp_check_days']:
                v = config.get(s, o)
                config.remove_option(s, o)
                config.set(s, 'days', v)
                changed = True
            if o in ['sync_period', 'push_period', 'comp_check_period']:
                v = config.get(s, o)
                config.remove_option(s, o)
                config.set(s, 'period', v)
                changed = True

    if changed:
        try:
            fp = open(nodeconf, 'w')
            config.write(fp)
            fp.close()
        except:
            print >>sys.stderr, "failed to write new %s"%nodeconf

def save_exc():
    logit("Begin")
    import traceback
    try:
        import tempfile

        try:
            import datetime
            now = str(datetime.datetime.now()).replace(' ', '-')
        except:
            now =""

        try:
            f = tempfile.NamedTemporaryFile(dir=pathtmp, prefix='exc-'+now+'-')
        except:
            return
        f.close()
        f = open(f.name, 'w')
        traceback.print_exc(file=f)
        print >>sys.stderr, "unexpected error. stack saved in %s"%f.name
        f.close()
    except:
        print >>sys.stderr, "unexpected error"
        traceback.print_exc()

def purge_collector_api_cache():
    logit("Begin")
    fname = os.path.join(pathvar, "collector")
    if os.path.exists(fname) and os.path.isfile(fname):
        os.unlink(fname)

def chmod_directories():
    if not hasattr(os, "walk"):
        return
    logit("Begin")
    if sysname == 'Windows':
	logit("Skip : unsupported on Windows")
        return
    for d in (pathbin, pathlib, pathusr):
        for dirname, dirnames, filenames in os.walk(d):
            for subdirname in dirnames:
                dirpath = os.path.join(dirname, subdirname)
                try:
                    os.chmod(dirpath, 0755)
                    msg = "Setting %s permissions to 0755" % dirpath
                except:
                    msg = "Error while trying to set %s permissions to 0755" % dirpath
                logit(msg)

def log_file_info(path):
    try:
        info = os.lstat(path)
    except:
	msg = "Error while trying to get [%s] os.lstat information" % path
        logit(msg)
	return
    string = "uid[%d] gid[%d] perms[%s] file[%s]" % (info.st_uid, info.st_gid, oct(info.st_mode & 0777), path)
    logit(string)

def dump_install_content():
    logit("Begin")
    if sysname == 'Windows':
        return
    if not hasattr(os, "walk"):
        return
    for d in (pathbin, pathlib, pathusr):
        for dirname, dirnames, filenames in os.walk(d):
            for subdirname in dirnames:
                dirpath = os.path.join(dirname, subdirname)
                log_file_info(dirpath)
            for filename in filenames:
                filepath = os.path.join(dirname, filename)
                log_file_info(filepath)

try:
    install_pythonlink()
    move_usr_to_opt()
    missing_dirs()
    convert_svclinks()
    install_cron()
    install_rc()
    gen_keys()
    install_profile()
    install_etc_path()
    install_bash_completion()
    move_host_mode()
    nodeconf_params()
    purge_collector_api_cache()
    chmod_directories()
    dump_install_content()
except:
    save_exc()
    sys.exit(1)
