#!/usr/bin/env perl
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
#

#-----------------------------------------------------------------------------

=head1    xcatconfig



 This is script is called during the initial installation of xCAT
    It can also be called directly to various parts of the configuration
    root ssh keys,  node host keys, credentials database setup or all

=cut

BEGIN
{
    $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
    $::XCATDIR  = $ENV{'XCATDIR'}  ? $ENV{'XCATDIR'}  : '/etc/xcat';
}

use lib "$::XCATROOT/lib/perl";
use strict;
use xCAT::Utils;
use xCAT::NetworkUtils;
use Getopt::Long;
use xCAT::MsgUtils;
use xCAT::Table;
use Socket;

#-----------------------------------------------------------------------------
# Main
$::progname = "xcatconfig";
my $args = join ' ', @ARGV;
$::command = "$0 $args";
Getopt::Long::Configure("bundling");
$Getopt::Long::ignorecase = 0;

# Default Install dir location
$::INSTALLDIR = "/install";

# Default TFTP dir location
$::TFTPDIR = "/tftpboot";

my $arraysize = @ARGV;
if ($arraysize == 0) {
    my $msg = "No parameters were supplied on the xcatconfig command. Run xcatconfig -h";
    xCAT::MsgUtils->message("E", $msg);
    exit 1;
}

Getopt::Long::Configure("posix_default");
Getopt::Long::Configure("no_gnu_compat");
Getopt::Long::Configure("bundling");

# parse the options
if (
    !GetOptions(
        'f|force'           => \$::FORCE,
        'i|initinstall'     => \$::INITIALINSTALL,
        'u|updateinstall'   => \$::UPDATEINSTALL,
        'k|sshkeys'         => \$::genSSHRootKeys,
        'm|mgtnode'         => \$::setupMNinDB,
        's|sshnodehostkeys' => \$::genSSHNodeHostKeys,
        't|tunables'        => \$::settunables,
        'c|credentials'     => \$::genCredentials,
        'd|database'        => \$::initDB,
        'h|help'            => \$::HELP,
        'v|version'         => \$::VERSION,
        'V|verbose'         => \$::VERBOSE,
        'installdir=s'      => \$::INSTALLDIR,
        'tftpdir=s'         => \$::TFTPDIR,
    )
  )
{
    &usage;
    exit(1);
}


# display the usage if -h or --help is specified
if ($::HELP)
{
    &usage;
    exit(0);
}

# display the version statement if -v or --verison is specified
if ($::VERSION)
{
    my $version = xCAT::Utils->Version();
    $version .= "\n";
    xCAT::MsgUtils->message("I", $version);
    exit 0;
}
if ($::FORCE)
{
    if ($::INITIALINSTALL
        || $::UPDATEINSTALL
        || $::genSSHRootKeys
        || $::genSSHNodeHostKey
        || $::genCredentials
        || $::settunables
        || $::initDB)
    {
        my $warning =
" The -f flag includes the function for the -i, -u, -k, -s, -c, -d flags. Do not combine with other flags.\n ";
        xCAT::MsgUtils->message("I", $warning);
        exit 1;
    }
}
if (($::INITIALINSTALL) && ($::UPDATEINSTALL))
{
    my $warning =
" The -i and -u flags may not be input to the command. Use one or the other. \n ";
    xCAT::MsgUtils->message("I", $warning);
    exit 1;
}

#
# Display command
#
verbose("Running $::command");
if (xCAT::Utils->isAIX())
{
    $::osname = 'AIX';
}
else
{
    $::osname = 'Linux';
}

# if on rhel6, check to see if perl-IO-Compress-Zlib* is installed
if (($::INITIALINSTALL) || ($::UPDATEINSTALL))
{
    my $os   = xCAT::Utils->osver();
    my $arch = `uname -p`;
    if (($os =~ /^rh.*6$/) && ($arch =~ /^x86_64/)) {
        if (!(-e "/usr/lib64/perl5/IO/Uncompress/Gunzip.pm")) {
            xCAT::MsgUtils->message('I', "perl-IO-Compress-Zlib* is not installed. If you try and use genesis discovery,  you will have fatal errors in the xcat daemon.\n Install  perl-IO-Compress-Zlib,perl-IO-Compress-Base rpms.");

        }

    }
}


#
# If the XCATPGPW environment variable is specified,
# call pgsqlsetup command with -N flag to setup PostgreSQL database.
# This is a requirement of PCM, it should be done only in install scenario but not update.
#
if ($::INITIALINSTALL || $::FORCE)
{
    if (($::osname eq 'Linux') && $ENV{'XCATPGPW'})
    {
        my $cmd = "XCATPGPW=$ENV{'XCATPGPW'} $::XCATROOT/bin/pgsqlsetup -i -N";
        my $outref = xCAT::Utils->runcmd("$cmd", 0);
        if ($::RUNCMD_RC != 0)
        {
            xCAT::MsgUtils->message('E', "Could not setup PostgreSQL, falling back to sqlite...");
            $cmd = "rm -f /etc/xcat/cfgloc";
            $outref = xCAT::Utils->runcmd("$cmd", -1);
            if ($::RUNCMD_RC != 0)
            {
                xCAT::MsgUtils->message('E', "Could not fall back to sqlite, where should we go?");
            }
        }
        else
        {
            # Init the database
            $::initDB = 1;
        }
    }
}

# To support AIX INUCLIENTS, to support the scenario where the user needs to install xCAT rpms
# into the INUCLIENT=1 environment, such as AIX diskless node(installing xCAT in AIX NIM SPOT),
# or alternative disk installation.
#

if (($::osname eq 'AIX') && ($ENV{'INUCLIENTS'} == 1))
{
    # INUCLIENTS is configured, add xcatconfig to /etc/inittab
    my $cmd = "/usr/sbin/lsitab xcatconfig > /dev/null 2>&1";
    my $rc  = system("$cmd") >> 8;
    if ($rc != 0)
    {
        # add new entry
        my $flag;
        if ($::INITIALINSTALL)
        {
            $flag = "-i";
        }

        if ($::UPDATEINSTALL)
        {
            $flag = "-u";
        }

        if ($::initDB)
        {
            $flag = "-d";
        }

        my $mkcmd = qq~/usr/sbin/mkitab "xcatconfig:2:once:$::XCATROOT/sbin/xcatconfig $flag > /dev/console 2>&1"~;
        system("$mkcmd");
    }
    exit(0);
}

if ($::osname eq 'AIX')
{
    $::arch = `uname -p`;

    #$::root = "";
    $::root = xCAT::Utils->getHomeDir();
}
else
{
    $::arch = `uname -m`;
    $::root = "/root";
}
chomp $::arch;
chomp $::root;

if ($::INITIALINSTALL || $::FORCE || $::UPDATEINSTALL)
{
    # Ubuntu uses upstart to manage dhcp server,
    # xCAT does not support upstart for now,
    # disable dhcp server in upstart and let xCAT totally manage dhcp server
    if (-e "/etc/debian_version")
    {
        # Try to stop isc-dhcp-server started by upstart
        my $cmd = "stop isc-dhcp-server";
        xCAT::Utils->runcmd("$cmd", -1);

        # Disable isc-dhcp-server in upstart
        `echo manual > /etc/init/isc-dhcp-server.override`;
    }
}

#
# Generate ssh host keys for the nodes
#
#
if (xCAT::Utils->isMN()) {
    if ($::FORCE || $::genSSHNodeHostKeys || $::INITIALINSTALL)
    {
        &genSSHNodeHostKey;
    }
}

#
# Set tunables
#
#
if (($::settunables) && ($::osname eq 'AIX')) {    # not supported on AIX
    xCAT::MsgUtils->message('E', "Setting tunables (-t) is not supported on AIX.");
    exit 1;
}

if ($::FORCE || $::settunables || $::INITIALINSTALL)
{
    if ($::osname eq 'Linux') {
        &settunables;
    }
}
#
#  gen root's ssh keys, if needed and copy to appropriate directories to
#  be used during install
#
if ($::INITIALINSTALL || $::FORCE || $::genSSHRootKeys)
{
    &genSSHRootKeys;    # gen new rsa ssh key for root
}

#
#	Update /etc/profile on AIX
#
if (($::INITIALINSTALL) || ($::UPDATEINSTALL))
{
    my $profname = "/etc/profile";
    if ($::osname eq 'AIX')
    {
        my $cmd = qq~cat $profname | grep "XCATROOT"~;
        my $outref = xCAT::Utils->runcmd("$cmd", -1);
        if ($::RUNCMD_RC != 0)    # no xcat paths in the /etc/profile
        {

            # make back up file
            my $cpcmd = qq~/bin/cp -p $profname $profname.orig~;
            my $outref = xCAT::Utils->runcmd("$cpcmd", 0);
            if ($::RUNCMD_RC != 0)
            {
                xCAT::MsgUtils->message('E', "Could not copy $profname.");
            }

            # add xCAT paths
            my $eccmd =
qq~echo '# xCAT setup\nXCATROOT=$::XCATROOT\nPATH=\$XCATROOT/bin:\$XCATROOT/sbin:\$XCATROOT/share/xcat/tools:\$PATH\nMANPATH=\$XCATROOT/share/man:\$MANPATH\nexport XCATROOT PATH MANPATH' >>$profname~;
            $outref = xCAT::Utils->runcmd("$eccmd", 0);
            if ($::RUNCMD_RC != 0)
            {
                xCAT::MsgUtils->message('E', "Could not update $profname.");
            }
        } else {    # xcat path is there, maybe  need to add /share/xcat/tools
            my $cmd = qq~cat $profname | grep "/share/xcat/tools"~;
            my $outref = xCAT::Utils->runcmd("$cmd", -1);
            if ($::RUNCMD_RC != 0)    # no tools paths in the /etc/profile
            {
                my $eccmd =
qq~echo 'PATH=\$XCATROOT/share/xcat/tools:\$PATH\nexport MANPATH' >>$profname~;
                $outref = xCAT::Utils->runcmd("$eccmd", 0);
                if ($::RUNCMD_RC != 0)
                {
                    xCAT::MsgUtils->message('E', "Could not update $profname.");
                }
            }
        }
    }
}

