view packaging/linux-installer.inc.in @ 859:df6f3b1cc41c

(issue53) Uninstall list-installed if requested.
author Andre Heinecke <andre.heinecke@intevation.de>
date Mon, 04 Aug 2014 17:56:42 +0200
parents 4dfb6f543a05
children 3f23130b16b2
line wrap: on
line source
#!/bin/bash
set -u

ME=`basename "$0"`
DEFAULT_PREFIX="$HOME/TrustBridge"
SYSDEFAULT_PREFIX="/usr/local"
CFGPATH="${XDG_CONFIG_HOME:-$HOME/.config}/BSI"
DATAPATH="${XDG_DATA_HOME:-$HOME/.local/share}/BSI/TrustBridge"
SYSCFGPATH="/etc/TrustBridge"
# FIXME:
# Set the real data path for system wide installation once its known.
SYSDATAPATH="$DATAPATH"
INSTCFGNAME="TrustBridge-inst.cfg"
FORCE=0
SYSINST=0
DEINSTALL=0
BINNAMES="###BINNAMES###"

declare -A instcfg oldinstcfg
declare inst_default_prefix instdata_path instcfg_path instcfg_file
instcfg=(
  [TIMESTMP]=`date -u +%Y%m%d%H%M%S`
  [VERSION]='@PROJECT_VERSION@'
  [PREFIX]=''
)
oldinstcfg=(
  [TIMESTMP]=''
  [VERSION]=''
  [PREFIX]=''
)

declare -A L10N_DE
###L10N_DE###

getxt()
{
  # Poor mans gettext for l10n completely self contained in one shell
  # script.
  MSGID="$1"
  shift
  case ${LANGUAGE:-${LC_ALL:-${LC_MESSAGES:-$LANG}}} in
    de*)
      if [ "${L10N_DE[$MSGID]}" ] ; then
          MSG="${L10N_DE[$MSGID]}"
      else
        MSG="$MSGID"
      fi
      ;;
    *)
      MSG="$MSGID"
      ;;
  esac

  printf "$MSG" "$@"
}

version()
{
  cat <<EOF
TrustBridge ${instcfg[VERSION]} Installer

Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik
Software engineering by Intevation GmbH

This is free software.  You may redistribute copies of it under the terms of
the GNU GPL (v>=2).   See LICENSE.txt for details.
There is NO WARRANTY, to the extent permitted by law.
EOF
  exit 0
}

fatal()
{
  getxt "$1" >&2
  if [ $DEINSTALL -eq 1 ] ; then
      getxt "Deinstallation failed.\n" >&2
  else
    getxt "Installation failed.\n" >&2
  fi
  exit 1
}

usage()
{
  getxt "Usage: %s [OPTION]...\n" "$ME"
  getxt "Install TrustBridge.\n\n"
  getxt "Options:\n"
  getxt "  -p, --prefix=PATH  install files in PATH\n"
  getxt "  -f, --force        install to given prefix, even when a current\n"
  getxt "                     installation with different prefix exists.\n"
  getxt "  -d, --deinstall    deinstall files from current installation\n"
  getxt "  -s, --system       create a system wide (de)installation\n"
  getxt "      --help         display this help and exit\n"
  getxt "      --version      output version information and exit\n"
  exit $1
}

yorn()
{
  local c
  while true ; do
    read -n 1 c
    echo
    case "$c" in
      y|Y|j|J)
        return 0
        ;;
      n|N)
        return 1
        ;;
      *)
        getxt >&2 "Answer [Y]es or [N]o:\n"
    esac
  done
}

parse_args()
{
  OPTS=`getopt \
      -l deinstall,force,help,prefix:,system,version \
      -o d,f,p:,s -n "$ME" -- "$@"`
  [ $? -eq 0 ] || usage 23

  eval set -- "$OPTS"

  while true ; do
    case "$1" in
      --prefix|-p)
        instcfg[PREFIX]="$2"
        shift 2
        ;;
      --system|-s)
        SYSINST=1
        shift 1
        ;;
      --force|-f)
        FORCE=1
        shift 1
        ;;
      --deinstall|-d)
        DEINSTALL=1
        shift 1
        ;;
      --help)
        usage 0
        ;;
      --version)
        version
        ;;
      --)
        shift
        break
        ;;
    esac
  done
}

