#! /usr/bin/python -E # # Copyright (C) 2007 Red Hat # see file 'COPYING' for use and warranty information # # 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; version 2 only # # This program is distributed 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # import os, sys, pwd, grp from optparse import OptionParser import traceback import logging import signal def usage(): print "ipa_webgui [-f|--foreground] [-d|--debug]" sys.exit(1) def parse_options(): parser = OptionParser() parser.add_option("-f", "--foreground", dest="foreground", action="store_true", default=False, help="Remain in the foreground") parser.add_option("-d", "--debug", dest="debug", action="store_true", default=False, help="Increase the amount of logging information") parser.add_option("--usage", action="store_true", help="Program usage") options, args = parser.parse_args(sys.argv) return options, args def daemonize(): # fork once so the parent can exit try: pid = os.fork() except OSError, e: raise Exception, "%s [%d]" % (e.strerror, e.errno) if pid != 0: os._exit(0) # become session leader os.setsid() # fork again to reparent to init try: pid = os.fork() except OSError, e: raise Exception, "%s [%d]" % (e.strerror, e.errno) if pid != 0: os._exit(0) os.chdir("/") os.umask(0) import resource maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1] if (maxfd == resource.RLIM_INFINITY): maxfd = 1024 # close all file descriptors for fd in range(0, maxfd): try: os.close(fd) except OSError: pass # stdin os.open("/dev/null", os.O_RDWR) # stdout os.open("/dev/null", os.O_RDWR) # stderr os.open("/dev/null", os.O_RDWR) def main(): options, args = parse_options() foreground = options.foreground if options.debug: loglevel = logging.DEBUG else: loglevel = logging.WARN # To make development easier, we detect if we are in the development # environment to load a different configuration and avoid becoming # a daemon devel = False if os.path.exists(os.path.join(os.path.dirname(__file__), "Makefile.am")): devel = True foreground = True if not foreground: try: daemonize() except Exception, e: sys.stderr.write("error becoming daemon: " + str(e)) sys.exit(1) if not foreground: try: daemonize() except Exception, e: sys.stderr.write("error becoming daemon: " + str(e)) sys.exit(1) # Drop privileges and write our pid file only if we're running as root if os.getuid() == 0: # Write out our pid file pidfile = open("/var/run/ipa_webgui.pid", "w") pidfile.write(str(os.getpid())) pidfile.close() # Drop privs apache_uid = pwd.getpwnam("apache")[2] apache_gid = grp.getgrnam("apache")[2] try: os.setgid(apache_gid) except OSError, e: log.error("Could not set effective group id: %s" % e) try: os.setuid(apache_uid) except OSError, e: log.error("Could not set effective user id: %s" % e) if foreground: logging.basicConfig(level=loglevel, format='%(asctime)s %(name)s %(levelname)s %(message)s', stream=sys.stderr) else: # This log file name needs to be kept in sync with the one in # ipa_webgui.cfg logging.basicConfig(level=loglevel, format='%(asctime)s %(name)s %(levelname)s %(message)s', filename='/var/log/ipa_error.log') sys.path.append("/usr/share/ipa") # this must be after sys.path is changed to work correctly import pkg_resources pkg_resources.require("TurboGears") pkg_resources.require("ipa_gui") from turbogears import update_config, start_server from turbogears.config import update import cherrypy cherrypy.lowercase_api = True try: if hasattr(signal, "SIGTERM"): def SIGTERM(signum=None, frame=None): cherrypy.server.stop() signal.signal(signal.SIGTERM, SIGTERM) except ValueError, _signal_exc: if _signal_exc.args[0] != "signal only works in main thread": raise # Shut down the logging set up here so that CherryPy logging can take # over. TurboGears configuration errors will not be caught. if not foreground: logging.shutdown() # Load the config - look for a local file first for development # and then the system config file if devel: update_config(configfile="dev.cfg", modulename="ipagui.config") update( { "i18n.locale_dir": "locales"} ) else: update_config(configfile="/usr/share/ipa/ipa_webgui.cfg", modulename="ipagui.config.app") update( { "i18n.locale_dir": "/usr/share/ipa/locales"} ) from ipagui.controllers import Root start_server(Root()) try: main() sys.exit(0) except SystemExit, e: sys.exit(e) except Exception, e: message = "failed to start web gui: %s" % str(e) print message for str in traceback.format_tb(sys.exc_info()[2]): message = message + "\n" + str logging.error(message) sys.exit(1)