Index: debian/control =================================================================== --- debian/control +++ debian/control @@ -7,16 +7,28 @@ Package: univention-net-installer Architecture: all -Depends: univention-client-boot-pxe, syslinux | syslinux-bin, univention-config-registry +Depends: univention-client-boot-pxe, syslinux | syslinux-bin, univention-config-registry, univention-net-installer-daemon Conflicts: univention-server-installer (<< 0.3) Description: UCS - automatic profile server installation - This package contain the automatic profile server installation. + This package contains the automatic profile server installation. . This package is part of Univention Corporate Server (UCS), an integrated, directory driven solution for managing corporate environments. For more information about UCS, refer to: http://www.univention.de/ +Package: univention-net-installer-daemon +Architecture: all +Depends: python-univention +Description: UCS - automatic profile server installation + This package contains a net installer daemon which removes the reinstallation + flag in the ldap directory. + . + This package is part of Univention Corporate Server (UCS), + an integrated, directory driven solution for managing + corporate environments. For more information about UCS, + refer to: http://www.univention.de/ + Package: univention-server-installer Architecture: all Depends: univention-net-installer Index: debian/univention-net-installer-daemon.init.d =================================================================== --- debian/univention-net-installer-daemon.init.d +++ debian/univention-net-installer-daemon.init.d @@ -0,0 +1,233 @@ +#!/bin/sh +# Univention Net Installer Daemon +# init script +# +# Copyright 2010 Univention GmbH +# +# http://www.univention.de/ +# +# All rights reserved. +# +# The source code of this program is made available +# under the terms of the GNU Affero General Public License version 3 +# (GNU AGPL V3) as published by the Free Software Foundation. +# +# Binary versions of this program provided by Univention to you as +# well as other copyrighted, protected or trademarked materials like +# Logos, graphics, fonts, specific documentations and configurations, +# cryptographic keys etc. are subject to a license agreement between +# you and Univention and not subject to the GNU AGPL V3. +# +# In the case you use this program under the terms of the GNU AGPL V3, +# the program is provided in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public +# License with the Debian GNU/Linux or Univention distribution in file +# /usr/share/common-licenses/AGPL-3; if not, see +# . +# +### BEGIN INIT INFO +# Provides: univention-net-installer-daemon +# Required-Start: $network $local_fs +# Required-Stop: +# Should-Start: $named +# Should-Stop: +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Univention Net Installer Daemon +# Description: Service to reset the reinstall flag +### END INIT INFO + +PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin + +DAEMON=/usr/sbin/univention-net-installer-daemon # Introduce the server's location here +NAME="univention-net-installer-daemon" # Introduce the short server's name here +DESC="Univention Net Installer Daemon" # Introduce a short description here +LOGDIR=/var/log/univention # Log directory to use + +PIDFILE=/var/run/$NAME.pid + +test -x "$DAEMON" || exit 0 + +. /lib/lsb/init-functions + +# Default options, these can be overriden by the information +# at /etc/default/$NAME +DAEMON_OPTS="-p 49173 -D -d 1" # Additional options given to the server + +DIETIME=10 # Time to wait for the server to die, in seconds + # If this value is set too low you might not + # let some servers to die gracefully and + # 'restart' will not work + +STARTTIME=2 # Time to wait for the server to start, in seconds + # If this value is set each time the server is + # started (on start or restart) the script will + # stall to try to determine if it is running + # If it is not set and the server takes time + # to setup a pid file the log message might + # be a false positive (says it did not start + # when it actually did) + +LOGFILE="$LOGDIR/$NAME.log" # Server logfile + +# Include defaults if available +if [ -f "/etc/default/$NAME" ] ; then + . "/etc/default/$NAME" +fi + +set -e + +running_pid() { +# Check if a given process pid's cmdline matches a given name + pid=$1 + name=$2 + [ -z "$pid" ] && return 1 + [ ! -d /proc/$pid ] && return 1 + cmd=`cat /proc/$pid/cmdline | tr "\000" "\n"|sed -ne 2p |cut -d : -f 1` + # Is this the expected server + [ "$cmd" != "$name" ] && return 1 + return 0 +} + +running() { +# Check if the process is running looking at /proc + # No pidfile, probably no daemon present + [ ! -f "$PIDFILE" ] && return 1 + pid=`cat $PIDFILE` + running_pid $pid "$DAEMON" || return 1 + return 0 +} + +start_server() { + start_daemon -p "$PIDFILE" "$DAEMON" $DAEMON_OPTS + errcode=$? + return $errcode +} + +stop_server() { + killproc -p "$PIDFILE" "$DAEMON" + errcode=$? + return $errcode +} + +reload_server() { + [ ! -f "$PIDFILE" ] && return 1 + pid=pidofproc $PIDFILE # This is the daemon's pid + # Send a SIGHUP + kill -1 $pid + return $? +} + +force_stop() { +# Force the process to die killing it manually + [ ! -e "$PIDFILE" ] && return + if running ; then + kill -15 $pid + # Is it really dead? + sleep "$DIETIME"s + if running ; then + kill -9 $pid + sleep "$DIETIME"s + if running ; then + echo "Cannot kill $NAME (pid=$pid)!" + exit 1 + fi + fi + fi + rm -f "$PIDFILE" +} + + +case "$1" in + start) + log_daemon_msg "Starting $DESC " "$NAME" + # Check if it's running first + if running ; then + log_progress_msg "apparently already running" + log_end_msg 0 + exit 0 + fi + if start_server ; then + # NOTE: Some servers might die some time after they start, + # this code will detect this issue if STARTTIME is set + # to a reasonable value + [ -n "$STARTTIME" ] && sleep $STARTTIME # Wait some time + if running ; then + # It's ok, the server started and is running + log_end_msg 0 + else + # It is not running after we did start + log_end_msg 1 + fi + else + # Either we could not start it + log_end_msg 1 + fi + ;; + stop) + log_daemon_msg "Stopping $DESC" "$NAME" + if running ; then + # Only stop the server if we see it running + errcode=0 + stop_server || errcode=$? + log_end_msg $errcode + else + # If it's not running don't do anything + log_progress_msg "apparently not running" + log_end_msg 0 + exit 0 + fi + ;; + force-stop) + # First try to stop gracefully the program + "$0" stop + if running; then + # If it's still running try to kill it more forcefully + log_daemon_msg "Stopping (force) $DESC" "$NAME" + errcode=0 + force_stop || errcode=$? + log_end_msg $errcode + fi + ;; + restart|force-reload) + log_daemon_msg "Restarting $DESC" "$NAME" + errcode=0 + stop_server || errcode=$? + # Wait some sensible amount, some server need this + [ -n "$DIETIME" ] && sleep $DIETIME + start_server || errcode=$? + [ -n "$STARTTIME" ] && sleep $STARTTIME + running || errcode=$? + log_end_msg $errcode + ;; + status) + + log_daemon_msg "Checking status of $DESC" "$NAME" + if running ; then + log_progress_msg "running" + log_end_msg 0 + else + log_progress_msg "apparently not running" + log_end_msg 1 + exit 1 + fi + ;; + # Use this if the daemon cannot reload + reload) + log_warning_msg "Reloading $NAME daemon: not implemented, as the daemon" + log_warning_msg "cannot re-read the config file (use restart)." + ;; + *) + N=/etc/init.d/$NAME + echo "Usage: $N {start|stop|force-stop|restart|force-reload|status}" >&2 + exit 1 + ;; +esac + +exit 0 +# vim:set ft=sh: + Index: debian/changelog =================================================================== --- debian/changelog +++ debian/changelog @@ -1,3 +1,22 @@ +univention-server-installer (4.1.2-1) unstable; urgency=low + + * Set STARTTIME in daemon init script to two seconds. + Ticket #2010090610002701 and Bug #1156 + + -- Stefan Gohmann Tue, 14 Sep 2010 14:40:18 +0200 + +univention-server-installer (4.1.1-1) unstable; urgency=low + + * Add a simple network daemon which removes the reinstall flag, for + example by running the following command: + echo $hostname | netcat $ldap_master 49173 + The daemon will be installed on the net install server by default + but the package (univention-net-installer-daemon) can also be + installed on the DC Master. + Ticket #2010090610002701 and Bug #1156 + + -- Stefan Gohmann Thu, 09 Sep 2010 08:51:41 +0200 + univention-server-installer (4.0.4-1) unstable; urgency=low * Increased size of ramdisk, this is required for amd64 systems Index: debian/rules =================================================================== --- debian/rules +++ debian/rules @@ -66,6 +66,7 @@ install -m0755 serverinstallerpxe.py $(D)/usr/lib/univention-directory-listener/system/ install -m0755 81univention-server-installation.inst $(D)/usr/lib/univention-install/ + install -m0755 univention-net-installer-daemon debian/univention-net-installer-daemon/usr/sbin/univention-net-installer-daemon univention-install-config-registry @@ -80,6 +81,7 @@ dh_installexamples dh_installmenu dh_installcron + dh_installinit dh_installman dh_installinfo dh_installchangelogs Index: debian/univention-net-installer-daemon.dirs =================================================================== --- debian/univention-net-installer-daemon.dirs +++ debian/univention-net-installer-daemon.dirs @@ -0,0 +1 @@ +usr/sbin/ Index: univention-net-installer-daemon =================================================================== --- univention-net-installer-daemon +++ univention-net-installer-daemon @@ -0,0 +1,138 @@ +#!/usr/bin/python2.4 +# -*- coding: utf-8 -*- +# +# Univention Net Installer Daemon +# UVMM handler +# +# Copyright 2010 Univention GmbH +# +# http://www.univention.de/ +# +# All rights reserved. +# +# The source code of this program is made available +# under the terms of the GNU Affero General Public License version 3 +# (GNU AGPL V3) as published by the Free Software Foundation. +# +# Binary versions of this program provided by Univention to you as +# well as other copyrighted, protected or trademarked materials like +# Logos, graphics, fonts, specific documentations and configurations, +# cryptographic keys etc. are subject to a license agreement between +# you and Univention and not subject to the GNU AGPL V3. +# +# In the case you use this program under the terms of the GNU AGPL V3, +# the program is provided in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public +# License with the Debian GNU/Linux or Univention distribution in file +# /usr/share/common-licenses/AGPL-3; if not, see +# . + +import sys, os, time +import signal +import socket +import univention.uldap +import univention.debug as ud +from optparse import OptionParser + +def createDaemon(options): + try: + pid = os.fork() + except OSError, e: + print 'Daemon Mode Error: %s' % e.strerror + + if (pid == 0): + os.setsid() + signal.signal(signal.SIGHUP, signal.SIG_IGN) + try: + pid = os.fork() + except OSError, e: + print 'Daemon Mode Error: %s' % e.strerror + if (pid == 0): + os.chdir("/") + os.umask(0) + else: + pf=open(options.pidfile, 'w+') + pf.write(str(pid)) + pf.close() + os._exit(0) + else: + os._exit(0) + + try: + maxfd = os.sysconf("SC_OPEN_MAX") + except (AttributeError, ValueError): + maxfd = 256 # default maximum + + for fd in range(0, maxfd): + try: + os.close(fd) + except OSError: # ERROR (ignore) + pass + + os.open("/dev/null", os.O_RDONLY) + os.open("/dev/null", os.O_RDWR) + os.open("/dev/null", os.O_RDWR) + +def getLDAPConnection(): + # TODO: check for an alternative binddn + if os.path.exists('/etc/ldap.secret'): + lo = univention.uldap.getAdminConnection() + else: + lo = univention.uldap.getMachineConnection() + return lo + +if __name__ == '__main__': + parser = OptionParser(usage='usage: %prog [options] command') + parser.add_option('-p', '--port', + action='store', dest='port', default="49173", type='int', + help='Port for the daemon [%(default)s]' % {'default':'%default'}) + parser.add_option('-P', '--pidfile', + action='store', dest='pidfile', default="/var/run/univention-net-installer-daemon.pid", + help='Path to the pid-file [%(default)s]' % {'default':'%default'}) + parser.add_option('-D', '--daemon', + action='store_true', dest='daemonize', default=False, + help='Fork into background') + parser.add_option('-d', '--debug', + action='store', dest='debug_level', default="1", type='int', + help='Debug level (0 to 4)') + + (options, arguments) = parser.parse_args() + + ud.init('/var/log/univention/net-installer-daemon.log', 1, 0) + ud.set_level( ud.LDAP, options.debug_level) + + if options.daemonize: + createDaemon(options) + + HOST = socket.gethostbyname(socket.gethostname()) + + size = 1024 # max hostname length + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + s.bind((HOST,options.port)) + s.listen(1) + while True: + client, address = s.accept() + data = client.recv(size) + if data: + data=data.strip() + try: + lo = getLDAPConnection() + result = lo.search(filter='(&(objectClass=univentionHost)(cn=%s)(univentionServerReinstall=1))' % data) + if len(result) == 0: + ud.debug(ud.LDAP, ud.ERROR, 'The computer object %s was not found. Please remove the reinstall flag manually.' % data) + else: + for r in result: + lo.modify(r[0], [('univentionServerReinstall', '1', '0')]) + ud.debug(ud.LDAP, ud.PROCESS, 'The computer object %s (%s) was sucessful modified. ' % (data, r[0])) + except: + time.sleep(1) + # for example bad search filter + pass + + client.close() +