init_vars()
{
  if [ $SYSINST -eq 1 ] ; then
      inst_default_prefix="$SYSDEFAULT_PREFIX"
      instcfg_path="${SYSCFGPATH}"
      instdata_path="${SYSDATAPATH}"
      autostart_path="$(getent passwd "${SUDO_USER}" | cut -d ':' -f 6)/.config/autostart"
  else
    inst_default_prefix="$DEFAULT_PREFIX"
    instcfg_path="${CFGPATH}"
    instdata_path="${DATAPATH}"
    autostart_path=${XDG_CONFIG_HOME:-~/.config/autostart}
  fi
    instcfg_file="${instcfg_path}/${INSTCFGNAME}"
}

write_instcfg()
{
  install -d `dirname "$instcfg_file"`
  echo "# Created by TrustBridge-Installer, don't touch!" >"$instcfg_file"
  for key in "${!instcfg[@]}" ; do
    echo "${key}=${instcfg[$key]}" >>"$instcfg_file"
  done
}

read_oldinstcfg()
{
  if [ -r "$instcfg_file" ] ; then
      getxt "Reading '%s' ...\n" "$instcfg_file"
      for key in "${!oldinstcfg[@]}" ; do
        oldinstcfg[$key]=`sed -n "/$key/s/[^=]*=\(.*\)/\1/p" "$instcfg_file"`
      done
  fi
}

check_priv()
{
  if [ $SYSINST -eq 1 -a "$UID" -ne 0 ] ; then
      fatal "System wide installation requires root privileges!\n"
  fi
}

rm_empty_dirs()
{
  # Args: $1 - DIRECTORY
  #
  # Recursively remove DIRECTORY and all it _parent_ directories as
  # long as they are empty.
  local directory="$1"
  while [ -d "$directory" -a -z "$(ls 2>/dev/null -A "$directory")" ] ; do
    getxt "Deleting empty directory '%s' ...\n" "$directory"
    rmdir "$directory"
    directory=`dirname "$directory"`
  done
}

rm_files()
{
  for file in "$@" ; do
    if [ -e "$file" ] ; then
        getxt "Deleting '%s' ...\n" "$file"
        rm "$file"
    fi
  done
}

setup_cronjob()
{
  local tmpcrontab=`mktemp`

  if [ $SYSINST -eq 1 -a "${SUDO_USER+X}" ] ; then
      local crontabopt="-u $SUDO_USER"
  else
      local crontabopt=''
  fi

  if [ "$1" != "deinstall" ] ; then
      local trustbridge_tray_starter="${instcfg[PREFIX]}/bin/trustbridge-tray-starter.sh"
  else
    local trustbridge_tray_starter="${oldinstcfg[PREFIX]}/bin/trustbridge-tray-starter.sh"
  fi

  crontab $crontabopt -l | \
      grep -vF "$trustbridge_tray_starter" \
           >"$tmpcrontab"
  if [ "$1" != "deinstall" ] ; then
      echo "$(( $RANDOM / 555 )) 12  * * * \"$trustbridge_tray_starter\"" \
           >>"$tmpcrontab"
  fi
  crontab $crontabopt "$tmpcrontab"
  rm "$tmpcrontab"
}

remove_cronjob()
{
  setup_cronjob deinstall
}

deinstall_certs()
{
  local cinst="${oldinstcfg[PREFIX]}/bin/cinst"
  local certlist=`ls 2>/dev/null -1  ${instdata_path}/list-installed.txt`

  getxt "Uninstalling certificates ...\n"

  if [ "$certlist" ] ; then
      getxt "Using certificate list '%s'.\n" "$certlist"
      if [ -x "$cinst" ] ; then
          "$cinst" "list=$certlist" "choices=uninstall"
      else
        getxt >&2 "WARNING: can't execute %s for certificate deinstallation.\n" "$cinst"
      fi
  else
    getxt "No certificate list found.  Nothing to do.\n"
  fi
}

