#!/bin/bash
# FOSSology postinstall script
# Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
#
# This script is for things that need to be done on the runtime system
# after we've installed the bits on the filesystem. It needs to be
# idempotent, meaning that running it repeatedly will still do the
# right thing, regardless of the success of previous runs.

## Options parsing and setup
# parse options
OPTS=`getopt -o adwseoh --long agent,database,web,web-only,scheduler,scheduler-only,everything,overwrite,help -n 'fo-postinstall' -- "$@"`

if [ $? != 0 ]; then
   echo "ERROR: Bad option specified."
   OPTS="--help"
fi

eval set -- "$OPTS"

# if no options or just -o then do everything
if [ "$OPTS" = " --" -o "$OPTS" = " -o --" ]; then
   EVERYTHING=1
fi

while true; do
   case "$1" in
      -a|--agent) AGENT=1; shift;;
      -d|--database) DATABASE=1; shift;;
      -w|--web) WEB=1; shift;;
      --web-only) WEBONLY=1; shift;;
      -s|--scheduler) SCHEDULER=1; shift;;
      --scheduler-only) SCHEDULERONLY=1; shift;;
      -e|--everything) EVERYTHING=1; shift;;
      -o|--overwrite) OVERWRITE=1; shift;;
      -h|--help)
         echo "Usage: fo-postinstall [options]";
	 echo "  -a or --agent      : agent specific actions"
	 echo "  -d or --database   : database specific actions"
	 echo "  -w or --web        : web interface specific actions"
	 echo "  -s or --scheduler  : scheduler specific actions"
	 echo "  -e or --everything : all actions (default)"
	 echo "  -o or --overwrite  : overwrite config files with new versions"
	 echo "  -h or --help       : this help text"
         echo " Special options"
         echo "  --web-only         : web, but exclude normal agent actions"
         echo "  --scheduler-only   : scheduler, but exclude normal agent actions"
	 exit;;
      --) shift; break;;
      *) echo "Error: option $1 not recognised"; exit 1;;
   esac
done

# the scheduler and web machines needs the agent stuff done too
if [ $SCHEDULER ]; then
   AGENT=1
   SCHEDULERONLY=1
fi
if [ $WEB ]; then
   AGENT=1
   WEBONLY=1
fi

if [ $EVERYTHING ]; then
   echo "*** Running postinstall for everything ***"
   AGENT=1
   DATABASE=1
   WEBONLY=1
   SCHEDULERONLY=1
fi

# This must run as root.
if [ `id -u` != "0" ] ; then
   echo "ERROR: fo-postinstall must run as root."
   echo "Aborting."
   exit 1
fi

########################################################################

if [ $DATABASE ]; then
   /usr/lib/fossology/dbcreate
fi # end of DATABASE

########################################################################