if ($::INITIALINSTALL || $::FORCE || $::UPDATEINSTALL)
{

    #
    # For all MNs create /var/log/consoles if needed
    # Conserver won't start without it
    #
    if (!-d "/var/log/consoles")
    {
        my $cmd = "/bin/mkdir -p /var/log/consoles";
        my $outref = xCAT::Utils->runcmd("$cmd", 0);
        if ($::RUNCMD_RC != 0)
        {
            xCAT::MsgUtils->message('E',
                "Could not create /var/log/consoles directory.");
        }
        else
        {
            verbose("Created /var/log/consoles directory.");
        }
    }

    if ($::osname eq 'AIX')
    {
        if ($::INITIALINSTALL) {    # do only on install
            xCAT::Utils->setupAIXconserver($::VERBOSE);
        }
        &setupAIXIPMITool;

        # Add the xcatd subsystem to the AIX
        no strict 'refs';
        my $mkssys_cmd =
"mkssys -p $::XCATROOT/sbin/xcatd -s xcatd -u 0 -S -n 15 -f 15 -a \"-f\"";
        system($mkssys_cmd);
        use strict;

        # if not Update,  add to inittab
        #  breaks HAMS to add on update
        if (!$::UPDATEINSTALL) {

            # for AIX systems add xcatd to the /etc/inittab file
            # add xcatd entry if one does not exist
            my $rcmd = "/bin/cat /etc/inittab | grep 'xcatd'";
            my $outref = xCAT::Utils->runcmd("$rcmd", -1);
            if ($::RUNCMD_RC != 0) {
                my $mkitab_cmd =
"mkitab \"xcatd:2:once:$::XCATROOT/sbin/restartxcatd > /dev/console 2>&1\" > /dev/null 2>&1";
                xCAT::Utils->runcmd("$mkitab_cmd", 0);
                if ($::RUNCMD_RC != 0) {
                    xCAT::MsgUtils->message('E', "Could not set up inittab.");
                }
            }
        }

        # add AIX needed exports
        &setupAIXexports;

    }

    else    # for Linux
    {
        &setupLinuxexports;    # add Linux exports

    }
}    # end install,update or force

#
#  set up the certificates for xcatd, gen new ones if requested or do not exist
#
if ($::INITIALINSTALL || $::UPDATEINSTALL || $::FORCE || $::genCredentials)
{
    &genCredentials;
}

#
# Setup  database
#
if ($::INITIALINSTALL || $::UPDATEINSTALL || $::FORCE || $::initDB)
{
    &initDB;
}

#
# set up syslog
#
# use postscript to set up syslog
if ($::INITIALINSTALL || $::FORCE || $::UPDATEINSTALL)
{
    my $cmd = "$::INSTALLDIR/postscripts/syslog";
    my $outref = xCAT::Utils->runcmd("$cmd", 0);
    if ($::RUNCMD_RC != 0)
    {
        xCAT::MsgUtils->message('E', "Could not set up syslog.");
    }
    else
    {
        verbose("syslog has been set up.");
    }
}

# The systemd only has LANG and PATH as default environmental variables,
# TERM is needed for KVM consoles(actually screen command needs TERM)
# import the TERM into systemd
if (-d "/usr/lib/systemd/system") {
    my $term = $ENV{'TERM'};
    if (!$term) {
        $term = "vt100";
    }
    my $cmd = "systemctl set-environment TERM=$term";
    xCAT::Utils->runcmd("$cmd", 0);
    if ($::RUNCMD_RC != 0) {
        xCAT::MsgUtils->message('E', "Could not set TERM into systemd.");
    } else {
        verbose("Imported TERM=$term into systemd.");
    }
}

#
#  start xcatd
#
if ($::INITIALINSTALL || $::FORCE || $::UPDATEINSTALL || $::genCredentials)
{
    my $xcmd;
    if ($::osname eq 'AIX')
    {
        $xcmd = "$::XCATROOT/sbin/restartxcatd";
        system($xcmd);
    }
    else
    {
        #since the xcatd service unit file is updated on xcat upgrade
        #"systemctl daemon-reload" need to be run to update the service unit
        if ($::UPDATEINSTALL) {
            $xcmd="type systemctl >/dev/null 2>&1 && systemctl daemon-reload";
            xCAT::Utils->runcmd("$xcmd", 0);
        }
        #$xcmd = "/etc/init.d/xcatd restart";
        xCAT::Utils->restartservice("xcatd");
    }

}

if ($::UPDATEINSTALL) {
    upgrade_conserver();
}

# more  config needed after xcatd start
if ($::INITIALINSTALL || $::FORCE)
{
    &startnamedonboot;
    my $cmd;
    if ($::osname eq 'Linux') {

        #Zap the almost certainly wrong pxelinux.cfg file
        if (-f "$::TFTPDIR/pxelinux.cfg/default")
        {
            $cmd = "/bin/rm $::TFTPDIR/pxelinux.cfg/default";
            my $outref = xCAT::Utils->runcmd("$cmd", 0);
            if ($::RUNCMD_RC != 0)
            {
                xCAT::MsgUtils->message('E',
                    "Could not remove $::TFTPDIR/pxelinux.cfg/default");
            }
            else
            {
                verbose("Removed $::TFTPDIR/pxelinux.cfg/default.");
            }
        }

        # makenetworks and setup http
        &makenetworks;
        &setuphttp;

        # chkconfig dhcpd on
        #system("chkconfig dhcpd on");
        xCAT::Utils->enableservice("dhcp");

        # Turn off selinux on RedHat
        if (-f "/etc/redhat-release")
        {
            my $rc = xCAT::Utils->isSELINUX();

            # rc 0 means SELinux is enabled
            # rc 1 means SELinux is not enabled
            if ($rc == 0)
            {
                xCAT::MsgUtils->message('W', "SELINUX is not disabled, disabling it now...");

                # set selinux be in permissive mode for running system,
                # if the user forgot to disable selinux,
                # try to not hurt xcat too much
                my $enforcefile;
                if (-f "/selinux/enforce")
                {
                    $enforcefile = "/selinux/enforce";
                } elsif (-f "/sys/fs/selinux/enforce") {
                    $enforcefile = "/sys/fs/selinux/enforce";
                }
                if ($enforcefile)
                {
                    my $cmd = "echo 0 > $enforcefile";
                    my $outref = xCAT::Utils->runcmd("$cmd", 0);
                    if ($::RUNCMD_RC != 0)
                    {
                        xCAT::MsgUtils->message('E', "Failed to disable SELINUX.");
                    }
                }

                # Disable selinux through reboots
                my $cmd = "sed -i 's/^SELINUX=.*\$/SELINUX=disabled/' /etc/selinux/config";
                my $outref = xCAT::Utils->runcmd("$cmd", 0);
                if ($::RUNCMD_RC != 0)
                {
                    xCAT::MsgUtils->message('E', "Failed to disable SELINUX.");
                }
            }
        }

        my $ret = xCAT::Utils->stopservice("firewall");
        if ($ret != 0)
        {
            xCAT::MsgUtils->message('E', "Failed to stop firewall");
        }

        $ret = xCAT::Utils->disableservice("firewall");
        if ($ret != 0)
        {
            xCAT::MsgUtils->message('E', "Failed to disable firewall on boot");
        }

        #}

        # Enable ip forwarding. In most cases,
        # the MN itself will act as the default gateway for the compute nodes,
        # ip forwarding is required for a network gateway
        xCAT::NetworkUtils->setup_ip_forwarding(1);

        # Enable ipv6 forwarding,
        # only if there are IPv6 networks in the networks table
        my $ipv6net = 0;
        my $ntab    = xCAT::Table->new('networks');
        if ($ntab)
        {
            foreach my $enet (@{ $ntab->getAllEntries() })
            {
                if ($enet->{'net'} =~ /:/)
                {
                    $ipv6net = 1;
                }
            }
            $ntab->close();
        }
        if ($ipv6net)
        {
            xCAT::NetworkUtils->setup_ipv6_forwarding(1);
        }


        my $linux_note =
"xCAT is now running, it is recommended to tabedit networks \nand set a dynamic ip address range on any networks where nodes \nare to be discovered. Then, run makedhcp -n to create a new dhcpd \nconfiguration file, and \/etc\/init.d\/dhcpd restart. Either examine sample \nconfiguration templates, or write your own, or specify a value per \nnode with nodeadd or tabedit.";
        xCAT::MsgUtils->message('I', $linux_note);

    } else {    #AIX
                # makenetworks
        &makenetworks;

        my $AIX_note =
          "xCAT is now running.";
        xCAT::MsgUtils->message('I', $AIX_note);
    }

}    #End - more - Linux-only config

# Run mknb to put xCAT-genesis-scripts-x86_64 and xCAT-genesis-base-x86_64 together and in /tftpboot
if (($::INITIALINSTALL || $::UPDATEINSTALL) && $::osname eq 'Linux') {
    &mknb;
}

END
{
    # Remove xcatconfig itself from the inittab

    if (($::osname eq 'AIX') && ($ENV{'INUCLIENTS'} != 1))
    {
        my $cmd = "/usr/sbin/lsitab xcatconfig > /dev/null 2>&1";
        my $rc  = system("$cmd") >> 8;
        if ($rc == 0)
        {
            my $rmcmd = '/usr/sbin/rmitab xcatconfig';
            system("$rmcmd");
        }
    }
}

# if xcatconfig -m request to setup the management node in the database
if ($::setupMNinDB) {
    &setupMNinDB;
}
exit;

#####################################
#  subroutines
#####################################

#-----------------------------------------------------------------------------

=head3    usage 
	
	Displays message for -h option

=cut

#-----------------------------------------------------------------------------

sub usage
{
    xCAT::MsgUtils->message(
        'I',
"Usage:\nxcatconfig - Performs basic xCAT setup operations on an xCAT management node. Only the -t option should be used on a Service Node.\n"
    );
    xCAT::MsgUtils->message(
        'I',
"xcatconfig [-h|--help]\nxcatconfig [-v|--version]\nxcatconfig [-f|--force] [-V|--verbose]\nxcatconfig [-i|--initinstall] [-V|--verbose]\nxcatconfig [-u|--updateinstall] [-V|--verbose]\nxcatconfig [-k|--sshkeys] [-s|--sshnodehostkeys] [-c|--credentials] [-d|database] [-m|mgtnode] [-t|tunables] [-V|--verbose]"
    );
}

sub verbose
{
    if (!$::VERBOSE) { return; }
    my $msg = shift;
    xCAT::MsgUtils->message("I", $msg);
}

#-----------------------------------------------------------------------------

=head3    genSSHRootKeys 
	
     Will generate a new ssh rsa key for the root user, if it does not exist or if requested by the input -k flag.

