#!/bin/sh
# IBM(c) 2010 EPL license http://www.eclipse.org/legal/epl-v10.html

#-------------------------------------------------------------------------------
#=head1  ospkgs
#=head2  Used on Linux only. It installs/updates the rpms thta are from OS distro. 
#        The environment variable OSPKGS contains the rpms to be installed/updated.
#        On MN, You need to:
#        1. update the rpms under /install/os/arch/... directory where 'os' and 'arch'
#           can be found in the nodetype table.
#        2. put new package names to /install/custom/netboot(install)/platform or 
#           /opt/xcat/share/xcat/netboot(install)/platform
#           directory. The file name is one of the following:
#              profile.os.arch.pkglist  
#              profile.os.pkglist   
#              profile.arch.pkglist  
#              profile.pkglist
#  You can run the following commands to install/update the rpms from os distro.
#       updatenode noderange ospkgs 
#       updatenode noderange -S    (this one intslls/updates rpms from os distro as well as otherpkgs)
#       updatenode noderange -P "ospkgs --keeprepo"  (this one will preserve the original repositories when installing/updating the rpms. )
#    
#   
#=cut
#-------------------------------------------------------------------------------

# pmatch determines if 1st argument string is matched by 2nd argument pattern

pmatch ()
{
  case $1 in
    $2) return 0;;  # zero return code means string matched by pattern
  esac

  return 1          # non-zero return code means string not matched by pattern
}

debug=0

OS_TYPE=`uname -s`

if [ "$OS_TYPE" != "Linux" ]; then
    #not supported on AIX
    echo "ospkgs script only runs on Linux."
    exit 0
fi

# This command only runs by updatenode command
if [ -z "$UPDATENODE" ] || [ $UPDATENODE -ne 1 ]; then
    echo "  Did not install any extra rpms."
    exit 0
fi 

if [ -z "$OSPKGS" ]; then 
  echo "$0: no extra rpms to install"
  exit 0
fi


argnum=$#;
args=$@
keeprepo=0
if [ $argnum -gt 0 ]; then
    if ( pmatch  "$args" "*keeprepo*" ); then
	keeprepo=1
    fi
    if ( pmatch  "$args" "*debug*" ); then
	debug=1
    fi
fi


if [ -z "$NFSSERVER" ]; then
    NFSSERVER=$MASTER
fi

if [ -z "$INSTALLDIR" ]; then
    INSTALLDIR="/install"
fi

#check if /install is mounted on the server, we may need to add code to conver NFSSERVER to ip 
mounted=0;
result=`mount |grep /install |grep $NFSSERVER`
if [ $? -eq 0 ]; then
    NFSSERVER="/install"
    mounted=1 
fi

if [ -z "$OSPKGDIR" ]; then
    if [ $mounted -eq 0 ]; then
        OSPKGDIR="$NFSSERVER$INSTALLDIR/$OSVER/$ARCH"
    else
        OSPKGDIR="$NFSSERVER/$OSVER/$ARCH"
    fi
    if ( pmatch "$OSVER" "sles*" ); then
	    OSPKGDIR="$OSPKGDIR/1"
    elif ( pmatch "$OSVER" "rhel*" ); then
        OSPKGDIR="$OSPKGDIR/Server"
    elif ( pmatch "$OSVER" "SL5*" ); then
        OSPKGDIR="$OSPKGDIR/SL"
    fi
fi

if [ "$SDKDIR" != "" ]; then 
    if [ $mounted -eq 0 ]; then
        SDKDIR="$NFSSERVER/$SDKDIR"
    fi
fi
    
