Mercurial > public > mercurial-scm > hg
annotate mercurial/server.py @ 37212:f09a2eab11cf
server: add an error feedback mechanism for when the daemon fails to launch
There's a recurring problem on Windows where `hg serve -d` will randomly fail to
spawn a detached process. The reason for the failure is completely hidden, and
it takes hours to get a single failure on my laptop. All this does is redirect
stdout/stderr of the child to a file until the lock file is freed, and then the
parent dumps it out if it fails to spawn.
I chose to put the output into the lock file because that is always cleaned up.
There's no way to report errors after that anyway. On Windows, killdaemons.py
is roughly `kill -9`, so this ensures that junk won't pile up.
This may end up being a case of EADDRINUSE. At least that's what I saw spit out
a few times (among other odd errors and missing output on Windows). But I also
managed to get the same thing on Fedora 26 by running test-hgwebdir.t with
--loop -j10 for several hours. Running `netstat` immediately after killing that
run printed a wall of sockets in the TIME_WAIT state, which were gone a couple
seconds later. I couldn't match up ports that failed, because --loop doesn't
print out the message about the port that was used. So maybe the fix is to
rotate the use of HGPORT[12] in the tests. But, let's collect some more data
first.
author | Matt Harbison <matt_harbison@yahoo.com> |
---|---|
date | Wed, 28 Mar 2018 00:11:09 -0400 |
parents | a8a902d7176e |
children | 73a60281a861 |
rev | line source |
---|---|
30506
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
1 # server.py - utility and factory of server |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
2 # |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com> |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
4 # |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
5 # This software may be used and distributed according to the terms of the |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
6 # GNU General Public License version 2 or any later version. |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
7 |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
8 from __future__ import absolute_import |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
9 |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
10 import os |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
11 import tempfile |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
12 |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
13 from .i18n import _ |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
14 |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
15 from . import ( |
30513
ff7df4bb75de
chgserver: make it a core module and drop extension flags
Yuya Nishihara <yuya@tcha.org>
parents:
30510
diff
changeset
|
16 chgserver, |
32005
2406dbba49bd
serve: add support for Mercurial subrepositories
Matt Harbison <matt_harbison@yahoo.com>
parents:
31548
diff
changeset
|
17 cmdutil, |
30507
dd539e2d89aa
server: move service table and factory from commandserver
Yuya Nishihara <yuya@tcha.org>
parents:
30506
diff
changeset
|
18 commandserver, |
30506
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
19 error, |
30509
add7bcad1d9c
server: move service factory from hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30507
diff
changeset
|
20 hgweb, |
32530
3f0936b2cea9
server: use pycompat to get argv
Augie Fackler <raf@durin42.com>
parents:
32291
diff
changeset
|
21 pycompat, |
30506
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
22 util, |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
23 ) |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
24 |
37119
d4a2e0d5d042
procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
34924
diff
changeset
|
25 from .utils import ( |
d4a2e0d5d042
procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
34924
diff
changeset
|
26 procutil, |
d4a2e0d5d042
procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
34924
diff
changeset
|
27 ) |
d4a2e0d5d042
procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
34924
diff
changeset
|
28 |
30506
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
29 def runservice(opts, parentfn=None, initfn=None, runfn=None, logfile=None, |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
30 runargs=None, appendpid=False): |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
31 '''Run a command as a service.''' |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
32 |
37212
f09a2eab11cf
server: add an error feedback mechanism for when the daemon fails to launch
Matt Harbison <matt_harbison@yahoo.com>
parents:
37120
diff
changeset
|
33 # When daemonized on Windows, redirect stdout/stderr to the lockfile (which |
f09a2eab11cf
server: add an error feedback mechanism for when the daemon fails to launch
Matt Harbison <matt_harbison@yahoo.com>
parents:
37120
diff
changeset
|
34 # gets cleaned up after the child is up and running), so that the parent can |
f09a2eab11cf
server: add an error feedback mechanism for when the daemon fails to launch
Matt Harbison <matt_harbison@yahoo.com>
parents:
37120
diff
changeset
|
35 # read and print the error if this child dies early. See 594dd384803c. On |
f09a2eab11cf
server: add an error feedback mechanism for when the daemon fails to launch
Matt Harbison <matt_harbison@yahoo.com>
parents:
37120
diff
changeset
|
36 # other platforms, the child can write to the parent's stdio directly, until |
f09a2eab11cf
server: add an error feedback mechanism for when the daemon fails to launch
Matt Harbison <matt_harbison@yahoo.com>
parents:
37120
diff
changeset
|
37 # it is redirected prior to runfn(). |
f09a2eab11cf
server: add an error feedback mechanism for when the daemon fails to launch
Matt Harbison <matt_harbison@yahoo.com>
parents:
37120
diff
changeset
|
38 if pycompat.iswindows and opts['daemon_postexec']: |
f09a2eab11cf
server: add an error feedback mechanism for when the daemon fails to launch
Matt Harbison <matt_harbison@yahoo.com>
parents:
37120
diff
changeset
|
39 for inst in opts['daemon_postexec']: |
f09a2eab11cf
server: add an error feedback mechanism for when the daemon fails to launch
Matt Harbison <matt_harbison@yahoo.com>
parents:
37120
diff
changeset
|
40 if inst.startswith('unlink:'): |
f09a2eab11cf
server: add an error feedback mechanism for when the daemon fails to launch
Matt Harbison <matt_harbison@yahoo.com>
parents:
37120
diff
changeset
|
41 lockpath = inst[7:] |
f09a2eab11cf
server: add an error feedback mechanism for when the daemon fails to launch
Matt Harbison <matt_harbison@yahoo.com>
parents:
37120
diff
changeset
|
42 if os.path.exists(lockpath): |
f09a2eab11cf
server: add an error feedback mechanism for when the daemon fails to launch
Matt Harbison <matt_harbison@yahoo.com>
parents:
37120
diff
changeset
|
43 procutil.stdout.flush() |
f09a2eab11cf
server: add an error feedback mechanism for when the daemon fails to launch
Matt Harbison <matt_harbison@yahoo.com>
parents:
37120
diff
changeset
|
44 procutil.stderr.flush() |
f09a2eab11cf
server: add an error feedback mechanism for when the daemon fails to launch
Matt Harbison <matt_harbison@yahoo.com>
parents:
37120
diff
changeset
|
45 |
f09a2eab11cf
server: add an error feedback mechanism for when the daemon fails to launch
Matt Harbison <matt_harbison@yahoo.com>
parents:
37120
diff
changeset
|
46 fd = os.open(lockpath, |
f09a2eab11cf
server: add an error feedback mechanism for when the daemon fails to launch
Matt Harbison <matt_harbison@yahoo.com>
parents:
37120
diff
changeset
|
47 os.O_WRONLY | os.O_APPEND | os.O_BINARY) |
f09a2eab11cf
server: add an error feedback mechanism for when the daemon fails to launch
Matt Harbison <matt_harbison@yahoo.com>
parents:
37120
diff
changeset
|
48 try: |
f09a2eab11cf
server: add an error feedback mechanism for when the daemon fails to launch
Matt Harbison <matt_harbison@yahoo.com>
parents:
37120
diff
changeset
|
49 os.dup2(fd, 1) |
f09a2eab11cf
server: add an error feedback mechanism for when the daemon fails to launch
Matt Harbison <matt_harbison@yahoo.com>
parents:
37120
diff
changeset
|
50 os.dup2(fd, 2) |
f09a2eab11cf
server: add an error feedback mechanism for when the daemon fails to launch
Matt Harbison <matt_harbison@yahoo.com>
parents:
37120
diff
changeset
|
51 finally: |
f09a2eab11cf
server: add an error feedback mechanism for when the daemon fails to launch
Matt Harbison <matt_harbison@yahoo.com>
parents:
37120
diff
changeset
|
52 os.close(fd) |
f09a2eab11cf
server: add an error feedback mechanism for when the daemon fails to launch
Matt Harbison <matt_harbison@yahoo.com>
parents:
37120
diff
changeset
|
53 |
30506
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
54 def writepid(pid): |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
55 if opts['pid_file']: |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
56 if appendpid: |
32548
d770a08ee9d9
server: write out pid using bytes IO instead of str IO
Augie Fackler <raf@durin42.com>
parents:
32530
diff
changeset
|
57 mode = 'ab' |
30506
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
58 else: |
32548
d770a08ee9d9
server: write out pid using bytes IO instead of str IO
Augie Fackler <raf@durin42.com>
parents:
32530
diff
changeset
|
59 mode = 'wb' |
30506
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
60 fp = open(opts['pid_file'], mode) |
32617
e48cb1c7a902
py3: simply use b'%d\n' to format pid in server.py
Yuya Nishihara <yuya@tcha.org>
parents:
32548
diff
changeset
|
61 fp.write('%d\n' % pid) |
30506
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
62 fp.close() |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
63 |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
64 if opts['daemon'] and not opts['daemon_postexec']: |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
65 # Signal child process startup with file removal |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
66 lockfd, lockpath = tempfile.mkstemp(prefix='hg-service-') |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
67 os.close(lockfd) |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
68 try: |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
69 if not runargs: |
37120
a8a902d7176e
procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
37119
diff
changeset
|
70 runargs = procutil.hgcmd() + pycompat.sysargv[1:] |
30506
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
71 runargs.append('--daemon-postexec=unlink:%s' % lockpath) |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
72 # Don't pass --cwd to the child process, because we've already |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
73 # changed directory. |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
74 for i in xrange(1, len(runargs)): |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
75 if runargs[i].startswith('--cwd='): |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
76 del runargs[i] |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
77 break |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
78 elif runargs[i].startswith('--cwd'): |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
79 del runargs[i:i + 2] |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
80 break |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
81 def condfn(): |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
82 return not os.path.exists(lockpath) |
37120
a8a902d7176e
procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
37119
diff
changeset
|
83 pid = procutil.rundetached(runargs, condfn) |
30506
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
84 if pid < 0: |
37212
f09a2eab11cf
server: add an error feedback mechanism for when the daemon fails to launch
Matt Harbison <matt_harbison@yahoo.com>
parents:
37120
diff
changeset
|
85 # If the daemonized process managed to write out an error msg, |
f09a2eab11cf
server: add an error feedback mechanism for when the daemon fails to launch
Matt Harbison <matt_harbison@yahoo.com>
parents:
37120
diff
changeset
|
86 # report it. |
f09a2eab11cf
server: add an error feedback mechanism for when the daemon fails to launch
Matt Harbison <matt_harbison@yahoo.com>
parents:
37120
diff
changeset
|
87 if pycompat.iswindows and os.path.exists(lockpath): |
f09a2eab11cf
server: add an error feedback mechanism for when the daemon fails to launch
Matt Harbison <matt_harbison@yahoo.com>
parents:
37120
diff
changeset
|
88 with open(lockpath) as log: |
f09a2eab11cf
server: add an error feedback mechanism for when the daemon fails to launch
Matt Harbison <matt_harbison@yahoo.com>
parents:
37120
diff
changeset
|
89 for line in log: |
f09a2eab11cf
server: add an error feedback mechanism for when the daemon fails to launch
Matt Harbison <matt_harbison@yahoo.com>
parents:
37120
diff
changeset
|
90 procutil.stderr.write(line) |
30506
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
91 raise error.Abort(_('child process failed to start')) |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
92 writepid(pid) |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
93 finally: |
31548 | 94 util.tryunlink(lockpath) |
30506
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
95 if parentfn: |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
96 return parentfn(pid) |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
97 else: |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
98 return |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
99 |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
100 if initfn: |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
101 initfn() |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
102 |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
103 if not opts['daemon']: |
37120
a8a902d7176e
procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
37119
diff
changeset
|
104 writepid(procutil.getpid()) |
30506
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
105 |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
106 if opts['daemon_postexec']: |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
107 try: |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
108 os.setsid() |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
109 except AttributeError: |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
110 pass |
37212
f09a2eab11cf
server: add an error feedback mechanism for when the daemon fails to launch
Matt Harbison <matt_harbison@yahoo.com>
parents:
37120
diff
changeset
|
111 |
f09a2eab11cf
server: add an error feedback mechanism for when the daemon fails to launch
Matt Harbison <matt_harbison@yahoo.com>
parents:
37120
diff
changeset
|
112 lockpath = None |
30506
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
113 for inst in opts['daemon_postexec']: |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
114 if inst.startswith('unlink:'): |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
115 lockpath = inst[7:] |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
116 elif inst.startswith('chdir:'): |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
117 os.chdir(inst[6:]) |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
118 elif inst != 'none': |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
119 raise error.Abort(_('invalid value for --daemon-postexec: %s') |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
120 % inst) |
37120
a8a902d7176e
procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
37119
diff
changeset
|
121 procutil.hidewindow() |
37119
d4a2e0d5d042
procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
34924
diff
changeset
|
122 procutil.stdout.flush() |
d4a2e0d5d042
procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
34924
diff
changeset
|
123 procutil.stderr.flush() |
30506
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
124 |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
125 nullfd = os.open(os.devnull, os.O_RDWR) |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
126 logfilefd = nullfd |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
127 if logfile: |
34924
bfcd0d227972
server: drop executable bit from daemon log file
Yuya Nishihara <yuya@tcha.org>
parents:
32617
diff
changeset
|
128 logfilefd = os.open(logfile, os.O_RDWR | os.O_CREAT | os.O_APPEND, |
bfcd0d227972
server: drop executable bit from daemon log file
Yuya Nishihara <yuya@tcha.org>
parents:
32617
diff
changeset
|
129 0o666) |
30506
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
130 os.dup2(nullfd, 0) |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
131 os.dup2(logfilefd, 1) |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
132 os.dup2(logfilefd, 2) |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
133 if nullfd not in (0, 1, 2): |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
134 os.close(nullfd) |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
135 if logfile and logfilefd not in (0, 1, 2): |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
136 os.close(logfilefd) |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
137 |
37212
f09a2eab11cf
server: add an error feedback mechanism for when the daemon fails to launch
Matt Harbison <matt_harbison@yahoo.com>
parents:
37120
diff
changeset
|
138 # Only unlink after redirecting stdout/stderr, so Windows doesn't |
f09a2eab11cf
server: add an error feedback mechanism for when the daemon fails to launch
Matt Harbison <matt_harbison@yahoo.com>
parents:
37120
diff
changeset
|
139 # complain about a sharing violation. |
f09a2eab11cf
server: add an error feedback mechanism for when the daemon fails to launch
Matt Harbison <matt_harbison@yahoo.com>
parents:
37120
diff
changeset
|
140 if lockpath: |
f09a2eab11cf
server: add an error feedback mechanism for when the daemon fails to launch
Matt Harbison <matt_harbison@yahoo.com>
parents:
37120
diff
changeset
|
141 os.unlink(lockpath) |
f09a2eab11cf
server: add an error feedback mechanism for when the daemon fails to launch
Matt Harbison <matt_harbison@yahoo.com>
parents:
37120
diff
changeset
|
142 |
30506
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
143 if runfn: |
d9d8d78e6bc9
server: move cmdutil.service() to new module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
144 return runfn() |
30507
dd539e2d89aa
server: move service table and factory from commandserver
Yuya Nishihara <yuya@tcha.org>
parents:
30506
diff
changeset
|
145 |
dd539e2d89aa
server: move service table and factory from commandserver
Yuya Nishihara <yuya@tcha.org>
parents:
30506
diff
changeset
|
146 _cmdservicemap = { |
30513
ff7df4bb75de
chgserver: make it a core module and drop extension flags
Yuya Nishihara <yuya@tcha.org>
parents:
30510
diff
changeset
|
147 'chgunix': chgserver.chgunixservice, |
30507
dd539e2d89aa
server: move service table and factory from commandserver
Yuya Nishihara <yuya@tcha.org>
parents:
30506
diff
changeset
|
148 'pipe': commandserver.pipeservice, |
dd539e2d89aa
server: move service table and factory from commandserver
Yuya Nishihara <yuya@tcha.org>
parents:
30506
diff
changeset
|
149 'unix': commandserver.unixforkingservice, |
dd539e2d89aa
server: move service table and factory from commandserver
Yuya Nishihara <yuya@tcha.org>
parents:
30506
diff
changeset
|
150 } |
dd539e2d89aa
server: move service table and factory from commandserver
Yuya Nishihara <yuya@tcha.org>
parents:
30506
diff
changeset
|
151 |
30510
a0878bc87379
server: add public function to select either cmdserver or hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30509
diff
changeset
|
152 def _createcmdservice(ui, repo, opts): |
30507
dd539e2d89aa
server: move service table and factory from commandserver
Yuya Nishihara <yuya@tcha.org>
parents:
30506
diff
changeset
|
153 mode = opts['cmdserver'] |
dd539e2d89aa
server: move service table and factory from commandserver
Yuya Nishihara <yuya@tcha.org>
parents:
30506
diff
changeset
|
154 try: |
dd539e2d89aa
server: move service table and factory from commandserver
Yuya Nishihara <yuya@tcha.org>
parents:
30506
diff
changeset
|
155 return _cmdservicemap[mode](ui, repo, opts) |
dd539e2d89aa
server: move service table and factory from commandserver
Yuya Nishihara <yuya@tcha.org>
parents:
30506
diff
changeset
|
156 except KeyError: |
dd539e2d89aa
server: move service table and factory from commandserver
Yuya Nishihara <yuya@tcha.org>
parents:
30506
diff
changeset
|
157 raise error.Abort(_('unknown mode %s') % mode) |
30509
add7bcad1d9c
server: move service factory from hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30507
diff
changeset
|
158 |
30510
a0878bc87379
server: add public function to select either cmdserver or hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30509
diff
changeset
|
159 def _createhgwebservice(ui, repo, opts): |
30509
add7bcad1d9c
server: move service factory from hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30507
diff
changeset
|
160 # this way we can check if something was given in the command-line |
add7bcad1d9c
server: move service factory from hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30507
diff
changeset
|
161 if opts.get('port'): |
add7bcad1d9c
server: move service factory from hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30507
diff
changeset
|
162 opts['port'] = util.getport(opts.get('port')) |
add7bcad1d9c
server: move service factory from hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30507
diff
changeset
|
163 |
32291
bd872f64a8ba
cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents:
32005
diff
changeset
|
164 alluis = {ui} |
30509
add7bcad1d9c
server: move service factory from hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30507
diff
changeset
|
165 if repo: |
add7bcad1d9c
server: move service factory from hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30507
diff
changeset
|
166 baseui = repo.baseui |
add7bcad1d9c
server: move service factory from hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30507
diff
changeset
|
167 alluis.update([repo.baseui, repo.ui]) |
add7bcad1d9c
server: move service factory from hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30507
diff
changeset
|
168 else: |
add7bcad1d9c
server: move service factory from hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30507
diff
changeset
|
169 baseui = ui |
add7bcad1d9c
server: move service factory from hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30507
diff
changeset
|
170 webconf = opts.get('web_conf') or opts.get('webdir_conf') |
add7bcad1d9c
server: move service factory from hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30507
diff
changeset
|
171 if webconf: |
32005
2406dbba49bd
serve: add support for Mercurial subrepositories
Matt Harbison <matt_harbison@yahoo.com>
parents:
31548
diff
changeset
|
172 if opts.get('subrepos'): |
2406dbba49bd
serve: add support for Mercurial subrepositories
Matt Harbison <matt_harbison@yahoo.com>
parents:
31548
diff
changeset
|
173 raise error.Abort(_('--web-conf cannot be used with --subrepos')) |
2406dbba49bd
serve: add support for Mercurial subrepositories
Matt Harbison <matt_harbison@yahoo.com>
parents:
31548
diff
changeset
|
174 |
30509
add7bcad1d9c
server: move service factory from hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30507
diff
changeset
|
175 # load server settings (e.g. web.port) to "copied" ui, which allows |
add7bcad1d9c
server: move service factory from hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30507
diff
changeset
|
176 # hgwebdir to reload webconf cleanly |
add7bcad1d9c
server: move service factory from hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30507
diff
changeset
|
177 servui = ui.copy() |
add7bcad1d9c
server: move service factory from hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30507
diff
changeset
|
178 servui.readconfig(webconf, sections=['web']) |
add7bcad1d9c
server: move service factory from hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30507
diff
changeset
|
179 alluis.add(servui) |
32005
2406dbba49bd
serve: add support for Mercurial subrepositories
Matt Harbison <matt_harbison@yahoo.com>
parents:
31548
diff
changeset
|
180 elif opts.get('subrepos'): |
2406dbba49bd
serve: add support for Mercurial subrepositories
Matt Harbison <matt_harbison@yahoo.com>
parents:
31548
diff
changeset
|
181 servui = ui |
2406dbba49bd
serve: add support for Mercurial subrepositories
Matt Harbison <matt_harbison@yahoo.com>
parents:
31548
diff
changeset
|
182 |
2406dbba49bd
serve: add support for Mercurial subrepositories
Matt Harbison <matt_harbison@yahoo.com>
parents:
31548
diff
changeset
|
183 # If repo is None, hgweb.createapp() already raises a proper abort |
2406dbba49bd
serve: add support for Mercurial subrepositories
Matt Harbison <matt_harbison@yahoo.com>
parents:
31548
diff
changeset
|
184 # message as long as webconf is None. |
2406dbba49bd
serve: add support for Mercurial subrepositories
Matt Harbison <matt_harbison@yahoo.com>
parents:
31548
diff
changeset
|
185 if repo: |
2406dbba49bd
serve: add support for Mercurial subrepositories
Matt Harbison <matt_harbison@yahoo.com>
parents:
31548
diff
changeset
|
186 webconf = dict() |
2406dbba49bd
serve: add support for Mercurial subrepositories
Matt Harbison <matt_harbison@yahoo.com>
parents:
31548
diff
changeset
|
187 cmdutil.addwebdirpath(repo, "", webconf) |
30509
add7bcad1d9c
server: move service factory from hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30507
diff
changeset
|
188 else: |
add7bcad1d9c
server: move service factory from hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30507
diff
changeset
|
189 servui = ui |
add7bcad1d9c
server: move service factory from hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30507
diff
changeset
|
190 |
add7bcad1d9c
server: move service factory from hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30507
diff
changeset
|
191 optlist = ("name templates style address port prefix ipv6" |
add7bcad1d9c
server: move service factory from hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30507
diff
changeset
|
192 " accesslog errorlog certificate encoding") |
add7bcad1d9c
server: move service factory from hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30507
diff
changeset
|
193 for o in optlist.split(): |
add7bcad1d9c
server: move service factory from hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30507
diff
changeset
|
194 val = opts.get(o, '') |
add7bcad1d9c
server: move service factory from hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30507
diff
changeset
|
195 if val in (None, ''): # should check against default options instead |
add7bcad1d9c
server: move service factory from hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30507
diff
changeset
|
196 continue |
add7bcad1d9c
server: move service factory from hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30507
diff
changeset
|
197 for u in alluis: |
add7bcad1d9c
server: move service factory from hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30507
diff
changeset
|
198 u.setconfig("web", o, val, 'serve') |
add7bcad1d9c
server: move service factory from hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30507
diff
changeset
|
199 |
add7bcad1d9c
server: move service factory from hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30507
diff
changeset
|
200 app = hgweb.createapp(baseui, repo, webconf) |
add7bcad1d9c
server: move service factory from hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30507
diff
changeset
|
201 return hgweb.httpservice(servui, app, opts) |
30510
a0878bc87379
server: add public function to select either cmdserver or hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30509
diff
changeset
|
202 |
a0878bc87379
server: add public function to select either cmdserver or hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30509
diff
changeset
|
203 def createservice(ui, repo, opts): |
a0878bc87379
server: add public function to select either cmdserver or hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30509
diff
changeset
|
204 if opts["cmdserver"]: |
a0878bc87379
server: add public function to select either cmdserver or hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30509
diff
changeset
|
205 return _createcmdservice(ui, repo, opts) |
a0878bc87379
server: add public function to select either cmdserver or hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30509
diff
changeset
|
206 else: |
a0878bc87379
server: add public function to select either cmdserver or hgweb
Yuya Nishihara <yuya@tcha.org>
parents:
30509
diff
changeset
|
207 return _createhgwebservice(ui, repo, opts) |