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:
needed_base='1.1.1'
### check base version
if [ ! -f /var/install/bin/check-version ] ||
[ `/var/install/bin/check-version base $needed_base` = "new" ]
then
echo
echo
colecho "The version of eisfair must be $needed_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 beispielsweise bei einem eisfair Version 1.0.3 gab es noch kein mecho.
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
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 nötigen 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 - setup for foo
#
# Creation: 2005-01-25 max
# Last Update: 2005-06-09 max
#
# Copyright (c) 2001-2007 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.
#------------------------------------------------------------------------
### package definition
package='foo'
package_name='foo server'
package_pos=80
### install startup/stop-scripts
package_start='S'${package_pos}${package}
package_kill='K'`/usr/bin/expr 100 - $package_pos`${package}
ln -sf /etc/init.d/$package /etc/rc2.d/$package_start
ln -sf /etc/init.d/$package /etc/rc2.d/$package_kill
### add menu
/var/install/bin/add-menu \
setup.services.menu \
setup.services.$package.menu \
$package_name
### install configuration
if [ -f "/etc/config.d/$package" ]
then
### update configuration
echo "loading previous configuration file ..."
/var/install/config.d/$package-update.sh
else
### install default configuartion
echo "loading initial configuration file ..."
cp -p /etc/default.d/$package /etc/config.d/$package
fi
### edit configuration
/var/install/bin/edit -apply $package "Edit $package_name configuration"
exit 0
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 eventuelle Änderungen der Konfiguration (z.B. Hinzufügen neuer 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 - update or generate new foo
# configuration
#
# Creation: 2004-08-14 max
# Last Update: 2005-06-09 max
#
# Copyright (c) 2001-2007 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.
#----------------------------------------------------------------------
# define this package
package='foo'
configfile=/etc/config.d/$package
# include eislib
. /var/install/include/eislib
. /var/install/include/configlib
#------------------------------------------------------------------------
# add variables
#------------------------------------------------------------------------
add_variables ()
{
added=0
mecho -info "adding new parameter(s) ..."
# v1.1.0
if ! grep -q ^FOO_NEW_VARIABLE $source_conf
then
mecho -std "- FOO_NEW_VARIABLE='12345'"
FOO_NEW_VARIABLE='12345'
added=1
fi
if [ $added -eq 1 ]
then
mecho -warn "... read documentation for new parameter(s)!"
anykey
else
mecho -std "... nothing to do."
fi
}
#------------------------------------------------------------------------
# modify variables
#------------------------------------------------------------------------
modify_variables ()
{
modified=0
mecho -info "modifying parameter(s) ..."
if echo "$FOO_VARIABLE_MODIFIED" | grep -q "_"
then
FOO_VARIABLE_MODIFIED=`echo "$FOO_VARIABLE_MODIFIED" | sed -e 's/_/-/g'`
mecho -std "- FOO_VARIABLE_MODIFIED '_' -> '-'"
modified=1
fi
if [ $modified = 1 ]
then
mecho -warn "... read documentation for modified parameter(s)!"
anykey
else
mecho -std "... nothing to do."
fi
}
#------------------------------------------------------------------------
# create new configuration
#------------------------------------------------------------------------
create_config ()
{
mecho -info "updating/creating configuration ..."
(
printgpl "foo" \
"2005-03-25" "max" \
"2001-2006 the eisfair team, c/o Frank Meyer, frank(at)eisfair(dot)org"
printgroup "General settings"
printvar "START_FOO" "start foo: yes or no"
echo
printvar "FOO_NEW_VARIABLE" "this is the new variable"
printvar "FOO_VARIABLE_MODIFIED" "this variable was modified"
printvar "" "and has a longer comment"
echo
printgroup "An array"
[ "$FOO_ARRAY_N" = "" ] && FOO_ARRAY_N=0 # FOO_ARRAY_N must be set
printvar "FOO_ARRAY_N" "number of foo array entries"
if [ $FOO_ARRAY_N -eq 0 ] # print at least one example
then
FOO_ARRAY_N=1
FOO_ARRAY_1_NAME='bar'
FOO_ARRAY_1_VALUE='12345'
fi
for idx in `seq $FOO_ARRAY_N`
do
echo ""
printvar 'FOO_ARRAY_'$idx'_NAME' "name of foo array element"
printvar 'FOO_ARRAY_'$idx'_VALUE' "value of foo array element"
done
echo
printend
) > $generate_conf
mecho -std "... finished."
anykey
}
#========================================================================
# main
#========================================================================
# setting defaults
source_conf=$configfile
generate_conf=$configfile
if [ -f $source_conf ]
then
# previous configuration file exists
mecho -info "previous configuration found ..."
. $source_conf
modify_variables
add_variables
create_config
# backup is done in edit script
else
mecho -error "no configuration $source_conf found - exiting."
anykey
fi
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 ähnliches 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) 2005 Jens Vehlhaber, jvehlhaber(at)buchenwald(dot)de
# Copyright (c) 2005-2007 Holger Bruenjes, holgerbruenjes(at)gmx(dot)net
#
# 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
packages_name=eisfax
# include configlib for using printvar
. /var/install/include/configlib
. /var/install/info.d/eisfax
### ---------------------------------------------------------------------------
### Set the default values for configuration
### ---------------------------------------------------------------------------
START_EISFAX='no'
EISFAX_COUNTRY_CODE='49'
EISFAX_AREA_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_FAX_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_HEADER_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 values
if [ -f /etc/config.d/${packages_name} ]
then
. /etc/config.d/${packages_name}
fi
}
### ---------------------------------------------------------------------------
### Write config and default files
### ---------------------------------------------------------------------------
make_config_file()
{
internal_conf_file=${1}
(
#--------------------------------------------------------------------------------
printgpl -conf ${packages_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 "EISFAX_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 ${packages_name} "2005-06-26" "jv" >/etc/check.d/${packages_name}
cat >>/etc/check.d/${packages_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/${packages_name}
chown root /etc/check.d/${packages_name}
printgpl -check_exp ${packages_name} "2005-06-26" "jv" >/etc/check.d/${packages_name}.exp
cat >>/etc/check.d/${packages_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/${packages_name}.exp
chown root /etc/check.d/${packages_name}.exp
printgpl -check_ext ${packages_name} "2005-08-31" "hb" >/etc/check.d/${packages_name}.ext
cat >>/etc/check.d/${packages_name}.ext <<EOF
if ( eisfax_analog_use == "yes" && eisfax_isdn_use == "yes" )
then
error " You configured EISFAX_ANALOG_USE and EISFAX_ISDN_USE 'yes', you can only one of this configured 'yes' "
fi
EOF
# Set rights for check.ext file
chmod 0600 /etc/check.d/${packages_name}.ext
chown root /etc/check.d/${packages_name}.ext
}
### ---------------------------------------------------------------------------
### Main
### ---------------------------------------------------------------------------
# write default config file
if [ -f /etc/config.d/${packages_name} ]
then
mecho -info -n "updating configuration ."
else
mecho -info -n "creating configuration ."
fi
make_config_file /etc/default.d/${packages_name}
# update from old version
mecho -info -n "."
rename_old_variables
# write new config file
mecho -info -n "."
make_config_file /etc/config.d/${packages_name}
# write check.d file
mecho -info -n "."
make_check_file
mecho -info ". finished"
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är, 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 - deinstallation of foo
#
# Creation: 2005-05-05 max
# Last Update: 2005-06-09 max
#
# Copyright (c) 2001-2007 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
package='foo'
if [ "$1" = "update" ]
then
mecho -info "Updating $package (removing previous version)"
update=1
else
mecho -info "Removing $package"
update=0
fi
# stop service
if [ -x /etc/init.d/$package ]
then
/etc/init.d/$package stop
fi
# remove start/stop scripts
rm -f /etc/rc?.d/???$package
rm -f /etc/init.d/boot.d/???$package
rm -f /etc/init.d/$package
rm -f /etc/init.d/boot.$package
# remove config files
if [ "$update" -eq "0" ] # don't delete config on update
then
mecho -std "- removing $package configuration"
rm -f /etc/config.d/$package
rm -f /etc/config.d/$package~
rm -f /etc/config.d/$package.*
rm -f /etc/backup.d/$package.*
fi
rm -f /etc/default.d/$package
# remove eischk, apply and update
rm -f /etc/check.d/$package
rm -f /etc/check.d/$package.*
rm -f /var/install/config.d/$package.sh
rm -f /var/install/config.d/$package-update.sh
# remove menu from menu system
if [ "$update" -eq "0" ] # don't remove menu on update
then
/var/install/bin/del-menu \
setup.services.menu \
setup.services.$package.menu
fi
# remove menu files
rm -f /var/install/menu/setup.services.$package.menu
# remove docs/package description
rm -r -f /usr/share/doc/$package
rm -f /var/install/packages/$package
rm -f /etc/filelist.d/${package}-files.txt
# remove this deinstall script
rm -f /var/install/deinstall/$package
### and now remove package specific files...
rm -f /usr/bin/foo
mecho -std "done."
mecho
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.
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.
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-2007 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
# include configuration
. /etc/config.d/foo
case $1
in
start)
### check if starting foo is allowed
if [ "$START_FOO" != "yes" ]
then
mecho -error "Skipping start of FOO because START_FOO is set to 'no'"
mecho "If you want to start FOO manually,
mecho "use the parameter 'forcestart' instead of 'start' with the init.d script"
exit 1
fi
### and now start foo
mecho -info "Starting foo ..."
foo start $FOO_PARAM
;;
forcestart)
### and now start foo
mecho -info "Starting foo ..."
foo start $FOO_PARAM
;;
stop)
mecho -info "Shutting down foo ..."
foo stop
;;
restart)
$0 stop
$0 start
;;
*)
echo "Usage: $0 {start|forcestart|stop|restart}"
;;
esac
exit 0
Im Beispiel ist neben den bereits oben 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.
Jens Vehlhaber 2008-03-01