if [ $mounted -eq 0 ]; then
    OSPKGDIR_NO_PREFIX=${OSPKGDIR#$INSTALLDIR}

    if [ "$OSPKGDIR" != "$OSPKGDIR_NO_PREFIX" ]; then
        OSPKGDIR="$NFSSERVER/$OSPKGDIR_NO_PREFIX"
    fi
fi

logger -t xcat "NFSSERVER=$NFSSERVER"
logger -t xcat "OSPKGDIR=$OSPKGDIR"
logger -t xcat "OSPKGS=$OSPKGS"

if [ $debug -ne 0 ]; then
    echo NFSSERVER=$NFSSERVER
    echo OSPKGDIR=$OSPKGDIR
    echo OSPKGS = $OSPKGS 
fi

pkgs=''  #packages
groups=''   #groups
pkgs_d=''   #packages to remove

OIFS=$IFS
IFS=$'\n'
if ( pmatch "$OSVER" "ubuntu*" ); then
    IFS=$(printf '\n')
fi

for x in `echo "$OSPKGS" | tr "," "\n"`
do
    #remove leading and trailing spaces
    x=`echo $x |sed 's/^ *//;s/ *$//'`
    #echo "x=$x"
    pos=`expr index  "$x" -`
    if [ $pos -eq 1 ]; then 
	pkgs_d="$pkgs_d ${x#-}"
    else
	pos=`expr index  "$x" @`
	if [ $pos -eq 1 ]; then 
	    #remove leading @
	    tmp=${x#@}
            #remove leading and trailing spaces
	    tmp=`echo $tmp |sed 's/^ *//;s/ *$//'`
            #if there are spaces in the middle of the name, quote it
	    pos=`expr index "$tmp" "\ "`
	    if [ $pos -gt 0  ]; then
		groups="$groups \"$tmp\""
	    else
		groups="$groups $tmp"
	    fi
	else
	    pkgs="$pkgs $x"
	fi
    fi
done
IFS=$OIFS

if [ $debug -ne 0 ]; then
    echo "pkgs=$pkgs"
    echo "groups=$groups"
    echo "remove pkgs=$pkgs_d"
fi

if ( pmatch "$OSVER" "sles10*" ); then
    #check if rug is installed
    result=`rpm -q rug`
    if [ $? -ne 0 ]; then 
	echo "Please install rug on $NODE."
	exit 1
    fi

    if [ $keeprepo -ne 1 ]; then
        #remove old repo
	old_repo=`rug sl |grep -e "^[0-9]" | cut -f2 -d '|'`
	for x in $old_repo
	do
            result=`rug sd $x`
	done
	result=`rug  refresh 2>&1`
	if [ $debug -ne 0 ]; then
	    echo "rug refresh"
	    echo $result
	fi
    fi

    #add new repo
    if [ $mounted -eq 0 ]; then
	path="http://$OSPKGDIR"
    else
        path="dir://$OSPKGDIR"
    fi
    result=`rug sa $path $OSVER`
    if [ $? -ne 0 ]; then 
	logger -t xcat "ospkgs: rug sa $path $OSVER\n    $result"
	echo "ospkgs: rug sa $path $OSVER"
	echo "    $result"
    fi
    result=`rug sub $OSVER`
    if [ $? -ne 0 ]; then 
	logger -t xcat "ospkgs: rug sub $OSVER\n    $result"
	echo "ospkgs: rug sub $OSVER"
	echo "    $result"
    fi
    result=`rug refresh 2>&1` 
    if [ $debug -ne 0 ]; then
	echo "rug refresh"
	echo $result
    fi

    result=`rug update -y --agree-to-third-party-licences`
    if [ $? -ne 0 ]; then 
	logger -t xcat "rug update -y --agree-to-third-party-licences\n    $result"
        echo "ospkgs: rug update -y --agree-to-third-party-licences"
		echo "    $result"
    else
	if [ $debug -ne 0 ]; then
	    echo "rug update -y --agree-to-third-party-licences"
	    echo $result
	fi
    fi


    #install the new patterns if any
    if [ -n "$groups" ]; then
	cmd="$ENVLIST rug install -y --agree-to-third-party-licences -t pattern $groups"
	result=`eval $cmd 2>&1`
	if [ $? -ne 0 ]; then 
	    logger -t xcat "ospkgs: $cmd\n    $result"
	    echo "ospkgs: $cmd"
	    echo $result
	else
	    if [ $debug -ne 0 ]; then
		echo "ospkgs: $cmd"
		echo $result
	    fi
	fi
    fi

    #install new rpms if any
    if [ -n "$pkgs" ]; then
	cmd="$ENVLIST rug install -y --agree-to-third-party-licences $pkgs"
	result=`eval $cmd 2>&1`
	if [ $? -ne 0 ]; then 
	    logger -t xcat "ospkgs: $cmd\n    $result"
	    echo "ospkgs: $cmd"
	    echo $result
	else
	    if [ $debug -ne 0 ]; then
		echo "ospkgs: $cmd"
		echo $result
	    fi
	fi
    fi

    #remove some packages if specified
    if [ -n "$pkgs_d" ]; then
	cmd="$ENVLIST rug remove -y $pkgs_d"
	result=`eval $cmd 2>&1`
	if [ $? -ne 0 ]; then 
	    logger -t xcat "ospkgs: $cmd\n    $result"
	    echo "ospkgs: $cmd"
	    echo $result
	else
	    if [ $debug -ne 0 ]; then
		echo "ospkgs: $cmd"
		echo $result
	    fi
	fi
    fi
elif ( pmatch "$OSVER" "sles11*" ); then
    #check if zypper is installed
    result=`rpm -q zypper`
    if [ $? -ne 0 ]; then 
	echo "Please install zypper on $NODE."
	exit 1
    fi
    if [ $keeprepo -ne 1 ]; then
	old_repo=`zypper lr |grep -e "^[0-9]" | cut -f2 -d '|'`
	for x in $old_repo
	do
            result=`zypper rr $x`
	done
	result=`zypper --non-interactive refresh 2>&1`
	if [ $debug -ne 0 ]; then
	    echo "zypper --non-interactive refresh"
	    echo $result
	fi
    fi

    if [ $mounted -eq 0 ]; then
	path="http://$OSPKGDIR"
    else
        path="file://$OSPKGDIR"
    fi
    result=`zypper ar $path $OSVER 2>&1`
    if [ $? -ne 0 ]; then 
	if ( ! pmatch "$result" "*exists*" ); then 
	    logger -t xcat "ospkgs: zypper ar $path $OSVER\n    $result"
	    echo "ospkgs: zypper ar $path $OSVER"
	    echo "    $result"
	fi
    fi

    if [ "$SDKDIR" != "" ]; then
        if [ $mounted -eq 0 ]; then
	    SDKDIR="http://$SDKDIR"
        else
            SDKDIR="file://$SDKDIR"
        fi
        result=`zypper ar $SDKDIR $OSVER-sdk 2>&1`
        if [ $? -ne 0 ]; then 
	    if ( ! pmatch "$result" "*exists*" ); then 
		logger -t xcat "ospkgs: zypper ar $SDKDIR $OSVER-sdk\n    $result"
		echo "ospkgs: zypper ar $SDKDIR $OSVER-sdk"
		echo "    $result"
	    fi
	fi
    fi
    
    result=`zypper --non-interactive refresh 2>&1` 
    if [ $debug -ne 0 ]; then
	echo "zypper --non-interactive refresh"
	echo $result
    fi

    #upgrade the all existing rpms
    result=`zypper --non-interactive update --auto-agree-with-licenses`
    if [ $? -ne 0 ]; then 
	logger -t xcat "ospkgs: zypper --non-interactive update --auto-agree-with-licenses\n    $result"
	echo "ospkgs: zypper --non-interactive update --auto-agree-with-licenses"
	echo "    $result"
    else
	if [ $debug -ne 0 ]; then
	    echo "ospkgs: zypper --non-interactive update --auto-agree-with-licenses"
	    echo $result
	fi
    fi

    #install the new patterns if any
    if [ -n "$groups" ]; then
	cmd="$ENVLIST zypper install -y --auto-agree-with-licenses -t pattern $groups"
	result=`eval $cmd 2>&1`
	if [ $? -ne 0 ]; then 
	    logger -t xcat "ospkgs: $cmd\n    $result"
	    echo "ospkgs: $cmd"
	    echo $result
	else
	    if [ $debug -ne 0 ]; then
		echo "ospkgs: $cmd"
		echo $result
	    fi
	fi
    fi

    #install new rpms if any
    if [ -n "$pkgs" ]; then
	cmd="$ENVLIST zypper install -y --auto-agree-with-licenses $pkgs"
	result=`eval $cmd 2>&1`
	if [ $? -ne 0 ]; then 
	    logger -t xcat "ospkgs: $cmd    $result"
	    echo "ospkgs: $cmd"
	    echo $result
	else
	    if [ $debug -ne 0 ]; then
		echo "ospkgs: $cmd"
		echo $result
	    fi
	fi
    fi

    #remove some packages if specified
    if [ -n "$pkgs_d" ]; then
	cmd="$ENVLIST zypper remove -y $pkgs_d"
	result=`eval $cmd 2>&1`
	if [ $? -ne 0 ]; then 
	    logger -t xcat "ospkgs: $cmd    $result"
	    echo "ospkgs: $cmd"
	    echo $result
	else
	    if [ $debug -ne 0 ]; then
		echo "ospkgs: $cmd"
		echo $result
	    fi
	fi
    fi
elif ( pmatch "$OSVER" "ubuntu*" ); then
	# verify dpkg is installed
	result=`which dpkg`
	if [ $? -ne 0 ]; then
		echo "Please install dpkg on $NODE."
		exit 1
	fi

	# verify apt is installed
	result=`dpkg -l apt`
	if [ $? -ne 0 ]; then
		echo "Please install apt on $NODE."
		exit 1
	fi

	# No need to setup a /etc/apt/sources.list.d/ file because installation
	# should already lead to /etc/apt/sources.list including the xcat install
	# media repository.

	# upgrade existing packages
	command="apt-get -y upgrade"
	echo "=== $command"
	$command

	# install groups (NOTE: It's not clear rpm-like "groups" are supported by dpkg/apt,
	# but keeping this here doesn't really hurt. Anything that looks like a group will
	# be installed as though it were a package.)
	if [ -n "$groups" ]; then
		command="$ENVLIST apt-get -q -y --force-yes install $groups"
		echo "=== $command"
		eval $command
	fi

	# install packages
	if [ -n "$pkgs" ]; then
		command="$ENVLIST apt-get -q -y --force-yes install $pkgs"
		echo "=== $command"
		eval $command
	fi

	# remove packages
	if [ -n "$pkgs_d" ]; then
		command="$ENVLIST apt-get -y remove $pkgs_d"
		echo "=== $command"
		eval $command
	fi
else 
    #check if yum is installed
    result=`rpm -q yum`
    if [ $? -ne 0 ]; then 
	echo "Please install yum on $NODE."
	exit 1;
    fi

    if [ $keeprepo -ne 1 ]; then
       #remove old repo
	mkdir -p /etc/yum.repos.d
	result=`rm /etc/yum.repos.d/*.repo 2>&1`
    fi

    result=`yum clean all`

    #create new repo file
    REPOFILE="/etc/yum.repos.d/$OSVER.repo"
    if [ ! -f $REPOFILE ]; then
	echo "[$OSVER]" > $REPOFILE
	echo "name=$OSVER" >> $REPOFILE
	if [ $mounted -eq 0 ]; then
	    echo "baseurl=http://$OSPKGDIR" >> $REPOFILE
	else
	    echo "baseurl=file://$OSPKGDIR" >> $REPOFILE
	fi
	echo "enabled=1" >> $REPOFILE
	echo "gpgcheck=0" >> $REPOFILE
    fi

    #import the release key?
    #my $key = "$installDIR/$os/$arch/RPM-GPG-KEY-redhat-release";
    #my $tmp = "/tmp/RPM-GPG-KEY-redhat-release";
    #my $tgt = "root@" . $node;
    #$out = `scp $key $tgt:$tmp`;
    #$out = `ssh $node "rpm --import $tmp"`;


    #upgrade the existing rpms
    result=`yum -y upgrade 2>&1`
    if [ $? -ne 0 ]; then 
	logger -t xcat "ospkgs: yum -y upgrade\n    $result"
	echo "ospkgs: yum -y upgrade"
	echo "    $result"
    else
	if [ $debug -ne 0 ]; then
	    echo "ospkgs: yum -y upgrade"
	    echo $result
	fi
    fi

    #install new groups if any
    if [ -n "$groups" ]; then
	cmd="echo $groups| $ENVLIST xargs yum -y groupinstall"
	result=`eval $cmd 2>&1`
	if [ $? -ne 0 ]; then 
	    logger -t xcat "ospkgs: $cmd\n    $result"
	    echo "ospkgs: $cmd"
	    echo $result
	else
	    if [ $debug -ne 0 ]; then
		echo "ospkgs: $cmd"
		echo $result
	    fi
	fi
    fi

    #install new rpms if any
    if [ -n "$pkgs" ]; then
	cmd="$ENVLIST yum -y install $pkgs"
	result=`eval $cmd 2>&1`
	if [ $? -ne 0 ]; then 
	    logger -t xcat "ospkgs: $cmd\n    $result"
	    echo "ospkgs: $cmd"
	    echo $result
	else
	    if [ $debug -ne 0 ]; then
		echo "ospkgs: $cmd"
		echo $result
	    fi
	fi
    fi

    #remove some rpms if specified
    if [ -n "$pkgs_d" ]; then
	cmd="$ENVLIST yum -y remove $pkgs_d"
	result=`eval $cmd 2>&1`
	if [ $? -ne 0 ]; then 
	    logger -t xcat "ospkgs: $cmd\n    $result"
	    echo "ospkgs: $cmd"
	    echo $result
	else
	    if [ $debug -ne 0 ]; then
		echo "ospkgs: $cmd"
		echo $result
	    fi
	fi
    fi
fi

exit 0