=cut

#-----------------------------------------------------------------------------

sub genSSHRootKeys

{

    #
    # create /.ssh dir if needed
    #
    my $sshdir = "$::root/.ssh";
    if (!-d $sshdir)
    {
        my $cmd = "/bin/mkdir -m 700 -p $sshdir";
        my $outref = xCAT::Utils->runcmd("$cmd", 0);
        if ($::RUNCMD_RC != 0)
        {
            xCAT::MsgUtils->message('E', "Could not create $sshdir directory.");
        }
        else
        {
            verbose("Created $sshdir directory.");
        }
    }

    #
    # create or modify the -/.ssh/config file
    #
    my $cfgfile = "$::root/.ssh/config";
    if (-f $cfgfile)
    {

        # it exists - so see if it needs to be updated
        my $cmd = "/bin/cat $cfgfile | grep 'StrictHostKeyChecking no'";
        my $outref = xCAT::Utils->runcmd("$cmd", -1);
        if ($::RUNCMD_RC != 0)
        {

            # ok - then add this entry
            my $cmd =
"/bin/echo StrictHostKeyChecking no >> $cfgfile; chmod  600 $cfgfile";
            my $outref = xCAT::Utils->runcmd("$cmd", 0);
            if ($::RUNCMD_RC != 0)
            {
                xCAT::MsgUtils->message('E',
                    "Could not update the $cfgfile file.");
            }
            else
            {
                xCAT::MsgUtils->message('I',
                    "Added updates to the $cfgfile file.");
            }
        }
        if (-e "/etc/debian_version") {
            my $out = `/bin/cat $cfgfile | grep 'HashKnownHosts'`;
            if ($out) {
`/bin/sed -e 's/.*HashKnownHosts.*/HashKnownHosts no/' $cfgfile > tempcfg;mv -f tempcfg $cfgfile`;
            }
            else {
                `/bin/echo HashKnownHosts no >> $cfgfile`;
            }
            `chmod  600 $cfgfile`;
        }
    }
    else
    {

        # file doesn't exist so just create it
        my $cmd =
          "/bin/echo StrictHostKeyChecking no > $cfgfile; chmod  600 $cfgfile";
        my $outref = xCAT::Utils->runcmd("$cmd", 0);
        if ($::RUNCMD_RC != 0)
        {
            xCAT::MsgUtils->message('E', "Could not update the $cfgfile file.");
        }
        else
        {
            xCAT::MsgUtils->message('I', "Added updates to the $cfgfile file.");
        }

        #debian or ubuntu, the HashKnownHosts default is yes, change it
        if (-e "/etc/debian_version") {
            $cmd = "/bin/echo HashKnownHosts no >> $cfgfile";
            xCAT::Utils->runcmd("$cmd", 0);
        }
    }

    #
    #  create /install/postscripts/_ssh if needed
    #
    if (!-d "$::INSTALLDIR/postscripts/_ssh")
    {
        my $cmd = "/bin/mkdir -m 755 -p $::INSTALLDIR/postscripts/_ssh";
        my $outref = xCAT::Utils->runcmd("$cmd", 0);
        if ($::RUNCMD_RC != 0)
        {
            xCAT::MsgUtils->message('E',
                "Could not create $::INSTALLDIR/postscripts/_ssh directory.");
        }
        else
        {
            verbose("Created $::INSTALLDIR/postscripts/_ssh directory.");
        }
    }

    #need to gen a new rsa key for root ssh, if Force, genkey or does not exist
    my $pubfile = "$::root/.ssh/id_rsa.pub";
    my $rsafile = "$::root/.ssh/id_rsa";

    # if exists,  and generated new then
    # need to remove the old files
    if ((-r $pubfile) && ($::FORCE || $::genSSHRootKeys))
    {

        my $cmd = "/bin/rm $::root/.ssh/id_rsa*";
        my $outref = xCAT::Utils->runcmd("$cmd", 0);
        if ($::RUNCMD_RC != 0)
        {
            xCAT::MsgUtils->message('E',
                "Could not remove id_rsa files from $::root/.ssh directory.");
        }
        else
        {
            xCAT::MsgUtils->message('I',
                "Removed id_rsa files from $::root/.ssh directory.");
        }
    }

    # ssh key does not exist, gen a new one else leave alone
    if (!-r $pubfile)
    {
        my $cmd = "/usr/bin/ssh-keygen -t rsa -q -b 2048 -N '' -f $rsafile";
        my $outref = xCAT::Utils->runcmd("$cmd", 0);
        if ($::RUNCMD_RC != 0)
        {
            xCAT::MsgUtils->message('E', "Could not generate $pubfile.");
        }
        else
        {
            xCAT::MsgUtils->message('I', "Generated $pubfile.");

        }
    }

    # copy authorized_keys for install on node
    if (-r $pubfile)
    {
        my $cmd =
          "/bin/cp -p $pubfile $::INSTALLDIR/postscripts/_ssh/authorized_keys ";
        my $outref = xCAT::Utils->runcmd("$cmd", 0);
        if ($::RUNCMD_RC != 0)
        {
            xCAT::MsgUtils->message(
                'E',
"Could not copy $pubfile to $::INSTALLDIR/postscripts/_ssh/authorized_keys."
            );
        }
        else
        {
            xCAT::MsgUtils->message(
                'I',
"Copied $pubfile to $::INSTALLDIR/postscripts/_ssh/authorized_keys."
            );
        }
    }
    else
    {
        xCAT::MsgUtils->message(
            'E',
"Could not copy $pubfile to $::INSTALLDIR/postscripts/_ssh/authorized_keys,because $pubfile does not exist."
        );
    }
}

#-----------------------------------------------------------------------------

=head3   settunables 
	
    Will set the default suggested tunables on the Management Node or service node for Linux 

=cut

#-----------------------------------------------------------------------------

sub settunables

{
    # tuning ARP on Linux
    # set for right now

    my $ECHO   = xCAT::Utils->fullpathbin("echo");
    my $cmd    = "$ECHO '1024' >/proc/sys/net/ipv4/neigh/default/gc_thresh1";
    my $outref = xCAT::Utils->runcmd("$cmd", 0);
    if ($::RUNCMD_RC != 0)
    {
        xCAT::MsgUtils->message('E', "Could not run $cmd.");
    }
    $cmd = "$ECHO '4096' >/proc/sys/net/ipv4/neigh/default/gc_thresh2";
    my $outref = xCAT::Utils->runcmd("$cmd", 0);
    if ($::RUNCMD_RC != 0)
    {
        xCAT::MsgUtils->message('E', "Could not run $cmd.");
    }
    $cmd = "$ECHO '8192' >/proc/sys/net/ipv4/neigh/default/gc_thresh3";
    my $outref = xCAT::Utils->runcmd("$cmd", 0);
    if ($::RUNCMD_RC != 0)
    {
        xCAT::MsgUtils->message('E', "Could not run $cmd.");
    }

    # set for after reboot
    if (!(-f "/etc/sysctl.conf.xcatbackup")) {    # not already backed up
        $cmd = "cp /etc/sysctl.conf /etc/sysctl.conf.xcatbackup";
        my $outref = xCAT::Utils->runcmd("$cmd", 0);
        if ($::RUNCMD_RC != 0)
        {
            xCAT::MsgUtils->message('E', "Could not backup /etc/sysctl.conf.");
            exit 1;
        }
    }

    #delete all occurance of the attribute and then add xCAT settings
    `sed -i '/net.ipv4.neigh.default.gc_thresh1 /'d /etc/sysctl.conf`;
    `echo "net.ipv4.neigh.default.gc_thresh1 = 1024" >>/etc/sysctl.conf`;
    `sed -i '/net.ipv4.neigh.default.gc_thresh2 /'d /etc/sysctl.conf`;
    `echo "net.ipv4.neigh.default.gc_thresh2 = 4096" >>/etc/sysctl.conf`;
    `sed -i '/net.ipv4.neigh.default.gc_thresh3 /'d /etc/sysctl.conf`;
    `echo "net.ipv4.neigh.default.gc_thresh3 = 8192" >>/etc/sysctl.conf`;

}

#-----------------------------------------------------------------------------

=head3    genSSHNodeHostKey 
	
  If node private node hostkeys do not exist in either directory or force option
   or generate host key option, we need to generate them
   These keys are installed on the nodes in /etc/ssh directory and allow the
   node to ssh to the other nodes and the MN or SN to be able to ssh to the node
   Without known_hosts warning messages.   
   They are store in /etc/xcat/hostkeys on the MN.
   The public key is also installed in  /install/postscripts/hostkeys
   for the install process 
   The private key  is downloaded by remoteshell postscript using the credentials.pm interface

=cut

#-----------------------------------------------------------------------------

sub genSSHNodeHostKey

