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

#-------------------------------------------------------------------------------
#=head1  otherpkgs
#=head2  It gets the extra rpms and install/update them.
#        The environment variable OTHERPKGS contains the rpms to be installed/updated.
#        On MN, You need to:
#        1. put rpms under /install/post/otherpkgs/os/arch directory where 'os' and 'arch'
#           can be found in the nodetype table.
#        2. put the name of the packages to /opt/xcat/share/xcat/netboot(install)/platform
#           directory. The file name is one of the following:
#              profile.os.arch.otherpkgs.pkglist  
#              profile.os.otherpkgs.pkglist   
#              profile.arch.otherpkgs.pkglist  
#              profile.otherpkgs.pkglist
#   The install/deployment process will pick up the rpms and install them on the nodes. 
#   However, if the nodes have already installed and up and running, you can run the following
#   command to have the extra rpms installed:
#       updatenode noderange otherpkgs 
#   
#=cut
#-------------------------------------------------------------------------------


# do nothing for diskless deployment case because it is done in the image already
if [[ $UPDATENODE -ne 1 ]]; then
  if [ "$NODESETSTATE" = "netboot" -o \
     "$NODESETSTATE" = "statelite" -o \
     "$NODESETSTATE" = "diskless" -o \
     "$NODESETSTATE" = "dataless" ] 
  then
      echo "  Did not install any extra rpms."
      exit 0
  fi
fi 

if [[ -z "$OTHERPKGS_INDEX" ]]; then 
  echo "$0: no extra rpms to install"
  exit 0
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=$INSTALLDIR
    mounted=1 
fi

if [[ -z "$OTHERPKGDIR" ]]; then
    OTHERPKGDIR="$NFSSERVER/post/otherpkgs/$OSVER/$ARCH"
fi

