1
2
3
4
5
6
7
8
9
10
11
12
13
14 __doc__="""ZenDaemon
15
16 Base class for making deamon programs
17
18 $Id: ZenDaemon.py,v 1.9 2003/08/29 20:33:10 edahl Exp $"""
19
20 __version__ = "$Revision: 1.9 $"[11:-2]
21
22 import sys
23 import os
24 import pwd
25 import signal
26 import logging
27
28 from CmdBase import CmdBase
29 from Utils import zenPath, HtmlFormatter
30
31
32
33 UMASK = 0022
34
35 WORKDIR = "/"
36
37
38 MAXFD = 3
39
40
41 if (hasattr(os, "devnull")):
42 REDIRECT_TO = os.devnull
43 else:
44 REDIRECT_TO = "/dev/null"
45
46
48
49 pidfile = None
50
66
67
69 rlog = logging.getLogger()
70 rlog.setLevel(logging.WARN)
71 mname = self.__class__.__name__
72 self.log = logging.getLogger("zen."+ mname)
73 zlog = logging.getLogger("zen")
74 zlog.setLevel(self.options.logseverity)
75 if self.options.daemon or self.options.logpath:
76 if self.options.logpath:
77 if not os.path.isdir(os.path.dirname(self.options.logpath)):
78 raise SystemExit("logpath:%s doesn't exist" %
79 self.options.logpath)
80 logdir = self.options.logpath
81 else:
82 logdir = zenPath("log")
83 logfile = os.path.join(logdir, mname.lower()+".log")
84 h = logging.FileHandler(logfile)
85 h.setFormatter(logging.Formatter(
86 "%(asctime)s %(levelname)s %(name)s: %(message)s",
87 "%Y-%m-%d %H:%M:%S"))
88 rlog.addHandler(h)
89 else:
90 logging.basicConfig()
91 if self.options.weblog:
92 [ h.setFormatter(HtmlFormatter()) for h in rlog.handlers ]
93
94
96 if not self.keeproot:
97 try:
98 cname = pwd.getpwuid(os.getuid())[0]
99 pwrec = pwd.getpwnam(self.options.uid)
100 os.setuid(pwrec.pw_uid)
101 os.environ['HOME'] = pwrec.pw_dir
102 except (KeyError, OSError):
103 print >>sys.stderr, "WARN: user:%s not found running as:%s"%(
104 self.options.uid,cname)
105
106
108 """Code below comes from the excelent recipe by Chad J. Schroeder.
109 """
110 try:
111 pid = os.fork()
112 except OSError, e:
113 raise Exception, "%s [%d]" % (e.strerror, e.errno)
114
115 if (pid == 0):
116 os.setsid()
117 try:
118 pid = os.fork()
119 except OSError, e:
120 raise Exception, "%s [%d]" % (e.strerror, e.errno)
121
122 if (pid == 0):
123 os.chdir(WORKDIR)
124 os.umask(UMASK)
125 else:
126 os._exit(0)
127 else:
128 os._exit(0)
129
130
131 for fd in range(0, MAXFD):
132 try:
133 os.close(fd)
134 except OSError:
135 pass
136
137 os.open(REDIRECT_TO, os.O_RDWR)
138
139 os.dup2(0, 1)
140 os.dup2(0, 2)
141 if os.path.exists(self.zenvar):
142 myname = sys.argv[0].split(os.sep)[-1] + ".pid"
143 self.pidfile = os.path.join(self.zenvar, myname)
144 fp = open(self.pidfile, 'w')
145 fp.write(str(os.getpid()))
146 fp.close()
147 else:
148 raise SystemExit("ERROR: unable to open pid file %s" % self.pidfile)
149 return(0)
150
151
162
163
165 CmdBase.buildOptions(self)
166 self.parser.add_option('--uid',dest='uid',default="zenoss",
167 help='user to become when running default:zenoss')
168 self.parser.add_option('-c', '--cycle',dest='cycle',
169 action="store_true", default=False,
170 help="Cycle continuously on cycleInterval from zope")
171 self.parser.add_option('-D', '--daemon', default=False,
172 dest='daemon',action="store_true",
173 help="Become a unix daemon")
174 self.parser.add_option('--weblog', default=False,
175 dest='weblog',action="store_true",
176 help="output log info in html table format")
177