#!/usr/lpp/mmfs/bin/mmksh
# IBM_PROLOG_BEGIN_TAG
# This is an automatically generated prolog.
#
# ts30_42S src/avs/fs/mmfs/rpm/SRC_BUILD/debian/gpl2deb.sh 1.1
#
# Licensed Materials - Property of IBM
#
# (C) COPYRIGHT International Business Machines Corp. 2015
# All Rights Reserved
#
# US Government Users Restricted Rights - Use, duplication or
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
#
# IBM_PROLOG_END_TAG
# %Z%%M% %I% %W% %G% %U%
#######################################################################
#
# Make deb package for gpl.
#
# Usage:
#  gpl2deb {-m MODKERNEL} {-r DEB_BUILD_ROOT} [-L logfile] 
#
#  gpfs.gplbin.deb will be produced under DEB_BUILD_ROOT
#######################################################################

sourceFile="gpl2deb.sh"
PS4='${0##*/}:${sourceFile}[$LINENO]> '
[[ -n $DEBUG || -n $DEBUGgpl2deb ]] && set -x

# check the existence of the tools
function checkToolExist
{
  typeset sourceFile="gpl2deb.sh"
  [[ -n $DEBUG || -n $DEBUGcheckToolExist ]] && set -x

  tool=$1

  /usr/bin/which $tool > /dev/null 2>&1
  if [[ $? -ne 0 ]]
  then
    print -u2 -- "Error: $tool doesn't exist!"
    return 1
  fi
  return 0
}

# get arch from "uname -m", not from MODKERNEL. Since in Ubuntu,
# MODKERNEL will be something like 3.16.0-28-generic, which does
# not reflect its architecture corretly.
#
# set global variable ARCH with hostarch.
function getArchitecture
{
  typeset sourceFile="gpl2deb.sh"
  [[ -n $DEBUG || -n $DEBUGgetArchitecture ]] && set -x

  print -- "LOG: get host architecture!" >>$LOGFILE 2>&1

  hostarch=$(/bin/uname -m)
  if [[ "$hostarch" = "x86_64" ]]
  then
    hostarch=amd64
  elif [[ "$hostarch" = "i386" || "$hostarch" = "i486" || "$hostarch" = "i586" \
          || "$hostarch" = "i686" ]]
  then
    hostarch=i386
  elif [[ "$hostarch" = "ppc64le" ]]
  then
    hostarch=ppc64el
  fi
  ARCH=$hostarch
  print -- "LOG: host arch is $hostarch!" >>$LOGFILE 2>&1
}

