/etc unter Versionskontrolle
Schon vor einige Zeit bin ich über einen Artikel zu etckeeper gestollperthttp://www.linux-magazin.de/ausgaben/2016/07/einfuehrung2/
ein sehr interesanter Ansatz, auch ein sehr netter Artikel zum Thema https://www.thomas-krenn.com/de/wiki/Etc-Verzeichnis_mit_etckeeper_versionieren
in den Artikel und Anleitungen die ich zu den Thema gefunden habe, gibt es einen Hinweis wie man cronjob einrichtet um einen Dailycommit durchzuführen, schon eine gute Idee, doch wenn man nicht der einzige Sysadmin auf einem System ist und diese noch schusseliger sind, als einer selbst, oder auch mal ein script oder Anwendung etwa in etc ändert dann wäre es tolle wenn die Versionierung denoch stattfindet.
Normalerweise kann man wohl davon ausgehen das eine Konfigdatei nicht mehrfach an einen Tag geändert wird, und so ein dailycomit ausreicht, man könnte auch per cron geringere Intervalle wählen.
ich hatte eine andere Idee, warum nicht einen commit wenn es eine Änderung gibt.
Also etc überwachen da fiel mir Inotify ein
https://en.wikipedia.org/wiki/Inotify
https://wiki.ubuntuusers.de/inotify/
Mit Inotify hatte ich schon Erfahrungen gesammelt.
Damals hatte ich mit Inotify bzw den Vorgänger (dnotify) ein FTP-Eingangsverzeichniss überwacht.¹
ich hatte die Idee einen eigenen Dämon zu nutzen der wenn gestartet etc überwacht und einen Commit durchführt
als ich dies tat war SysVinit bei mir noch der vorwiegende Initprozess, systemd gab es am horizont und ebenso upstart, so richtig freude hatte ich damals daran nicht.
also erstmal ein init script schreiben
--- /etc/init.d/autoetckeeper ---
#!/bin/bash
# Start/stop the autoetckeeper daemon.
#
### BEGIN INIT INFO
# Provides: autoetckeeper
# Required-Start: $remote_fs
# Required-Stop: $remote_fs
# Should-Start: $network $syslog
# Should-Stop: $network $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Regular background program processing daemon
# Description: /usr/sbin/autoetckeeper is UNIX program that auto commit changes in /etc
### END INIT INFO
PATH=/bin:/usr/bin:/sbin:/usr/sbin
DESC="autoetckeeper daemon"
NAME=autoetckeeper
DAEMON=/usr/sbin/autoetckeeper
PIDFILE=/var/run/autoetckeeper
SCRIPTNAME=/etc/init.d/"$NAME"
test -f $DAEMON || exit 0
#. /lib/lsb/init-functions
case "$1" in
start) echo "Starting autoetckeeper"
$DAEMON &
#log_end_msg $?
;;
stop) echo "Stopping autoetckeeper"
pid=$( head /var/run/etckeeperauto.pid )
kill -15 $pid
#log_end_msg $RETVAL
;;
restart) #log_daemon_msg "Restarting periodic command scheduler" "cron"
$0 stop
$0 start
;;
status)
pid=$( head /var/run/etckeeperauto.pid )
if [[ $(ps -eaf | grep $pid | grep -c "inotifywait") -gt 0 ]]
then
echo "autoetckeeper [OK]"
else
echo "autoetckeeper [FALSE]"
fi
;;
*) echo "Usage: /etc/init.d/autoetckeeper {start|stop|status|restart}"
exit 2
;;
esac
exit 0
dann bedraf es noch den Dämon den es zu starten gab
--- /usr/sbin/autoetckeeper ---
#!/bin/bash
###################################################################################################################################################
## Copyright (c) 2015,"fridy" ##
## All rights reserved. ##
##-----------------------------------------------------------------------------------------------------------------------------------------------##
## Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:##
##-----------------------------------------------------------------------------------------------------------------------------------------------##
## * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. ##
## * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the ##
## documentation and/or other materials provided with the distribution. ##
## * Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this ##
## software without specific prior written permission. ##
##-----------------------------------------------------------------------------------------------------------------------------------------------##
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ##
## TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ##
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, ##
## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ##
## LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ##
## SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ##
##-----------------------------------------------------------------------------------------------------------------------------------------------##
###################################################################################################################################################
#Pfad zum logger
LOGGER=/usr/bin/logger
##Traphandling
trap_exit () {
exit 0
}
trap_int() {
clean
exit 1
}
trap_term () {
clean
exit 3
}
lock () {
$LOGGER -p info -t autoetckeeper "auto etckeeper start"
if [[ -d $lock ]]
then
pids=$(head -1 $pid)
ps_liste=$(ps -eaf | grep $pids | grep "inotifywait" | awk '{print $2}')
#echo "pids: $pids psliste $psliste') "
if [[ $(ps -eaf | grep $pids | grep "inotifywait" | awk '{print $2}'| wc -l) -eq 0 ]]
th
rm -fr $lock
else
for inotify_pid in $(ps -eaf | grep $pids | grep "inotifywait" | awk '{print $2}')
do
#echo "pids: $pids inotify_pid $inotify_pid"
kill -HUP $inotify_pid
done
# exit 1
rm -fr $lock
fi
fi
mkdir $lock
if [[ $? -eq 0 ]]
then
echo -e $(date +%d'.'%m'.'%Y' '%X)":\t Lock erfolgreich gesetzt" >> $log
else
echo -e $(date +%d'.'%m'.'%Y' '%X)":\t Lock nicht erfolgreich gesetzt" >> $log
$LOGGER -p info -t autoetckeeper "Lock nicht erfolgreich gesetzt"
exit 1
fi
}
trap trap_exit EXIT
trap trap_int INT
trap trap_term TERM
function clean () {
if [[ -f "$lock" ]] || [[ -d "$lock" ]]
then
#rm -frv $lock
rm -fr $lock
fi
pids=$(head -1 $pid)
for inotify_pid in $(ps -eaf | grep $pids | grep "inotifywait" | awk '{print $2}')
do
kill -15 $inotify_pid
done
sleep 1
for inotify_pid in $(ps -eaf | grep $pids | grep "inotifywait" | awk '{print $2}')
do
kill -9 $inotify_pid
done
}
log=/var/log/etckeeperauto.log
pid=/var/run/etckeeperauto.pid
pid_new=/tmp/etckeeperpid.new
lock=/var/lock/etckeeperauto
function autocommit () {
pushd /etc > /dev/null
while inot=$(inotifywait -q -r -e modify -e create -e delete -e move /etc)
do
if [[ $(echo $inot | grep -v "swp"| grep -v ".git/" | wc -l ) -gt 0 ]]
then
lockfile=/var/cache/etckeeper/packagelist.pre-install
if [ -e "$lockfile" ] && [ -n "$(find "$lockfile" -mmin +15)" ]; then
rm -f "$lockfile" # stale
fi
if [ ! -e "$lockfile" ]; then
if etckeeper unclean; then
msg=$(git status --short)
etckeeper commit -m "Auto change by script \n $msg" >> $log
echo "$(date) : git gc" >> $log
git gc --quiet
fi
fi
fi
done
popdi > /dev/null
}
function main () {
echo $$ > $pid_new
lock
mv $pid_new $pid
set -e
if [ -x /usr/bin/etckeeper ] && [ -e /etc/etckeeper/etckeeper.conf ]; then
. /etc/etckeeper/etckeeper.conf
autocommit
else
$LOGGER -p err -t autoetckeeper "etckeeper didn't find"
exit 1
fi
exit 0
}
main
--
[Unit]
Description=Automatischer commit etckeeper
After=network.target auditd.service
[Service]
EnvironmentFile=-/etc/default/autoetckeeper
ExecStart=/usr/sbin/autoetckeeper -D OPTS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
[Install]
WantedBy=multi-user.target
Alias=autoetckeeper.service
--mit systemd hatte ich noch keine Erfarungen, bzw die ersten waren nicht so gut, und wenn es auf systemen schon da war nutze ich auch die kompatibilität zu SysVinit also init scripte. heute finde ich die Eventmaschine systemd sehr hilfreich und mag viele ihrer Fähigkeiten.²
jetzt mal noch ein systemd service
--
--
¹Es war eine Datenanlieferung, bei der die angelieferten Daten in einen workflow gingen. Die vorherige Lösung war ein Script das jede minute das Verzeichniss überprüfte, wenn eine Datei im Verzeichniss war wurde nach einem sleep die dateigröße verglichen wenn sie sich nicht verändert hatte, wurde die Datei in den Workflow geschickt, wenn sie sich verändert hatte würde die Datei übergangen, so das sie beim einen nächsten Durchlauf in den Workflow geschickt wird. Die Lösung funktioniert recht gut hatte ihre schwächen wenn die Datenübertragung wären des sleeps nicht stafand aber die Datei denoch nicht vollständig übertragen wurde. eine eraste damalige Idee den schreibpointer der Datei mitels lsof zu prüfen, wenn es keinen gab war die Datei fertig. das war schon viel besser als die Lösung davor. Aber der Ansprüch das es doch auch noch "schöner" gehen muss führte zu eine lösung mit dnotify und nach upgrade auf eine neueren Kernelversion zu inotify.
²vielleicht werde ich mich hier auch mal tiefgreifender zu systemd äußern
Kommentare
Kommentar veröffentlichen