Da es zur Installation einer Software meist nicht ausreicht, die Dateien an die richtige Stelle zu kopieren, sondern normalerweise zusätzlich gewisse aktionen ausgeführt werden müssen, gibt es auf eisfair die Installationsskripte preinstall.sh und install.sh.
Beide Skripte sind optional, müssen also nicht zwingend in jedem Paket enthalten sein.
Bei der Paketinstallation wird nach dem Download des Pakets als erstes - falls vorhanden - das Skript tmp/preinstall.sh aus dem archiv extrahiert und ausgeführt.
In diesem Skript wird üblicherweise als erster Schritt eine überprüfung der installierten Base-Version durchgeführt. auf <require-package> darf man sich hier nicht verlassen, da dieses Tag erst mit Base Version 1.0.3, und die Variante über Paketnamen erst seit Base Version 1.0.8 eingeführt wurde.
Beispiel für die Prüfung der eisfair -Version in preinstall.sh:
required_base='1.6.3'
### check base version
if [ ! -f /var/install/bin/check-version ] ||
[ `/var/install/bin/check-version base $required_base` = 'new' ]
then
echo
echo
colecho "Wrong eisfair version!" rd w brinv
colecho "Version must be $required_base or higher." rd w brinv
colecho "Please update your eisfair system first." rd w brinv
echo
echo
exit 1
fi
Dies ist auch die einzige Stelle, an der echo/colecho noch erlaubt ist. Die Verwendung von mecho ist hier nicht möglich, da ja gerade auf eine installierte base-Version geprüft wird und es beispielsweise bei eisfair Version 1.0.3 noch kein mecho gab.
Wie in diesem Beispiel ersichtlich kann die Installation im Fehlerfall über einen Rückgabewert ungleich Null abgebrochen werden.
Neben dieser Prüfung von Installationsvoraussetzungen können in diesem Skript Vorbereitungen zur Installation getroffen werden, beispielsweise die Deinstallation der vorhergehenden Version eines Pakets.
Beispiel für die Deinstallation einer alten Paketversion in preinstall.sh:
package='foo'
### deinstall old package version
if [ -f "/var/install/deinstall/${package}" ]
then
/var/install/deinstall/${package} update
fi
Ab der eisfair Version 1.7.1 können Pakete bei einem update auch über die Standardfunktionen, messages, Meldungen schreiben, dafür ist eine Anpassung für die Deinstallation notwendig. Auch sollte der Parameter update mit '--' 2 Zeichen beginnen, --update. Vorsicht bitte bei Paketen, die im Deinstall Skript noch 'update' stehen haben
Beispiel für die Deinstallation einer alten Paketversion in preinstall.sh:
package='foo'
### deinstall old package version
if [ -f "/var/install/deinstall/${package}" ]
then
/var/install/deinstall/del-package -p ${package} --update
fi
achtung: Bei der ausführung der preinstall.sh sind die Dateien des Pakets noch nicht installiert. auf Paketbestandteile kann daher nicht zugegriffen werden!
Sofern das Preinstall-Skript nicht mit einem Fehler abgebrochen hat, wird als nächster Schritt das komplette Tar-archiv entpackt, und zwar immer vom Root-Verzeichnis ,,/`` ausgehend, so dass alle Dateien im richtigen Verzeichnis landen.
Danach wird - falls vorhanden - das Skript /tmp/install.sh ausgeführt. Dieses Skript dient zur Installation des Pakets, also z.B. zur Erstellung von notwendigen symbolischen Links, zum Einfügen von Menüeinträgen oder zur übernahme der Konfiguration einer alten Paketversion.
Beispiel für die Installation eines eisfair-Pakets:
#!/bin/sh
# -----------------------------------------------------------------------
# /tmp/install.sh - foo installation
#
# Creation : 2009-12-31 starwarsfan
# Last update: $Id: foo 22527 2010-01-02 16:51:38Z starwarsfan $
#
# Copyright (c) 2001-2011 the eisfair team, <team(at)eisfair(dot)org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# -----------------------------------------------------------------------
# include eislib
. /var/install/include/eislib
# set package name
packageName=foo
# -----------------------------------------------------------------------
# Setup step 1
# -----------------------------------------------------------------------
# -----------------------------------------------------------------------
# add menu
# -----------------------------------------------------------------------
/var/install/bin/add-menu \
setup.services.menu \
setup.services.${packageName}.menu \
"${packageName}"
# -----------------------------------------------------------------------
# Create default config
# -----------------------------------------------------------------------
if [ -f "/etc/config.d/${packageName}" ]
then
mecho --info -n "Updating configuration ."
update=true
else
mecho --info -n "Creating configuration ."
update=false
fi
/var/install/config.d/${packageName}-update.sh &
while [ -n "`ps --no-headers $!`" ]
do
mecho --info -n "."
sleep 1
done
echo
# -----------------------------------------------------------------------
# Start configuration editor if necessary
# -----------------------------------------------------------------------
. /etc/config.d/${packageName}
if [ "${START_FOO}" = 'no' ]
then
/var/install/bin/edit \
-apply ${packageName} "Edit ${packageName} configuration"
else
/var/install/config.d/${packageName}.sh --quiet
fi
exit 0
# -----------------------------------------------------------------------
# End
# -----------------------------------------------------------------------
Beim Update eines Pakets gibt es mehrere Dinge zu beachten. Besonders ist zu Berücksichtigen, dass das Upgrade oftmals nicht von der letzten Version erfolgt, sondern dass ein Update auch von einer sehr viel älteren Version erfolgen kann.
In jedem Fall müssen beim Update die obsoleten Dateien der Vorversion entfernt werden. Zudem ist es für eisfair -Pakete verpfichtend, dass die Konfiguration der Vorversion übernommen wird. Dabei müssen auch eventülle änderungen der Konfiguration (z.B. Hinzufügen neür Variablen) durchgeführt werden.
Für das Entfernen der Vorversion hat sich die Verwendung des Deinstall-Skripts der alten Version bewährt. Da bei einem Update nicht alle Dateien gelöscht werden dürfen (z.B. die Konfiguration), muss das Deinstall-Skript einen Update-Modus kennen, d.h. es werden nicht alle Dateien gelöscht, wenn der Parameter ,,update`` übergeben wird. Ein Beispiel dazu ist im Deinstall-Script unter ,,Deinstallieren von Paketen`` zu finden.
Bei der übernahme der Konfiguration gibt es mehrere Fälle. Im einfachsten Fall handelt es sich gar nicht um ein Update des Pakets sondern um eine Neuinstallation und es ist die Default-Konfiguration aus /etc/default.d/ zu übernehmen.
Sofern bereits eine Konfiguration einer Vorversion unter /etc/config.d/ vorhanden ist, dient diese als Basis zur Erstellung der Konfiguration. Dabei müssen:
Für diese übernahme der Konfiguration muss daher ein eigenes Skript erstellt werden, das üblicherweise /var/install/config.d/$package-update.sh genannt wird.
Beispiel für ein Skript zur übernahme der Konfiguration eines eisfair -Pakets:
#!/bin/sh
# -----------------------------------------------------------------------
# /var/install/config.d/foo-update.sh - paramater update script
#
# Creation : 2009-12-31 starwarsfan
# Last update: $Id: foo-update.sh 2342 2010-01-02 16:51:38Z starwarsfan $
#
# Copyright (c) 2001-2011 the eisfair team, <team(at)eisfair(dot)org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# -----------------------------------------------------------------------
#exec 2> `pwd`/foo-update-trace$$.log
#set -x
# include configlib for using printvar
. /var/install/include/configlib
# set packages name
packageName=foo
# -----------------------------------------------------------------------
# Set the default val"us for configuration
# -----------------------------------------------------------------------
START_FOO='no'
# -----------------------------------------------------------------------
# Read old configuration and rename old variables
# -----------------------------------------------------------------------
renameOldVariables()
{
# read old values
if [ -f /etc/config.d/${packageName} ]
then
/var/install/bin/backup-file --quiet ${packageName}
. /etc/config.d/${packageName}
fi
}
# -----------------------------------------------------------------------
# Write config and default files
# -----------------------------------------------------------------------
makeConfigFile()
{
internal_conf_file=${1}
{
# -------------------------------------------------------------------
printgpl --conf ${packageName} "2009-12-31" "starwarsfan"
# -------------------------------------------------------------------
# -------------------------------------------------------------------
printgroup "Basic configuration"
# -------------------------------------------------------------------
printvar "START_FOO" "Use: yes or no"
# -------------------------------------------------------------------
printend
# -------------------------------------------------------------------
} > ${internal_conf_file}
# Set rights
chmod 0600 ${internal_conf_file}
chown root ${internal_conf_file}
}
# -----------------------------------------------------------------------
# Create the check.d file
# -----------------------------------------------------------------------
makeCheckFile()
{
printgpl --check ${packageName} '2009-12-31' 'starwarsfan' \
>/etc/check.d/${packageName}
cat >> /etc/check.d/${packageName} <<EOFG
# Variable OPT_VARIABLE VARIABLE_N VALUE
START_FOO - - YESNO
EOFG
# Set rights for check.d file
chmod 0600 /etc/check.d/${packageName}
chown root /etc/check.d/${packageName}
# printgpl --check_exp ${packageName} '2009-12-31' 'starwarsfan' \
# >/etc/check.d/${packageName}.exp
# cat >> /etc/check.d/${packageName}.exp <<EOFG
#
#
#EOFG
# Set rights for check.exp file
# chmod 0600 /etc/check.d/${packageName}.exp
# chown root /etc/check.d/${packageName}.exp
# printgpl -check_ext ${packageName} '2009-12-31' 'starwarsfan' \
# >/etc/check.d/${packageName}.ext
# cat >> /etc/check.d/${packageName}.ext <<EOFG
#
#
#EOFG
# Set rights for check.ext file
# chmod 0600 /etc/check.d/${packageName}.ext
# chown root /etc/check.d/${packageName}.ext
}
# -----------------------------------------------------------------------
# Main
# -----------------------------------------------------------------------
# Write default config file
makeConfigFile /etc/default.d/${packageName}
# Update from old version
renameOldVariables
# Write new config file
makeConfigFile /etc/config.d/${packageName}
# Write check.d file
makeCheckFile
exit 0
# -----------------------------------------------------------------------
# End
# -----------------------------------------------------------------------
Je nach Anwendungsfall muss dieses Script natürlich noch um die Behandlung weiterer Fälle wie ,,Löschen von Variablen``, ,,Umbenennen von Variablen`` oder ähnlichem erweitert werden.
Es ist zu beachten, das bei array Variablen der erste Eintrag vorhanden sein muss, auch wenn das gesamte array nicht verwendet wird. Dies ist besonders bei Nutzung von joe oder vi an Stelle des ece als Editor relevant.
Nach dem Neuschreiben der Konfiguration muss diese noch auf Gültigkeit geprüft und der Dienst neu gestartet werden. Das kann mit einem direkten Aufruf des Edit-Skripts geschehen und gibt dem Anwender gleich die Möglichkeit, die veränderte Konfiguration zu überarbeiten.
Bei Verwendung dieses Beispiels werden die Dateien unter
/etc/default.d und /etc/check.d nicht mit ausgeliefert,
da diese beim Verarbeiten des $package-update.sh erzeugt
werden.
Gleichzeitig wird bei den check Dateien mit 'Here-Documents' gearbeitet.
#!/bin/sh
# -----------------------------------------------------------------------
# /var/install/config.d/eisfax-update.sh - parameter update script
#
# Creation: 2005-05-29 jv
# Last Update: 2006-06-11 hb
#
# Copyright (c) 2001-2011 the eisfair team, team(at)eisfair(dot)org
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# -----------------------------------------------------------------------
#exec 2>/public/eisfax-update-trace$$.log
#set -x
package_name=eisfax
# include configlib for using printvar
. /var/install/include/configlib
. /var/lib/eisfax/eisfax.info
### ---------------------------------------------------------------------
### Set the default values for configuration
### ---------------------------------------------------------------------
START_EISFAX='no'
EISFAX_COUNTRY_CODE='49'
EISFAX_AREAa_CODE='40'
EISFAX_LONG_DISTANCE_PREFIX='0'
EISFAX_INTERNATIONAL_PREFIX='00'
EISFAX_MAX_DIALS='6'
EISFAX_ADMIN_USER_FAX_PASSWD=''
EISFAX_SAMBA_PRINTER_AUTO='yes'
EISFAX_ANALOG_USE='no'
EISFAX_ANALOG_N='1'
EISFAX_ANALOG_1_NaME=''
EISFAX_ANALOG_1_ACTIVE='no'
EISFAX_ANALOG_1_DEVICE='ttyS0'
EISFAX_ANALOG_1_FAaX_PRINTER_NAME='EISFAX'
EISFAX_ANALOG_1_CONFIGURE_AUTO='yes'
EISFAX_ANALOG_1_ID='+49.40.12345678'
EISFAX_ANALOG_1_LOCaL_IDENTIFIER='Fax-Station'
EISFAX_ANALOG_1_SERVER_NaME='EISFAX Server'
EISFAX_ANALOG_1_FAX_HEADER='von %%l %%n an %%d Seite %%P von %%T /'
EISFAX_ANALOG_1_HEAaDER_DaTE='%F %R'
EISFAX_ANALOG_1_RINGS_BEFORE_ANSWER='1'
EISFAX_ANALOG_1_SPEAKER_VOLUME='off'
EISFAX_ANALOG_1_SND='yes'
[...]
### ---------------------------------------------------------------------
### Read old configuration and rename old variables
### ---------------------------------------------------------------------
rename_old_variables()
{
# read old val"us
if [ -f /etc/config.d/${package_name} ]
then
/var/install/bin/backup-file --quiet ${package_name}
. /etc/config.d/${package_name}
fi
}
### ---------------------------------------------------------------------
### Write config and default files
### ---------------------------------------------------------------------
make_config_file()
{
internal_conf_file=${1}
{
# -------------------------------------------------------------------
printgpl --conf ${package_name} "2005-06-26" "hb"
# -------------------------------------------------------------------
# -------------------------------------------------------------------
printgroup "Basic configuration"
# -------------------------------------------------------------------
printvar "START_EISFAX" "Start EISFAX server"
printvar "EISFAX_COUNTRY_CODE" ""
printvar "EISFAX_AREA_CODE" ""
printvar "EISFAX_LONG_DISTANCE_PREFIX" ""
printvar "EISFAaX_INTERNATIONAL_PREFIX" ""
printvar "EISFAX_MAX_DIALS" "Wieviele Wahlwiederholungen"
printvar "" "ausgefuehrt werden sollen"
printvar "EISFAX_ADMIN_USER_FAX_PASSWD" "Passwd for admin-user fax"
printvar "EISFAX_SAMBA_PRINTER_AUTO" "Soll EISFAX die Samba config"
printvar "" "aufrufen: yes or no"
# -------------------------------------------------------------------
printgroup "ANALOG settings"
# -------------------------------------------------------------------
printvar "EISFAX_ANALOG_USE" "Use: yes or no"
printvar "EISFAX_ANALOG_N" "number of modems"
# begin EISFAX_ANALOG_N
idx=1
while [ "${idx}" -le "${EISFAX_ANALOG_N}" ]
do
# section marker EISFAX_ANALOG_N
if [ "${idx}" -le "${EISFAX_ANALOG_N}" ]
then
# -----------------------------------------------------------
printgroup "EISFAX_ANALOG_${idx}"
# -----------------------------------------------------------
fi
printvar "EISFAX_ANALOG_${idx}_NAME" \
"Use a name what ever you want, it's only for you"
printvar "EISFAX_ANALOG_${idx}_ACTIVE" "Use only: yes or no"
printvar "EISFAX_ANALOG_${idx}_DEVICE" "ttyS0 or ttyS1 or ttyS2"
printvar "EISFAX_ANALOG_${idx}_FaX_PRINTER_NAME" \
"Please, look at the Doku"
printvar "EISFAX_ANALOG_${idx}_CONFIGURE_AUTO" \
"Use: yes or no or scratch"
printvar "EISFAX_ANALOG_${idx}_ID"
"Your Fax-ID (+49.40.12345678)"
printvar "EISFAX_ANALOG_${idx}_LOCAL_IDENTIFIER" \
"Fax_Station name (fax header)"
printvar "EISFAX_ANALOG_${idx}_SERVER_NAME" "EISFAX Server"
printvar "EISFAX_ANALOG_${idx}_FAX_HEADER" \
"von %%l %%n an %%d Seite %%P von %%T /"
printvar "EISFAX_ANALOG_${idx}_HEADER_DATE" "%F %R"
printvar "EISFAX_ANALOG_${idx}_RINGS_BEFORE_ANSWER" "1"
printvar "EISFAX_ANALOG_${idx}_SPEAKER_VOLUME" \
"off, quiet, low, medium, high"
printvar "EISFAX_ANALOG_${idx}_SND" "Use: yes or no"
[...]
# end EISFAX_ANALG_N
idx=`${EXPR_EXEC} ${idx} + 1`
done
# -------------------------------------------------------------------
printend
# -------------------------------------------------------------------
} > ${internal_conf_file}
# Set rights
chmod 0600 ${internal_conf_file}
chown root ${internal_conf_file}
}
### ---------------------------------------------------------------------
### Create the check.d file
### ---------------------------------------------------------------------
make_check_file()
{
printgpl --check ${package_name} "2005-06-26" "jv" \
>/etc/check.d/${package_name}
cat >>/etc/check.d/${package_name} <<EOF
# Variable OPT_VARIABLE VARIABLE_N VALUE
START_EISFAX - - YESNO
EISFAX_COUNTRY_CODE START_EISFAX - EISFAX_COUNTRYC
EISFAX_AREA_CODE START_EISFAX - NONE
EISFAX_LONG_DISTANCE_PREFIX START_EISFAX - ENUMERIC
EISFAX_INTERNATIONaL_PREFIX START_EISFAX - ENUMERIC
EISFAX_MAX_DIALS START_EISFAX - NUMERIC
EISFAX_aDMIN_USER_FaX_PaSSWD START_EISFAX - NOTEMPTY
EISFAX_SAMBA_PRINTER_AUTO START_EISFAX - YESNO
EISFAX_ANALOG_USE START_EISFAX - YESNO
EISFAX_ANALOG_N EISFAX_ANALOG_USE - NUMERIC
EISFAX_ANALOG_%_NAME EISFAX_ANALOG_USE EISFAX_ANALOG_N NONE
EISFAX_ANALOG_%_ACTIVE EISFAX_ANALOG_USE EISFAX_ANALOG_N YESNO
EISFAX_ANALOG_%_DEVICE EISFAX_ANALOG_%_ACTIVE EISFAX_ANALOG_N NOTEMPTY
EISFAX_ANALOG_%_FaX_PRINTER_NAME EISFAX_ANALOG_%_ACTIVE EISFAX_ANALOG_N EISFAX_SPRINTER_ERR
EISFAX_ANALOG_%_FaX_PRINTER_NAME EISFAX_ANALOG_%_ACTIVE EISFAX_ANALOG_N WARN_EISFAX_SPRINTER_WARN
EISFAX_ANALOG_%_CONFIGURE_AUTO EISFAX_ANALOG_%_ACTIVE EISFAX_ANALOG_N EISFAX_CONFIGURE
EISFAX_ANALOG_%_ID EISFAX_ANALOG_%_ACTIVE EISFAX_ANALOG_N NOTEMPTY
EISFAX_ANALOG_%_LOCAL_IDENTIFIER EISFAX_ANALOG_%_ACTIVE EISFAX_ANALOG_N NOTEMPTY
EISFAX_ANALOG_%_SERVER_NaME EISFAX_ANALOG_%_ACTIVE EISFAX_ANALOG_N NOTEMPTY
EISFAX_ANALOG_%_FaX_HEaDER EISFAX_ANALOG_%_ACTIVE EISFAX_ANALOG_N NOTEMPTY
EISFAX_ANALOG_%_HEaDER_DaTE EISFAX_ANALOG_%_ACTIVE EISFAX_ANALOG_N NOTEMPTY
EISFAX_ANALOG_%_RINGS_BEFORE_aNSWER EISFAX_ANALOG_%_ACTIVE EISFAX_ANALOG_N NUMERIC
EISFAX_ANALOG_%_SPEAKER_VOLUME EISFAX_ANALOG_%_ACTIVE EISFAX_ANALOG_N EISFAX_SVOLUME
EISFAX_ANALOG_%_SND EISFAX_ANALOG_%_ACTIVE EISFAX_ANALOG_N YESNO
[...]
EOF
# Set rights for check.d file
chmod 0600 /etc/check.d/${package_name}
chown root /etc/check.d/${package_name}
printgpl --check_exp ${package_name} "2005-06-26" "jv" \
>/etc/check.d/${package_name}.exp
cat >>/etc/check.d/${package_name}.exp <<EOF
EISFAX_USER = '([-,_[:lower:]0-9])+'
: 'no valid user name, because only the following charctershare allowed: a-z, 0-9, ., _ and -'
EISFAX_COUNTRYC = '(RE:NUMERIC)(RE:NUMERIC)'
: 'Use numeric country code: 00 ... 99'
EISFAX_FTYPE = '()|pdf|tif|ps|png'
: 'Use only: pdf, tif, ps or png'
EISFAX_RFTYPE = 'pdf|tif|ps'
: 'Use only: pdf, tif, or ps'
EISFAX_RSEND = '()|no|faxmaster|(RE:MAILADDR)|(RE:EISFAX_USER)'
: 'Use only: no or faxmaster or e-mail address'
EISFAX_FMaSTER = 'yes|no|errors'
: 'Use only: yes, no, errors'
EISFAX_SVOLUME = 'off|quiet|low|medium|high'
: 'Use only: off, quiet, low, medium or high'
EISFAX_PQUEUE = 'pr[1-3]|repr[1-9]?[0-9]|usbpr[1-9]?[0-9]'
: 'Use only: pr1, pr2, pr3, repr1 ... repr99, usbpr1 ... usbpr99'
[...]
EOF
# Set rights for check.exp file
chmod 0600 /etc/check.d/${package_name}.exp
chown root /etc/check.d/${package_name}.exp
printgpl --check_ext ${package_name} "2005-08-31" "hb" \
>/etc/check.d/${package_name}.ext
cat >>/etc/check.d/${package_name}.ext <<EOF
if ( EISFAX_ANALOG_use == "yes" && EISFAX_isdn_use == "yes" )
then
error "Either EISFAX_ANALOG_USE _or_ EISFAX_ISDN_USE can be 'yes' "
fi
EOF
# Set rights for check.ext file
chmod 0600 /etc/check.d/${package_name}.ext
chown root /etc/check.d/${package_name}.ext
}
### ---------------------------------------------------------------------
### Main
### ---------------------------------------------------------------------
# write default config file
make_config_file /etc/default.d/${package_name}
# update from old version
rename_old_variables
# write new config file
make_config_file /etc/config.d/${package_name}
# write check.d file
make_check_file
exit 0
### ---------------------------------------------------------------------
### End
###----------------------------------------------------------------------
Zu jedem Paket gehört auch noch eine Liste der enthaltenen Dateien
und ihrer Rechte. Diese soll später u.a. zur Überprüfung der
Dateirechte dienen. Das kann besonders für Library Pakete wichtig
werden, da das Überprüfen der Anwesenheit der
Paketbeschreibungsdatei wenig über die Vollständigkeit der
installierten Bibliotheken aussagt. Auch an eine Anpassung der
Deinstallationsscripte ist in diesem Zusammenhang gedacht. Die Datei
ist wie folgt aufgebaut:
Filetype b = Bin"ar, u = Unix-Text
Rights Zugriffsrechte
User Benutzer
Group Gruppe
Package Paketname
File Datei mir relativem Verzeichnis
Beispiel:
# ----------------------------------------------------------------------- # foo-files.txt - list of all files of package 'foo' # # Creation: 2004-11-17 jv # Last update: 2006-05-30 max # ----------------------------------------------------------------------- u 0755 root root foo tmp/install.sh u 0755 root root foo tmp/preinstall.sh b 0755 root root foo usr/bin/foorun b 0644 root root foo usr/local/foo/bin/foo.so u 0644 root root foo usr/local/foo/UDF/foosql.sql u 0644 root root foo usr/share/doc/foo/changes.txt u 0644 root root foo usr/share/doc/foo/foo.txt
Die Deinstallationsroutine muss in der Datei /var/install/deinstall/$package abgelegt werden und beinhaltet sämtliche notwendigen Aktionen um ein Paket wieder sauber vom System zu entfernen.
Die gängigsten Punkte sind:
Nicht entfernt werden dürfen im allgemeinen:
Eine abweichende Entscheidung muss im Einzelfall geklärt werden.
Sofern die Deinstallationsroutine auch zum Update eines Paketes genutzt wird, muss dort eine Sonderbehandlung erfolgen.
Beispiel für ein Skript zur Übernahme der Konfiguration eines eisfair-Pakets:
#!/bin/sh
# -----------------------------------------------------------------------
# /var/install/deinstall/foo - deinstall script
#
# Creation : 2009-12-31 starwarsfan
# Last update: $Id: foo 22527 2010-01-02 16:51:38Z starwarsfan $
#
# Copyright (c) 2001-2011 the eisfair team, <team(at)eisfair(dot)org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# -----------------------------------------------------------------------
# Set package name
packageName=foo
# Set filelist
filelist=/etc/filelist.d/foo-files.txt
# Check if this is an update
if [ "${1}" = "--update" ]
then
update=true
# -------------------------------------------------------------------
# add everything to this list what should _not_ be removed during an
# update. This can be folders too, but let the bash expand their
# content using an '*' like 'foo/bar/*'. The entries listet here must
# be given on the file list of the package. all other stuff must be
# remove by hand using an additional line like 'rm /foo/bar/bla.txt'.
filesToLeave="etc/config.d/foo
etc/backup.d/foo*
etc/filelist.d/foo-files.txt
var/install/deinstall/foo
var/install/menu/setup.services.foo*"
else
filesToLeave=''
fi
# -----------------------------------------------------------------------
# Remove package content except some special files if it's an update
# instead of a deinstallation
# -----------------------------------------------------------------------
while read id perm user group package file
do
# ------------------------------------------------
# Remove file only if it is not on the ignore list
removeCurrentFile=true
for currentFileToLeave in ${filesToLeave}
do
if [ "${currentFileToLeave}" == "${file}" ]
then
removeCurrentFile=false
break
fi
done
if ${removeCurrentFile}
then
case ${id} in
b|u)
if [ "${file}" != "tmp/install.sh" -a \
"${file}" != "tmp/preinstall.sh" ]
then
rm -f /${file}
fi
;;
f)
# Remove directories
rmdir --ignore-fail-on-non-empty /${file} 2>/dev/null
;;
esac
fi
done < ${filelist}
# -----------------------------------------------------------------------
# Check files and default config must be removed separately because they
# are not on the file list if the package is used as it was created by
# create-package-new.sh, they are created dynamically during installation
# -----------------------------------------------------------------------
rm -f /etc/check.d/foo*
rm -f /etc/default.d/foo*
# -----------------------------------------------------------------------
# Stop remove for update only
# -----------------------------------------------------------------------
if ${update:-false}
then
exit 0
fi
# -----------------------------------------------------------------------
# Remove package from menu system / remove all menu and config files
# -----------------------------------------------------------------------
/var/install/bin/del-menu setup.services.menu setup.services.foo.menu
# -----------------------------------------------------------------------
# Remove config file
# -----------------------------------------------------------------------
rm -f /etc/config.d/foo
rm -f /etc/backup.d/foo*
rm -f /etc/filelist.d/foo-files.txt
# -----------------------------------------------------------------------
# Remove deinstall script
# -----------------------------------------------------------------------
rm -f /var/install/deinstall/foo
# -----------------------------------------------------------------------
exit 0
Wie bei Linux üblich werden im Rahmen des Systemstarts die einzelnen Dienste über Kontrollskripte (,,Init-Skript``) im Verzeichnis /etc/init.d/ gestartet und beim Shutdown wieder beendet.
Um diesen Mechanismus nutzen zu können, benötigt man als erstes das Init-Skript namens /etc/init.d/$package. Dieses muss mehrere Startparameter verstehen --zumindest start zum Starten des Dienstes sowie stop zum Stoppen des Dienstes. Auch sollte es den Parameter '--quiet' verstehen, damit beim Aufruf mit diesem Parameter die 'echo' Ausgaben auf die Console unterdrückt werden.
Um nun festzulegen, dass ein Dienst gestartet werden soll, und an welcher Stelle im Startprozess dies geschehen soll, muss dieses Skript unter /etc/rc2.d/Snn$package verlinkt werden.
Anstatt rc2.d können dabei je nach Runlevel die Verzeichnisse rc0.d, rc2.d, rc6.d und/oder rcS.d in Frage kommen, wobei für die meisten Serverdienste wohl nur Runlevel 2 relevant ist.
Die Startposition wird dabei numerisch direkt hinter dem S angegeben und ist oben mit nn symbolisiert. Die niedrigen Nummern werden dabei für die für den Serverbetrieb nötigen Funktionen (z.B. SCSI-Treiber, Netzwerktreiber + Einstellungen) verwendet. Bei der Auswahl der Startposition für das eigene Paket ist darauf zu achten, dass es sich harmonisch in die Startreihenfolge einfügt.
ANALOG dazu wird das selbe Skript unter /etc/rc2.d/Kmm$package verlinkt, um das Beenden des Dienstes beim Shutdown zu steuern. Hier ist darauf zu achten, dass unkritische Dienste als erstes beendet werden.
ACHTUNG
Grundsatz: Die Summe der Start- und Stopposition muss
immer 100 ergeben.
Das Skript /etc/init.d/functions stellt ab der eisfair -base 1.7.4 die Funktionen wie sie im Nachfolgenden Beispiel benutzt werden bereit.
Beispiel für ein Init-Script:
#!/bin/sh
# -----------------------------------------------------------------------
# /etc/init.d/foo - init script for foo
#
# Creation: 2005-05-12 max
# Last Update: 2005-07-20 fabian
#
# Copyright (c) 2001-2011 the eisfair team, team(at)eisfair(dot)org
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# -----------------------------------------------------------------------
# include functions
. /etc/init.d/functions
# include configuration
. /etc/config.d/foo
_do_start ()
{
if ${forcestart:-false}
then
START_FOO=yes
fi
### check if starting foo is allowed
if [ "$START_FOO" = 'yes' ]
then
boot_mesg " * Starting foo ..."
loadproc foo
fi
}
_do_stop ()
{
boot_mesg " * Stopping foo ..."
killproc foo
}
_do_status ()
{
statusproc foo
}
_do_usage ()
{
echo "Usage: $0 [-q|--quiet] {start|forcestart|stop|restart}"
{
#--------------------------------------------------------------------------
# main
#--------------------------------------------------------------------------
while [ ${#} -gt 0 ]
do
case "${1}" in
-q|--quiet)
_quiet=true
shift
;;
*)
_action=${1}
shift
;;
esac
done
case "$(_action}" in
start)
_do_start
;;
forcestart)
forcestart=true
_do_start
;;
stop)
_do_stop
;;
restart)
_do_stop
sleep 3
_do_start
;;
status)
_do_status
;;
*)
_do_usage
exit 1
;;
esac
exit 0
Im Beispiel ist neben den oben bereits erklärten Parametern start und stop der Parameter restart aufgeführt, der für die Verarbeitung einer Konfiguartionsänderung notwendig ist und im weiteren Verlauf dieser Dokumentation noch näher erklärt wird.
Hinweis
Es muss garantiert sein, dass der Dienst im init.d-Script
startbar ist, auch wenn START_FOO auf ,,no`` gesetzt ist. Dies wird
über den Parameter ,,forcestart`` gewährleistet.
Als weiteres Startskript gibt es /etc/init.d/boot.$package. Dieses Skript dient zum Aufräumen vor dem eigentlichen Starten des Dienstes und wird vor den Init-Skripten beim Systemstart ausgeführt.
Für dieses Skript ist ANALOG ein Link /etc/init.d/boot.d/Snn$package zur Festlegung der Startposition zu erstellen. auch dieses Skript wird mit dem Parameter start aufgerufen.
Hier können z.B. übriggebliebene temporäre Dateien oder auch eventuell veränderte Zugriffsrechte einer Datei oder eines Verzeichnisses korrigiert werden.
Yves Schumann 2012-02-05