Mercurial > trustbridge
view packaging/linux-installer.inc.in @ 1070:f110a3f6e387
(issue114) Fine tune ACL propagation
using mkdir_p the ACL of the parent directories would
propagate to all subdirectories and objects in the directory.
Now we only use ACL propagation in the last directory to make
sure that files we might create in that directory inherit the
correct (resitricted) ACL
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Wed, 10 Sep 2014 16:41:36 +0200 |
parents | 709a7633a2c6 |
children | 7e1fd6d96714 |
line wrap: on
line source
#!/bin/bash # Um TrustBridge zu installieren: # 1. Prüfen Sie ob Sie dieser Datei genügend vertrauen, um ihr die Kontrolle # über diesen Rechner zu übergeben. Beispielsweise durch Vergleich mit # einer starken Prüfsumme aus einer zweiten, unabhängigen Quelle. # 2. Öffnen Sie eine Kommandozeile, z.B. klicken Sie auf das "Terminal"-Symbol. # 3. Wechseln Sie in das Verzeichnis, in welchem diese Datei gespeichert ist. # Geben Sie Z.B. in die Kommandozeile ein: cd ~/Schreibtisch # 4. Starten Sie die Anwendung auf der Kommandozeile, beispielsweise # als Installation nur für den aktuellen Nutzer, indem Sie eingeben: # bash TrustBridge-1.0.0-i386.sh # Tipp: Die Tab-Taste nach dem "Tr" ergänzt oft den ganzen Namen. # # NB: Wir konnten kein übliches .deb Paket verwenden, da wir Ihnen # auch die Installation als reiner Nutzer ohne Admin-Rechte ermöglichen. # # To install TrustBridge: # 1. Verify that you trust this specific file far enough, that you are willing # to hand over the control of your computer to it. For example compare # a strong checksum of the file to one from a second, independent source. # 2. Open a command line, e.g. click on the "Terminal"-Symbol. # 3. Change your working directory to where this file is stored. # For example type "cd ~/Desktop" on your command line. # 4. Start the installation on the command line, e.g. for the current user # only by typing something like "bash TrustBridge-1.0.0-i386.sh". # Hint: If you press the tab-key after "Tr" it may complete the filename. # # N.B. We could not have used a .deb package, because the installation must # also work without without adminstrator priviledges. # # # Search the file for 'version()' to find the license information. 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 UPDATE=0 SHOWAFTERUPDATE=0 BINNAMES="###BINNAMES###" ICONNAME="###ICONNAME###" HELPNAMES="###HELPNAMES###" HELPNAMES_SOURCES="###HELPNAMES_SOURCES###" HELPNAMES_STATIC="###HELPNAMES_STATIC###" HELPNAMES_IMG="###HELPNAMES_IMG###" ARCH="###ARCH###" 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 file is Free Software under the GNU GPL (v>=2) and comes with ABSOLUTELY NO WARRANTY! See LICENSE.txt for details. 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,update,show-after-update,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 ;; --update) UPDATE=1 shift 1 ;; --show-after-update) SHOWAFTERUPDATE=1 shift 1 ;; --help) usage 0 ;; --version) version ;; --) shift break ;; esac done } init_vars() { if [ -n "${SUDO_USER-}" ] ; then # Default to system wide installation when running with sudo SYSINST=1 fi 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" startmenu_path="/usr/share/applications" else inst_default_prefix="$DEFAULT_PREFIX" instcfg_path="${CFGPATH}" instdata_path="${DATAPATH}" autostart_path=${XDG_CONFIG_HOME:-~/.config/autostart} startmenu_path=${XDG_DATA_HOME:-~/.local/share/applications} if [ $DEINSTALL -eq 1 ] ; then if [ ! -r ${instcfg_path}/${INSTCFGNAME} ]; then if [ -r ${SYSCFGPATH}/${INSTCFGNAME} ]; then # Fall back to system uninstallation if no user config found SYSINST=1 init_vars check_priv fi fi fi fi instcfg_file="${instcfg_path}/${INSTCFGNAME}" extra_bin_path=`mktemp --tmpdir -d tmpbin.XXXXXXXXXX` HOST_ARCH=$(uname -m) } finished() { echo echo "#################################################################################" if [ $SYSINST -eq 1 ]; then getxt "System wide installation successful.\n" else getxt "Single user installation successful.\n" fi getxt "TrustBridge has been installed to: '%s'\n\n" "${instcfg[PREFIX]}" if [ $SYSINST -eq 1 ]; then getxt "If you do not want to change the certificates of other users\n" getxt "uninstall it with:\n" echo " 'sudo $0 -d'" getxt "And install it again without sudo:\n" echo " $0" RUNCMD="su -l $SUDO_USER -c " else getxt "If you want to change the certificates of all users\n" getxt "uninstall it with:\n" echo " '$0 -d'" getxt "And install it again using sudo:\n" echo " sudo $0" RUNCMD="" fi echo "#################################################################################" getxt "Press enter to launch '%s'\n" "${instcfg[PREFIX]}/bin/trustbridge" if [ $UPDATE -eq 0 ]; then read $RUNCMD "${instcfg[PREFIX]}/bin/trustbridge" & else if [ $SHOWAFTERUPDATE -eq 0 ]; then $RUNCMD "${instcfg[PREFIX]}/bin/trustbridge" --tray & else $RUNCMD "${instcfg[PREFIX]}/bin/trustbridge" & fi fi } cleanup() { getxt "Cleaning up temporary stuff ...\n" # remove temporary directories, # $lock_dir is generate by the shar if [ -z "${lock_dir-}" ]; then exit fi for dir in "${instcfg[PREFIX]}/$lock_dir" "$extra_bin_path" ; do [ -d "$dir" ] && rm -rf "$dir" done } 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 or deinstallation 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" update-desktop-database 2>&1 || true getxt "Removing TrustBridge from start menu\n" rm_files "${startmenu_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" # images deinstdir="${oldinstcfg[PREFIX]}/share/doc/trustbridge/_images" for file in $HELPNAMES_IMG; do local path="${deinstdir}/$file" if [ -f "$path" ]; then getxt "Deleting '%s' ...\n" "$path" rm "$path" || getxt >&2 "WARNING: Could not delete: '%s'!\n" "$path" fi done rm_empty_dirs "$deinstdir" # Javascript sources deinstdir="${oldinstcfg[PREFIX]}/share/doc/trustbridge/_sources" for file in $HELPNAMES_SOURCES; do local path="${deinstdir}/$file" if [ -f "$path" ]; then getxt "Deleting '%s' ...\n" "$path" rm "$path" || getxt >&2 "WARNING: Could not delete: '%s'!\n" "$path" fi done rm_empty_dirs "$deinstdir" # Static files deinstdir="${oldinstcfg[PREFIX]}/share/doc/trustbridge/_static" for file in $HELPNAMES_STATIC; do local path="${deinstdir}/$file" if [ -f "$path" ]; then getxt "Deleting '%s' ...\n" "$path" rm "$path" || getxt >&2 "WARNING: Could not delete: '%s'!\n" "$path" fi done rm_empty_dirs "$deinstdir" # The actual html deinstdir="${oldinstcfg[PREFIX]}/share/doc/trustbridge" for file in $HELPNAMES; do local path="${deinstdir}/$file" if [ -f "$path" ]; then getxt "Deleting '%s' ...\n" "$path" rm "$path" || getxt >&2 "WARNING: Could not delete: '%s'!\n" "$path" fi done rm_empty_dirs "$deinstdir" deinstdir="${oldinstcfg[PREFIX]}/share/pixmaps/trustbridge" getxt "Deinstalling from '%s'.\n" "${oldinstcfg[PREFIX]}" for file in $ICONNAME; do local path="${deinstdir}/$file" getxt "Deleting '%s' ...\n" "$path" rm "$path" || getxt >&2 "WARNING: Could not delete: '%s'!\n" "$path" done deinstdir="${oldinstcfg[PREFIX]}/share/pixmaps/trustbridge" rm_empty_dirs "$deinstdir" deinstdir="${oldinstcfg[PREFIX]}/share/pixmaps" rm_empty_dirs "$deinstdir" deinstdir="${oldinstcfg[PREFIX]}/share" 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" } write_startmenu() { cat > "$1" << EOF [Desktop Entry] Type=Application Name=TrustBridge Comment=Install and update trusted root certificates Comment[de]=Vertrauenswürdige Wurzelzertifikate installieren und aktualisieren Exec=${instcfg[PREFIX]}/bin/trustbridge Icon=${instcfg[PREFIX]}/share/pixmaps/trustbridge/trustbridge.png Terminal=false Categories=Network;Qt; StartupNotify=false EOF } setup_startmenu() { # Supported desktop environments: Unity, GNOME, XFCE, LXDE, KDE # System wide installation with a nonstandard XDG_DATA_HOME is not # respected with regards to autostart. if [ ! -d "${startmenu_path}" ]; then install -d "${startmenu_path}" || \ fatal "Failed to create startmenu directory: '%s'\n" "$startmenu_path" fi write_startmenu "${startmenu_path}/trustbridge.desktop" update-desktop-database 2>&1 || true } 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" } provide_uudecode_maybe() { # The shar needs uudecode, which might not be installed. If its not # available we will provide our own python based implementation. if which uudecode >/dev/null 2>&1 ; then getxt "Found system uudecode.\n" else local myuudecode="$extra_bin_path/uudecode" cat >"$myuudecode" <<EOF #!/usr/bin/python2 import os import sys import uu os.path.chmod = os.chmod def rm_if_exists(file): try: os.remove(file) except OSError: pass os.path.exists = rm_if_exists if len(sys.argv) > 1: f = open(sys.argv[1], 'r') else: f = sys.stdin uu.decode(f, None, None, 1) EOF chmod 755 "$myuudecode" PATH="${extra_bin_path}:$PATH" getxt "Using python uudecode provided by installer.\n" fi } #====================================================================== # main() trap cleanup EXIT parse_args "$@" check_priv init_vars read_oldinstcfg cat <<EOF ------------------------------------------------------------------------ TrustBridge - Installer Version ${instcfg[VERSION]} - ${ARCH} (Testversion) ------------------------------------------------------------------------ EOF if [ "$ARCH" == "x86_64" -a "$ARCH" != "$HOST_ARCH" ]; then getxt "It appears your system architecture is %s.\n" "$HOST_ARCH" getxt "This installer is for 64 bit systems.\n" getxt "Really install TrustBridge for '%s' systems? [y/n]\n" "${ARCH}" yorn || exit 0 fi if [ "$ARCH" == "i386" ]; then if [[ "$HOST_ARCH" != *86 ]]; then getxt "It appears your system architecture is %s.\n" "$HOST_ARCH" getxt "This installer is for 32 bit systems.\n" getxt "Really install TrustBridge for '%s' systems? [y/n]\n" "${ARCH}" yorn || exit 0 fi fi 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 "checking for uudecode ...\n" provide_uudecode_maybe 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 "Setting up start menu entries ...\n" setup_startmenu getxt "Writing installation configuration to: %s ...\n" "$instcfg_file" write_instcfg finished # cleanup # is called implicitly at exit via trap... exit 0