if [ $mounted -eq 0 ]; then
    OTHERPKGDIR=${OTHERPKGDIR/#$INSTALLDIR/$NFSSERVER/}
fi

echo NFSSERVER=$NFSSERVER
logger -t xcat "NFSSERVER=$NFSSERVER"
echo OTHERPKGDIR=$OTHERPKGDIR
logger -t xcat "OTHERPKGDIR=$OTHERPKGDIR"

if [ -x "/sbin/dhcpcd" ]; then
    dhcpcd -n $PRIMARYNIC
fi

#check if the node has yum or zypper installed, it will try yum first, then zypper and last rpm
hasyum=0  
haszypper=0        
result=`rpm -q yum`
if [ $? -eq 0 ]; then 
    hasyum=1
else
    result=`rpm -q zypper`
    if [ "$?" = "0" ]; then 
	haszypper=1
    fi
fi


# To support the #NEW_INSTALL_LIST# entry in otherpkgs.pkglist files,
# multiple lists of packages are provided to this script in the form:
#  OTHERPKGS1, OTHERPKGS2, ... OTHERPKSn where n=OTHERPKGS_INDEX
# Each sublist will be installed in a separate call (separate pass
#  through this loop)
op_index=1
#echo "OTHERPKGS_INDEX = $OTHERPKGS_INDEX"
while [ $op_index -le $OTHERPKGS_INDEX ]; do 
    eval pkglist=\$OTHERPKGS$op_index
    #echo "pkglist = $pkglist"
    if [ $hasyum -eq 1 ]; then 
        mkdir -p /etc/yum.repos.d
        result=`rm /etc/yum.repos.d/xCAT-otherpkgs*.repo 2>&1`
        result=`yum clean all`
        repo_base="/etc/yum.repos.d"
    elif [ $haszypper -eq 1 ]; then
        #remove old repo
        old_repo=`zypper sl |grep xcat-otherpkgs | cut -f2 -d '|'`
        for x in $old_repo
        do
            result=`zypper sd $x`
        done
	zypper --non-interactive refresh
        repo_base="/tmp"
    fi

    repo_path=()
    repo_pkgs=""
    repo_pkgs_preremove=""
    repo_pkgs_postremove=""
    plain_pkgs=""
    plain_pkgs_preremove=""
    plain_pkgs_postremove=""
    handled_path=()
    for x in `echo "$pkglist" | tr "," "\n"`
    do
        #check if the file name starts with -- or -. 
        #If it is start with -,  then the rpm must be removed before installing other packages
        #If it is start with --, then the rpm will be removed after  installing other packages
        string_type=0;  #nornmal rpm
        pos=`expr index  $x -`
        if [ $pos -eq 1 ]; then 
	    x=`echo ${x#-}`
	    pos=`expr index  $x -`
	    if [ $pos -eq 1 ]; then
	        x=`echo ${x#-}`
	        string_type=1  #start with --
	    else
	        string_type=-1 #start with -
	    fi
        fi
	    
        if [ $hasyum -eq 0 ] && [ $haszypper -eq 0 ]; then
	    if [  $string_type -eq -1 ]; then
	        plain_pkgs_preremove="$plain_pkgs_preremove $x"
            elif [  $string_type -eq 1 ]; then
	        plain_pkgs_postremove="$plain_pkgs_postremove $x"
	    else
	        plain_pkgs="$plain_pkgs $x*"
	    fi
	    continue
        fi

        if [  $string_type -eq -1 ]; then
	    repo_pkgs_preremove="$repo_pkgs_preremove $x"
        elif [  $string_type -eq 1 ]; then
	    repo_pkgs_postremove="$repo_pkgs_postremove $x"
        else
	    fn=`basename $x`
	    path=`dirname $x`
	    whole_path=$OTHERPKGDIR/$path
	    #whole_path=$OTHERPKGDIR
	
            #find out if this path has already handled
	    try_repo=1
	    rc=1
	    i=0
	    while [ $i -lt ${#handled_path[*]} ]; do
	        if [ ${handled_path[$i]} = $path ]; then
		    try_repo=0
		    j=0
		    while [ $j -lt ${#repo_path[*]} ]; do
		        if [ ${repo_path[$j]} = $path ]; then
			    rc=0
			    break
		        fi
		        let j++
		    done
		    break 
	        fi
	        let i++
	    done
	
	
            #try to add the path to the repo
	    if [ $try_repo -eq 1 ]; then
	        index=${#repo_path[*]}
	        REPOFILE="$repo_base/xCAT-otherpkgs$index.repo"
	        echo "[xcat-otherpkgs$index]" > $REPOFILE
	        echo "name=xcat-otherpkgs$index" >> $REPOFILE
	        if [ $mounted -eq 0 ]; then
		    echo "baseurl=ftp://$whole_path" >> $REPOFILE
	        else
		    echo "baseurl=file://$whole_path" >> $REPOFILE
	        fi
	        echo "enabled=1" >> $REPOFILE
	        echo "gpgcheck=0" >> $REPOFILE
	    
	        if [ $hasyum -eq 1 ]; then 
	            #use yum
		    result=`yum list $fn 2>&1`
		    if [ $? -eq 0 ]; then  
		        rc=0
		        repo_path[${#repo_path[*]}]=$path
		    else
		        rm $REPOFILE
		    fi
	        elif [ $haszypper -eq 1 ]; then
                    #use zypper
		    if [[ "$OSVER" = sles11* ]]; then
		        result=`zypper ar -c $REPOFILE`
		    else
		        result=`zypper sa -c $REPOFILE` 
		    fi	
		
		    result=`zypper --non-interactive refresh xcat-otherpkgs$index 2>&1`
		    if [ $? -eq 0 ]; then  
		        rc=0
		        repo_path[${#repo_path[*]}]=$path
		    else
		        result=`zypper sd xcat-otherpkgs$index`
		    fi
	        fi
	    fi
	
	    if [ $rc -eq 0 ]; then
	        repo_pkgs="$repo_pkgs $fn"  
	    else
                #now no hope we have to use rpm command
	        plain_pkgs="$plain_pkgs $x*"
	    fi
	    handled_path[${#handled_path[*]}]=$path
        fi
    done  

    #now update all the existing rpms
    if [ $hasyum -eq 1 ]; then 
        echo "yum -y upgrade"
        result=`yum -y upgrade 2>&1`
        logger -t xcat "$result"
        if [ $? -ne 0 ]; then 
	    logger -t xcat "otherpkgs: $result"
        fi
        echo "$result"
    elif [ $haszypper -eq 1 ]; then
        echo "zypper --non-interactive update --auto-agree-with-license"
	result=`zypper --non-interactive update --auto-agree-with-license 2>&1`
        logger -t xcat "$result"
	if [ $? -ne 0 ]; then 
            logger -t xcat "otherpkgs: $result"
	fi
        echo "$result"
    fi     

    #echo "repo_pkgs=$repo_pkgs,\nrepo_pkgs_preremove=$repo_pkgs_preremove,\nrepo_pkgs_postremove=$repo_pkgs_postremove"
    #echo "plain_pkgs=$plain_pkgs,\nplain_pkgs_preremove=$plain_pkgs_preremove,\nplain_pkgs_postremove=$plain_pkgs_postremove"


    #Now we have parsed the input, let's remove rpms if is specified with -
    if [ "$repo_pkgs_preremove" != "" ]; then
        if [ $hasyum -eq 1 ]; then 
            echo "yum -y remove $repo_pkgs_preremove"
            result=`yum -y remove $repo_pkgs_preremove 2>&1`
            logger -t xcat "$result"
            if [ $? -ne 0 ]; then 
	        logger -t xcat "otherpkgs: $result"
            fi
            echo "$result"
        elif [ $haszypper -eq 1 ]; then
            echo "zypper remove -y $repo_pkgs_preremove"
	    result=`zypper remove -y $repo_pkgs_preremove 2>&1`
            logger -t xcat "$result"
	    if [ $? -ne 0 ]; then 
                logger -t xcat "otherpkgs: $result"
	    fi
            echo "$result"
        fi
    fi 

    if [ "$plain_pkgs_preremove" != "" ]; then 
        echo "rpm -ev $plain_pkgs_preremove" 
        result=`rpm -ev $plain_pkgs_preremove 2>&1`
        logger -t xcat "$result"
        if [ $? -ne 0 ]; then 
	    logger -t xcat "otherpkgs $result"
        fi
        echo "$result"
    fi


    #installation using yum or zypper     
    if [ "$repo_pkgs" != "" ]; then
        if [ $hasyum -eq 1 ]; then 
            echo "yum -y install $repo_pkgs"
            result=`yum -y install $repo_pkgs 2>&1`
	    logger -t xcat "$result"
            if [ $? -ne 0 ]; then 
                logger -t xcat "otherpkgs: $result"
            fi
            echo "$result"
        elif [ $haszypper -eq 1 ]; then
            echo "zypper install -y $repo_pkgs"
	    result=`zypper install -y $repo_pkgs 2>&1`
            logger -t xcat "$result"
	    if [ $? -ne 0 ]; then 
                logger -t xcat "otherpkgs: $result"
	    fi
            echo "$result"
            #remove the repos
            #old_repo=`zypper lr -u |grep xcat-otherpkgs | cut -f2 -d '|'`
            #for x in $old_repo
            #do
            #    result=`zypper sd $x`
            #done
        fi
    fi 

    #Handle the rest with rpm
    if [ "$plain_pkgs" != "" ]; then 
        if [ $mounted -eq 0 ]; then
	    dir_no_ftproot=${OTHERPKGDIR#$INSTALLDIR/}
            mkdir -p /xcatpost/$dir_no_ftproot 
            rm -f -R /xcatpost/$dir_no_ftproot/*
            mkdir -p /tmp/postage/
            rm -f -R /tmp/postage/*
            cd /tmp/postage
    
            for x in `echo "$plain_pkgs" | tr " " "\n"`
            do
	        wget -l inf -N -r --waitretry=10 --random-wait --retry-connrefused -t 0 -T 60 ftp://$OTHERPKGDIR/$x 2> /tmp/wget.log  
            done
    
            mv $dir_no_ftproot/* /xcatpost/$dir_no_ftproot; 
            rm -rf $NFSSERVER
            cd /xcatpost/$dir_no_ftproot
        else
            cd $OTHERPKGDIR
        fi

        echo "rpm -Uvh --replacepkgs $plain_pkgs" 
        result=`rpm -Uvh --replacepkgs $plain_pkgs 2>&1`
        #result=`rpm -Fvh $plain_pkgs 2>&1`
        logger -t xcat "$result"
        if [ $? -ne 0 ]; then 
	    logger -t xcat "otherpkgs $result"
        fi
        echo "$result"
    
        if [ $mounted -eq 0 ]; then
	    cd /xcatpost
	    dir_no_ftproot=${OTHERPKGDIR#$INSTALLDIR/}
            dir_no_ftproot=${dir_no_ftproot/\/*/}
            rm -f -R $dir_no_ftproot
        fi
    fi

    #remove more rpms if specified with --
    if [ "$repo_pkgs_postremove" != "" ]; then
        if [ $hasyum -eq 1 ]; then 
            echo "yum -y removel $repo_pkgs_postremove"
            result=`yum -y remove $repo_pkgs_postremove 2>&1`
            logger -t xcat "$result"
            if [ $? -ne 0 ]; then 
                logger -t xcat "otherpkgs: $result"
            fi
            echo "$result"
        elif [ $haszypper -eq 1 ]; then
            echo "zypper remove -y $repo_pkgs_postremove"
	    result=`zypper remove -y $repo_pkgs_postremove 2>&1`
            logger -t xcat "$result"
	    if [ $? -ne 0 ]; then 
                logger -t xcat "otherpkgs: $result"
    	    fi
            echo "$result"
        fi
    fi 

    if [ "$plain_pkgs_postremove" != "" ]; then 
        echo "rpm -ev $plain_pkgs_postremove" 
        result=`rpm -ev $plain_pkgs_postremove 2>&1`
        logger -t xcat "$result"
        if [ $? -ne 0 ]; then 
       	    logger -t xcat "otherpkgs $result"
        fi
        echo "$result"
    fi

    let op_index=$op_index+1
done

exit 0