deinstall_etc()
{
  getxt "Removing cron job ...\n"
  remove_cronjob

  # FIXME: delete all files created by the application.
  local tbcfg_files=( "${instcfg_path}/TrustBridge.ini"
                      "${instcfg_path}/trustbridge-tray-starter.cfg"
                      "$instcfg_file" )

  getxt "Removing certificate lists from: %s:\n" "$instdata_path"
  rm_files "$instdata_path"/list-*.txt

  getxt "Removing PID file from: %s:\n" "$instdata_path"
  rm_files "$instdata_path"/*.pid
  rm_empty_dirs "$instdata_path"

  getxt "Removing configuration files:\n"
  rm_files "${tbcfg_files[@]}"
  rm_empty_dirs "$instcfg_path"

  getxt "Removing TrustBridge from autostart\n"
  rm_files "${autostart_path}/trustbridge.desktop"
}

deinstall()
{
  if [ "${oldinstcfg[PREFIX]}" ] ; then
      getxt "Really deinstall TrustBridge from '%s'? [y/n]\n" "${oldinstcfg[PREFIX]}"
      yorn || exit 0
      deinstall_certs
      local deinstdir="${oldinstcfg[PREFIX]}/bin"
      getxt "Deinstalling from '%s'.\n" "${oldinstcfg[PREFIX]}"
      for file in $BINNAMES ; do
        local path="${deinstdir}/$file"
        getxt "Deleting '%s' ...\n" "$path"
        rm "$path" || getxt >&2 "WARNING: Could not delete: '%s'!\n" "$path"
      done
      rm_empty_dirs "$deinstdir"
      deinstall_etc
      getxt "Deinstallation finished.\n"
  else
    getxt "No current installation found!  No harm done.\n"
  fi
}

write_autostart()
{
  cat > "$1" << EOF
[Desktop Entry]
Type=Application
Name=TrustBridge
Exec="${instcfg[PREFIX]}/bin/trustbridge" --tray
EOF
  chown "${SUDO_USER:-${USER}}" "$1"
  chmod 700 "$1"
}

setup_autostart()
{
  # Supported desktop environments: Unity, GNOME, XFCE, LXDE, KDE
  # System wide installation with a nonstandard XDG_CONFIG_HOME or KDEHOME is not
  # respected with regards to autostart.
  if [ ! -d "${autostart_path}" ]; then
    install -d "${autostart_path}" || \
      fatal "Failed to create autostart directory: '%s'\n" "$autostart_path"
  fi

  write_autostart "${autostart_path}/trustbridge.desktop"
}

#======================================================================
# main()

parse_args "$@"
init_vars
check_priv
read_oldinstcfg

cat <<EOF
------------------------------------------------------------------------

   TrustBridge - Installer
   Version ${instcfg[VERSION]}

------------------------------------------------------------------------
EOF

if [ $DEINSTALL -eq 1 ] ; then
    deinstall
    # Stop after deinstallation:
    exit 0
fi

if [ -z "${instcfg[PREFIX]}" ] ; then

    if [ "${oldinstcfg[PREFIX]}" ] ; then
        inst_default_prefix="${oldinstcfg[PREFIX]}"
        getxt "An existing installation (v%s) was detected!\n" "${oldinstcfg[VERSION]}"
        getxt "It is HIGHLY RECOMMENDED to accept the default prefix\n"
        getxt "to update the current installation.\n"
        getxt "For a new prefix you should deinstall first!\n"
    fi
    getxt "Select installation prefix for TrustBridge [%s]: " "${inst_default_prefix}"
    read -e instcfg[PREFIX]

    [ -z "${instcfg[PREFIX]}" ] && instcfg[PREFIX]="${inst_default_prefix}"
else
  # Prefix was given on invocation:
  if [ "${oldinstcfg[PREFIX]}" -a \
       "${instcfg[PREFIX]}" != "${oldinstcfg[PREFIX]}" -a \
       $FORCE -ne 1 ] ; then
      fatal "Prefix differs from current installation (%s).  Aborting!\n" "${oldinstcfg[PREFIX]}"
  fi
fi

getxt "Installing to '%s':\n" "${instcfg[PREFIX]}"

if [ ! -d "${instcfg[PREFIX]}" ] ; then
    getxt "creating installation directory ...\n"
    install -d "${instcfg[PREFIX]}" || fatal "Could not create '%s'!\n" "${instcfg[PREFIX]}"
fi

getxt "unpacking files ...\n"
cd "${instcfg[PREFIX]}"

set +u
set -- '-c'
# ----------------------------------------------------------------------
# regular shar archive inserted here:
###SHAR###
# ----------------------------------------------------------------------

getxt "Preparing trustbridge-tray-starter ...\n"
sed -i "/^PREFIX=/c\PREFIX='${instcfg[PREFIX]}'" \
    "${instcfg[PREFIX]}/bin/trustbridge-tray-starter.sh"

getxt "Setting up cronjob ...\n"
setup_cronjob

getxt "Setting up autostart ...\n"
setup_autostart

getxt "Writing installation configuration to: %s ...\n" "$instcfg_file"
write_instcfg
exit 0

http://wald.intevation.org/projects/trustbridge/