{

    my $hostkey  = "$::INSTALLDIR/postscripts/hostkeys/ssh_host_rsa_key";
    my $hostkey2 = "/etc/xcat/hostkeys/ssh_host_rsa_key";

    #create directories /etc/xcat/hostkeys and /install/postscripts/hostkeys
    if (!-d "$::INSTALLDIR/postscripts/hostkeys")    # dir for public keys
    {
        my $cmd = "/bin/mkdir -m 755 -p $::INSTALLDIR/postscripts/hostkeys";
        my $outref = xCAT::Utils->runcmd("$cmd", 0);
        if ($::RUNCMD_RC != 0)
        {
            xCAT::MsgUtils->message(
                'E',
                "Could not create $::INSTALLDIR/postscripts/hostkeys directory."
            );
        }
    }
    if (!-d "/etc/xcat/hostkeys")    # directory for public/private keys
    {
        my $cmd = "/bin/mkdir -p /etc/xcat/hostkeys";
        my $outref = xCAT::Utils->runcmd("$cmd", 0);
        if ($::RUNCMD_RC != 0)
        {
            xCAT::MsgUtils->message('E',
                "Could not create /etc/xcat/hostkeys directory.");
        }
    }

    # remove the old keys  from the /intall/postscripts/hostkeys directroy
    if (-r $hostkey)
    {
        my $cmd = "/bin/rm $::INSTALLDIR/postscripts/hostkeys/ssh_host*";
        my $outref = xCAT::Utils->runcmd("$cmd", -1);
        if ($::RUNCMD_RC != 0)
        {
            xCAT::MsgUtils->message(
                'I',
"Could not remove ssh keys from $::INSTALLDIR/postscripts/hostkeys directory. They may not exist."
            );
        }
    }

    # remove the old keys from the /etc/xcat/hostkeys directory
    if (-r $hostkey2)
    {
        my $cmd = "/bin/rm /etc/xcat/hostkeys/ssh_host*";
        my $outref = xCAT::Utils->runcmd("$cmd", -1);
        if ($::RUNCMD_RC != 0)
        {
            xCAT::MsgUtils->message(
                'I',
"Could not remove ssh keys from /etc/xcat/hostkeys directory. They may not exist."
            );
        }
    }

    #
    # generate new hostkeys
    #

    my ($rlogin,$rpass,$ruid,$rgid) = getpwnam("root");
    my ($sname, $spasswd,$sgid,$smembers)=getgrnam("ssh_keys");
    my @sshkeylist;
    xCAT::MsgUtils->message('I', "Generating new node hostkeys...");
    xCAT::MsgUtils->message('I', "Generating SSH2 RSA Key...");
    my $cmd =
"/usr/bin/ssh-keygen -t rsa -f /etc/xcat/hostkeys/ssh_host_rsa_key -C '' -N ''";
    my $outref = xCAT::Utils->runcmd("$cmd", 0);
    if ($::RUNCMD_RC != 0)
    {
        xCAT::MsgUtils->message('E', "Could not generate SSH2 RSA key.");
    }
    else{
        push @sshkeylist,"/etc/xcat/hostkeys/ssh_host_rsa_key";
    }


    xCAT::MsgUtils->message('I', "Generating SSH2 DSA Key...");
    $cmd =
"/usr/bin/ssh-keygen -t dsa -f /etc/xcat/hostkeys/ssh_host_dsa_key -C '' -N ''";
    $outref = xCAT::Utils->runcmd("$cmd", 0);
    if ($::RUNCMD_RC != 0)
    {
        xCAT::MsgUtils->message('E', "Could not generate SSH2 DSA key.");
    }
    else{
        push @sshkeylist,"/etc/xcat/hostkeys/ssh_host_dsa_key";
    }

    # see if this system supports the ecdsa
    xCAT::Utils->runcmd('rm -rf /tmp/ecdsa_key >/dev/null 2>&1 ; /usr/bin/ssh-keygen -t ecdsa -f /tmp/ecdsa_key  -P "" &>/dev/null', 0);
    if ($::RUNCMD_RC == 0) {
        xCAT::MsgUtils->message('I', "Generating SSH2 ECDSA Key...");
        $cmd =
"/usr/bin/ssh-keygen -t ecdsa -f /etc/xcat/hostkeys/ssh_host_ecdsa_key -C '' -N ''";
        $outref = xCAT::Utils->runcmd("$cmd", 0);
        if ($::RUNCMD_RC != 0)
        {
            xCAT::MsgUtils->message('E', "Could not generate SSH2 ECDSA key.");
        }
	else{
            push @sshkeylist,"/etc/xcat/hostkeys/ssh_host_ecdsa_key";
	}
    }

    if(@sshkeylist){
        if(defined $ruid && defined $sgid){
            chown $ruid,$sgid,@sshkeylist;
        }
        chmod 0640,@sshkeylist;
    }

    # copy the public keys to install directory
    $cmd =
      "/bin/cp /etc/xcat/hostkeys/*.pub $::INSTALLDIR/postscripts/hostkeys/.";
    $outref = xCAT::Utils->runcmd("$cmd", 0);
    if ($::RUNCMD_RC != 0)
    {
        xCAT::MsgUtils->message('E', "$cmd not successful.");
    }
    else
    {
        verbose("$cmd is successful");
    }

}

sub is_redhat6sp4
{
    if (-e "/etc/redhat-release") {
        open(my $relfile, "<", "/etc/redhat-release");
        my $line = <$relfile>;
        close($relfile);
        if ($line =~ /Red Hat Enterprise Linux Server release 6.[4-5]/i) {
            return 1;
        }
    }
    return 0;
}



#-----------------------------------------------------------------------------

=head3    initDB 
	
    Will initialize the DB if it does not already exist,  also updates with
	new data needed or database changes during xCAT  install.

=cut

#-----------------------------------------------------------------------------

sub initDB

