]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - windows/tahoesvc.py
a2b5392a42dae35cde4911d38b46a81bc8e27a78
[tahoe-lafs/tahoe-lafs.git] / windows / tahoesvc.py
1 import sys
2 reload(sys)
3 sys.setdefaultencoding("utf-8")
4
5 import win32serviceutil
6 import win32service
7 import win32event
8 import win32evtlogutil
9
10 import os
11 import thread
12 import time
13 import traceback
14
15 # this logging should go away once service startup is considered debugged.
16 logfilehandle = file('c:\\tahoe_service.log', 'ab+')
17 def logmsg(msg):
18     logfilehandle.write("%s: %s\r\n" % (time.strftime('%Y%m%d_%H%M%S'), msg))
19     logfilehandle.flush()
20 logmsg('service loaded')
21
22 #
23 # Now with some bootstrap util functions in place, let's try and init things:
24 try:
25     from allmydata.util import pkgresutil # override pkg_resources zip provider for py2exe deployment
26     pkgresutil.install() # this is done before nevow is imported
27
28     logmsg('loading base dir')
29     from allmydata.windows import registry
30     basedir = registry.get_base_dir_path()
31     logmsg("got base dir (%s)" % (basedir,))
32     if not basedir:
33         regpth = "%s : %s " % (registry._AMD_KEY, registry._BDIR_KEY)
34         raise RuntimeError('"%s" not set in registry' % (regpth,))
35     os.chdir(basedir)
36     logmsg("chdir(%s)" % (basedir,))
37 except:
38     logmsg("exception")
39     traceback.print_exc(None, logfilehandle)
40     logfilehandle.flush()
41     logfilehandle.close()
42     raise
43
44 class Tahoe(win32serviceutil.ServiceFramework):
45     _svc_name_ = "Tahoe"
46     _svc_display_name_ = "Allmydata Tahoe Node"
47     def __init__(self, args):
48         logmsg("init")
49         try:
50             # The exe-file has messages for the Event Log Viewer.
51             # Register the exe-file as event source.
52             #
53             # Probably it would be better if this is done at installation time,
54             # so that it also could be removed if the service is uninstalled.
55             # Unfortunately it cannot be done in the 'if __name__ == "__main__"'
56             # block below, because the 'frozen' exe-file does not run this code.
57             #
58             logmsg("service start")
59             win32evtlogutil.AddSourceToRegistry(self._svc_display_name_,
60                                                 sys.executable,
61                                                 "Application")
62             win32serviceutil.ServiceFramework.__init__(self, args)
63             self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
64         except:
65             try:
66                 logmsg("exception")
67                 traceback.print_exc(None, logfilehandle)
68                 logfilehandle.flush()
69                 logfilehandle.close()
70             except:
71                 os.abort()
72
73     def SvcStop(self):
74         logmsg("service stop")
75         self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
76         win32event.SetEvent(self.hWaitStop)
77
78     def SvcDoRun(self):
79         try:
80             logmsg("service run")
81             import servicemanager
82             # Write a 'started' event to the event log...
83             win32evtlogutil.ReportEvent(self._svc_display_name_,
84                                         servicemanager.PYS_SERVICE_STARTED,
85                                         0, # category
86                                         servicemanager.EVENTLOG_INFORMATION_TYPE,
87                                         (self._svc_name_, ''))
88
89             reactor_type = registry.get_registry_value('reactor')
90             if reactor_type == 'iocp':
91                 from twisted.internet import iocpreactor
92                 iocpreactor.install()
93             else:
94                 from twisted.internet import selectreactor
95                 selectreactor.install()
96             from twisted.internet import reactor
97
98             if os.path.exists('DISABLE_STARTUP'):
99                 logmsg("DISABLE_STARTUP exists: exiting")
100             else:
101                 logmsg("runing reactorthread")
102
103                 # launch main thread...
104                 thread.start_new_thread(self.launch_node, ())
105
106                 # ...and block until service stop request
107                 win32event.WaitForSingleObject(self.hWaitStop, win32event.INFINITE)
108
109                 logmsg("wake up")
110
111                 reactor.callFromThread(reactor.stop)
112
113                 time.sleep(2) # give the node/reactor a chance to cleanup
114
115             # and write a 'stopped' event to the event log.
116             win32evtlogutil.ReportEvent(self._svc_display_name_,
117                                         servicemanager.PYS_SERVICE_STOPPED,
118                                         0, # category
119                                         servicemanager.EVENTLOG_INFORMATION_TYPE,
120                                         (self._svc_name_, ''))
121         except:
122             try:
123                 logmsg("exception")
124                 traceback.print_exc(None, logfilehandle)
125                 logfilehandle.flush()
126                 logfilehandle.close()
127             except:
128                 os.abort()
129
130     def launch_node(self):
131         try:
132             logmsg("main thread startup")
133
134             import depends # import dependencies so that py2exe finds them
135             _junk = depends # appease pyflakes
136
137             from twisted.internet import reactor
138             from twisted.python import log, logfile
139             from allmydata import client
140
141             # set up twisted logging. this will become part of the node rsn.
142             logdir = os.path.join(basedir, 'logs')
143             if not os.path.exists(logdir):
144                 os.makedirs(logdir)
145             lf = logfile.LogFile('tahoesvc.log', logdir)
146             log.startLogging(lf)
147
148             # run the node itself
149             c = client.Client(basedir)
150             reactor.callLater(0, c.startService) # after reactor startup
151             reactor.run(installSignalHandlers=False)
152
153             logmsg("main thread shutdown")
154         except:
155             logmsg("exception")
156             traceback.print_exc(None, logfilehandle)
157             logfilehandle.flush()
158             os.abort()
159
160 if __name__ == '__main__':
161     logmsg("service main")
162     win32serviceutil.HandleCommandLine(Tahoe)
163