if [ $AGENT ]; then

   ## get path to repo
   if [ -e "/etc/fossology/RepPath.conf" ] ; then
      REPO=`cat /etc/fossology/RepPath.conf`
   else
      echo "ERROR: Cannot find /etc/fossology/RepPath.conf"
      exit 1
   fi

   ## create user and group
   # Because we are doing these by name, in the multi-machine install case
   # we may end up with uid/gid being different across machines. This will
   # either need to be fixed by hand or with NFSv4 you can use rpc.idmapd
   # to do uid/gid mapping. More details will be provided in the multi-machine
   # documentation.

   # Make sure the user and group exist, if not then create
   echo "*** Creating user and group ***"

   # check for group
   if grep -q "^fossy:" /etc/group; then
      echo "NOTE: group 'fossy' already exists, good."
   else
      # use addgroup if it exists since it supports --system
      if [ -f /usr/sbin/addgroup -a ! -L /usr/sbin/addgroup ]; then
         addgroup --system fossy
      else
         groupadd fossy
      fi
      if [ "$?" != "0" ] ; then
         echo "ERROR: Unable to create group 'fossy'"
         exit 1
      else
         echo "NOTE: group 'fossy' created"
      fi
   fi

   # check for user
   if grep -q "^fossy:" /etc/passwd; then
      echo "NOTE: user 'fossy' already exists, good."
      USERSHELL=`grep "^fossy:" /etc/passwd |cut -d: -f 7`
      if [ "$USERSHELL" = "/bin/false" ]; then
         echo "ERROR: fossy shell must be a real shell"
         exit 1
      fi
   else
      # ensure that the full parent path of the HOME exists first
      mkdir -p ${REPO%/*/*}
      # use adduser if it exists since it supports --system, but
      # not if it's a symlink (probably to /usr/sbin/useradd)
      if [ -f /usr/sbin/adduser -a ! -L /usr/sbin/adduser ]; then
         adduser --gecos "fossology" --ingroup fossy --system \
           --shell /bin/bash --home "${REPO%/*}" fossy
      else
         useradd -c "fossology" -g fossy -m \
           -s /bin/bash -d "${REPO%/*}" fossy
      fi
      if [ "$?" != "0" ] ; then
         echo "ERROR: Unable to create user 'fossy'"
         exit 1
      else
         echo "NOTE: user 'fossy' created"
      fi
   fi

   ## check for existance/ownership/permissions of needed directories
   echo "*** Making sure needed dirs exist with right ownership/permissions ***"
   if [ ! -d "/var/lib/fossology" ] ; then
      mkdir -m 2775 -p "/var/lib/fossology"
   fi
   chown root:fossy /var/lib/fossology
   chmod 2775 /var/lib/fossology
   if [ ! -d "/var/lib/fossology/agents" ] ; then
      mkdir -m 2775 -p "/var/lib/fossology/agents"
   fi
   chown root:fossy /var/lib/fossology/agents
   chmod 2775 /var/lib/fossology/agents

   if [ ! -d "$REPO" ] ; then
      mkdir -p "$REPO"
      chown fossy:fossy $REPO
      # FIXME: which specific directories do we need setgid for?
      chmod 2770 $REPO
      # make sure the parent dir has the right permissions too
      chown fossy:fossy ${REPO%/*}
      chmod 2770 ${REPO%/*}
   else
      echo "NOTE: Repository already exists at $REPO"
   fi

   # ununpack before svn 1715 created it's directory with wrong permissions
   # if the directory already exists ensure that it's permissions are correct
   # this can be removed in the next release after 1.0.0, assuming we will
   # require pre-1.0.0 users to upgrade to 1.0.0 first
   if [ -d "$REPO/ununpack" ]; then
      chmod 2770 $REPO/ununpack
   fi

   if [ -e "/etc/fossology/Hosts.conf" ] ; then
      # if we have a default Hosts.conf file, check if $REPO/localhost
      # exists and if not then create it
      grep -q "^localhost" /etc/fossology/Hosts.conf
      if [ $? == 0 ] ; then
         if [ ! -d "$REPO/localhost" ] ; then
            echo "NOTE: creating new $REPO/localhost directory"
            mkdir $REPO/localhost
            chown fossy:fossy $REPO/localhost
            chmod 2770 $REPO/localhost
         else
            echo "NOTE: $REPO/localhost directory already exists"
         fi
      fi
   else
      # if we don't have a default Hosts.conf file then it's a
      # multi-machine install and the end user needs to setup
      echo "NOTE: Hosts.conf indicates a multi-machine install. Please"
      echo "  make sure that the corresponding agents directories exist"
      echo "  in $REPO and are fossy:fossy and 2770."
   fi

   ## check that the db is accessable
   echo "*** Checking database connectivity ***"
   DBCONF="/etc/fossology/Db.conf"
   if [ ! -f $DBCONF ]; then
      echo "ERROR: missing $DBCONF, cannot proceed."
   fi

   # make install sets Db.conf's mode to 660, but can't chgrp it because
   # the group doesn't exist until we create it above. So chgrp now
   chgrp fossy $DBCONF || echo "ERROR: failed to chgrp $DBCONF"

   # check that we can talk to the db
   if [ -x /usr/lib/fossology/dbcheck ]; then
      /usr/lib/fossology/dbcheck
   else
      echo "ERROR: no /usr/lib/fossology/dbcheck, have you installed?"
      exit 1
   fi
   if [ $? != 0 ]; then
      echo "ERROR: unable to connect to database, please check /etc/fossology/Db.conf"
      exit 1
   else
      echo "NOTE: Connect succeeded, database is working."
   fi


   ## Initialize the tables, License.bsam, and other setup done by fossinit
   # In multi-system installs the database machine must be installed first
   # in order for this to work on other machines.
   echo "*** Initializing database tables ***"
   /usr/bin/fossinit
   if [ $? != 0 ] ; then
     echo "ERROR: Unable to initialize."
     exit 1
   fi

fi # end of AGENT

########################################################################

if [ $SCHEDULERONLY ]; then
   echo "*** Setting up scheduler ***"

   # scheduler config file
   # this has to be done after the database is setup
   # BTW- mkschedconf seems to be hardcoded to use localhost, if that
   # is ever fixed this code might need to be too
   echo "*** Checking Scheduler.conf ***"
   SCHEDCONF=/etc/fossology/Scheduler.conf
   if [ ! -f "$SCHEDCONF" -o "$OVERWRITE" ] ; then
      mkdir -p `dirname $SCHEDCONF`
      /usr/lib/fossology/mkschedconf -o $SCHEDCONF -L
      echo "NOTE: default $SCHEDCONF created."
      echo "  Please check that is it correct for your environment or"
      echo "  create a different one with mkschedconf."
   else
      echo "NOTE: $SCHEDCONF already exists,"
      echo "  consider checking it or recreating with mkschedconf."
   fi

   # Create the scheduler log directory.
   if [ -f /var/log/fossology ] ; then
     # Must be a directory and not a file
     rm -f /var/log/fossology
   fi
   if [ ! -d /var/log/fossology ] ; then
     mkdir -p /var/log/fossology
   fi
   chown -R fossy:fossy /var/log/fossology
   chmod 2775 /var/log/fossology
   find /var/log/fossology -type f | while read i ; do chmod 660 "$i" ; done
fi # end of SCHEDULERONLY

########################################################################

if [ $WEBONLY ]; then
   echo "*** Setting up the web interface ***"

   # See if web server user exists, if so add to the group.
   # check for www-data (Debian, etc)
   grep -q "^www-data:" /etc/passwd
   if [ $? == 0 ] ; then
     echo "NOTE: Adding user www-data to group fossy"
     # this is smart enough to not add multiple times so it's ok to repeat
     usermod -G fossy -a www-data
   fi
   # check for apache (RHEL/CentOS, etc)
   grep -q "^apache:" /etc/passwd
   if [ $? == 0 ] ; then
     echo "NOTE: Adding user apache to group fossy"
     # this is smart enough to not add multiple times so it's ok to repeat
     usermod -G fossy -a apache
   fi

fi # end of WEBONLY

########################################################################

echo "FOSSology postinstall complete, but sure to complete the remaining"
echo "  steps in the INSTALL instructions."