{

    my $hname = `hostname`;
    chomp $hname;

    # some values common to both AIX & Linux
    my $xcatport   = "3001";
    my $xcatiport  = "3002";
    my $tftpdir    = "$::TFTPDIR";
    my $installdir = "$::INSTALLDIR";
    my $master;
    $master = xCAT::NetworkUtils->getipaddr($hname);
    if (!$master) {
        xCAT::MsgUtils->message("E", "Hostname resolution for $hname failed, setting the site.master to NORESOLUTION for now, after the xCAT installation is finished, fix this hostname resolution problem, change the site.master to the correct value and then resart xcatd.");
        $master = "NORESOLUTION";
    }

    # get forwarders which are the nameserver entries in /etc/resolv.conf
    # don't use if the address is this machine (Management Node)
    my $forwarders;

    # find out the names for the Management Node
    my @MNnodeinfo   = xCAT::NetworkUtils->determinehostname;
    my $MNnodename   = pop @MNnodeinfo;                         # hostname
    my @MNnodeipaddr = @MNnodeinfo;                             # ipaddresses

    my @names;
    my @tmpnames =
      xCAT::Utils->runcmd(
        "/bin/grep ^[^#]*nameserver /etc/resolv.conf | awk '{print \$2}'", -1);
    foreach my $ip (@tmpnames) {
        if (!grep(/^$ip$/, @MNnodeipaddr))
        {                                                       # if not the MN
            push @names, $ip;    # add it as a forwarder
        }
    }
    if (@names)
    {
        $forwarders = join(',', @names);
    }

    # for policy table
    # get hostname from the /etc/xcat/cert/server-cert.pem
    my $MNname;
    if (-e ("/etc/xcat/cert/server-cert.pem")) {
        my $cmd = "grep Subject /etc/xcat/cert/server-cert.pem";
        my $result = xCAT::Utils->runcmd($cmd, 0);
        if ($::RUNCMD_RC != 0)
        {
            xCAT::MsgUtils->message("E", "Error from $cmd.\n MN policy not created.");

        }
        (my $subject, my $mname) = split /CN=/, $result;
        ($MNname, my $endstuff) = split /Subject/, $mname;
        $MNname =~ s/\s*//g;
    }

    # set value based on OS
    my ($domain, $timezone);
    my $timezone = xCAT::Utils->gettimezone();
    if ($::osname eq 'AIX')
    {
        my ($name, $rest) = split('\.', $hname);
        if ($rest)
        {
            ($domain = $hname) =~ s/^.*?\.//;
        }
        else
        {
            $domain = "";
        }

    }
    else    # linux
    {
        $domain = `hostname -d`;
    }

    chomp $timezone;
    chomp $master;
    chomp $domain;

    # create basic site definition, if they do not exist reset request
    if (((!-r "/etc/xcat/site.sqlite") && (!-r "/etc/xcat/cfgloc"))
        || $::FORCE
        || $::initDB)
    {
        my $chtabcmds;
        my $confdir     = "/etc/xcat";
        my $syncdir     = "/var/xcat/syncfiles";
        my $nodesyncdir = "/var/xcat/node/syncfiles";
        $chtabcmds = "$::XCATROOT/sbin/chtab key=blademaxp site.value=64;";
        $chtabcmds .= "$::XCATROOT/sbin/chtab key=domain site.value=$domain;";
        $chtabcmds .= "$::XCATROOT/sbin/chtab key=fsptimeout site.value=0;";
        $chtabcmds .=
          "$::XCATROOT/sbin/chtab key=installdir site.value=$installdir;";

        if ($::osname eq 'Linux')
        {
            $chtabcmds .= "$::XCATROOT/sbin/chtab key=ipmimaxp site.value=64;";
            $chtabcmds .=
              "$::XCATROOT/sbin/chtab key=ipmiretries site.value=3;";
            $chtabcmds .=
              "$::XCATROOT/sbin/chtab key=ipmitimeout site.value=2;";
            $chtabcmds .=
              "$::XCATROOT/sbin/chtab key=consoleondemand site.value=no;";
        }
        $chtabcmds .= "$::XCATROOT/sbin/chtab key=master site.value=$master;";
        if ($forwarders) {
            $chtabcmds .= "$::XCATROOT/sbin/chtab key=forwarders site.value=$forwarders;";
        }
        $chtabcmds .= "$::XCATROOT/sbin/chtab key=nameservers site.value=$master;";
        $chtabcmds .= "$::XCATROOT/sbin/chtab key=maxssh site.value=8;";
        $chtabcmds .= "$::XCATROOT/sbin/chtab key=ppcmaxp site.value=64;";
        $chtabcmds .= "$::XCATROOT/sbin/chtab key=ppcretry site.value=3;";
        $chtabcmds .= "$::XCATROOT/sbin/chtab key=ppctimeout site.value=0;";
        $chtabcmds .= "$::XCATROOT/sbin/chtab key=powerinterval site.value=0;";
        $chtabcmds .= "$::XCATROOT/sbin/chtab key=syspowerinterval site.value=0;";
        $chtabcmds .= "$::XCATROOT/sbin/chtab key=sharedtftp site.value=1;";
        $chtabcmds .=
          "$::XCATROOT/sbin/chtab key=SNsyncfiledir site.value=$syncdir;";
        $chtabcmds .=
          "$::XCATROOT/sbin/chtab key=nodesyncfiledir site.value=$nodesyncdir;";
        $chtabcmds .= "$::XCATROOT/sbin/chtab key=tftpdir site.value=$tftpdir;";
        $chtabcmds .=
          "$::XCATROOT/sbin/chtab key=xcatdport site.value=$xcatport;";
        $chtabcmds .=
          "$::XCATROOT/sbin/chtab key=xcatiport site.value=$xcatiport;";
        $chtabcmds .=
          "$::XCATROOT/sbin/chtab key=xcatconfdir site.value=$confdir;";
        $chtabcmds .=
          "$::XCATROOT/sbin/chtab key=timezone site.value=\"$timezone\";";

        $chtabcmds .= "$::XCATROOT/sbin/chtab key=useNmapfromMN site.value=no;";
        $chtabcmds .= "$::XCATROOT/sbin/chtab key=enableASMI site.value=no;";
        $chtabcmds .= "$::XCATROOT/sbin/chtab key=db2installloc site.value=\/mntdb2;";
        $chtabcmds .= "$::XCATROOT/sbin/chtab key=databaseloc site.value=\/var\/lib;";
        $chtabcmds .= "$::XCATROOT/sbin/chtab key=sshbetweennodes site.value=ALLGROUPS;";
        $chtabcmds .= "$::XCATROOT/sbin/chtab key=dnshandler site.value=ddns;";
        $chtabcmds .= "$::XCATROOT/sbin/chtab key=vsftp site.value=n;";
        $chtabcmds .= "$::XCATROOT/sbin/chtab key=cleanupxcatpost site.value=no;";
        $chtabcmds .= "$::XCATROOT/sbin/chtab key=dhcplease site.value=43200;";
        $chtabcmds .= "$::XCATROOT/sbin/chtab key=auditnosyslog site.value=0;";
        $chtabcmds .= "$::XCATROOT/sbin/chtab key=xcatsslversion site.value=TLSv1;";
        $chtabcmds .= "$::XCATROOT/sbin/chtab key=auditskipcmds site.value=ALL;";

        #$chtabcmds .= "$::XCATROOT/sbin/chtab key=useflowcontrol site.value=yes;"; # need to fix 4031

        if ($::osname eq 'AIX')
        {
            $chtabcmds .=
              "$::XCATROOT/sbin/chtab key=useSSHonAIX site.value=yes;";
            $chtabcmds .=
              "$::XCATROOT/sbin/chtab key=useNFSv4onAIX site.value=no;";
            $chtabcmds .=
              "$::XCATROOT/sbin/chtab key=consoleondemand site.value=yes;";
        }

        my $outref = xCAT::Utils->runcmd("$chtabcmds", 0);
        if ($::RUNCMD_RC != 0)
        {
            xCAT::MsgUtils->message('E', "Could not create site definition.");
        }
        else
        {
            verbose("Updated cluster site definition.");
        }
    }

    # create default postscript list in postscripts table
    # if it does not exist, or request reset

    if (((!-r "/etc/xcat/postscripts.sqlite") && (!-r "/etc/xcat/cfgloc"))
        || $::FORCE
        || $::initDB)
    {

        # For Linux check to see if otherpkgs in the postscripts table
        # if it is do not change it, otherwise put in postbootscripts
        my $chtabcmds          = "";
        my $otherpkgsprocessed = 0;
        my $otherpkgsexist;
        if ($::osname eq 'Linux') {
            $otherpkgsexist = &checkotherpkgs;

            #  0 = does not exist
            #  1 = exists in postscripts
            #  2 = exists in postbootscripts

            # if otherpkgs does not exist or we are initializing the DB
            # put in postbootscripts
            if (($otherpkgsexist == 0) || ($::initDB))
            {
                $chtabcmds =
"$::XCATROOT/sbin/chtab node=xcatdefaults postscripts.postbootscripts='otherpkgs';";
                $otherpkgsprocessed = 1;
            }

            # if already processed otherpkgs or it is in postbootscripts attr
            # then don't put otherpkgs in the postscripts attribute
            # else it was in postscripts attribute so leave it there.
            if (($otherpkgsprocessed == 1) || ($otherpkgsexist == 2))
            {
                $chtabcmds .=
"$::XCATROOT/sbin/chtab node=xcatdefaults postscripts.postscripts='syslog,remoteshell,syncfiles';";
            }
            else
            {    # put otherpkgs in postscripts attr
                $chtabcmds .=
"$::XCATROOT/sbin/chtab node=xcatdefaults postscripts.postscripts='syslog,remoteshell,otherpkgs,syncfiles';";
            }

            # add servicenode default
            $chtabcmds .=
"$::XCATROOT/sbin/chtab node=service postscripts.postscripts='servicenode'";

        }
        if ($::osname eq 'AIX') {    # we don't use otherpkgs on AIX

            $chtabcmds .=
"$::XCATROOT/sbin/chtab node=xcatdefaults postscripts.postscripts='syslog,remoteshell,syncfiles';";
            $chtabcmds .=
"$::XCATROOT/sbin/chtab node=service postscripts.postscripts='servicenode'";

        }

        my $outref = xCAT::Utils->runcmd("$chtabcmds", 0);
        if ($::RUNCMD_RC != 0)
        {
            xCAT::MsgUtils->message('E',
                "Could not create postscripts definition.");
        }
        else
        {
            verbose("Created postscripts definition.");
        }
    }

    # create or reset basic policy table definitions
    if (((!-r "/etc/xcat/policy.sqlite") && (!-r "/etc/xcat/cfgloc"))
        || $::FORCE
        || $::initDB)
    {
        my $chtabcmds;
        if ($::osname eq 'AIX')
        {
            $chtabcmds =
"$::XCATROOT/sbin/chtab priority=1 policy.name=root policy.rule=allow;";
            if (defined($MNname)) {
                $chtabcmds .=
"$::XCATROOT/sbin/chtab priority=1.2 policy.name=$MNname policy.rule=trusted;";
            }
            $chtabcmds .=
"$::XCATROOT/sbin/chtab priority=4.4 policy.commands=getpostscript policy.rule=allow;";
            $chtabcmds .=
"$::XCATROOT/sbin/chtab priority=4.5 policy.commands=getcredentials policy.rule=allow;";
            $chtabcmds .=
"$::XCATROOT/sbin/chtab priority=4.6 policy.commands=syncfiles policy.rule=allow;";
            $chtabcmds .=
"$::XCATROOT/sbin/chtab priority=2.3 policy.commands=lsxcatd policy.rule=allow;";
        }
        else    # linux
        {
            $chtabcmds =
"$::XCATROOT/sbin/chtab priority=1 policy.name=root policy.rule=allow;";
            if (defined($MNname)) {
                $chtabcmds .=
"$::XCATROOT/sbin/chtab priority=1.2 policy.name=$MNname policy.rule=trusted;";
            }
            $chtabcmds .=
"$::XCATROOT/sbin/chtab priority=2 policy.commands=getbmcconfig policy.rule=allow;";
            $chtabcmds .=
"$::XCATROOT/sbin/chtab priority=2.1 policy.commands=remoteimmsetup policy.rule=allow;";
            $chtabcmds .=
"$::XCATROOT/sbin/chtab priority=2.3 policy.commands=lsxcatd policy.rule=allow;";
            $chtabcmds .=
"$::XCATROOT/sbin/chtab priority=3 policy.commands=nextdestiny policy.rule=allow;";
            $chtabcmds .=
"$::XCATROOT/sbin/chtab priority=4 policy.commands=getdestiny policy.rule=allow;";
            $chtabcmds .=
"$::XCATROOT/sbin/chtab priority=4.4 policy.commands=getpostscript policy.rule=allow;";
            $chtabcmds .=
"$::XCATROOT/sbin/chtab priority=4.5 policy.commands=getcredentials policy.rule=allow;";
            $chtabcmds .=
"$::XCATROOT/sbin/chtab priority=4.6 policy.commands=syncfiles policy.rule=allow;";
            $chtabcmds .=
"$::XCATROOT/sbin/chtab priority=4.7 policy.commands=litefile policy.rule=allow;";
            $chtabcmds .=
"$::XCATROOT/sbin/chtab priority=4.8 policy.commands=litetree policy.rule=allow;";
            $chtabcmds .=
"$::XCATROOT/sbin/chtab priority=4.9 policy.commands=getadapter policy.rule=allow;";
        }
        my $outref = xCAT::Utils->runcmd("$chtabcmds", 0);
        if ($::RUNCMD_RC != 0)
        {
            xCAT::MsgUtils->message('E', "Could not create policy definition.");
        }
        else
        {
            verbose("Created policy definition.");
        }
    }

    # update install processing
    if ($::UPDATEINSTALL)
    {
        # setup Management Node policy to trusted
        my $chtabcmds;
        $chtabcmds =
"$::XCATROOT/sbin/chtab priority=1.2 policy.name=$MNname policy.rule=trusted;";
        $chtabcmds .=
"$::XCATROOT/sbin/chtab priority=2.3 policy.commands=lsxcatd policy.rule=allow;";
        $chtabcmds .=
"$::XCATROOT/sbin/chtab priority=2.1 policy.commands=remoteimmsetup policy.rule=allow;";
        $chtabcmds .=
"$::XCATROOT/sbin/chtab priority=4.9 policy.commands=getadapter policy.rule=allow;";
        my $outref = xCAT::Utils->runcmd("$chtabcmds", 0);

        if ($::RUNCMD_RC != 0)
        {
            xCAT::MsgUtils->message('E',
                "Could not update policy.name=$hname rule.");
        }
        else
        {
            verbose("Updated policy definition for MN.");
        }

        # add statelite policies on update for Linux
        if ($::osname eq 'Linux') {
            $chtabcmds =
"$::XCATROOT/sbin/chtab priority=4.7 policy.commands=litefile policy.rule=allow;";
            $chtabcmds .=
"$::XCATROOT/sbin/chtab priority=4.8 policy.commands=litetree policy.rule=allow;";
            my $outref = xCAT::Utils->runcmd("$chtabcmds", 0);
            if ($::RUNCMD_RC != 0)
            {
                xCAT::MsgUtils->message('E', "Could not create statelite policy.");
            }
            else
            {
                verbose("Created statelite policy definition.");
            }
        }

        # For Linux check to see if otherpkgs is in the postscripts table
        # if it is do not change it, otherwise put in postbootscripts
        #  0 = does not exist
        #  1 = exists in postscripts
        #  2 = exists in postbootscripts
        my $otherpkgsexist;
        $chtabcmds = "";
        if ($::osname eq 'Linux') {
            $otherpkgsexist = &checkotherpkgs;
            if (($otherpkgsexist == 1) || ($otherpkgsexist == 2)) {

                # otherpkgs already in postscripts or in postbootscripts
                # just add syncfiles
                $chtabcmds = "$::XCATROOT/sbin/chtab node=xcatdefaults postscripts.postscripts+='syncfiles'";
            }
            else
            {    #  otherpkgs does not exist
                    #  put in postbootscripts
                $chtabcmds = "$::XCATROOT/sbin/chtab node=xcatdefaults postscripts.postbootscripts+='otherpkgs';";
            }
        } else {    # AIX ,  no otherpkgs just add syncfiles
            $chtabcmds = "$::XCATROOT/sbin/chtab node=xcatdefaults postscripts.postscripts+='syncfiles'";
        }

        if ($chtabcmds ne "") {
            my $outref = xCAT::Utils->runcmd("$chtabcmds", 0);
            if ($::RUNCMD_RC != 0)
            {
                xCAT::MsgUtils->message('E',
                    "Could not update postscripts definition.");
            }
            else
            {
                verbose("Updated postscripts definition.");
            }
        }

        # remove any xcatdefaults node in nodelist
        # leave to cleanup from previous bug
        my $rmdefault = "$::XCATROOT/sbin/chtab -d node=xcatdefaults nodelist";
        $outref = xCAT::Utils->runcmd("$rmdefault", 0);
        if ($::RUNCMD_RC != 0)
        {
            xCAT::MsgUtils->message('E', "Could not remove xcatdefaults.");
        }
        else
        {
            verbose("Removed xcatdefaults.");
        }

        # switch from bind.pm to ddns.pm
        # give a warning message for the first time
        my $cmds = "XCATBYPASS=Y $::XCATROOT/sbin/tabdump site 2>/dev/null |grep dnshandler";
        $outref = xCAT::Utils->runcmd("$cmds", -1);
        if ($::RUNCMD_RC != 0)
        {
            # set site.dnshandler
            $cmds = "$::XCATROOT/sbin/chtab key=dnshandler site.value=ddns;";
            $outref = xCAT::Utils->runcmd("$cmds", 0);
            if ($::RUNCMD_RC != 0)
            {
                xCAT::MsgUtils->message('E', "Could not set ddns as dnshandler.");
            }
        }

        # Set default value for site.xcatsslversion when update xcat
        $cmds = "XCATBYPASS=Y $::XCATROOT/sbin/tabdump site 2>/dev/null |grep xcatsslversion";
        xCAT::Utils->runcmd("$cmds", -1);
        if ($::RUNCMD_RC != 0) {

            # if site.xcatsslversion was not set, then set the default value TLSv1
            $cmds = "$::XCATROOT/sbin/chtab key=xcatsslversion site.value=TLSv1;";
            xCAT::Utils->runcmd("$cmds", 0);
            if ($::RUNCMD_RC != 0) {
                xCAT::MsgUtils->message('E', "Could not add default value for site.xcatsslversion.");
            }
        }
    }

    # remove xcatserver,xcatclient
    # from the postscripts. They are now called by servicenode
    &cleanupPSTable;

}    # end initial DB install setup

