##// END OF EJS Templates
server: move cmdutil.service() to new module (API)...
Yuya Nishihara -
r30506:d9d8d78e default
parent child Browse files
Show More
@@ -0,0 +1,107 b''
1 # server.py - utility and factory of server
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 #
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
7
8 from __future__ import absolute_import
9
10 import errno
11 import os
12 import sys
13 import tempfile
14
15 from .i18n import _
16
17 from . import (
18 error,
19 util,
20 )
21
22 def runservice(opts, parentfn=None, initfn=None, runfn=None, logfile=None,
23 runargs=None, appendpid=False):
24 '''Run a command as a service.'''
25
26 def writepid(pid):
27 if opts['pid_file']:
28 if appendpid:
29 mode = 'a'
30 else:
31 mode = 'w'
32 fp = open(opts['pid_file'], mode)
33 fp.write(str(pid) + '\n')
34 fp.close()
35
36 if opts['daemon'] and not opts['daemon_postexec']:
37 # Signal child process startup with file removal
38 lockfd, lockpath = tempfile.mkstemp(prefix='hg-service-')
39 os.close(lockfd)
40 try:
41 if not runargs:
42 runargs = util.hgcmd() + sys.argv[1:]
43 runargs.append('--daemon-postexec=unlink:%s' % lockpath)
44 # Don't pass --cwd to the child process, because we've already
45 # changed directory.
46 for i in xrange(1, len(runargs)):
47 if runargs[i].startswith('--cwd='):
48 del runargs[i]
49 break
50 elif runargs[i].startswith('--cwd'):
51 del runargs[i:i + 2]
52 break
53 def condfn():
54 return not os.path.exists(lockpath)
55 pid = util.rundetached(runargs, condfn)
56 if pid < 0:
57 raise error.Abort(_('child process failed to start'))
58 writepid(pid)
59 finally:
60 try:
61 os.unlink(lockpath)
62 except OSError as e:
63 if e.errno != errno.ENOENT:
64 raise
65 if parentfn:
66 return parentfn(pid)
67 else:
68 return
69
70 if initfn:
71 initfn()
72
73 if not opts['daemon']:
74 writepid(util.getpid())
75
76 if opts['daemon_postexec']:
77 try:
78 os.setsid()
79 except AttributeError:
80 pass
81 for inst in opts['daemon_postexec']:
82 if inst.startswith('unlink:'):
83 lockpath = inst[7:]
84 os.unlink(lockpath)
85 elif inst.startswith('chdir:'):
86 os.chdir(inst[6:])
87 elif inst != 'none':
88 raise error.Abort(_('invalid value for --daemon-postexec: %s')
89 % inst)
90 util.hidewindow()
91 util.stdout.flush()
92 util.stderr.flush()
93
94 nullfd = os.open(os.devnull, os.O_RDWR)
95 logfilefd = nullfd
96 if logfile:
97 logfilefd = os.open(logfile, os.O_RDWR | os.O_CREAT | os.O_APPEND)
98 os.dup2(nullfd, 0)
99 os.dup2(logfilefd, 1)
100 os.dup2(logfilefd, 2)
101 if nullfd not in (0, 1, 2):
102 os.close(nullfd)
103 if logfile and logfilefd not in (0, 1, 2):
104 os.close(logfilefd)
105
106 if runfn:
107 return runfn()
@@ -10,7 +10,6 b' from __future__ import absolute_import'
10 import errno
10 import errno
11 import os
11 import os
12 import re
12 import re
13 import sys
14 import tempfile
13 import tempfile
15
14
16 from .i18n import _
15 from .i18n import _
@@ -821,93 +820,6 b' def copy(ui, repo, pats, opts, rename=Fa'
821
820
822 return errors != 0
821 return errors != 0
823
822
824 def service(opts, parentfn=None, initfn=None, runfn=None, logfile=None,
825 runargs=None, appendpid=False):
826 '''Run a command as a service.'''
827
828 def writepid(pid):
829 if opts['pid_file']:
830 if appendpid:
831 mode = 'a'
832 else:
833 mode = 'w'
834 fp = open(opts['pid_file'], mode)
835 fp.write(str(pid) + '\n')
836 fp.close()
837
838 if opts['daemon'] and not opts['daemon_postexec']:
839 # Signal child process startup with file removal
840 lockfd, lockpath = tempfile.mkstemp(prefix='hg-service-')
841 os.close(lockfd)
842 try:
843 if not runargs:
844 runargs = util.hgcmd() + sys.argv[1:]
845 runargs.append('--daemon-postexec=unlink:%s' % lockpath)
846 # Don't pass --cwd to the child process, because we've already
847 # changed directory.
848 for i in xrange(1, len(runargs)):
849 if runargs[i].startswith('--cwd='):
850 del runargs[i]
851 break
852 elif runargs[i].startswith('--cwd'):
853 del runargs[i:i + 2]
854 break
855 def condfn():
856 return not os.path.exists(lockpath)
857 pid = util.rundetached(runargs, condfn)
858 if pid < 0:
859 raise error.Abort(_('child process failed to start'))
860 writepid(pid)
861 finally:
862 try:
863 os.unlink(lockpath)
864 except OSError as e:
865 if e.errno != errno.ENOENT:
866 raise
867 if parentfn:
868 return parentfn(pid)
869 else:
870 return
871
872 if initfn:
873 initfn()
874
875 if not opts['daemon']:
876 writepid(util.getpid())
877
878 if opts['daemon_postexec']:
879 try:
880 os.setsid()
881 except AttributeError:
882 pass
883 for inst in opts['daemon_postexec']:
884 if inst.startswith('unlink:'):
885 lockpath = inst[7:]
886 os.unlink(lockpath)
887 elif inst.startswith('chdir:'):
888 os.chdir(inst[6:])
889 elif inst != 'none':
890 raise error.Abort(_('invalid value for --daemon-postexec: %s')
891 % inst)
892 util.hidewindow()
893 util.stdout.flush()
894 util.stderr.flush()
895
896 nullfd = os.open(os.devnull, os.O_RDWR)
897 logfilefd = nullfd
898 if logfile:
899 logfilefd = os.open(logfile, os.O_RDWR | os.O_CREAT | os.O_APPEND)
900 os.dup2(nullfd, 0)
901 os.dup2(logfilefd, 1)
902 os.dup2(logfilefd, 2)
903 if nullfd not in (0, 1, 2):
904 os.close(nullfd)
905 if logfile and logfilefd not in (0, 1, 2):
906 os.close(logfilefd)
907
908 if runfn:
909 return runfn()
910
911 ## facility to let extension process additional data into an import patch
823 ## facility to let extension process additional data into an import patch
912 # list of identifier to be executed in order
824 # list of identifier to be executed in order
913 extrapreimport = [] # run before commit
825 extrapreimport = [] # run before commit
@@ -67,6 +67,7 b' from . import ('
67 revlog,
67 revlog,
68 revset,
68 revset,
69 scmutil,
69 scmutil,
70 server,
70 setdiscovery,
71 setdiscovery,
71 sshserver,
72 sshserver,
72 sslutil,
73 sslutil,
@@ -6301,7 +6302,7 b' def serve(ui, repo, **opts):'
6301 service = commandserver.createservice(ui, repo, opts)
6302 service = commandserver.createservice(ui, repo, opts)
6302 else:
6303 else:
6303 service = hgweb.createservice(ui, repo, opts)
6304 service = hgweb.createservice(ui, repo, opts)
6304 return cmdutil.service(opts, initfn=service.init, runfn=service.run)
6305 return server.runservice(opts, initfn=service.init, runfn=service.run)
6305
6306
6306 @command('^status|st',
6307 @command('^status|st',
6307 [('A', 'all', None, _('show status of all files')),
6308 [('A', 'all', None, _('show status of all files')),
@@ -11,7 +11,7 b' import signal'
11 import sys
11 import sys
12
12
13 from mercurial import (
13 from mercurial import (
14 cmdutil,
14 server,
15 util,
15 util,
16 )
16 )
17
17
@@ -51,5 +51,5 b" if __name__ == '__main__':"
51 'daemon': not options.foreground,
51 'daemon': not options.foreground,
52 'daemon_postexec': options.daemon_postexec}
52 'daemon_postexec': options.daemon_postexec}
53 service = simplehttpservice(options.host, options.port)
53 service = simplehttpservice(options.host, options.port)
54 cmdutil.service(opts, initfn=service.init, runfn=service.run,
54 server.runservice(opts, initfn=service.init, runfn=service.run,
55 runargs=[sys.executable, __file__] + sys.argv[1:])
55 runargs=[sys.executable, __file__] + sys.argv[1:])
@@ -11,7 +11,7 b' import ssl'
11 import sys
11 import sys
12
12
13 from mercurial import (
13 from mercurial import (
14 cmdutil,
14 server,
15 sslutil,
15 sslutil,
16 ui as uimod,
16 ui as uimod,
17 )
17 )
@@ -75,8 +75,8 b' def main():'
75 dummysmtpsecureserver(addr, opts.certificate)
75 dummysmtpsecureserver(addr, opts.certificate)
76 log('listening at %s:%d\n' % addr)
76 log('listening at %s:%d\n' % addr)
77
77
78 cmdutil.service(vars(opts), initfn=init, runfn=run,
78 server.runservice(vars(opts), initfn=init, runfn=run,
79 runargs=[sys.executable, __file__] + sys.argv[1:])
79 runargs=[sys.executable, __file__] + sys.argv[1:])
80
80
81 if __name__ == '__main__':
81 if __name__ == '__main__':
82 main()
82 main()
General Comments 0
You need to be logged in to leave comments. Login now