##// END OF EJS Templates
server: use pycompat to get argv
Augie Fackler -
r32530:3f0936b2 default
parent child Browse files
Show More
@@ -1,169 +1,169
1 # server.py - utility and factory of server
1 # server.py - utility and factory of server
2 #
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
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.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import os
10 import os
11 import sys
12 import tempfile
11 import tempfile
13
12
14 from .i18n import _
13 from .i18n import _
15
14
16 from . import (
15 from . import (
17 chgserver,
16 chgserver,
18 cmdutil,
17 cmdutil,
19 commandserver,
18 commandserver,
20 error,
19 error,
21 hgweb,
20 hgweb,
21 pycompat,
22 util,
22 util,
23 )
23 )
24
24
25 def runservice(opts, parentfn=None, initfn=None, runfn=None, logfile=None,
25 def runservice(opts, parentfn=None, initfn=None, runfn=None, logfile=None,
26 runargs=None, appendpid=False):
26 runargs=None, appendpid=False):
27 '''Run a command as a service.'''
27 '''Run a command as a service.'''
28
28
29 def writepid(pid):
29 def writepid(pid):
30 if opts['pid_file']:
30 if opts['pid_file']:
31 if appendpid:
31 if appendpid:
32 mode = 'a'
32 mode = 'a'
33 else:
33 else:
34 mode = 'w'
34 mode = 'w'
35 fp = open(opts['pid_file'], mode)
35 fp = open(opts['pid_file'], mode)
36 fp.write(str(pid) + '\n')
36 fp.write(str(pid) + '\n')
37 fp.close()
37 fp.close()
38
38
39 if opts['daemon'] and not opts['daemon_postexec']:
39 if opts['daemon'] and not opts['daemon_postexec']:
40 # Signal child process startup with file removal
40 # Signal child process startup with file removal
41 lockfd, lockpath = tempfile.mkstemp(prefix='hg-service-')
41 lockfd, lockpath = tempfile.mkstemp(prefix='hg-service-')
42 os.close(lockfd)
42 os.close(lockfd)
43 try:
43 try:
44 if not runargs:
44 if not runargs:
45 runargs = util.hgcmd() + sys.argv[1:]
45 runargs = util.hgcmd() + pycompat.sysargv[1:]
46 runargs.append('--daemon-postexec=unlink:%s' % lockpath)
46 runargs.append('--daemon-postexec=unlink:%s' % lockpath)
47 # Don't pass --cwd to the child process, because we've already
47 # Don't pass --cwd to the child process, because we've already
48 # changed directory.
48 # changed directory.
49 for i in xrange(1, len(runargs)):
49 for i in xrange(1, len(runargs)):
50 if runargs[i].startswith('--cwd='):
50 if runargs[i].startswith('--cwd='):
51 del runargs[i]
51 del runargs[i]
52 break
52 break
53 elif runargs[i].startswith('--cwd'):
53 elif runargs[i].startswith('--cwd'):
54 del runargs[i:i + 2]
54 del runargs[i:i + 2]
55 break
55 break
56 def condfn():
56 def condfn():
57 return not os.path.exists(lockpath)
57 return not os.path.exists(lockpath)
58 pid = util.rundetached(runargs, condfn)
58 pid = util.rundetached(runargs, condfn)
59 if pid < 0:
59 if pid < 0:
60 raise error.Abort(_('child process failed to start'))
60 raise error.Abort(_('child process failed to start'))
61 writepid(pid)
61 writepid(pid)
62 finally:
62 finally:
63 util.tryunlink(lockpath)
63 util.tryunlink(lockpath)
64 if parentfn:
64 if parentfn:
65 return parentfn(pid)
65 return parentfn(pid)
66 else:
66 else:
67 return
67 return
68
68
69 if initfn:
69 if initfn:
70 initfn()
70 initfn()
71
71
72 if not opts['daemon']:
72 if not opts['daemon']:
73 writepid(util.getpid())
73 writepid(util.getpid())
74
74
75 if opts['daemon_postexec']:
75 if opts['daemon_postexec']:
76 try:
76 try:
77 os.setsid()
77 os.setsid()
78 except AttributeError:
78 except AttributeError:
79 pass
79 pass
80 for inst in opts['daemon_postexec']:
80 for inst in opts['daemon_postexec']:
81 if inst.startswith('unlink:'):
81 if inst.startswith('unlink:'):
82 lockpath = inst[7:]
82 lockpath = inst[7:]
83 os.unlink(lockpath)
83 os.unlink(lockpath)
84 elif inst.startswith('chdir:'):
84 elif inst.startswith('chdir:'):
85 os.chdir(inst[6:])
85 os.chdir(inst[6:])
86 elif inst != 'none':
86 elif inst != 'none':
87 raise error.Abort(_('invalid value for --daemon-postexec: %s')
87 raise error.Abort(_('invalid value for --daemon-postexec: %s')
88 % inst)
88 % inst)
89 util.hidewindow()
89 util.hidewindow()
90 util.stdout.flush()
90 util.stdout.flush()
91 util.stderr.flush()
91 util.stderr.flush()
92
92
93 nullfd = os.open(os.devnull, os.O_RDWR)
93 nullfd = os.open(os.devnull, os.O_RDWR)
94 logfilefd = nullfd
94 logfilefd = nullfd
95 if logfile:
95 if logfile:
96 logfilefd = os.open(logfile, os.O_RDWR | os.O_CREAT | os.O_APPEND)
96 logfilefd = os.open(logfile, os.O_RDWR | os.O_CREAT | os.O_APPEND)
97 os.dup2(nullfd, 0)
97 os.dup2(nullfd, 0)
98 os.dup2(logfilefd, 1)
98 os.dup2(logfilefd, 1)
99 os.dup2(logfilefd, 2)
99 os.dup2(logfilefd, 2)
100 if nullfd not in (0, 1, 2):
100 if nullfd not in (0, 1, 2):
101 os.close(nullfd)
101 os.close(nullfd)
102 if logfile and logfilefd not in (0, 1, 2):
102 if logfile and logfilefd not in (0, 1, 2):
103 os.close(logfilefd)
103 os.close(logfilefd)
104
104
105 if runfn:
105 if runfn:
106 return runfn()
106 return runfn()
107
107
108 _cmdservicemap = {
108 _cmdservicemap = {
109 'chgunix': chgserver.chgunixservice,
109 'chgunix': chgserver.chgunixservice,
110 'pipe': commandserver.pipeservice,
110 'pipe': commandserver.pipeservice,
111 'unix': commandserver.unixforkingservice,
111 'unix': commandserver.unixforkingservice,
112 }
112 }
113
113
114 def _createcmdservice(ui, repo, opts):
114 def _createcmdservice(ui, repo, opts):
115 mode = opts['cmdserver']
115 mode = opts['cmdserver']
116 try:
116 try:
117 return _cmdservicemap[mode](ui, repo, opts)
117 return _cmdservicemap[mode](ui, repo, opts)
118 except KeyError:
118 except KeyError:
119 raise error.Abort(_('unknown mode %s') % mode)
119 raise error.Abort(_('unknown mode %s') % mode)
120
120
121 def _createhgwebservice(ui, repo, opts):
121 def _createhgwebservice(ui, repo, opts):
122 # this way we can check if something was given in the command-line
122 # this way we can check if something was given in the command-line
123 if opts.get('port'):
123 if opts.get('port'):
124 opts['port'] = util.getport(opts.get('port'))
124 opts['port'] = util.getport(opts.get('port'))
125
125
126 alluis = {ui}
126 alluis = {ui}
127 if repo:
127 if repo:
128 baseui = repo.baseui
128 baseui = repo.baseui
129 alluis.update([repo.baseui, repo.ui])
129 alluis.update([repo.baseui, repo.ui])
130 else:
130 else:
131 baseui = ui
131 baseui = ui
132 webconf = opts.get('web_conf') or opts.get('webdir_conf')
132 webconf = opts.get('web_conf') or opts.get('webdir_conf')
133 if webconf:
133 if webconf:
134 if opts.get('subrepos'):
134 if opts.get('subrepos'):
135 raise error.Abort(_('--web-conf cannot be used with --subrepos'))
135 raise error.Abort(_('--web-conf cannot be used with --subrepos'))
136
136
137 # load server settings (e.g. web.port) to "copied" ui, which allows
137 # load server settings (e.g. web.port) to "copied" ui, which allows
138 # hgwebdir to reload webconf cleanly
138 # hgwebdir to reload webconf cleanly
139 servui = ui.copy()
139 servui = ui.copy()
140 servui.readconfig(webconf, sections=['web'])
140 servui.readconfig(webconf, sections=['web'])
141 alluis.add(servui)
141 alluis.add(servui)
142 elif opts.get('subrepos'):
142 elif opts.get('subrepos'):
143 servui = ui
143 servui = ui
144
144
145 # If repo is None, hgweb.createapp() already raises a proper abort
145 # If repo is None, hgweb.createapp() already raises a proper abort
146 # message as long as webconf is None.
146 # message as long as webconf is None.
147 if repo:
147 if repo:
148 webconf = dict()
148 webconf = dict()
149 cmdutil.addwebdirpath(repo, "", webconf)
149 cmdutil.addwebdirpath(repo, "", webconf)
150 else:
150 else:
151 servui = ui
151 servui = ui
152
152
153 optlist = ("name templates style address port prefix ipv6"
153 optlist = ("name templates style address port prefix ipv6"
154 " accesslog errorlog certificate encoding")
154 " accesslog errorlog certificate encoding")
155 for o in optlist.split():
155 for o in optlist.split():
156 val = opts.get(o, '')
156 val = opts.get(o, '')
157 if val in (None, ''): # should check against default options instead
157 if val in (None, ''): # should check against default options instead
158 continue
158 continue
159 for u in alluis:
159 for u in alluis:
160 u.setconfig("web", o, val, 'serve')
160 u.setconfig("web", o, val, 'serve')
161
161
162 app = hgweb.createapp(baseui, repo, webconf)
162 app = hgweb.createapp(baseui, repo, webconf)
163 return hgweb.httpservice(servui, app, opts)
163 return hgweb.httpservice(servui, app, opts)
164
164
165 def createservice(ui, repo, opts):
165 def createservice(ui, repo, opts):
166 if opts["cmdserver"]:
166 if opts["cmdserver"]:
167 return _createcmdservice(ui, repo, opts)
167 return _createcmdservice(ui, repo, opts)
168 else:
168 else:
169 return _createhgwebservice(ui, repo, opts)
169 return _createhgwebservice(ui, repo, opts)
General Comments 0
You need to be logged in to leave comments. Login now