#-----------------------------------------------------------------------------

=head3    check for otherpkgs 
	
    Check to see if other pkgs exists in postscripts table.
	If it does not we will be putting it in postbootscripts
          return exist_flag

	  exist_flag = 0 does not exist
	  exist_flag = 1 exists  in postscripts
	  exist_flag = 2 exists in postbootscripts

=cut

#-----------------------------------------------------------------------------

sub checkotherpkgs
{
    my $otherpkgsexist = 0;
    my $postscriptstab = xCAT::Table->new('postscripts');
    my $attr           = "xcatdefaults";
    my @values;
    if ($postscriptstab)
    {
        my $ref = $postscriptstab->getAttribs({ node => $attr }, 'postscripts');
        if ($ref)
        {
            @values = $ref->{postscripts};
            if (grep(/otherpkgs/, @values))
            {
                $otherpkgsexist = 1;
            }
        }
        if ($otherpkgsexist == 0)
        {

            # check postbootscripts
            my $ref = $postscriptstab->getAttribs({ node => $attr }, 'postbootscripts');
            if ($ref)
            {
                @values = $ref->{postscripts};
                if (grep(/otherpkgs/, @values))
                {
                    $otherpkgsexist = 2;
                }
            }
        }
    }
    return $otherpkgsexist;
}

#-----------------------------------------------------------------------------

=head3    genCredentials 
	
    Will generate the xCAT credential,  if new install or requested to 
	regenerate.

=cut

#-----------------------------------------------------------------------------

sub genCredentials
{
    my $add_user_func = sub {
        my $user = shift;
        my ($cmd, $outref, $rc);
        $rc = getgrnam($user);
        if (!$rc) {
            $cmd = "groupadd --system $user";
            $outref = xCAT::Utils->runcmd("$cmd", 0);
            if ($::RUNCMD_RC != 0) {
                xCAT::MsgUtils->message('E', "$cmd failed");
                return;
            }
        }
        $rc = getpwnam($user);
        if (!$rc) {
            $cmd = "useradd --system -g $user -s /bin/bash -d /home/$user -m $user";
            $outref = xCAT::Utils->runcmd("$cmd", 0);
            if ($::RUNCMD_RC != 0) {
                xCAT::MsgUtils->message('E', "$cmd failed");
                return;
            }
        }
    };

    my $hname = `hostname`;
    chomp $hname;
    if ((!-d "/etc/xcat/ca") || $::FORCE || $::genCredentials)
    {
        xCAT::MsgUtils->message(
            'I',
"\nSetting up basic certificates.  Respond with a \'y\' when prompted.\n"
        );
        my $cmd =
"echo 'y\ny\ny\ny' |$::XCATROOT/share/xcat/scripts/setup-xcat-ca.sh 'xCAT CA'";
        verbose("Running $cmd");
        my $rc = system($cmd);
        if ($rc >> 8)
        {
            xCAT::MsgUtils->message('E',
                "Could not create xCAT certificate in /etc/xcat/ca.");
        }
        else
        {
            xCAT::MsgUtils->message('I', "Created xCAT certificate.");
        }
    }

    #  copy to postscript directory  just non-sensitive files
    my $cmd = "/bin/rm -rf $::INSTALLDIR/postscripts/ca >/dev/null 2>&1";
    my $outref = xCAT::Utils->runcmd("$cmd", 0);
    $cmd = "/bin/mkdir -m 755 -p $::INSTALLDIR/postscripts/ca";
    $outref = xCAT::Utils->runcmd("$cmd", 0);
    if ($::RUNCMD_RC != 0)
    {
        xCAT::MsgUtils->message('E',
            "Could not create $::INSTALLDIR/postscripts/ca directory.");
    }

    $cmd = "/bin/cp -p /etc/xcat/ca/ca-cert.pem $::INSTALLDIR/postscripts/ca/ca-cert.pem";
    $outref = xCAT::Utils->runcmd("$cmd", 0);
    if ($::RUNCMD_RC != 0)
    {
        xCAT::MsgUtils->message(
            'E',
            "$cmd failed"
        );
    }
    else
    {
        verbose "$cmd succeeded.";
    }

    if ((!-d "/etc/xcat/cert") || $::FORCE || $::genCredentials)
    {
        my $cmd =
"echo 'y\ny\ny\ny' |$::XCATROOT/share/xcat/scripts/setup-server-cert.sh $hname";
        verbose("Running $cmd");
        my $rc = system($cmd);
        if ($rc >> 8)
        {
            xCAT::MsgUtils->message('E',
                "Could not create xCAT certificate in /etc/xcat/cert.");
        }
        else
        {
            if ($::genCredentials) {    # if just generating new credentials
                xCAT::MsgUtils->message('I', "Created xCAT certificate.");
                my $chtabcmds =
"$::XCATROOT/sbin/chtab priority=1.2 policy.name=$hname policy.rule=trusted;";
                my $outref = xCAT::Utils->runcmd("$chtabcmds", 0);
                if ($::RUNCMD_RC != 0)
                {
                    xCAT::MsgUtils->message('E', "Could not create policy definition.$chtabcmds.");
                }
            }
        }
    }
    if ((!-d "/etc/xcatdockerca/cert") || $::FORCE || $::genCredentials) {
        my $cmd = "echo 'y\ny\ny\ny' |$::XCATROOT/share/xcat/scripts/setup-dockerhost-cert.sh";
        verbose("Running $cmd");
        my $rc = system($cmd);
        if ($rc >> 8) {
            xCAT::MsgUtils->message('E',
"Could not create xCAT dockerhost certificate in /etc/xcatdockerca/cert.");
        } else {
            verbose("Create xCAT dockerhost certificate in /etc/xcatdockerca/cert directory.");
        }
    }

    #  copy to postscript directory, no longer use cert directory
    $cmd = "/bin/rm -rf $::INSTALLDIR/postscripts/cert >/dev/null 2>&1";
    $outref = xCAT::Utils->runcmd("$cmd", 0);

    if ((!-r "$::root/.xcat/client-key.pem") || $::FORCE || $::genCredentials)
    {

        my $cmd =
"echo 'y\ny\ny\ny' |$::XCATROOT/share/xcat/scripts/setup-local-client.sh root";
        verbose("Running $cmd");
        my $rc = system($cmd);
        if ($rc >> 8)
        {
            xCAT::MsgUtils->message('E',
                "Could not create xCAT certificate in /.xcat/client-key.pem.");
        }
        else
        {
            xCAT::MsgUtils->message('I', "Created xCAT certificate.");
        }
    }

    if ((!-r "/home/conserver/.xcat/client-key.pem") || $::FORCE || $::genCredentials)
    {
        $add_user_func->('conserver');
        my $cmd =
"echo 'y\ny\ny\ny' |$::XCATROOT/share/xcat/scripts/setup-local-client.sh conserver";
        verbose("Running $cmd");
        my $rc = system($cmd);
        if ($rc >> 8)
        {
            xCAT::MsgUtils->message('E',
"Could not create xCAT certificate in /home/conserver/.xcat/client-key.pem.");
        }
        else
        {
            xCAT::MsgUtils->message('I', "Created xCAT certificate.");
        }
    }

    #  copy to postscript directory
    $cmd    = "/bin/rm -rf $::INSTALLDIR/postscripts/_xcat >/dev/null 2>&1";
    $outref = xCAT::Utils->runcmd("$cmd", 0);
    $cmd    = "/bin/mkdir -m 755 -p $::INSTALLDIR/postscripts/_xcat";
    $outref = xCAT::Utils->runcmd("$cmd", 0);
    if ($::RUNCMD_RC != 0)
    {
        xCAT::MsgUtils->message('E',
            "Could not create $::INSTALLDIR/postscripts/_xcat directory.");
    }
    else
    {
        verbose("Created $::INSTALLDIR/postscripts/_xcat directory.");
    }
    $cmd = "/bin/cp -p $::root/.xcat/ca.pem $::INSTALLDIR/postscripts/_xcat/ca.pem";
    $outref = xCAT::Utils->runcmd("$cmd", 0);
    if ($::RUNCMD_RC != 0)
    {
        xCAT::MsgUtils->message(
            'E',
"Could not copy $::root/.xcat/ca.pem to  $::INSTALLDIR/postscripts/_xcat directory."
        );
    }
    else
    {
        verbose "Copied $::root/.xcat/ca.pem to $::INSTALLDIR/postscripts/_xcat directory.";
    }
}