# get build information from gpfs.gplbin.spec, including gpfs
# version, %pre, %post, %preun, %postun, and set global variable
# VERSION, DEBNAME, PREINST_SCRIPT, POSTINST_SCRIPT, PRERM_SCRIPT,
# POSTRM_SCRIPT
function getSpecInfo
{
  typeset sourceFile="gpl2deb.sh"
  [[ -n $DEBUG || -n $DEBUGgetSpecInfo ]] && set -x

  print -- "LOG: get the build information from $GPLBIN_SPEC!" >>$LOGFILE 2>&1

  # version and release
  versionLine=$(/bin/sed -n '/Version/p' $GPLBIN_SPEC)
  releaseLine=$(/bin/sed -n '/Release/p' $GPLBIN_SPEC)
  [[ -z $versionLine || -z $releaseLine ]] && \
    print -u2 --  "Error: could not get GPFS version or release from $GPLBIN_SPEC!" && exit 1
  version=${versionLine##*: }
  release=${releaseLine##*: }
  VERSION=$version"-"$release

  DEBNAME=gpfs.gplbin-${MODKERNEL}_${VERSION}_${ARCH}.deb

  # rpm %pre    ==> deb preinst
  PREINST_SCRIPT=$(/bin/sed -n '/^%pre$/{:loop;/^%post$/!{n;{/^%post$/q};p;b loop;}}' \
                    $GPLBIN_SPEC)
  # rpm %post   ==> deb postinst
  POSTINST_SCRIPT=$(/bin/sed -n '/^%post$/{:loop;/^%preun$/!{n;{/^%preun$/q};p;b loop;}}' \
                    $GPLBIN_SPEC)
  # rpm %preun  ==> deb prerm
  PRERM_SCRIPT=$(/bin/sed -n '/^%preun$/{:loop;/^%postun$/!{n;{/^%postun$/q};p;b loop;}}' \
                    $GPLBIN_SPEC)
  # rpm %postun ==> deb postrm
  POSTRM_SCRIPT=$(/bin/sed -n '/^%postun$/{:loop;n;p;b loop;}' \
                    $GPLBIN_SPEC)
  [[ -z $PREINST_SCRIPT || -z $POSTINST_SCRIPT || -z $PRERM_SCRIPT || -z $POSTRM_SCRIPT ]] && \
    print -u2 --  "Error: could not get GPFS %pre/%post/%preun/%postun from $GPLBIN_SPEC!" && exit 1
}

# prepare the necessary files before making the build.
function prepareBuild
{
  typeset sourceFile="gpl2deb.sh"
  [[ -n $DEBUG || -n $DEBUGprepareBuild ]] && set -x

  print -- "LOG: prepare the control file for $DEBNAME!" >>$LOGFILE 2>&1

  #1, modify the control file in DEB_BUILD_TMP dir
  /bin/cp -pr ${DEBIAN_DIR} ${DEB_BUILD_TMP}
  CONTROLFILE="${DEB_BUILD_TMP}/debian/control"
  /bin/cp -f ${CONTROLFILE} ${CONTROLFILE}.tmp

  /bin/sed -e "s/^Architecture: /Architecture: $ARCH/g" \
           -e "s/^Package: gpfs.gplbin/Package: gpfs.gplbin-$MODKERNEL/g" \
           ${CONTROLFILE}.tmp > ${CONTROLFILE}
  /bin/rm -f ${CONTROLFILE}.tmp

  /bin/cat ${CONTROLFILE} >>$LOGFILE 2>&1

  #2, modify the changelog file
  CHANGELOG="${DEB_BUILD_TMP}/debian/changelog"
  /bin/cp -f ${CHANGELOG} ${CHANGELOG}.tmp
  /bin/sed -e "s/stable/gpfs.gplbin ($VERSION) stable/g" \
    ${CHANGELOG}.tmp > ${CHANGELOG}
  /bin/rm -f ${CHANGELOG}.tmp

  #3, produce preinst/postinst/prerm/postrm based on gpfs.gplbin.spec
  PREINST="${DEB_BUILD_TMP}/debian/preinst"
  POSTINST="${DEB_BUILD_TMP}/debian/postinst"
  PRERM="${DEB_BUILD_TMP}/debian/prerm"
  POSTRM="${DEB_BUILD_TMP}/debian/postrm"

  print "#!/bin/bash\n$PREINST_SCRIPT" > ${PREINST}
  print "#!/bin/bash\n$POSTINST_SCRIPT" > ${POSTINST}
  print "#!/bin/bash\n$PRERM_SCRIPT" > ${PRERM}
  print "#!/bin/bash\n$POSTRM_SCRIPT" > ${POSTRM}

  #4, shell script chmod to x
  for file in preinst postinst prerm postrm
  do
    [[ -f $DEB_BUILD_TMP/debian/$file ]] && /bin/chmod +x $DEB_BUILD_TMP/debian/$file
  done

  #5, copy lxtrace-$MODKERNEL, mmfs26.ko,
  # mmfslinux.ko and tracedev.ko to pseudo dir under DEB_BUILD_TMP
  DEB_BIN_DIR="${DEB_BUILD_TMP}/usr/lpp/mmfs/bin"
  DEB_KO_DIR="${DEB_BUILD_TMP}/lib/modules/${MODKERNEL}/extra"

  /bin/mkdir -p ${DEB_BIN_DIR}
  /bin/mkdir -p ${DEB_KO_DIR}

  /bin/cp $SRCBIN/lxtrace-$MODKERNEL $DEB_BIN_DIR
  /bin/chmod 755 $DEB_BIN_DIR/lxtrace-$MODKERNEL

  /bin/cp $GPLDIR/mmfs26.ko $DEB_KO_DIR
  /bin/cp $GPLDIR/mmfslinux.ko $DEB_KO_DIR
  /bin/cp $GPLDIR/tracedev.ko $DEB_KO_DIR
  /bin/chmod 755 $DEB_KO_DIR/mmfs26.ko
  /bin/chmod 755 $DEB_KO_DIR/mmfslinux.ko
  /bin/chmod 755 $DEB_KO_DIR/tracedev.ko
}

# make the deb package
# the final package name is restored in $DEBNAME
function makeBuild
{
  typeset sourceFile="gpl2deb.sh"
  [[ -n $DEBUG || -n $DEBUGmakeBuild ]] && set -x

  # build the deb package
  print -- "LOG: make the deb package $DEBNAME!" >>$LOGFILE 2>&1

  cd $DEB_BUILD_TMP

  if [[ $buildMethod = "dpkg" ]]
  then
    # make the package with dpkg manually
    /bin/mkdir tmp
    /bin/cp -pr debian tmp/DEBIAN
    [[ -d usr ]] && /bin/mv usr tmp/
    [[ -d lib ]] && /bin/mv lib tmp/
    /usr/bin/find tmp -type f | /usr/bin/xargs file | /bin/grep ELF | cut -d: -f 1 | \
    /usr/bin/xargs dpkg-shlibdeps >>$LOGFILE 2>&1
    dpkg-gencontrol -isp -Ptmp -p"gpfs.gplbin-${MODKERNEL}" >>$LOGFILE 2>&1
    dpkg --build tmp ../$DEBNAME >>$LOGFILE 2>&1
  else
    # make the package with debuild
    debuild -uc -us -b -d -i >>$LOGFILE 2>&1
  fi

  if [[ $? -ne 0 || ! -f ../$DEBNAME ]]
  then
    print -u2 -- "Error: error happened while making the deb package!"
    cd - >/dev/null 2>&1
    exit 1
  fi
  print -u1 -- "Wrote: $DEB_BUILD_ROOT/$DEBNAME"
  cd - >/dev/null 2>&1
}

function usage
{
  print -u2 -- "Usage: gpl2deb {-m MODKERNEL} {-r DEB_BUILD_ROOT} [-L logfile] "
  print -u2 -- "  -m kernel version of build machine"
  print -u2 -- "  -r root directory for building deb"
  print -u2 -- "  -L logfile: log file for debugging"
}

#####################################################################
# Process the command arguments.
#####################################################################
LOGFILE=/dev/null
DEB_BUILD_ROOT=
DEB_BUILD_TMP=
MODKERNEL=

while getopts L:r:m: OPT
do
  case $OPT in

    L) LOGFILE="$OPTARG"
       ;;

    r) DEB_BUILD_ROOT="$OPTARG"
       ;;

    m) MODKERNEL="$OPTARG"
       ;;
  esac
