Aufgrund von extrem gründlichen Vandalismus musste die Wiki leider für Gäste schreibgeschützt werden :(


bottrd

bottrd ist ein Python-Script, welches bei unserem Bot dafür sorgt, dass er immer läuft. Es läuft im Hintergrund, startet bottr und wartet nur darauf, dass bottr abstürzt. Ist das passiert, wird er sofort wieder gestartet (damit wird der Bot-Befehl terminate zu einer Restart-Funktion ;-)). bottrd an sich prüft derzeit aus mysteriösen Gründen nicht, ob es bereits läuft. Bitte lasse es daher nicht im Cronjob laufen, sondern starte es bei Systemstart. Ich persönlich starte es in der Shell (bash) mit folgendem Kommando:

nohup python bottrd.py -d > /dev/null 2>&1 &

Das Script wurde noch nicht nennenswert auf anderen Servern getestet, anzupassen sind die Variablen phpfile und cwd auf deinen Bot. Auch ansonsten übernehme ich keine Haftung und gebe keinen Support für das Script! Es ist eine Entwicklerversion!

bottrd kann auch als reines Start-Script eingesetzt werden (-s), dabei wird derzeit aber der aktuelle Bot beendet.
Version vom 15.01.2010 16:31:

bottrd.py - bottr Start-Skript und bottr-Daemon
AUFRUF
./bottrd.py OPTIONS

OPTIONS
-d / --daemon
	Startet bottrd.py als Daemon. Wenn die PHP-Datei nach über 10 Sekunden Laufzeit abstuerzt, wird sie erneut gestartet ansonsten wird erst eine Minute gewartet
-s / --start
	Startet die PHP-Datei. Beendet laufende Instanzen.
-q / --quiet
	Keine unnoetige Ausgabe
-h / --stop
	Stoppt einen laufenden Daemon (funktioniert leider NOCH nicht)
bottrd.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import subprocess
import sys
import datetime
import time
import signal
 
##### CUSTOMIZE THIS
phpfile = 'bot.php'
cwd = '/var/www/web/bottr/bot'
 
######################## SCRIPT
 
##### CHECK ENVIRONMENT
def whereis(program):
    for path in os.environ.get('PATH', '').split(':'):
        if os.path.exists(os.path.join(path, program)) and \
           not os.path.isdir(os.path.join(path, program)):
            return os.path.join(path, program)
    return None
 
phpexec = '';
if whereis('php5') != None:
	phpexec = 'php5';
if whereis('php') != None:
	phpexec = 'php';
if phpexec == '':
	print('PHP executable not found')
	exit()
 
if os.path.isdir(cwd):
	cwd = cwd
else:
	cwd = './'
 
##### FUNKTIONEN
def check_pid(pid):
    #""" Check For the existence of a unix pid. """
    #try:
    #    os.kill(pid, 0)
    #except OSError:
    #    return False
    #else:
    #    return True
	if os.path.exists("/proc/"+str(pid)):
		return True
	else:
		return False
 
##### KLASSE
class bottrd:
	def __init__(self):
		global quiet
	def daemon(self):
		global quiet
		if quiet != True:
			print 'Starting daemon...'
		try:
			f = open('bottrd.pid', "r")
			thepid = f.read().strip()
			if thepid != '':
				thepid = int(thepid)
				if check_pid(thepid):
					os.kill(thepid, signal.SIGKILL)
					if quiet != True:
						print 'Killed old daemon...'
 
			f = open('cache/mypid.dat', "r")
			thepid = f.read().strip()
			if thepid != '':
				thepid = int(thepid)
				if check_pid(thepid):
					os.kill(thepid, signal.SIGKILL)
					if quiet != True:
						print 'Killed old bot...'
		except IOError:
			if quiet != True:
				print 'IOError...'
 
		pid = os.getpid()
		strpid = str(os.getpid())
		try:
			f = open('bottrd.pid', "w+")
			f.write(strpid)
			print (strpid)
		except IOError:
			if quiet != True:
				print 'IOError...'
 
		while True:
			if quiet != True:
				print 'Starting instance...'
			starttime = datetime.datetime.now()
			proc = subprocess.Popen(args = [phpexec, '-f', phpfile], stdin = None, stdout = open('/dev/null', 'w'), stderr = subprocess.STDOUT, cwd = cwd)
			if quiet != True:
				print 'PID: '+str(proc.pid)
			proc.wait()
			if quiet != True:
				print 'Instance terminated...'
			deltas = (datetime.datetime.now()-starttime).seconds
			if quiet != True:
				print 'Lifetime '+str(deltas)+' Seconds, Returned: '+str(proc.returncode)+' ...'
			if deltas < 10:
				if quiet != True:
					print 'Wait a minute...'
				time.sleep(60)
		exit()
	def start(self):
		try:
			f = open('cache/mypid.dat', "r")
			thepid = f.read().strip()
			if thepid != '':
				thepid = int(thepid)
				if check_pid(thepid):
					os.kill(thepid, signal.SIGKILL)
					if quiet != True:
						print 'Killed old bot...'
		except IOError:
			if quiet != True:
				print 'IOError...'
 
		proc = subprocess.Popen(args = ['nohup', phpexec, '-f', phpfile], stdin = None, stdout = open('/dev/null', 'w'), stderr = subprocess.STDOUT, cwd = cwd)
		exit()
	def stop(self):
		try:
			f = open('bottrd.pid', "r")
			thepid = f.read().strip()
			if thepid != '':
				thepid = int(thepid)
				if check_pid(thepid):
					os.kill(thepid, signal.SIGKILL)
		except IOError:
			if quiet != True:
				print 'IOError...'
		exit()
	def help(self):
		print """bottrd.py - bottr Start-Skript und bottr-Daemon
AUFRUF
./bottrd.py OPTIONS
 
OPTIONS
-d / --daemon
	Startet bottrd.py als Daemon. Wenn die PHP-Datei nach über 10 Sekunden Laufzeit abstuerzt, wird sie erneut gestartet ansonsten wird erst eine Minute gewartet
-s / --start
	Startet die PHP-Datei. Beendet laufende Instanzen.
-q / --quiet
	Keine unnoetige Ausgabe
-h / --stop
	Stoppt einen laufenden Daemon (funktioniert leider NOCH nicht)
		"""
 
##### PARSE COMMAND LINE
args = sys.argv[1:];
quiet = False
mode = ''
for arg in args:
    if arg == '--help':
		bottrd.help()
		exit()
    elif arg in ('-d', '--daemon'):
		mode = 'daemon'
    elif arg in ('-s', '--start'):
		mode = 'start'
    elif arg in ('-h', '--stop'):
		mode = 'stop'
    if arg in ('-q', '--quiet'):
		quiet = True
 
##### START
inst = bottrd()
if mode == 'daemon':
	inst.daemon()
elif mode == 'start':
	inst.start()
elif mode == 'stop':
	inst.stop()
else:
	inst.help()
	exit()

Eigene Werkzeuge