#-----------------------------------------------------------------------------

=head3    setupAIXIPMITool 
       
     Set AIX IPMI Tool 
 
=cut

#-----------------------------------------------------------------------------

sub setupAIXIPMITool

{
    if (!-f "/usr/bin/ipmitool")
    {
        my $cmd = "ln -sf /opt/freeware/bin/ipmitool /usr/bin/ipmitool";
        my $outref = xCAT::Utils->runcmd("$cmd", 0);
        if ($::RUNCMD_RC != 0)
        {
            xCAT::MsgUtils->message(
                'E',
                "Could not ln -sf /opt/freeware/bin/ipmitool /usr/bin/ipmitool."
            );
        }
        else
        {
            verbose("ln -sf /opt/freeware/bin/ipmitool /usr/bin/ipmitool.");
        }
    }
}

#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------

=head3    setupAIXexports 
	
    Set AIX exports 

=cut

#-----------------------------------------------------------------------------

sub setupAIXexports

{
    # check if /install/postscripts is exported
    my $lsnfsexpcmd =
      "/usr/sbin/lsnfsexp -d $::INSTALLDIR/postscripts 2>&1";
    my $outref = xCAT::Utils->runcmd("$lsnfsexpcmd", -1);
    if (($::RUNCMD_RC != 0) || ($outref !~ /-vers=3:4/))
    {

        # if not exported for both NFS version 3 and version 4,
        # make sure it is exported with -vers=3:4
        my $rmnfsexpcmd = "/usr/sbin/rmnfsexp -d $::INSTALLDIR/postscripts 2>&1";
        xCAT::Utils->runcmd("$rmnfsexpcmd", -1);

        my $mknfsexpcmd =
          "mknfsexp -d $::INSTALLDIR/postscripts '-B' -v '3,4' -t 'ro'";
        my $outref2 = xCAT::Utils->runcmd("$mknfsexpcmd", -1);
        if ($::RUNCMD_RC != 0)
        {
            xCAT::MsgUtils->message('E',
                "Could not export directory $::INSTALLDIR/postscripts.");
        }
    }
}

#-----------------------------------------------------------------------------

=head3    setupLinuxexports 
	
    Set Linux exports 

=cut

#-----------------------------------------------------------------------------

sub setupLinuxexports
{
    my $changed_exports = 0;

    #
    #  add tftpboot to /etc/exports - if needed
    #

    my $cmd = "/bin/cat /etc/exports | grep '$::TFTPDIR'";
    my $outref = xCAT::Utils->runcmd("$cmd", -1);
    if ($::RUNCMD_RC != 0)
    {

        # ok - then add this entry
        #SECURITY: this has potential for sharing private host/user keys
        my $cmd =
"/bin/echo '$::TFTPDIR *(rw,no_root_squash,sync,no_subtree_check)' >> /etc/exports";

        my $outref = xCAT::Utils->runcmd("$cmd", 0);
        if ($::RUNCMD_RC != 0)
        {
            xCAT::MsgUtils->message('E',
                "Could not update the /etc/exports file.");
        }
        else
        {
            verbose("Added $::TFTPDIR to the /etc/exports file.");
            $changed_exports++;
        }
    }

    #
    #  add /install to /etc/exports - if needed
    #

    $cmd = "/bin/cat /etc/exports | grep '$::INSTALLDIR'";
    $outref = xCAT::Utils->runcmd("$cmd", -1);
    if ($::RUNCMD_RC != 0)
    {

        # ok - then add this entry
        #SECURITY: this has potential for sharing private host/user keys
        my $cmd =
"/bin/echo '$::INSTALLDIR *(rw,no_root_squash,sync,no_subtree_check)' >> /etc/exports";
        my $outref = xCAT::Utils->runcmd("$cmd", 0);
        if ($::RUNCMD_RC != 0)
        {
            xCAT::MsgUtils->message('E',
                "Could not update the /etc/exports file.");
        }
        else
        {
            verbose("Added $::INSTALLDIR to the /etc/exports file.");
            $changed_exports++;
        }
    }

    if ($changed_exports)
    {

        # restart nfs
        #    my $cmd;
        #    my $os = xCAT::Utils->osver();
        #    my $SERVICE = xCAT::Utils->fullpathbin("service");
        #    if ($os =~ /sles/) {
        #       $cmd = "$SERVICE nfsserver restart";
        #    } else {
        #       $cmd = "$SERVICE nfs restart";
        #    }
        #    my $outref = xCAT::Utils->runcmd("$cmd", 0);
        #    if ($::RUNCMD_RC != 0)
        my $ret = xCAT::Utils->restartservice("nfs");
        if ($ret != 0)
        {
            xCAT::MsgUtils->message('E', "Could not restart NFS.");
        }
        else
        {
            xCAT::MsgUtils->message('I', "NFS has been restarted.");
        }

        #my $CHKCONFIG=xCAT::Utils->fullpathbin("chkconfig");
        #if ($os =~ /sles/) {
        #  $cmd = "$CHKCONFIG nfsserver on";
        #} else {
        #  $cmd = "$CHKCONFIG nfs on";
        #}
        #$outref = xCAT::Utils->runcmd("$cmd", 0);
        #if ($::RUNCMD_RC != 0)


        $ret = xCAT::Utils->enableservice("nfs");
        if ($ret != 0)
        {
            xCAT::MsgUtils->message('E', "Could not enable NFS.");
        }
        else
        {
            verbose("NFS has been enabled.");
        }
        $cmd = "/usr/sbin/exportfs -a";
        $outref = xCAT::Utils->runcmd("$cmd", 0);
        if ($::RUNCMD_RC != 0)
        {
            xCAT::MsgUtils->message('E', "Error with $cmd.");
        }
        else
        {
            verbose("Ran $cmd.");
        }
    }
}

#-----------------------------------------------------------------------------

=head3    mknb 
	
   Creates a network boot root image on Linux 
   Run mknb to put xCAT-genesis-scripts-x86_64 and xCAT-genesis-base-x86_64 together and in /tftpboot
   From 2.12.2, both xCAT-genesis-scripts-x86_64 and xCAT-genesis-scripts-ppc64 will be installed.
   So, will run mknb twice, one for ppc64 and another for x86_64
=cut

#-----------------------------------------------------------------------------
sub mknb
{
    # The xCAT-genesis-scripts.spec file touches /etc/xcat/genesis-scripts-updated or
    # the xCAT-genesis-base.spec file touches /etc/xcat/genesis-base-updated,
    # so we know to run mknb here.
    my $cmd = "$::XCATROOT/sbin/mknb";
    my $run_mknb = 0;
    if (-f '/etc/xcat/genesis-scripts-updated') {
        unlink '/etc/xcat/genesis-scripts-updated';
        $run_mknb = 1;
        xCAT::MsgUtils->message('I', "Running '$cmd', triggered by the installation/update of xCAT-genesis-scripts ...");
    }
    if (-f '/etc/xcat/genesis-base-updated') {
        unlink '/etc/xcat/genesis-base-updated';
        unless ($run_mknb) {
            $run_mknb = 1;
            xCAT::MsgUtils->message('I', "Running '$cmd', triggered by the installation/update of xCAT-genesis-base ...");
        }
    }
    if ($run_mknb) {
        foreach (qw(ppc64 x86_64)) {
            system("$cmd $_");
            if ($? != 0) {
                my $rc = $? >> 8;
                xCAT::MsgUtils->message('E', "The 'mknb $_' command returned error code: $rc.");
            }
            else {
                xCAT::MsgUtils->message('I', "The 'mknb $_' command completed successfully.");
            }
        }
    }
}

#-----------------------------------------------------------------------------

=head3    makenetworks 
	
     Runs makenetworks on AIX and Linux 

=cut

#-----------------------------------------------------------------------------
sub makenetworks
{

    # run makenetworks
    my $cmd = "XCATBYPASS=Y $::XCATROOT/sbin/makenetworks";
    my $outref = xCAT::Utils->runcmd("$cmd", 0);
    if ($::RUNCMD_RC != 0)
    {
        verbose("The makenetworks command returned error: $::RUNCMD_RC");
    }
    else
    {
        verbose("The makenetworks command was run with no error.");
    }


}

#-----------------------------------------------------------------------------

=head3    setuphttp 
	
     initializes http  on Linux

=cut

#-----------------------------------------------------------------------------
sub setuphttp
{

    #    my $cmd;
    #    my $distro = xCAT::Utils->osver();
    #    # restart httpd
    #    if (-e "/etc/init.d/apache2")
    #    {    #for sles/ubuntu
    #        $cmd = "/etc/init.d/apache2 stop; /etc/init.d/apache2 start";
    #    }
    #    elsif  (-e "/etc/init.d/httpd")
    #    {
    #        $cmd = "/etc/init.d/httpd stop; /etc/init.d/httpd start";
    #    }
    #    else
    #    {
    #        $cmd = "service httpd stop; service httpd start";
    #    }

    #    my $outref = xCAT::Utils->runcmd("$cmd", 0);
    #    if ($::RUNCMD_RC != 0)
    my $ret = xCAT::Utils->restartservice("http");
    if ($ret != 0)
    {
        xCAT::MsgUtils->message('E', "Could not restart httpd.");
    }
    else
    {
        xCAT::MsgUtils->message('I', "httpd has been restarted.");
    }

    # enable httpd
    #if (-e "/etc/init.d/apache2")
    #{
    #    if ( $distro =~ /ubuntu.*/ || $distro =~ /debian.*/i) {
    #        $cmd = "/usr/sbin/update-rc.d apache2 enable";
    #    }
    #    else
    #    {   # for sles
    #        $cmd = "/sbin/chkconfig apache2 on";
    #    }
    #}
    #else
    #{
    #     my $CHKCONFIG = xCAT::Utils->fullpathbin("chkconfig");
    #     $cmd = "$CHKCONFIG httpd on";
    #}



    #$outref = xCAT::Utils->runcmd("$cmd", 0);
    #if ($::RUNCMD_RC != 0)
    $ret = xCAT::Utils->enableservice("http");
    if ($ret != 0)
    {
        xCAT::MsgUtils->message('E', "Could not enable httpd.");
    }
    else
    {
        verbose("httpd has been enabled.");
    }
}