done

shift OPTIND-1
[[ $# != 0 ]] && usage && exit 1

[[ -z $DEB_BUILD_ROOT ]] && \
   print -u2 --  "Error: could not get DEB_BUILD_ROOT from makefile!" && exit 1

[[ -z $MODKERNEL ]] && \
   print -u2 --  "Error: could not get MODKERNEL from makefile!" && exit 1

DEB_BUILD_TMP=$DEB_BUILD_ROOT/BUILD_TMP_FILES

# we have built GPFS, so SHARKCLONEROOT should be set already
if [ -z $SHARKCLONEROOT ]; then
  print -u2 --  "Error: SHARKCLONEROOT is not set!"
  exit 1
fi

# make sure dirs have been created
# DEBIAN_DIR: dir that contains control files for deb package
DEBIAN_DIR=$SHARKCLONEROOT/config/debian
GPLDIR=$SHARKCLONEROOT/gpl-linux
SRCBIN=$SHARKCLONEROOT/bin

[[ ! -d $DEBIAN_DIR ]] && \
  print -u2 --  "Error: could not find $SHARKCLONEROOT/config/debian!" && exit 1
[[ ! -d $GPLDIR ]] && \
  print -u2 --  "Error: could not find $SHARKCLONEROOT/gpl-linux!" && exit 1
[[ ! -d $SRCBIN ]] && \
  print -u2 --  "Error: could not find $SHARKCLONEROOT/bin!" && exit 1

# get GPFS version from config/gpfs.gplbin.spec
GPLBIN_SPEC=$SHARKCLONEROOT/config/gpfs.gplbin.spec
VERSION=
PREINST_SCRIPT=
POSTINST_SCRIPT=
PRERM_SCRIPT=
POSTRM_SCRIPT=
DEBNAME=

# check the existence of gpfs.gplbin.spec
if [[ ! -e $GPLBIN_SPEC ]]; then
  print -u2 -- "Error: gpfs.gplbin.spec doesn't exist, could not get GPFS version!"
  exit 1
fi

# use dpkg as default deb packager
buildMethod=dpkg
checkToolExist dpkg
if [[ $? -eq "1" ]]; then
  checkToolExist debuild
  if [[ $? -eq "1" ]]; then 
    print -u2 -- "Error: Deb packaging tools not found, Please install dpkg or debuild!"
    exit 1
  else  
    buildMethod=debuild
  fi
fi

/bin/rm -rf $DEB_BUILD_ROOT
/bin/mkdir -p $DEB_BUILD_TMP

getArchitecture
getSpecInfo
prepareBuild
makeBuild

/bin/rm -rf $DEB_BUILD_TMP
