#!/usr/bin/env python

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

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

p0755 = int("0755", 8)
p0700 = int("0700", 8)
p0644 = int("0644", 8)
utf8patterns = ['UTF-8', 'UTF8', 'utf-8', 'utf8']

postinstall_d = sys.path[0]
if '/catalog/' in postinstall_d:
    # hpux packaging subsystem executes the postinstall from dir
    # /var/tmp/XXXXXXXXX/catalog/opensvc/commands/
    postinstall_d = "/usr/share/opensvc/bin"
    lsb = True
elif postinstall_d == "/usr/share/opensvc/bin":
    lsb = True
else:
    # windows install or unix execution from a non-lsb tree (ex: /opt/opensvc/)
    lsb = False

if lsb:
    pathsbin = "/usr/bin"
    pathsvc = None
    pathetc = "/etc/opensvc"
    pathvar = "/var/lib/opensvc"
    pathlck = '/var/lib/opensvc/lock'
    pathtmp = "/var/tmp/opensvc"
    pathlog = "/var/log/opensvc"
    pathbin = "/usr/share/opensvc/bin"
    pathlib = "/usr/share/opensvc/lib"
    pathini = "/usr/share/opensvc/bin/init"
    pathusr = None
else:
    pathsbin = postinstall_d
    pathsvc = os.path.realpath(os.path.join(pathsbin, '..'))
    pathetc = os.path.join(pathsvc, 'etc')
    pathvar = os.path.join(pathsvc, 'var')
    pathlck = os.path.join(pathvar, 'lock')
    pathtmp = os.path.join(pathsvc, 'tmp')
    pathlog = os.path.join(pathsvc, 'log')
    pathbin = postinstall_d
    pathlib = os.path.join(pathsvc, 'lib')
    pathini = os.path.join(pathsvc, 'bin', 'init')
    pathusr = os.path.join(pathsvc, 'usr')

def any(iterable):
    for element in iterable:
        if element:
            return True
    return False

def make_sure_path_exists(path):
    if os.path.exists(path):
        return
    os.makedirs(path, p0755)

def logit(msg, stdout=False, stderr=False):
    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()
    if stdout:
        sys.stdout.write(msg+"\n")
    if stderr:
        sys.stderr.write("error ==> %s\n" % (msg))

def osrun(cmd, stdout=False, stderr=False):
    ret = None
    if sysname == 'Windows':
        logit("cmd [%s]"%cmd, stdout, stderr)
        os.system(cmd)
    else:
        ret = os.WEXITSTATUS(os.system(cmd))
        logit("cmd [%s]  ret[%s]"%(cmd, ret), stdout, stderr)
    if ret is not None:
        return ret

make_sure_path_exists(pathlog)

if sysname == 'SunOS':
    osvcfmri = 'svc:/site/application/opensvc:boot'
    cmd = ['svcs', '-vl', osvcfmri, '2>/dev/null']
    ret = osrun(' '.join(cmd))
    if ret == 0:
        # Solaris install from IPS package with standard FMRI
        logit("Solaris postinstall check for first run", stdout=False)
        cmd = ['svcprop', '-p', 'boot/firstrun', osvcfmri, '|', 'grep', 'done']
        ret = osrun(' '.join(cmd))
        if ret == 0:
            logit("Solaris postinstall already executed. Exiting.", stdout=False)
            sys.exit(0)

logit("\nStarting OpenSVC postinstall\n", stdout=True)

SolarisRootRelocate = False
if sysname == 'SunOS' and "PKG_INSTALL_ROOT" in os.environ and os.environ['PKG_INSTALL_ROOT'] != '/':
    logit("SunOS PKG_INSTALL_ROOT <%s>"%(os.environ['PKG_INSTALL_ROOT']))
    SolarisRootRelocate = True