#-----------------------------------------------------------------------------

=head3   cleanupPSTable 
	
   Any line in the postscripts table that has the following
   entry will have xcatserver,xcatclient remove because they
   are not called by servicenode

   ..."servicenode,xcatserver,xcatclient.."... 
    becomes
   ..."servicenode,.."... 
 

   Any line in the postscripts table that has aixremoteshell, 
   aixremoteshell will be replaced by remoteshell unless it is
   already on the line.  remoteshell now calls aixremoteshell, if on an
   AIX node.  

   ...,"syslog,aixremoteshell,syncfiles",,, 
   becomes
   ...,"syslog,remoteshell,syncfiles",,, 

=cut

#-----------------------------------------------------------------------------
sub cleanupPSTable
{
    my $rc = 0;
    my $tab;
    if ($tab = xCAT::Table->new("postscripts")) {
        my @tableentries = $tab->getAllAttribs('node', 'postscripts');
        foreach my $entry (@tableentries) {
            my $changeit = 0;
            my $node     = $entry->{'node'};
            my $pslist = $entry->{'postscripts'}; # get list of postscripts on the line
            if ($pslist) {
                my $servicenode    = 0;
                my $aixremoteshell = 0;
                my $remoteshell    = 0;
                my $newpslist      = "\'";
                my @ps             = split(",", $pslist);

                # now check is servicenode and xcatclient and/or xcatserver on the line
                foreach my $pscript (@ps) {

                    # check for aixremoteshell, need to replace with remoteshell
                    if ($pscript =~ /(^|\|)aixremoteshell($|\|)/i) {
                        $aixremoteshell = 1;
                    }
                    if ($pscript =~ /(^|\|)remoteshell($|\|)/i) {
                        $remoteshell = 1;
                    }
                    if ($pscript =~ /(^|\|)servicenode($|\|)/i) { # found servicenode ps
                        $newpslist .= $pscript;
                        $newpslist .= ",";
                        $servicenode = 1;
                    } else {    # process rest of ps list
                         # if servicenode and aixremoteshell not found on the line go
                         # to the next line
                        if (($servicenode == 0) && ($aixremoteshell == 0)) {
                            $newpslist .= $pscript;
                            $newpslist .= ",";

                        } else {

                            # servicenode found, do not keep xcatserver/xcatclient or
                            # aixremoteshell, and no remoteshell replace with remoteshell
                            if (($aixremoteshell == 1) && ($remoteshell == 0)) {
                                $newpslist .= "remoteshell,";
                                $changeit = 1;   # had to replace aixremoteshell
                                next;
                            }

                            # if already put in remoteshell, then skip any more
                            # occurances of remoteshell on the line
                            if (($aixremoteshell == 1) && ($remoteshell == 1)) {
                                next;
                            }
                            if (($pscript =~ /(^|\|)xcatserver($|\|)/i) || ($pscript =~ /(^|\|)xcatclient($|\|)/i)) {
                                $changeit = 1; # had to remove xcatserver/xcatclient
                                next;
                            } else {
                                $newpslist .= $pscript;
                                $newpslist .= ",";
                            }
                        }    # end servicenode processing
                    }
                }
                chop $newpslist;
                $newpslist .= "\'";
                if ($changeit == 1) {    # we had to modify the line
                    my $chtabcmds .=
"$::XCATROOT/sbin/chtab node=$node postscripts.postscripts=$newpslist;";
                    my $outref = xCAT::Utils->runcmd("$chtabcmds", 0);
                    if ($::RUNCMD_RC != 0)
                    {
                        xCAT::MsgUtils->message('E',
"Could not modify postscripts definition for $node.");
                    }
                }
            }
        }
    }
    else
    {
        xCAT::MsgUtils->message("E", " Could not open the postscripts table\n");
        return 1;
    }

    return $rc
}

#-----------------------------------------------------------------------------

=head3   setupMNinDB 
	
 Will add the management node to the noderes table with group=__mgmtnode  
 Will add the management node to the servicenode tble with group=__mgmtnode  


=cut

#-----------------------------------------------------------------------------
sub setupMNinDB
{
    my $mnname = `hostname`;
    chomp $mnname;
    $mnname && $mnname =~ s/\..*//;    # strip off domain

    # check to see if MN already defined in the nodelist

    my $defined = 0;
    my $cmds = "XCATBYPASS=Y $::XCATROOT/sbin/tabdump nodelist | grep  __mgmtnode";
    my @output = xCAT::Utils->runcmd("$cmds", -1);

    if ($::RUNCMD_RC == 0)             # found nodes in __mgmtnode
    {
        my $chtabcmds;

        # Look through the MN list and see if this MN is defined
        foreach my $line (@output) {
            my @mn = split(",", $line);
            $mn[0] =~ s/"//g;          # remove the quotes
            if ($mn[0] eq $mnname) {   # already in the database
                verbose("$mnname already defined in the the nodelist table.");
                $defined = 1;
                last;
            }
        }
    }

    # now add with the new name , if not already there
    if ($defined == 0) {
        my $chtabcmds = "$::XCATROOT/sbin/chtab node=$mnname nodelist.groups=__mgmtnode;";
        my $outref = xCAT::Utils->runcmd("$chtabcmds", 0);
        if ($::RUNCMD_RC != 0)
        {
            xCAT::MsgUtils->message('E', "Could not add $mnname to the noderes table.");
        }
        else
        {
            verbose("Added $mnname to the noderes table.");
        }

    }

    # now add to the servicenode table with default settings
    # check to see if MN already defined in the servicenode table
    my $cmds = "XCATBYPASS=Y $::XCATROOT/sbin/tabdump servicenode | grep  __mgmtnode";
    my $output = xCAT::Utils->runcmd("$cmds", -1);
    if ($::RUNCMD_RC != 0)    # no management node defined
    {
        #  add to the servicenode table
        my $chtabcmds;
        if (xCAT::Utils->isLinux()) {

            # always setup tftp
            $chtabcmds =
"$::XCATROOT/sbin/chtab node=__mgmtnode servicenode.tftpserver=yes ";

            # check setting of site.vsftp to see if we want to setup ftp
            $cmds = "XCATBYPASS=Y $::XCATROOT/sbin/tabdump site | grep vsftp";
            $output = xCAT::Utils->runcmd("$cmds", -1);
            if ($::RUNCMD_RC == 0) {    # vsftp  defined
                    # check the setting to see if we want ftp
                my @vals = split(',', $output);
                if ($vals[1] && ($vals[1] !~ /0|NO|No|no|N|n/)) {    # setup ftp
                    $chtabcmds .= " servicenode.ftpserver=yes ";
                }
            }
        } else {    # AIX, don't define any services just add the MN node
            $chtabcmds =
"$::XCATROOT/sbin/chtab node=__mgmtnode servicenode.ftpserver=no;";
        }

        my $outref = xCAT::Utils->runcmd("$chtabcmds", 0);
        if ($::RUNCMD_RC != 0)
        {
            xCAT::MsgUtils->message('E', "Could not add $mnname to the servicenode table.");
        }
        else
        {
            verbose("Added $mnname to the servicenode table table.");
        }

    } else {    # it was already defined in the servicenode table
        verbose("$mnname already defined in the the servicenode table.");

    }
    xCAT::MsgUtils->message('I', "Management Node defined in the database.");
    return;
}

#-----------------------------------------------------------------------------

=head3    startnamedonboot 
	
     Configure named to start on boot

=cut

#-----------------------------------------------------------------------------
sub startnamedonboot
{
    # start named on boot
    my $distro = xCAT::Utils->osver();
    if (xCAT::Utils->isAIX())
    {
        #/etc/inittab
        my $cmd = "/usr/sbin/lsitab named > /dev/null 2>&1";
        my $rc  = system("$cmd") >> 8;
        if ($rc != 0)
        {
            #add new entry
            my $mkcmd = qq~/usr/sbin/mkitab "named:2:once:/usr/sbin/named > /dev/console 2>&1"~;
            system("$mkcmd");

            xCAT::MsgUtils->message("I", "named has been enabled on boot.");
        }
    }
    else
    {
        #chkconfig
        #my $serv = "named";
        #my $cmd = "/sbin/chkconfig $serv on";
        #if ( $distro =~ /ubuntu.*/ || $distro =~ /debian.*/i) {
        #    $serv = "bind9";
        #    $cmd = "update-rc.d $serv enable";
        #}

        #"service named start" is very slowly,sometimes hang in rhels6.4 after installation
        #a work around is to generate /etc/rndc-key during xCAT installation
        if (is_redhat6sp4()) {
            system("rndc-confgen -a -r /dev/urandom");
        }

        #my $outref = xCAT::Utils->runcmd("$cmd", 0);
        #if ($::RUNCMD_RC != 0)
        my $ret = xCAT::Utils->enableservice("named");
        if ($ret != 0)
        {
            xCAT::MsgUtils->message("E", "Could not enable dns server.");
        }
        else
        {
            xCAT::MsgUtils->message("I", "dns server has been enabled on boot.");
        }
    }
}

#-----------------------------------------------------------------------------

=head3    upgrade_conserver

     Update conserver configuration files while upgrading xcat

=cut

#-----------------------------------------------------------------------------
sub upgrade_conserver
{
    my $version = xCAT::Utils::get_conserver_version();
    if (!$version) {
        return;
    }
    if (xCAT::Utils::calc_conserver_version($version) < xCAT::Utils::calc_conserver_version("8.1.19")) {
        return;
    }
    my $cmd = "/bin/cat /etc/conserver.cf | grep sslauthority";
    xCAT::Utils->runcmd($cmd, -1);
    if ($::RUNCMD_RC != 0) {
        return;
    }
    $cmd = "sed -i 's/sslauthority/sslcacertificatefile/1' /etc/conserver.cf";
    xCAT::Utils->runcmd($cmd, 0);
    if ($::RUNCMD_RC != 0) {
        return;
    }
    #restart conserver daemon
    if (xCAT::Utils->isAIX()) {
        $cmd = "stopsrc -s conserver";
        xCAT::Utils->runcmd($cmd, 0);
        $cmd = "startsrc -s conserver";
        xCAT::Utils->runcmd($cmd, 0);
    } else {
        $cmd = "/etc/init.d/conserver stop";
        xCAT::Utils->runcmd($cmd, 0);
        $cmd = "/etc/init.d/conserver start";
        xCAT::Utils->runcmd($cmd, 0);
    }
}