variables = {
    "pathsvc": pathsvc,
    "pathsbin": pathsbin,
    "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 install_cron():
    logit("begin")
    if sysname == 'Windows':
        logit("windows not applicable")
        return
    else:
        return install_cron_unix()

def install_winservice():
    if sysname != 'Windows':
        return
    logit("begin")
    logit("install OpenSVC agent winservice", stdout=True)
    schedstop()
    time.sleep(3)
    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")
    logit("_cmd %s"%_cmd)
    rc = '"'+sys.executable+'" "'+os.path.join(pathlib, 'osvcd_winservice.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 save_file(infile):
    logit("begin")
    logit("infile <%s>"%infile)
    if not os.path.exists(infile):
        return True
    try:
        import datetime
        timestamp = str(datetime.datetime.now())
        tmp = timestamp.replace(" ", ".")
        ts = tmp.replace(":", ".")
    except:
        ts = 'opensvc.postinstall'
    ofname = os.path.basename(infile)
    logit("ofname <%s>"%ofname)
    nfname = ofname + '.crontab.' + ts
    logit("nfname <%s>"%nfname)
    outfile = os.path.join(os.sep, pathtmp, nfname)
    logit("outfile <%s>"%outfile)

    logit("saving file <%s> to <%s>"%(infile, outfile), stdout=True)
    try:
        shutil.copyfile(infile, outfile)
    except:
        import traceback
        traceback.print_exc()
        logit("error while trying to save file <%s> to <%s>"%(infile, outfile), stderr=True)
        return False
    return True


def install_cron_unix():
    logit("begin")
    """install opensvc cron jobs
    """

    remove_entries = [
        'bin/nodemgr schedulers',
        'bin/nodemgr compliance check',
        'bin/svcmon ',
        'bin/cron/opensvc',
        'svcmgr resource monitor',
        'svcmgr resource_monitor',
        'nodemgr cron',
        'perfagt.'+sysname,
    ]

    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:
        logit("looping crontab location <%s>"%loc)
        if os.path.exists(os.path.dirname(loc)):
            if not root_crontab:
                root_crontab = loc
                logit("identifying <%s> as root crontab"%root_crontab)
            elif os.path.exists(loc):
                logit("adding <%s> to purge table"%loc)
                purge.append(loc)

    if not root_crontab:
        logit("no root crontab found in usual locations <%s>"%str(root_crontab_locs), stderr=True)
        return False

    new = False
    if os.path.exists(root_crontab):
        try:
            f = open(root_crontab, 'r')
            new = f.readlines()
            f.close()
            logit("loaded crontab <%s> content <%s>"%(root_crontab, new))
        except:
            f.close()
            import traceback
            traceback.print_exc()

    if not new:
        logit("empty crontab found. skipping purge.", stderr=False)
        if os.path.exists(root_crontab) and os.stat(root_crontab).st_size == 0:
            logit("removing crontab %s"%root_crontab)
            os.unlink(root_crontab)
        return False

    i = -1
    for line in new:
        i += 1
        for re in remove_entries:
            logit("looping re <%s>"%re)
            if line.find(re) != -1:
                logit("delete line <%s> from <%s>"%(re, root_crontab))
                del new[i]

    logit("saving crontab <%s>"%root_crontab)
    try:
        save_file(root_crontab)
    except:
        logit('Error while trying to backup crontab <%s>. skipping crontab update'%(root_crontab), stderr=True)
        return False

    logit("updating crontab <%s> with content <%s>"%(root_crontab, new))
    try:
        f = open(root_crontab, 'w')
        f.write(''.join(new))
        f.close()
    except:
        logit("error while trying to update crontab %s"%root_crontab, stderr=True)
        f.close()
        import traceback
        traceback.print_exc()

    """ Activate changes (actually only needed on HP-UX)
    """
    if sysname in ("HP-UX", "SunOS") and root_crontab.find('/var/spool/') != -1:
        logit("crontab activation requested")
        cmd = ['crontab', root_crontab]
        ret = osrun(' '.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):
            logit("removing %s"%f)
            os.unlink(f)


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

def activate_systemd(launcher):
    logit("begin")
    systemdsvcs = ['opensvc-agent.service', 'opensvc-services.service']

    for systemdsvc in systemdsvcs:
        _activate_systemd(systemdsvc)

def _activate_systemd(systemdsvc):

    if not os.path.islink('/lib') and os.path.isdir('/lib/systemd/system'):
        systemd_unit_path = '/lib/systemd/system'
    else:
        systemd_unit_path = '/usr/lib/systemd/system'

    systemd_unit_paths = [
        systemd_unit_path,
        '/etc/systemd/system/',
    ]

    installed = False
    for path in systemd_unit_paths:
        if os.path.exists(os.path.dirname(path)):
            # populate systemd tree with opensvc unit file
            src = os.path.join(pathini, "systemd."+systemdsvc)
            dst = os.path.join(path, systemdsvc)
            try:
                shutil.copyfile(src, dst)
                os.chmod(dst, p0644)
                installed = True
                break
            except IOError as exc:
                if exc.errno == 30:
                    continue
                logit("issue met while trying to install systemd unit file: %s"%str(exc), stderr=True)
            except OSError as exc:
                if exc.errno == 30:
                    continue
                logit("issue met while trying to install systemd unit file: %s"%str(exc), stderr=True)
            except Exception as exc:
                logit("issue met while trying to install systemd unit file: %s"%str(exc), stderr=True)

    if installed is not True:
        logit("issue met while trying to identify suitable systemd unit file location", stderr=True)
    else:
        logit("installing %s systemd unit file in %s"%(systemdsvc, path), stdout=True)

    # reset paths in ExecStart and ExecStop
    osrun("sed -i 's@/usr/share/opensvc/bin@"+pathbin+"@' "+dst)

    # reset path in PIDFile
    osrun("sed -i 's@/var/lib/opensvc@"+pathvar+"@' "+dst)

    # reload systemd configuration
    logit("reloading systemd configuration", stdout=True)
    cmd = ['systemctl', '-q', 'daemon-reload']
    ret = osrun(' '.join(cmd))
    if ret > 0:
        logit("issue met during systemctl reload", stderr=True)

    # enable opensvc agent startup through systemd
    logit("enabling systemd configuration")
    cmd = ['systemctl', '-q', 'disable', systemdsvc]
    ret = osrun(' '.join(cmd))
    cmd = ['systemctl', '-q', 'enable', systemdsvc]
    ret = osrun(' '.join(cmd))
    if ret > 0:
        logit("issue met during systemctl enable", stderr=True)


def systemd_mgmt():
    logit("begin")
    cmd = ['systemctl', '--version', '>>/dev/null', '2>&1']
    ret = osrun(' '.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 = osrun(' '.join(cmd))
    if ret > 0:
        logit("issue met while trying to remove opensvc rc launchers", stderr=True)
        return False
    cmd = ['update-rc.d', 'opensvc', 'defaults']
    ret = osrun(' '.join(cmd))
    if ret > 0:
        logit("issue met while trying to install opensvc rc launchers", stderr=True)
        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"):
        logit("removing /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):
                logit("removing %s"%l)
                os.unlink(l)
            logit("create link %s -> %s"%(l, rc))
            os.symlink(rc, l)
    try:
        f = open("/etc/rc.config.d/opensvc", "w")
        f.write("RUN_OPENSVC=1\n")
        f.close()
    except:
        logit("issue met while trying to install rc.config.d opensvc file", stderr=True)
        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):
                logit("removing %s"%l)
                os.unlink(l)
            logit("create link %s -> %s"%(l, rc))
            os.symlink(rc, l)
    return True

def activate_OSF1(launcher):
    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):
                logit("removing %s"%l)
                os.unlink(l)
            logit("symlinking %s and %s"%(rc, 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):
                logit("removing %s"%l)
                os.unlink(l)
            logit("symlinking %s and %s"%(rc, l))
            os.symlink(rc, l)
    return True

def activate_openrc(launcher):
    logit("begin")
    cmd = ['rc-update', '--help', '>>/dev/null 2>&1']
    ret = osrun(' '.join(cmd))
    if ret == 127:
        logit("rc-update command not found, skipping opensvc init setup", stdout=True)
        return False
    cmd = ['rc-update', 'delete', '-a', 'opensvc']
    ret = osrun(' '.join(cmd))
    cmd = ['rc-update', 'add', 'opensvc', 'default']
    ret = osrun(' '.join(cmd))
    if ret > 0:
        logit("issue met while trying to install opensvc rc launchers", stderr=True)
        return False
    return True

def activate_FreeBSD(launcher):
    logit("begin")
    cmd = ['sysrc', '-f', '/etc/rc.conf.d/opensvc', 'opensvc_enable=YES']
    ret = osrun(' '.join(cmd))
    if ret > 0:
        logit("issue met while trying to install opensvc rc launchers", stderr=True)
        return False
    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
        msg = line.rstrip('\n')
        logit(msg, stdout=True)
    fileinput.close()

def get_keyval_in(key, path2f):
    logit("begin")
    val = None
    try:
        f = open(path2f, 'r')
        data = f.readlines()
        f.close()
    except:
        f.close()
        import traceback
        traceback.print_exc()

    for line in data:
        if line.startswith(key):
            val=line.split('=')[-1].strip()
            logit("found value <%s> for key <%s> in file <%s>"%(val, key, path2f))
            break

    return val

def is_lang_utf8(file):
    logit("begin")
    lang = get_keyval_in('LANG', file)
    if lang is not None:
        if any(pattern in lang for pattern in utf8patterns):
            return True
    return False

def is_system_locale_utf8():
    """
    Check if system locale is utf8
    """
    logit("begin")
    localetmp = pathtmp + '/locale.postinstall'
    cmd = ['locale', '>', localetmp]
    ret = osrun(' '.join(cmd))
    if ret > 0:
        logit("error while trying to query locale with command <%s>"%(cmd), stderr=True)
        return False
    try:
        return is_lang_utf8(localetmp)
    finally:
        try:
            os.unlink(localetmp)
        except Exception:
            pass

def is_osvc_locale_utf8(file):
    """
    Check if osvc locale is utf8
    """
    logit("begin")
    return is_lang_utf8(file)

def appends2f(str, fname):
    try:
        f = open(fname, "a")
        f.write(str + "\n")
        f.close()
        logit("added string <%s> to file <%s>"%(str, fname))
    except:
        logit("issue met while trying to append string <%s> to file <%s>"%(str, fname), stderr=True)
        f.close()
        import traceback
        traceback.print_exc()

def find_locale():
    logit("begin")
    """ try to identify best utf8 locale
    """
    localetmp = pathtmp + '/locale.all'
    cmd = ['locale', '-a', '>', localetmp]
    ret = osrun(' '.join(cmd))
    if ret > 0:
        logit("error while trying to build locale list with command <%s>"%(cmd), stderr=True)
        return None

    data = []
    try:
        f = open(localetmp, 'r')
        while True:
            try:
                line = f.readline()
            except Exception:
                break
            if not line:
                break
            data.append(line)
        f.close()
    except:
        f.close()
        import traceback
        traceback.print_exc()

    candidates = []
    for l in data:
        if any(pattern in l for pattern in utf8patterns):
            candidates.append(l.strip())

    logit("utf8 locale candidates <%s>"%(candidates))
    for l in candidates:
        if l.startswith('C'):
            return l

    for l in candidates:
        if l.startswith('en_US'):
            return l

    for l in candidates:
        if l.startswith('en_'):
            return l

    logit("no suitable utf8 locale found")
    return None

def install_locale(path2file):
    logit("begin")
    """ install utf8 locale
    """
    lang = get_keyval_in('LANG', path2file)
    if lang is not None:
        logit("LANG <%s> already set with non utf8 locale"%(lang), stderr=True)
    else:
        locale = find_locale()
        if locale is not None:
            appends2f("LANG=" + locale, path2file)
            appends2f("export LANG", path2file)

def install_params(path2file):
    logit("begin")
    """ install template file with tunable variables
    """
    if os.path.exists(path2file):
        logit("file %s already present"%path2file)
        return

    src = os.path.join(pathini, 'opensvc.defaults.parameters')
    with open(src, "r") as f:
        buff = f.read()
    if sys.executable != "/usr/bin/python":
        buff += "OSVC_PYTHON=%s\n" % sys.executable
    if os.path.join("share", "opensvc", "bin") not in __file__:
        root_path = os.path.realpath(os.path.join(os.path.dirname(__file__), ".."))
        buff += "OSVC_ROOT_PATH=%s\n" % root_path
    try:
        logit("writing new <%s>"%path2file)
        with open(path2file, "w") as f:
            f.write(buff)
        os.chmod(path2file, p0644)
    except:
        import traceback
        traceback.print_exc()

def os_release():
    os_release_f = os.path.join(os.sep, "etc", "os-release")
    data = {"ID": "==magic1234"}
    if not os.path.exists(os_release_f):
        return data
    filep = open(os_release_f, "r")
    try:
        for line in filep.readlines():
            line = line.strip("\n")
            try:
                var, val = line.split("=", 1)
            except:
                continue
            data[var] = val.strip('"')
    finally:
        filep.close()
    return data

def install_rc():
    logit("begin")
    """install startup script
    """
    params = None
    copyrc = True

    if reldata["ID"] in ("gentoo"):
        rc = '/etc/init.d/opensvc'
        params = '/etc/conf.d/opensvc'
        src = os.path.join(pathini, 'opensvc.init.openrc')
        if systemd_mgmt():
            logit("gentoo with systemd")
            copyrc = False
            activate = activate_systemd
        else:
            logit("gentoo with openrc")
            activate = activate_openrc
    elif reldata["ID"] in ("ubuntu", "debian") or os.path.exists('/etc/debian_version'):
        rc = '/etc/init.d/opensvc'
        params = '/etc/default/opensvc'
        src = os.path.join(pathini, '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 reldata["ID"] == "arch" or os.path.exists('/etc/arch-release'):
        rc = '/etc/init.d/opensvc'
        params = '/etc/default/opensvc'
        src = os.path.join(pathini, 'opensvc.init.debian')
        if systemd_mgmt():
            logit("arch with systemd")
            copyrc = False
            activate = activate_systemd
    elif reldata["ID"] in ("sles", "caasp") or os.path.exists('/etc/SuSE-release'):
        rc = '/etc/init.d/opensvc'
        params = '/etc/sysconfig/opensvc'
        src = os.path.join(pathini, '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 reldata["ID"] in ("alpine") or os.path.exists('/etc/alpine-release'):
        rc = '/etc/init.d/opensvc'
        params = '/etc/conf.d/opensvc'
        src = os.path.join(pathini, 'opensvc.init.openrc')
        activate = activate_openrc
    elif reldata["ID"] in ("centos", "rhel", "fedora") or os.path.exists('/etc/redhat-release'):
        params = '/etc/sysconfig/opensvc'
        src = os.path.join(pathini, '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 = os.path.join(pathini, '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"] + os.path.join(pathini, 'opensvc.init.SunOS')
        else:
            rc = '/etc/init.d/opensvc'
            params = '/etc/default/opensvc'
            src = os.path.join(pathini, 'opensvc.init.SunOS')
        activate = activate_SunOS
    elif sysname == "OSF1":
        rc = '/sbin/init.d/opensvc'
        src = os.path.join(pathini, 'opensvc.init.OSF1')
        activate = activate_OSF1
    elif sysname == "FreeBSD":
        rc = '/usr/local/etc/rc.d/opensvc'
        params = '/etc/defaults/opensvc'
        src = os.path.join(pathini, 'opensvc.init.FreeBSD')
        activate = activate_FreeBSD
    elif sysname == "AIX":
        rc = '/etc/rc.d/init.d/opensvc'
        src = os.path.join(pathini, 'opensvc.init.AIX')
        activate = activate_AIX
    elif sysname == "Darwin":
        rc = '/Library/LaunchDaemons/com.opensvc.svcmgr.plist'
        params = '/etc/defaults/opensvc'
        src = os.path.join(pathini, 'darwin.com.opensvc.svcmgr.plist')
        activate = activate_Darwin
    elif sysname == 'Windows':
        return False
    else:
        logit("could not select an init script: unsupported operating system", stderr=True)
        return False

    if os.path.islink(rc):
        logit("removing link %s"%rc)
        os.unlink(rc)

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

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

    if params is not None:
        logit("checking locale setup")
        if not is_system_locale_utf8() and not is_osvc_locale_utf8(params):
            logit("locale is not utf8")
            install_locale(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("sshhome <%s>"%sshhome)
    if not os.path.exists(sshhome):
        logit("create dir %s"%sshhome, stdout=True)
        os.makedirs(sshhome, p0700)
    priv = os.path.join(sshhome, "id_rsa")
    pub = os.path.join(sshhome, "id_rsa.pub")
    if os.path.exists(pub) or os.path.exists(priv):
        logit("either %s or %s already exist"%(pub, priv))
        return
    cmd = ['ssh-keygen', '--help', '>>/dev/null 2>&1']
    ret = osrun(' '.join(cmd))
    if ret == 127:
        logit("ssh-keygen command not found, skipping key creation", stdout=True)
        return
    cmd = ['ssh-keygen', '-t', 'rsa', '-b', '2048', '-P', '""', '-f', priv]
    try:
        ret = osrun(' '.join(cmd))
    except:
        logit("Error while trying to generate ssh keys")

def missing_dir(pathd):
    logit("begin")
    if not os.path.exists(pathd):
        logit("create dir %s"%pathd, stdout=True)
        os.makedirs(pathd, p0755)

def missing_dirs():
    logit("begin")
    missing_dir(pathlog)
    missing_dir(pathtmp)
    missing_dir(pathvar)
    missing_dir(pathetc)
    missing_dir(pathlck)

def move_env_to_conf():
    for fpath in glob.glob(os.path.join(pathetc, "*.env")):
        svcname = os.path.basename(fpath)[:-4]
        new_basename = svcname+".conf"
        new_fpath = os.path.join(pathetc, new_basename)
        shutil.move(fpath, new_fpath)

def move_var_files_in_subdirs():
    for fpath in glob.glob(os.path.join(pathvar, "last_*")):
        dst = os.path.join(pathvar, "node")
        if not os.path.exists(dst):
            os.makedirs(dst)
        fname = os.path.basename(fpath)
        new_fpath = os.path.join(dst, fname)
        logit("move %s to %s" % (fpath, new_fpath))
        shutil.move(fpath, new_fpath)

    for fpath in glob.glob(os.path.join(pathvar, "*_last_*")):
        fname = os.path.basename(fpath)
        svcname = fname.split("_last_")[0]
        dst = os.path.join(pathvar, svcname)
        if not os.path.exists(dst):
            os.makedirs(dst)
        fname = fname.replace(svcname+"_", "")
        new_fpath = os.path.join(dst, fname)
        logit("move %s to %s" % (fpath, new_fpath))
        shutil.move(fpath, new_fpath)

    for fpath in glob.glob(os.path.join(pathvar, "*.push")):
        svcname = os.path.basename(fpath).split(".push")[0]
        dst = os.path.join(pathvar, svcname)
        if not os.path.exists(dst):
            os.makedirs(dst)
        fname = "last_pushed_env"
        new_fpath = os.path.join(dst, fname)
        logit("move %s to %s" % (fpath, new_fpath))
        shutil.move(fpath, new_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):
        logit("found old var %s"%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:
                logit("file %s already exist"%dst)
                continue
            if os.path.isdir(f):
                logit("copying dir %s to %s"%(f, dst))
                shutil.copytree(f, dst, symlinks=True)
            elif os.path.islink(f):
                linkto = os.readlink(f)
                logit("create link %s -> %s"%(dst, linkto))
                os.symlink(linkto, dst)
            else:
                logit("copying file %s to %s"%(f, dst))
                shutil.copy2(f, dst)

    if os.path.exists(old_pathetc):
        logit("found old etc %s"%old_pathetc)
        for f in glob.glob(old_pathetc+'/*'):
            dst = os.path.join(pathetc, os.path.basename(f))
            if os.path.exists(dst):
                logit("file %s already exist"%dst)
                continue
            if os.path.islink(f):
                linkto = os.readlink(f)
                logit("create link %s -> %s"%(dst, linkto))
                os.symlink(linkto, dst)
            elif os.path.isdir(f):
                logit("copying dir %s to %s"%(f, dst))
                shutil.copytree(f, dst, symlinks=True)
            else:
                logit("copying file %s to %s"%(f, dst))
                shutil.copy2(f, dst)

    if os.path.exists(old_pathsvc):
        logit("removing old_pathsvc %s"%old_pathsvc)
        shutil.rmtree(old_pathsvc)

    if os.path.islink(linksvc) and os.path.realpath(linksvc) == old_pathsvc:
        logit("removing linksvc %s"%linksvc)
        os.unlink(linksvc)

def move_var_files_19():
    # node frozen flag
    old_node_frozen = os.path.join(pathvar, "FROZEN")
    pathvar_node = os.path.join(pathvar, "node")
    if not os.path.exists(pathvar_node):
        os.makedirs(pathvar_node, p0755)
    if os.path.exists(old_node_frozen):
        node_frozen = os.path.join(pathvar_node, "frozen")
        shutil.move(old_node_frozen, node_frozen)

    # service frozen flag
    for fpath in glob.glob(os.path.join(pathvar, "FROZEN.*")):
        svcname = os.path.basename(fpath).replace("FROZEN.", "")
        pathvar_svc = os.path.join(pathvar, "services", svcname)
        if not os.path.exists(pathvar_svc):
            os.makedirs(pathvar_svc, p0755)
        svc_frozen = os.path.join(pathvar_svc, "frozen")
        shutil.move(fpath, svc_frozen)

    # stats
    pathstats = os.path.join(pathvar, "stats")
    if not os.path.exists(pathstats):
        os.makedirs(pathstats, p0755)
    for fpath in glob.glob(os.path.join(pathvar, "stats_*")):
        fname = os.path.basename(fpath).replace("stats_", "")
        dst = os.path.join(pathvar, "stats", fname)
        shutil.move(fpath, dst)


def install_etc_path():
    logit("begin")
    p = os.path.join(os.sep, 'etc', 'PATH')
    if not os.path.exists(p):
        logit("etc/PATH not found")
        return
    try:
        logit("loading %s"%(p))
        f = open(p, "r")
        buff = f.read()
        f.close()
    except:
        logit("issue met while trying to read %s"%(p), stderr=True)
        return
    l = buff.strip().split(":")
    n = len(l)
    for op in (pathbin, pathetc):
        if op in l:
            logit("dir %s already present in %s"%(op, p))
            continue
        logit("adding dir %s"%(op))
        l.append(op)
    if len(l) == n:
        logit("nothing changed in %s"%(p))
        return
    try:
        logit("updating %s"%(p))
        f = open(p, "w")
        f.write(":".join(l)+'\n')
        f.close()
    except:
        logit("issue met while trying to write %s"%(p), stderr=True)
        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 = """
if ! echo ${PATH} | grep -qw %(pathbin)s; then
	PATH=${PATH}:%(pathbin)s
fi

om() {
        case "$1 $2" in
        "ctx get")
		[ -z "$OSVC_CONTEXT" ] && echo "(local)" || echo $OSVC_CONTEXT
		;;
        "ctx set")
                test -z "$3" && {
                        echo "om ctx set <context>" >&2
                        return 1
                }
                echo "context switch: $OSVC_CONTEXT => $3"
                export OSVC_CONTEXT=$3
                ;;
        "ctx unset")
                unset OSVC_CONTEXT
                ;;
        "ns get"|"getns "*)
		[ -z "$OSVC_NAMESPACE" ] && echo "(none)" || echo $OSVC_NAMESPACE
		;;
        "ns set")
                test -z "$3" && {
                        echo "om ns set <ns>" >&2
                        return 1
                }
                test "$3"=="root" -o -d %(pathetc)s/namespaces/$3 || {
                        echo "namespace $2 does not exist" >&2
                        return 1
                }
                echo "namespace switch: $OSVC_NAMESPACE => $3"
                export OSVC_NAMESPACE=$3
                ;;
        "ns unset")
                unset OSVC_NAMESPACE
                ;;
        "setns "*)
                test -z "$2" && {
                        echo "om setns <ns>" >&2
                        return 1
                }
                test "$2"=="root" -o -d %(pathetc)s/namespaces/$2 || {
                        echo "namespace $2 does not exist" >&2
                        return 1
                }
                echo "namespace switch: $OSVC_NAMESPACE => $2"
                export OSVC_NAMESPACE=$2
                ;;
        "unsetns "*)
                unset OSVC_NAMESPACE
                ;;
        *)
                %(pathbin)s/om "$@"
                ;;
        esac
}
""" % dict(pathetc=pathetc, pathbin=pathbin)

    if not os.path.exists(prof_d):
        logit("no profile directory found")
        return
    try:
        logit("installing profile in file %s"%(prof))
        f = open(prof, 'w')
        f.write(buff)
        f.close()
    except:
        logit("issue met while trying to install profile in file %s"%(prof), stderr=True)
        f.close()
        import traceback
        traceback.print_exc()

def install_bash_completion():
    logit("begin")
    if sysname == 'SunOS':
        if os.path.exists("/etc/bash") and not os.path.exists("/etc/bash/bash_completion.d"):
            os.makedirs("/etc/bash/bash_completion.d", p0755)
    root = pathsvc if pathsvc else ""
    src = os.path.join(root, 'usr', 'share', 'bash_completion.d', 'opensvc.sh')
    dst = None
    ds = [os.path.join(os.sep, 'etc', 'bash_completion.d'),
          os.path.join(os.sep, 'etc', 'bash', 'bash_completion.d')]
    for d in ds:
        if os.path.exists(d):
            dst = os.path.join(d, 'opensvc.sh')
            break
    if dst is None:
        logit("no bash completion directory found")
        return
    deprecated_dst = os.path.join(d, 'opensvc')
    if os.path.exists(deprecated_dst):
        logit("remove deprecated bash completion file %s"%deprecated_dst)
        os.unlink(deprecated_dst)
    if not root:
        # the completion script is installed by the package
        return
    try:
        logit("installing bash completion file src %s to tgt %s"%(src, dst))
        shutil.copyfile(src, dst)
        os.chmod(dst, p0644)
    except:
        logit("issue met while trying to install bash completion file src %s to tgt %s"%(src, dst))

def install_link(source, target):
    logit("begin")
    if source == '' or target == '':
        logit("bad parameters")
        return False
    if os.path.realpath(source) == os.path.realpath(target):
        logit("link already ok")
        return True
    if os.path.islink(target) or os.path.exists(target):
        logit("unlink %s", target)
        os.unlink(target)
    try:
        logit("create link %s -> %s"%(target, source))
        os.symlink(source, target)
    except:
        logit("issue met while trying to symlink src %s with tgt %s"%(source, target))

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


def install_pythonlink_windows():
    logit("begin")
    logit("before appending pathlib to syspath")
    logit(os.environ["PATH"])
    sys.path = [pathlib] + sys.path
    logit("after appending pathlib to syspath")
    logit(os.environ["PATH"])
    try:
        from rcUtilitiesWindows import get_registry_value
    except ImportError:
        return
    logit("before reading installfolder in registry")
    try:
        installfolder = get_registry_value('HKEY_CURRENT_USER', 'Software\\OpenSVC', 'path')
    except:
        logit("issue met while trying to read path into registry HKCU/Software/OpenSVC/path", stderr=True)
        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 move_host_mode():
    logit("begin")
    hm = os.path.join(pathvar, 'host_mode')
    cf = os.path.join(pathetc, 'node.conf')
    nodemgr = os.path.join(pathsbin, 'nodemgr')
    if not os.path.exists(hm):
        logit("file %s does not exist"%hm)
        return
    try:
        fp = open(hm, 'r')
        mode = fp.read().split()[0]
        fp.close()
    except:
        logit("failed to read old host_mode. renamed to %s"%(hm+'.old'))
        shutil.move(hm, hm+'.old')
        return
    cmd = [nodemgr, 'set', '--param', 'node.host_mode', '--value', mode]
    ret = osrun(' '.join(cmd))
    if ret != 0:
        logit("failed to set host_mode in node.conf", stdout=True)
        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):
        logit("unlink file %s"%dotnodeconf)
        os.unlink(dotnodeconf)

    if not os.path.exists(nodeconf):
        logit("file %s does not exist"%nodeconf)
        return

    try:
        import ConfigParser
    except ImportError:
        import configparser as ConfigParser
    import copy
    try:
        config = ConfigParser.RawConfigParser()
    except AttributeError:
        logit("issue occured while trying to instantiate configparser")
        return
    config.read(nodeconf)
    changed = False

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

    # sync section goes to etc/.node.conf
    if config.has_section('sync'):
        logit("removing sync in node.conf")
        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']:
                logit("looping %s"%o)
                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']:
                logit("looping %s"%o)
                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']:
                logit("looping %s"%o)
                v = config.get(s, o)
                config.remove_option(s, o)
                config.set(s, 'period', v)
                changed = True

    if changed:
        logit("writing new node.conf")
        try:
            fp = open(nodeconf, 'w')
            config.write(fp)
            fp.close()
        except:
            logit("failed to write new %s"%nodeconf, stderr=True)

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)
        logit("unexpected error. stack saved in %s"%f.name, stderr=True)
        f.close()
    except:
        logit("unexpected error", stderr=True)
        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):
        logit("unlink file %s"%fname)
        os.unlink(fname)

def chmod_directories():
    logit("begin")
    if not hasattr(os, "walk"):
        logit("os.walk not available")
        return
    if sysname == 'Windows':
        logit("skip : unsupported on Windows")
        return
    for d in (pathbin, pathlib, pathusr):
        if d is None:
            continue
        for dirname, dirnames, filenames in os.walk(d):
            for subdirname in dirnames:
                dirpath = os.path.join(dirname, subdirname)
                try:
                    os.chmod(dirpath, p0755)
                    msg = "setting %s permissions to 0755" % dirpath
                except:
                    msg = "issue met while trying to set %s permissions to 0755" % dirpath
                logit(msg)

def log_file_info(path):
    try:
        info = os.lstat(path)
    except:
        msg = "issue met 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 & 777), path)
    logit(string)

def dump_install_content():
    logit("begin")
    if sysname == 'Windows':
        logit("skip : unsupported on Windows")
        return
    if not hasattr(os, "walk"):
        logit("os.walk not available")
        return
    for d in (pathbin, pathlib, pathusr):
        if d is None:
            continue
        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)

def convert_to_ns():
    import re
    if sysname == 'Windows':
        logit("skip : unsupported on Windows")
        return
    for p in glob.glob(pathvar+"/services"):
        d = re.sub("/services$", "/svc", p)
        if not os.path.exists(d):
            logit("migrate %s => %s" % (p, d))
            shutil.move(p, d)
    for p in glob.glob(pathvar+"/namespaces/*/services"):
        d = re.sub("/services$", "/svc", p)
        if not os.path.exists(d):
            logit("migrate %s => %s" % (p, d))
            shutil.move(p, d)
    for p in glob.glob(pathetc+"/namespaces/system/cluster.conf"):
        d = pathetc+"/cluster.conf"
        make_sure_path_exists(os.path.dirname(d))
        if not os.path.exists(d):
            logit("migrate %s => %s" % (p, d))
            shutil.move(p, d)
    for p in glob.glob(pathetc+"/namespaces/*/*.conf"):
        l = p.split("/")
        l.insert(-1, "svc")
        d = "/".join(l)
        make_sure_path_exists(os.path.dirname(d))
        if not os.path.exists(d):
            logit("migrate %s => %s" % (p, d))
            shutil.move(p, d)
    for p in glob.glob(pathlog+"/*/*.log*"):
        l = p.split("/")
        l.insert(-2, "namespace")
        l.insert(-1, "svc")
        d = "/".join(l)
        make_sure_path_exists(os.path.dirname(d))
        if not os.path.exists(d):
            logit("migrate %s => %s" % (p, d))
            shutil.move(p, d)

def convert_to_lsb():
    logit("begin")
    if sysname == 'Windows':
        logit("skip : unsupported on Windows")
        return
    if len(glob.glob(pathetc+"/*")) > 0:
        logit("skip : skip convert to lsb because /etc/opensvc/ is not empty")
        return
    if not os.path.exists("/opt/opensvc"):
        logit("skip : skip convert to lsb because /opt/opensvc/ does not exist")
        return
    for p in glob.glob("/opt/opensvc/etc/*conf") + glob.glob("/opt/opensvc/etc/sssu") + glob.glob("/opt/opensvc/etc/*pem") + glob.glob("/opt/opensvc/etc/*pub"):
        logit("migrate " + p)
        shutil.copy(p, pathetc)
    for p in glob.glob("/opt/opensvc/etc/*.env"):
        logit("migrate " + p)
        svcname = os.path.basename(p)[:-4]
        shutil.copy(os.path.realpath(p), pathetc)
        os.symlink("/usr/bin/svcmgr", os.path.join(pathetc, svcname))
    for p in glob.glob("/opt/opensvc/etc/*.d") + glob.glob("/opt/opensvc/etc/*.dir"):
        logit("migrate " + p)
        if os.path.islink(p):
            bp = os.path.basename(p)
            linkto = os.readlink(p)
            if linkto.startswith("/opt/opensvc/etc"):
                linkto.replace("/opt/opensvc/etc/", "")
            dst = os.path.join(pathetc, bp)
            os.symlink(linkto, dst)
        elif os.path.isdir(p):
            bp = os.path.basename(p)
            dst = os.path.join(pathetc, bp)
            shutil.copytree(p, dst, symlinks=True)
        else:
            shutil.copy(p, pathetc)
    for p in glob.glob("/opt/opensvc/var/*"):
        if os.path.basename(p) == "btrfs":
            continue
        logit("migrate " + p)
        bp = os.path.basename(p)
        dst = os.path.join(pathvar, bp)
        if os.path.exists(dst):
            continue
        if os.path.isdir(p):
            try:
                shutil.copytree(p, dst, symlinks=True)
            except:
                # best effort for var
                pass
        else:
            shutil.copy(p, pathvar)

def restart_daemon():
    logit("begin")
    flag = os.path.join(pathvar, "postinstall.restart")
    if not os.path.exists(flag):
        return
    try:
        # never risk triggering "boot" actions on services, for
        # example due to a reference or format change for boot id
        os.unlink(os.path.join(pathvar, "node", "last_boot_id"))
    except:
        pass
    os.unlink(flag)
    os.environ['OPENSVC_AGENT_UPGRADE'] = "1"
    cmd = "%s/nodemgr daemon start" % pathbin
    osrun(cmd, stdout=True)
    cmd = "%s/nodemgr daemon running" % pathbin
    osrun(cmd)
    del os.environ['OPENSVC_AGENT_UPGRADE']

def init_secret():
    logit("begin")
    time.sleep(1)
    if sysname == 'Windows':
        cmd = "nodemgr ping --node 127.0.0.1"
    else:
        cmd = "%s/nodemgr ping --node 127.0.0.1" % pathbin
    osrun(cmd)

def solaris_fmri_setprop():
    logit("begin")
    if sysname != 'SunOS':
        logit("Only useful on SunOS", stdout=False)
        return
    else:
        logit("issuing setprop on fmri", stdout=False)
        osvcfmri = 'svc:/site/application/opensvc:boot'
        cmd = ['svccfg', '-s', osvcfmri, 'setprop', 'boot/firstrun', '=', 'done', '2>/dev/null']
        ret = osrun(' '.join(cmd))
        if ret == 0:
            # setprop ok, Solaris install from IPS package with standard FMRI
            logit("setprop ok. now refreshing fmri", stdout=False)
            cmd = ['svccfg', '-s', osvcfmri, 'refresh']
            ret = osrun(' '.join(cmd))
            if ret == 0:
                logit("fmri refresh successfully executed", stdout=False)

def remove_svclinks():
    logit("remove svclinks (deprecated)", stdout=False)
    svcmgr = os.path.realpath(os.path.join(pathsbin, 'svcmgr'))
    for path in glob.glob(os.path.join(pathetc, "*", "*", "*", "*")) + \
                glob.glob(os.path.join(pathetc, "*", "*", "*")) + \
                glob.glob(os.path.join(pathetc, "*", "*")) + \
                glob.glob(os.path.join(pathetc, "*")):
        if not os.path.islink(path):
            continue
        if os.path.realpath(path) != svcmgr:
            continue
        logit(" rm %s" % path, stdout=False)
        os.unlink(path)

try:
    reldata = os_release()
    move_var_files_in_subdirs()
    move_usr_to_opt()
    missing_dirs()
    install_cron()
    install_rc()
    gen_keys()
    install_profile()
    install_etc_path()
    install_bash_completion()
    move_host_mode()
    install_pythonlink()
    nodeconf_params()
    purge_collector_api_cache()
    chmod_directories()
    convert_to_lsb()
    move_env_to_conf()
    move_var_files_19()
    dump_install_content()
    convert_to_ns()
    restart_daemon()
    init_secret()
    solaris_fmri_setprop()
    remove_svclinks()
    logit("\nOpenSVC postinstall terminated\n", stdout=True)
except:
    save_exc()
    sys.exit(1)
