Mercurial > hg
annotate hgext/chgserver.py @ 29500:4b16a5bd9948
sslutil: try to find CA certficates in well-known locations
Many Linux distros and other Nixen have CA certificates in well-defined
locations. Rather than potentially fail to load any CA certificates at
all (which will always result in a certificate verification failure),
we scan for paths to known CA certificate files and load one if seen.
Because a proper Mercurial install will have the path to the CA
certificate file defined at install time, we print a warning that
the install isn't proper and provide a URL with instructions to
correct things.
We only perform path-based fallback on Pythons that don't know
how to call into OpenSSL to load the default verify locations. This
is because we trust that Python/OpenSSL is properly configured
and knows better than Mercurial. So this new code effectively only
runs on Python <2.7.9 (technically Pythons without the modern ssl
module).
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Wed, 06 Jul 2016 21:16:00 -0700 |
parents | 71ed5a3ef8a9 |
children | 540c01a18bb7 |
rev | line source |
---|---|
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
1 # chgserver.py - command server extension for cHg |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
2 # |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
3 # Copyright 2011 Yuya Nishihara <yuya@tcha.org> |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
4 # |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
5 # This software may be used and distributed according to the terms of the |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
6 # GNU General Public License version 2 or any later version. |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
7 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
8 """command server extension for cHg (EXPERIMENTAL) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
9 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
10 'S' channel (read/write) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
11 propagate ui.system() request to client |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
12 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
13 'attachio' command |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
14 attach client's stdio passed by sendmsg() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
15 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
16 'chdir' command |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
17 change current directory |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
18 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
19 'getpager' command |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
20 checks if pager is enabled and which pager should be executed |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
21 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
22 'setenv' command |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
23 replace os.environ completely |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
24 |
28325 | 25 'setumask' command |
26 set umask | |
27 | |
28350
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
28 'validate' command |
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
29 reload the config and check if the server is up to date |
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
30 |
28325 | 31 Config |
32 ------ | |
33 | |
34 :: | |
35 | |
36 [chgserver] | |
37 idletimeout = 3600 # seconds, after which an idle server will exit | |
28326
ea400a4f32e6
chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents:
28325
diff
changeset
|
38 skiphash = False # whether to skip config or env change checks |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
39 """ |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
40 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
41 from __future__ import absolute_import |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
42 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
43 import errno |
28553
5346e9b910fc
chgserver: add an explicit gc to trigger __del__
Jun Wu <quark@fb.com>
parents:
28537
diff
changeset
|
44 import gc |
29341
0d83ad967bf8
cleanup: replace uses of util.(md5|sha1|sha256|sha512) with hashlib.\1
Augie Fackler <raf@durin42.com>
parents:
29101
diff
changeset
|
45 import hashlib |
28276
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
46 import inspect |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
47 import os |
28770
97c8da2f89f9
chgserver: change random state after fork
Jun Wu <quark@fb.com>
parents:
28768
diff
changeset
|
48 import random |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
49 import re |
29428
247ea0dfdb94
chgserver: do not ignore SIGPIPE if pager is used
Jun Wu <quark@fb.com>
parents:
29341
diff
changeset
|
50 import signal |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
51 import struct |
28276
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
52 import sys |
28223
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
53 import threading |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
54 import time |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
55 import traceback |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
56 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
57 from mercurial.i18n import _ |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
58 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
59 from mercurial import ( |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
60 cmdutil, |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
61 commands, |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
62 commandserver, |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
63 dispatch, |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
64 error, |
28276
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
65 extensions, |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
66 osutil, |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
67 util, |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
68 ) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
69 |
29433
33770d2b6cf9
py3: conditionalize SocketServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents:
29428
diff
changeset
|
70 socketserver = util.socketserver |
33770d2b6cf9
py3: conditionalize SocketServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents:
29428
diff
changeset
|
71 |
27793
8c9bbf5cd349
chgserver: mark as a built-in extension
Yuya Nishihara <yuya@tcha.org>
parents:
27792
diff
changeset
|
72 # Note for extension authors: ONLY specify testedwith = 'internal' for |
8c9bbf5cd349
chgserver: mark as a built-in extension
Yuya Nishihara <yuya@tcha.org>
parents:
27792
diff
changeset
|
73 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should |
8c9bbf5cd349
chgserver: mark as a built-in extension
Yuya Nishihara <yuya@tcha.org>
parents:
27792
diff
changeset
|
74 # be specifying the version(s) of Mercurial they are tested with, or |
8c9bbf5cd349
chgserver: mark as a built-in extension
Yuya Nishihara <yuya@tcha.org>
parents:
27792
diff
changeset
|
75 # leave the attribute unspecified. |
8c9bbf5cd349
chgserver: mark as a built-in extension
Yuya Nishihara <yuya@tcha.org>
parents:
27792
diff
changeset
|
76 testedwith = 'internal' |
8c9bbf5cd349
chgserver: mark as a built-in extension
Yuya Nishihara <yuya@tcha.org>
parents:
27792
diff
changeset
|
77 |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
78 _log = commandserver.log |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
79 |
28262
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
80 def _hashlist(items): |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
81 """return sha1 hexdigest for a list""" |
29341
0d83ad967bf8
cleanup: replace uses of util.(md5|sha1|sha256|sha512) with hashlib.\1
Augie Fackler <raf@durin42.com>
parents:
29101
diff
changeset
|
82 return hashlib.sha1(str(items)).hexdigest() |
28262
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
83 |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
84 # sensitive config sections affecting confighash |
28478
e6e183687545
chgserver: include [extdiff] in confighash
Jun Wu <quark@fb.com>
parents:
28454
diff
changeset
|
85 _configsections = [ |
29101
57a24a85a2bc
chgserver: add [alias] to confighash
Jun Wu <quark@fb.com>
parents:
29088
diff
changeset
|
86 'alias', # affects global state commands.table |
28478
e6e183687545
chgserver: include [extdiff] in confighash
Jun Wu <quark@fb.com>
parents:
28454
diff
changeset
|
87 'extdiff', # uisetup will register new commands |
e6e183687545
chgserver: include [extdiff] in confighash
Jun Wu <quark@fb.com>
parents:
28454
diff
changeset
|
88 'extensions', |
e6e183687545
chgserver: include [extdiff] in confighash
Jun Wu <quark@fb.com>
parents:
28454
diff
changeset
|
89 ] |
28262
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
90 |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
91 # sensitive environment variables affecting confighash |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
92 _envre = re.compile(r'''\A(?: |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
93 CHGHG |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
94 |HG.* |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
95 |LANG(?:UAGE)? |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
96 |LC_.* |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
97 |LD_.* |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
98 |PATH |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
99 |PYTHON.* |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
100 |TERM(?:INFO)? |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
101 |TZ |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
102 )\Z''', re.X) |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
103 |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
104 def _confighash(ui): |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
105 """return a quick hash for detecting config/env changes |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
106 |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
107 confighash is the hash of sensitive config items and environment variables. |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
108 |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
109 for chgserver, it is designed that once confighash changes, the server is |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
110 not qualified to serve its client and should redirect the client to a new |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
111 server. different from mtimehash, confighash change will not mark the |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
112 server outdated and exit since the user can have different configs at the |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
113 same time. |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
114 """ |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
115 sectionitems = [] |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
116 for section in _configsections: |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
117 sectionitems.append(ui.configitems(section)) |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
118 sectionhash = _hashlist(sectionitems) |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
119 envitems = [(k, v) for k, v in os.environ.iteritems() if _envre.match(k)] |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
120 envhash = _hashlist(sorted(envitems)) |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
121 return sectionhash[:6] + envhash[:6] |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
122 |
28276
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
123 def _getmtimepaths(ui): |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
124 """get a list of paths that should be checked to detect change |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
125 |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
126 The list will include: |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
127 - extensions (will not cover all files for complex extensions) |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
128 - mercurial/__version__.py |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
129 - python binary |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
130 """ |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
131 modules = [m for n, m in extensions.extensions(ui)] |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
132 try: |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
133 from mercurial import __version__ |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
134 modules.append(__version__) |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
135 except ImportError: |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
136 pass |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
137 files = [sys.executable] |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
138 for m in modules: |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
139 try: |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
140 files.append(inspect.getabsfile(m)) |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
141 except TypeError: |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
142 pass |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
143 return sorted(set(files)) |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
144 |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
145 def _mtimehash(paths): |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
146 """return a quick hash for detecting file changes |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
147 |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
148 mtimehash calls stat on given paths and calculate a hash based on size and |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
149 mtime of each file. mtimehash does not read file content because reading is |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
150 expensive. therefore it's not 100% reliable for detecting content changes. |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
151 it's possible to return different hashes for same file contents. |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
152 it's also possible to return a same hash for different file contents for |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
153 some carefully crafted situation. |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
154 |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
155 for chgserver, it is designed that once mtimehash changes, the server is |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
156 considered outdated immediately and should no longer provide service. |
29462
71ed5a3ef8a9
chgserver: document why we don't merge mtimehash and confighash
Jun Wu <quark@fb.com>
parents:
29433
diff
changeset
|
157 |
71ed5a3ef8a9
chgserver: document why we don't merge mtimehash and confighash
Jun Wu <quark@fb.com>
parents:
29433
diff
changeset
|
158 mtimehash is not included in confighash because we only know the paths of |
71ed5a3ef8a9
chgserver: document why we don't merge mtimehash and confighash
Jun Wu <quark@fb.com>
parents:
29433
diff
changeset
|
159 extensions after importing them (there is imp.find_module but that faces |
71ed5a3ef8a9
chgserver: document why we don't merge mtimehash and confighash
Jun Wu <quark@fb.com>
parents:
29433
diff
changeset
|
160 race conditions). We need to calculate confighash without importing. |
28276
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
161 """ |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
162 def trystat(path): |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
163 try: |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
164 st = os.stat(path) |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
165 return (st.st_mtime, st.st_size) |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
166 except OSError: |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
167 # could be ENOENT, EPERM etc. not fatal in any case |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
168 pass |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
169 return _hashlist(map(trystat, paths))[:12] |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
170 |
28277
cdc6319f6a7d
chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents:
28276
diff
changeset
|
171 class hashstate(object): |
cdc6319f6a7d
chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents:
28276
diff
changeset
|
172 """a structure storing confighash, mtimehash, paths used for mtimehash""" |
cdc6319f6a7d
chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents:
28276
diff
changeset
|
173 def __init__(self, confighash, mtimehash, mtimepaths): |
cdc6319f6a7d
chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents:
28276
diff
changeset
|
174 self.confighash = confighash |
cdc6319f6a7d
chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents:
28276
diff
changeset
|
175 self.mtimehash = mtimehash |
cdc6319f6a7d
chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents:
28276
diff
changeset
|
176 self.mtimepaths = mtimepaths |
cdc6319f6a7d
chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents:
28276
diff
changeset
|
177 |
cdc6319f6a7d
chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents:
28276
diff
changeset
|
178 @staticmethod |
cdc6319f6a7d
chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents:
28276
diff
changeset
|
179 def fromui(ui, mtimepaths=None): |
cdc6319f6a7d
chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents:
28276
diff
changeset
|
180 if mtimepaths is None: |
cdc6319f6a7d
chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents:
28276
diff
changeset
|
181 mtimepaths = _getmtimepaths(ui) |
cdc6319f6a7d
chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents:
28276
diff
changeset
|
182 confighash = _confighash(ui) |
cdc6319f6a7d
chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents:
28276
diff
changeset
|
183 mtimehash = _mtimehash(mtimepaths) |
cdc6319f6a7d
chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents:
28276
diff
changeset
|
184 _log('confighash = %s mtimehash = %s\n' % (confighash, mtimehash)) |
cdc6319f6a7d
chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents:
28276
diff
changeset
|
185 return hashstate(confighash, mtimehash, mtimepaths) |
cdc6319f6a7d
chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents:
28276
diff
changeset
|
186 |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
187 # copied from hgext/pager.py:uisetup() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
188 def _setuppagercmd(ui, options, cmd): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
189 if not ui.formatted(): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
190 return |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
191 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
192 p = ui.config("pager", "pager", os.environ.get("PAGER")) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
193 usepager = False |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
194 always = util.parsebool(options['pager']) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
195 auto = options['pager'] == 'auto' |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
196 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
197 if not p: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
198 pass |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
199 elif always: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
200 usepager = True |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
201 elif not auto: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
202 usepager = False |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
203 else: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
204 attended = ['annotate', 'cat', 'diff', 'export', 'glog', 'log', 'qdiff'] |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
205 attend = ui.configlist('pager', 'attend', attended) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
206 ignore = ui.configlist('pager', 'ignore') |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
207 cmds, _ = cmdutil.findcmd(cmd, commands.table) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
208 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
209 for cmd in cmds: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
210 var = 'attend-%s' % cmd |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
211 if ui.config('pager', var): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
212 usepager = ui.configbool('pager', var) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
213 break |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
214 if (cmd in attend or |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
215 (cmd not in ignore and not attend)): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
216 usepager = True |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
217 break |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
218 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
219 if usepager: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
220 ui.setconfig('ui', 'formatted', ui.formatted(), 'pager') |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
221 ui.setconfig('ui', 'interactive', False, 'pager') |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
222 return p |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
223 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
224 def _newchgui(srcui, csystem): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
225 class chgui(srcui.__class__): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
226 def __init__(self, src=None): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
227 super(chgui, self).__init__(src) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
228 if src: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
229 self._csystem = getattr(src, '_csystem', csystem) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
230 else: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
231 self._csystem = csystem |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
232 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
233 def system(self, cmd, environ=None, cwd=None, onerr=None, |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
234 errprefix=None): |
28586
82cee85d5274
chgserver: use old ui.system if fout is not stdout or needs to be captured
Jun Wu <quark@fb.com>
parents:
28553
diff
changeset
|
235 # fallback to the original system method if the output needs to be |
82cee85d5274
chgserver: use old ui.system if fout is not stdout or needs to be captured
Jun Wu <quark@fb.com>
parents:
28553
diff
changeset
|
236 # captured (to self._buffers), or the output stream is not stdout |
82cee85d5274
chgserver: use old ui.system if fout is not stdout or needs to be captured
Jun Wu <quark@fb.com>
parents:
28553
diff
changeset
|
237 # (e.g. stderr, cStringIO), because the chg client is not aware of |
82cee85d5274
chgserver: use old ui.system if fout is not stdout or needs to be captured
Jun Wu <quark@fb.com>
parents:
28553
diff
changeset
|
238 # these situations and will behave differently (write to stdout). |
82cee85d5274
chgserver: use old ui.system if fout is not stdout or needs to be captured
Jun Wu <quark@fb.com>
parents:
28553
diff
changeset
|
239 if (any(s[1] for s in self._bufferstates) |
82cee85d5274
chgserver: use old ui.system if fout is not stdout or needs to be captured
Jun Wu <quark@fb.com>
parents:
28553
diff
changeset
|
240 or not util.safehasattr(self.fout, 'fileno') |
82cee85d5274
chgserver: use old ui.system if fout is not stdout or needs to be captured
Jun Wu <quark@fb.com>
parents:
28553
diff
changeset
|
241 or self.fout.fileno() != sys.stdout.fileno()): |
82cee85d5274
chgserver: use old ui.system if fout is not stdout or needs to be captured
Jun Wu <quark@fb.com>
parents:
28553
diff
changeset
|
242 return super(chgui, self).system(cmd, environ, cwd, onerr, |
82cee85d5274
chgserver: use old ui.system if fout is not stdout or needs to be captured
Jun Wu <quark@fb.com>
parents:
28553
diff
changeset
|
243 errprefix) |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
244 # copied from mercurial/util.py:system() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
245 self.flush() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
246 def py2shell(val): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
247 if val is None or val is False: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
248 return '0' |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
249 if val is True: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
250 return '1' |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
251 return str(val) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
252 env = os.environ.copy() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
253 if environ: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
254 env.update((k, py2shell(v)) for k, v in environ.iteritems()) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
255 env['HG'] = util.hgexecutable() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
256 rc = self._csystem(cmd, env, cwd) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
257 if rc and onerr: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
258 errmsg = '%s %s' % (os.path.basename(cmd.split(None, 1)[0]), |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
259 util.explainexit(rc)[0]) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
260 if errprefix: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
261 errmsg = '%s: %s' % (errprefix, errmsg) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
262 raise onerr(errmsg) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
263 return rc |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
264 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
265 return chgui(srcui) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
266 |
28602
83127a9fe76e
chgserver: drop old hack to recreate ui on HGPLAIN change
Yuya Nishihara <yuya@tcha.org>
parents:
28599
diff
changeset
|
267 def _loadnewui(srcui, args): |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
268 newui = srcui.__class__() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
269 for a in ['fin', 'fout', 'ferr', 'environ']: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
270 setattr(newui, a, getattr(srcui, a)) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
271 if util.safehasattr(srcui, '_csystem'): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
272 newui._csystem = srcui._csystem |
28264
3682e201cce6
chgserver: make _renewui load repo and command line configs
Jun Wu <quark@fb.com>
parents:
28262
diff
changeset
|
273 |
3682e201cce6
chgserver: make _renewui load repo and command line configs
Jun Wu <quark@fb.com>
parents:
28262
diff
changeset
|
274 # internal config: extensions.chgserver |
3682e201cce6
chgserver: make _renewui load repo and command line configs
Jun Wu <quark@fb.com>
parents:
28262
diff
changeset
|
275 newui.setconfig('extensions', 'chgserver', |
3682e201cce6
chgserver: make _renewui load repo and command line configs
Jun Wu <quark@fb.com>
parents:
28262
diff
changeset
|
276 srcui.config('extensions', 'chgserver'), '--config') |
3682e201cce6
chgserver: make _renewui load repo and command line configs
Jun Wu <quark@fb.com>
parents:
28262
diff
changeset
|
277 |
3682e201cce6
chgserver: make _renewui load repo and command line configs
Jun Wu <quark@fb.com>
parents:
28262
diff
changeset
|
278 # command line args |
28767
73bfd9a54a5c
chgserver: move args copying logic to the correct place
Jun Wu <quark@fb.com>
parents:
28603
diff
changeset
|
279 args = args[:] |
28264
3682e201cce6
chgserver: make _renewui load repo and command line configs
Jun Wu <quark@fb.com>
parents:
28262
diff
changeset
|
280 dispatch._parseconfig(newui, dispatch._earlygetopt(['--config'], args)) |
3682e201cce6
chgserver: make _renewui load repo and command line configs
Jun Wu <quark@fb.com>
parents:
28262
diff
changeset
|
281 |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
282 # stolen from tortoisehg.util.copydynamicconfig() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
283 for section, name, value in srcui.walkconfig(): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
284 source = srcui.configsource(section, name) |
28264
3682e201cce6
chgserver: make _renewui load repo and command line configs
Jun Wu <quark@fb.com>
parents:
28262
diff
changeset
|
285 if ':' in source or source == '--config': |
3682e201cce6
chgserver: make _renewui load repo and command line configs
Jun Wu <quark@fb.com>
parents:
28262
diff
changeset
|
286 # path:line or command line |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
287 continue |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
288 if source == 'none': |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
289 # ui.configsource returns 'none' by default |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
290 source = '' |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
291 newui.setconfig(section, name, value, source) |
28599
0e7a929754aa
chgserver: use global ui instead of repo ui for dispatch.request.ui
Jun Wu <quark@fb.com>
parents:
28586
diff
changeset
|
292 |
0e7a929754aa
chgserver: use global ui instead of repo ui for dispatch.request.ui
Jun Wu <quark@fb.com>
parents:
28586
diff
changeset
|
293 # load wd and repo config, copied from dispatch.py |
0e7a929754aa
chgserver: use global ui instead of repo ui for dispatch.request.ui
Jun Wu <quark@fb.com>
parents:
28586
diff
changeset
|
294 cwds = dispatch._earlygetopt(['--cwd'], args) |
0e7a929754aa
chgserver: use global ui instead of repo ui for dispatch.request.ui
Jun Wu <quark@fb.com>
parents:
28586
diff
changeset
|
295 cwd = cwds and os.path.realpath(cwds[-1]) or None |
0e7a929754aa
chgserver: use global ui instead of repo ui for dispatch.request.ui
Jun Wu <quark@fb.com>
parents:
28586
diff
changeset
|
296 rpath = dispatch._earlygetopt(["-R", "--repository", "--repo"], args) |
0e7a929754aa
chgserver: use global ui instead of repo ui for dispatch.request.ui
Jun Wu <quark@fb.com>
parents:
28586
diff
changeset
|
297 path, newlui = dispatch._getlocal(newui, rpath, wd=cwd) |
0e7a929754aa
chgserver: use global ui instead of repo ui for dispatch.request.ui
Jun Wu <quark@fb.com>
parents:
28586
diff
changeset
|
298 |
0e7a929754aa
chgserver: use global ui instead of repo ui for dispatch.request.ui
Jun Wu <quark@fb.com>
parents:
28586
diff
changeset
|
299 return (newui, newlui) |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
300 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
301 class channeledsystem(object): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
302 """Propagate ui.system() request in the following format: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
303 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
304 payload length (unsigned int), |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
305 cmd, '\0', |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
306 cwd, '\0', |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
307 envkey, '=', val, '\0', |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
308 ... |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
309 envkey, '=', val |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
310 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
311 and waits: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
312 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
313 exitcode length (unsigned int), |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
314 exitcode (int) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
315 """ |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
316 def __init__(self, in_, out, channel): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
317 self.in_ = in_ |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
318 self.out = out |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
319 self.channel = channel |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
320 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
321 def __call__(self, cmd, environ, cwd): |
28514
0747ef2c4ab2
chgserver: resolve relative path before sending via system channel
Jun Wu <quark@fb.com>
parents:
28511
diff
changeset
|
322 args = [util.quotecommand(cmd), os.path.abspath(cwd or '.')] |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
323 args.extend('%s=%s' % (k, v) for k, v in environ.iteritems()) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
324 data = '\0'.join(args) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
325 self.out.write(struct.pack('>cI', self.channel, len(data))) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
326 self.out.write(data) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
327 self.out.flush() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
328 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
329 length = self.in_.read(4) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
330 length, = struct.unpack('>I', length) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
331 if length != 4: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
332 raise error.Abort(_('invalid response')) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
333 rc, = struct.unpack('>i', self.in_.read(4)) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
334 return rc |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
335 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
336 _iochannels = [ |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
337 # server.ch, ui.fp, mode |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
338 ('cin', 'fin', 'rb'), |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
339 ('cout', 'fout', 'wb'), |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
340 ('cerr', 'ferr', 'wb'), |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
341 ] |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
342 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
343 class chgcmdserver(commandserver.server): |
28328
e00e57d83653
chgserver: pass hashstate and base server address to chgcmdserver
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
344 def __init__(self, ui, repo, fin, fout, sock, hashstate, baseaddress): |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
345 super(chgcmdserver, self).__init__( |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
346 _newchgui(ui, channeledsystem(fin, fout, 'S')), repo, fin, fout) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
347 self.clientsock = sock |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
348 self._oldios = [] # original (self.ch, ui.fp, fd) before "attachio" |
28328
e00e57d83653
chgserver: pass hashstate and base server address to chgcmdserver
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
349 self.hashstate = hashstate |
e00e57d83653
chgserver: pass hashstate and base server address to chgcmdserver
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
350 self.baseaddress = baseaddress |
28350
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
351 if hashstate is not None: |
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
352 self.capabilities = self.capabilities.copy() |
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
353 self.capabilities['validate'] = chgcmdserver.validate |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
354 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
355 def cleanup(self): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
356 # dispatch._runcatch() does not flush outputs if exception is not |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
357 # handled by dispatch._dispatch() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
358 self.ui.flush() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
359 self._restoreio() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
360 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
361 def attachio(self): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
362 """Attach to client's stdio passed via unix domain socket; all |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
363 channels except cresult will no longer be used |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
364 """ |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
365 # tell client to sendmsg() with 1-byte payload, which makes it |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
366 # distinctive from "attachio\n" command consumed by client.read() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
367 self.clientsock.sendall(struct.pack('>cI', 'I', 1)) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
368 clientfds = osutil.recvfds(self.clientsock.fileno()) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
369 _log('received fds: %r\n' % clientfds) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
370 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
371 ui = self.ui |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
372 ui.flush() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
373 first = self._saveio() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
374 for fd, (cn, fn, mode) in zip(clientfds, _iochannels): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
375 assert fd > 0 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
376 fp = getattr(ui, fn) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
377 os.dup2(fd, fp.fileno()) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
378 os.close(fd) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
379 if not first: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
380 continue |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
381 # reset buffering mode when client is first attached. as we want |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
382 # to see output immediately on pager, the mode stays unchanged |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
383 # when client re-attached. ferr is unchanged because it should |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
384 # be unbuffered no matter if it is a tty or not. |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
385 if fn == 'ferr': |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
386 newfp = fp |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
387 else: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
388 # make it line buffered explicitly because the default is |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
389 # decided on first write(), where fout could be a pager. |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
390 if fp.isatty(): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
391 bufsize = 1 # line buffered |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
392 else: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
393 bufsize = -1 # system default |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
394 newfp = os.fdopen(fp.fileno(), mode, bufsize) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
395 setattr(ui, fn, newfp) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
396 setattr(self, cn, newfp) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
397 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
398 self.cresult.write(struct.pack('>i', len(clientfds))) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
399 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
400 def _saveio(self): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
401 if self._oldios: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
402 return False |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
403 ui = self.ui |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
404 for cn, fn, _mode in _iochannels: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
405 ch = getattr(self, cn) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
406 fp = getattr(ui, fn) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
407 fd = os.dup(fp.fileno()) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
408 self._oldios.append((ch, fp, fd)) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
409 return True |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
410 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
411 def _restoreio(self): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
412 ui = self.ui |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
413 for (ch, fp, fd), (cn, fn, _mode) in zip(self._oldios, _iochannels): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
414 newfp = getattr(ui, fn) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
415 # close newfp while it's associated with client; otherwise it |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
416 # would be closed when newfp is deleted |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
417 if newfp is not fp: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
418 newfp.close() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
419 # restore original fd: fp is open again |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
420 os.dup2(fd, fp.fileno()) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
421 os.close(fd) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
422 setattr(self, cn, ch) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
423 setattr(ui, fn, fp) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
424 del self._oldios[:] |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
425 |
28350
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
426 def validate(self): |
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
427 """Reload the config and check if the server is up to date |
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
428 |
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
429 Read a list of '\0' separated arguments. |
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
430 Write a non-empty list of '\0' separated instruction strings or '\0' |
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
431 if the list is empty. |
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
432 An instruction string could be either: |
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
433 - "unlink $path", the client should unlink the path to stop the |
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
434 outdated server. |
28535
aa082a8125da
chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents:
28516
diff
changeset
|
435 - "redirect $path", the client should attempt to connect to $path |
aa082a8125da
chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents:
28516
diff
changeset
|
436 first. If it does not work, start a new server. It implies |
aa082a8125da
chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents:
28516
diff
changeset
|
437 "reconnect". |
28516
3bf2892f685f
chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents:
28514
diff
changeset
|
438 - "exit $n", the client should exit directly with code n. |
3bf2892f685f
chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents:
28514
diff
changeset
|
439 This may happen if we cannot parse the config. |
28535
aa082a8125da
chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents:
28516
diff
changeset
|
440 - "reconnect", the client should close the connection and |
aa082a8125da
chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents:
28516
diff
changeset
|
441 reconnect. |
aa082a8125da
chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents:
28516
diff
changeset
|
442 If neither "reconnect" nor "redirect" is included in the instruction |
aa082a8125da
chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents:
28516
diff
changeset
|
443 list, the client can continue with this server after completing all |
aa082a8125da
chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents:
28516
diff
changeset
|
444 the instructions. |
28350
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
445 """ |
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
446 args = self._readlist() |
28516
3bf2892f685f
chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents:
28514
diff
changeset
|
447 try: |
28599
0e7a929754aa
chgserver: use global ui instead of repo ui for dispatch.request.ui
Jun Wu <quark@fb.com>
parents:
28586
diff
changeset
|
448 self.ui, lui = _loadnewui(self.ui, args) |
28516
3bf2892f685f
chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents:
28514
diff
changeset
|
449 except error.ParseError as inst: |
3bf2892f685f
chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents:
28514
diff
changeset
|
450 dispatch._formatparse(self.ui.warn, inst) |
3bf2892f685f
chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents:
28514
diff
changeset
|
451 self.ui.flush() |
3bf2892f685f
chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents:
28514
diff
changeset
|
452 self.cresult.write('exit 255') |
3bf2892f685f
chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents:
28514
diff
changeset
|
453 return |
28599
0e7a929754aa
chgserver: use global ui instead of repo ui for dispatch.request.ui
Jun Wu <quark@fb.com>
parents:
28586
diff
changeset
|
454 newhash = hashstate.fromui(lui, self.hashstate.mtimepaths) |
28350
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
455 insts = [] |
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
456 if newhash.mtimehash != self.hashstate.mtimehash: |
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
457 addr = _hashaddress(self.baseaddress, self.hashstate.confighash) |
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
458 insts.append('unlink %s' % addr) |
28536
a979f5b03320
chgserver: invalidate the server if extensions fail to load
Jun Wu <quark@fb.com>
parents:
28535
diff
changeset
|
459 # mtimehash is empty if one or more extensions fail to load. |
a979f5b03320
chgserver: invalidate the server if extensions fail to load
Jun Wu <quark@fb.com>
parents:
28535
diff
changeset
|
460 # to be compatible with hg, still serve the client this time. |
a979f5b03320
chgserver: invalidate the server if extensions fail to load
Jun Wu <quark@fb.com>
parents:
28535
diff
changeset
|
461 if self.hashstate.mtimehash: |
a979f5b03320
chgserver: invalidate the server if extensions fail to load
Jun Wu <quark@fb.com>
parents:
28535
diff
changeset
|
462 insts.append('reconnect') |
28350
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
463 if newhash.confighash != self.hashstate.confighash: |
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
464 addr = _hashaddress(self.baseaddress, newhash.confighash) |
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
465 insts.append('redirect %s' % addr) |
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
466 _log('validate: %s\n' % insts) |
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
467 self.cresult.write('\0'.join(insts) or '\0') |
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
468 |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
469 def chdir(self): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
470 """Change current directory |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
471 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
472 Note that the behavior of --cwd option is bit different from this. |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
473 It does not affect --config parameter. |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
474 """ |
28158
7cc57a531f0c
chgserver: use _readlist and _readstr
Jun Wu <quark@fb.com>
parents:
28014
diff
changeset
|
475 path = self._readstr() |
7cc57a531f0c
chgserver: use _readlist and _readstr
Jun Wu <quark@fb.com>
parents:
28014
diff
changeset
|
476 if not path: |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
477 return |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
478 _log('chdir to %r\n' % path) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
479 os.chdir(path) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
480 |
28159 | 481 def setumask(self): |
482 """Change umask""" | |
483 mask = struct.unpack('>I', self._read(4))[0] | |
484 _log('setumask %r\n' % mask) | |
485 os.umask(mask) | |
486 | |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
487 def getpager(self): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
488 """Read cmdargs and write pager command to r-channel if enabled |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
489 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
490 If pager isn't enabled, this writes '\0' because channeledoutput |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
491 does not allow to write empty data. |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
492 """ |
28158
7cc57a531f0c
chgserver: use _readlist and _readstr
Jun Wu <quark@fb.com>
parents:
28014
diff
changeset
|
493 args = self._readlist() |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
494 try: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
495 cmd, _func, args, options, _cmdoptions = dispatch._parse(self.ui, |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
496 args) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
497 except (error.Abort, error.AmbiguousCommand, error.CommandError, |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
498 error.UnknownCommand): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
499 cmd = None |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
500 options = {} |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
501 if not cmd or 'pager' not in options: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
502 self.cresult.write('\0') |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
503 return |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
504 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
505 pagercmd = _setuppagercmd(self.ui, options, cmd) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
506 if pagercmd: |
29428
247ea0dfdb94
chgserver: do not ignore SIGPIPE if pager is used
Jun Wu <quark@fb.com>
parents:
29341
diff
changeset
|
507 # Python's SIGPIPE is SIG_IGN by default. change to SIG_DFL so |
247ea0dfdb94
chgserver: do not ignore SIGPIPE if pager is used
Jun Wu <quark@fb.com>
parents:
29341
diff
changeset
|
508 # we can exit if the pipe to the pager is closed |
247ea0dfdb94
chgserver: do not ignore SIGPIPE if pager is used
Jun Wu <quark@fb.com>
parents:
29341
diff
changeset
|
509 if util.safehasattr(signal, 'SIGPIPE') and \ |
247ea0dfdb94
chgserver: do not ignore SIGPIPE if pager is used
Jun Wu <quark@fb.com>
parents:
29341
diff
changeset
|
510 signal.getsignal(signal.SIGPIPE) == signal.SIG_IGN: |
247ea0dfdb94
chgserver: do not ignore SIGPIPE if pager is used
Jun Wu <quark@fb.com>
parents:
29341
diff
changeset
|
511 signal.signal(signal.SIGPIPE, signal.SIG_DFL) |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
512 self.cresult.write(pagercmd) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
513 else: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
514 self.cresult.write('\0') |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
515 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
516 def setenv(self): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
517 """Clear and update os.environ |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
518 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
519 Note that not all variables can make an effect on the running process. |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
520 """ |
28158
7cc57a531f0c
chgserver: use _readlist and _readstr
Jun Wu <quark@fb.com>
parents:
28014
diff
changeset
|
521 l = self._readlist() |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
522 try: |
28158
7cc57a531f0c
chgserver: use _readlist and _readstr
Jun Wu <quark@fb.com>
parents:
28014
diff
changeset
|
523 newenv = dict(s.split('=', 1) for s in l) |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
524 except ValueError: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
525 raise ValueError('unexpected value in setenv request') |
28602
83127a9fe76e
chgserver: drop old hack to recreate ui on HGPLAIN change
Yuya Nishihara <yuya@tcha.org>
parents:
28599
diff
changeset
|
526 _log('setenv: %r\n' % sorted(newenv.keys())) |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
527 os.environ.clear() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
528 os.environ.update(newenv) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
529 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
530 capabilities = commandserver.server.capabilities.copy() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
531 capabilities.update({'attachio': attachio, |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
532 'chdir': chdir, |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
533 'getpager': getpager, |
28159 | 534 'setenv': setenv, |
535 'setumask': setumask}) | |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
536 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
537 # copied from mercurial/commandserver.py |
29433
33770d2b6cf9
py3: conditionalize SocketServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents:
29428
diff
changeset
|
538 class _requesthandler(socketserver.StreamRequestHandler): |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
539 def handle(self): |
28014
83fc0c055664
chgserver: create new process group after fork (issue5051)
Jun Wu <quark@fb.com>
parents:
27793
diff
changeset
|
540 # use a different process group from the master process, making this |
83fc0c055664
chgserver: create new process group after fork (issue5051)
Jun Wu <quark@fb.com>
parents:
27793
diff
changeset
|
541 # process pass kernel "is_current_pgrp_orphaned" check so signals like |
83fc0c055664
chgserver: create new process group after fork (issue5051)
Jun Wu <quark@fb.com>
parents:
27793
diff
changeset
|
542 # SIGTSTP, SIGTTIN, SIGTTOU are not ignored. |
83fc0c055664
chgserver: create new process group after fork (issue5051)
Jun Wu <quark@fb.com>
parents:
27793
diff
changeset
|
543 os.setpgid(0, 0) |
28770
97c8da2f89f9
chgserver: change random state after fork
Jun Wu <quark@fb.com>
parents:
28768
diff
changeset
|
544 # change random state otherwise forked request handlers would have a |
97c8da2f89f9
chgserver: change random state after fork
Jun Wu <quark@fb.com>
parents:
28768
diff
changeset
|
545 # same state inherited from parent. |
97c8da2f89f9
chgserver: change random state after fork
Jun Wu <quark@fb.com>
parents:
28768
diff
changeset
|
546 random.seed() |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
547 ui = self.server.ui |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
548 repo = self.server.repo |
28511
ff5f923fca3c
cmdserver: write early exception to 'e' channel in 'unix' mode
Yuya Nishihara <yuya@tcha.org>
parents:
28482
diff
changeset
|
549 sv = None |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
550 try: |
28511
ff5f923fca3c
cmdserver: write early exception to 'e' channel in 'unix' mode
Yuya Nishihara <yuya@tcha.org>
parents:
28482
diff
changeset
|
551 sv = chgcmdserver(ui, repo, self.rfile, self.wfile, self.connection, |
ff5f923fca3c
cmdserver: write early exception to 'e' channel in 'unix' mode
Yuya Nishihara <yuya@tcha.org>
parents:
28482
diff
changeset
|
552 self.server.hashstate, self.server.baseaddress) |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
553 try: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
554 sv.serve() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
555 # handle exceptions that may be raised by command server. most of |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
556 # known exceptions are caught by dispatch. |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
557 except error.Abort as inst: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
558 ui.warn(_('abort: %s\n') % inst) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
559 except IOError as inst: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
560 if inst.errno != errno.EPIPE: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
561 raise |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
562 except KeyboardInterrupt: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
563 pass |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
564 finally: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
565 sv.cleanup() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
566 except: # re-raises |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
567 # also write traceback to error channel. otherwise client cannot |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
568 # see it because it is written to server's stderr by default. |
28511
ff5f923fca3c
cmdserver: write early exception to 'e' channel in 'unix' mode
Yuya Nishihara <yuya@tcha.org>
parents:
28482
diff
changeset
|
569 if sv: |
ff5f923fca3c
cmdserver: write early exception to 'e' channel in 'unix' mode
Yuya Nishihara <yuya@tcha.org>
parents:
28482
diff
changeset
|
570 cerr = sv.cerr |
ff5f923fca3c
cmdserver: write early exception to 'e' channel in 'unix' mode
Yuya Nishihara <yuya@tcha.org>
parents:
28482
diff
changeset
|
571 else: |
ff5f923fca3c
cmdserver: write early exception to 'e' channel in 'unix' mode
Yuya Nishihara <yuya@tcha.org>
parents:
28482
diff
changeset
|
572 cerr = commandserver.channeledoutput(self.wfile, 'e') |
ff5f923fca3c
cmdserver: write early exception to 'e' channel in 'unix' mode
Yuya Nishihara <yuya@tcha.org>
parents:
28482
diff
changeset
|
573 traceback.print_exc(file=cerr) |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
574 raise |
28553
5346e9b910fc
chgserver: add an explicit gc to trigger __del__
Jun Wu <quark@fb.com>
parents:
28537
diff
changeset
|
575 finally: |
5346e9b910fc
chgserver: add an explicit gc to trigger __del__
Jun Wu <quark@fb.com>
parents:
28537
diff
changeset
|
576 # trigger __del__ since ForkingMixIn uses os._exit |
5346e9b910fc
chgserver: add an explicit gc to trigger __del__
Jun Wu <quark@fb.com>
parents:
28537
diff
changeset
|
577 gc.collect() |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
578 |
28223
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
579 def _tempaddress(address): |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
580 return '%s.%d.tmp' % (address, os.getpid()) |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
581 |
28326
ea400a4f32e6
chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents:
28325
diff
changeset
|
582 def _hashaddress(address, hashstr): |
ea400a4f32e6
chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents:
28325
diff
changeset
|
583 return '%s-%s' % (address, hashstr) |
ea400a4f32e6
chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents:
28325
diff
changeset
|
584 |
28223
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
585 class AutoExitMixIn: # use old-style to comply with SocketServer design |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
586 lastactive = time.time() |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
587 idletimeout = 3600 # default 1 hour |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
588 |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
589 def startautoexitthread(self): |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
590 # note: the auto-exit check here is cheap enough to not use a thread, |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
591 # be done in serve_forever. however SocketServer is hook-unfriendly, |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
592 # you simply cannot hook serve_forever without copying a lot of code. |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
593 # besides, serve_forever's docstring suggests using thread. |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
594 thread = threading.Thread(target=self._autoexitloop) |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
595 thread.daemon = True |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
596 thread.start() |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
597 |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
598 def _autoexitloop(self, interval=1): |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
599 while True: |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
600 time.sleep(interval) |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
601 if not self.issocketowner(): |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
602 _log('%s is not owned, exiting.\n' % self.server_address) |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
603 break |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
604 if time.time() - self.lastactive > self.idletimeout: |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
605 _log('being idle too long. exiting.\n') |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
606 break |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
607 self.shutdown() |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
608 |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
609 def process_request(self, request, address): |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
610 self.lastactive = time.time() |
29433
33770d2b6cf9
py3: conditionalize SocketServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents:
29428
diff
changeset
|
611 return socketserver.ForkingMixIn.process_request( |
28223
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
612 self, request, address) |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
613 |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
614 def server_bind(self): |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
615 # use a unique temp address so we can stat the file and do ownership |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
616 # check later |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
617 tempaddress = _tempaddress(self.server_address) |
28768
2461f33c9f97
chgserver: use relative path at socket.bind
Jun Wu <quark@fb.com>
parents:
28767
diff
changeset
|
618 # use relative path instead of full path at bind() if possible, since |
2461f33c9f97
chgserver: use relative path at socket.bind
Jun Wu <quark@fb.com>
parents:
28767
diff
changeset
|
619 # AF_UNIX path has very small length limit (107 chars) on common |
2461f33c9f97
chgserver: use relative path at socket.bind
Jun Wu <quark@fb.com>
parents:
28767
diff
changeset
|
620 # platforms (see sys/un.h) |
2461f33c9f97
chgserver: use relative path at socket.bind
Jun Wu <quark@fb.com>
parents:
28767
diff
changeset
|
621 dirname, basename = os.path.split(tempaddress) |
2461f33c9f97
chgserver: use relative path at socket.bind
Jun Wu <quark@fb.com>
parents:
28767
diff
changeset
|
622 bakwdfd = None |
2461f33c9f97
chgserver: use relative path at socket.bind
Jun Wu <quark@fb.com>
parents:
28767
diff
changeset
|
623 if dirname: |
2461f33c9f97
chgserver: use relative path at socket.bind
Jun Wu <quark@fb.com>
parents:
28767
diff
changeset
|
624 bakwdfd = os.open('.', os.O_DIRECTORY) |
2461f33c9f97
chgserver: use relative path at socket.bind
Jun Wu <quark@fb.com>
parents:
28767
diff
changeset
|
625 os.chdir(dirname) |
2461f33c9f97
chgserver: use relative path at socket.bind
Jun Wu <quark@fb.com>
parents:
28767
diff
changeset
|
626 self.socket.bind(basename) |
2461f33c9f97
chgserver: use relative path at socket.bind
Jun Wu <quark@fb.com>
parents:
28767
diff
changeset
|
627 self._socketstat = os.stat(basename) |
28223
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
628 # rename will replace the old socket file if exists atomically. the |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
629 # old server will detect ownership change and exit. |
28768
2461f33c9f97
chgserver: use relative path at socket.bind
Jun Wu <quark@fb.com>
parents:
28767
diff
changeset
|
630 util.rename(basename, self.server_address) |
2461f33c9f97
chgserver: use relative path at socket.bind
Jun Wu <quark@fb.com>
parents:
28767
diff
changeset
|
631 if bakwdfd: |
2461f33c9f97
chgserver: use relative path at socket.bind
Jun Wu <quark@fb.com>
parents:
28767
diff
changeset
|
632 os.fchdir(bakwdfd) |
2461f33c9f97
chgserver: use relative path at socket.bind
Jun Wu <quark@fb.com>
parents:
28767
diff
changeset
|
633 os.close(bakwdfd) |
28223
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
634 |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
635 def issocketowner(self): |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
636 try: |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
637 stat = os.stat(self.server_address) |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
638 return (stat.st_ino == self._socketstat.st_ino and |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
639 stat.st_mtime == self._socketstat.st_mtime) |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
640 except OSError: |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
641 return False |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
642 |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
643 def unlinksocketfile(self): |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
644 if not self.issocketowner(): |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
645 return |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
646 # it is possible to have a race condition here that we may |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
647 # remove another server's socket file. but that's okay |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
648 # since that server will detect and exit automatically and |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
649 # the client will start a new server on demand. |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
650 try: |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
651 os.unlink(self.server_address) |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
652 except OSError as exc: |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
653 if exc.errno != errno.ENOENT: |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
654 raise |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
655 |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
656 class chgunixservice(commandserver.unixservice): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
657 def init(self): |
28603
f467073cd798
chgserver: drop bundle.mainreporoot config
Jun Wu <quark@fb.com>
parents:
28602
diff
changeset
|
658 if self.repo: |
f467073cd798
chgserver: drop bundle.mainreporoot config
Jun Wu <quark@fb.com>
parents:
28602
diff
changeset
|
659 # one chgserver can serve multiple repos. drop repo infomation |
f467073cd798
chgserver: drop bundle.mainreporoot config
Jun Wu <quark@fb.com>
parents:
28602
diff
changeset
|
660 self.ui.setconfig('bundle', 'mainreporoot', '', 'repo') |
f467073cd798
chgserver: drop bundle.mainreporoot config
Jun Wu <quark@fb.com>
parents:
28602
diff
changeset
|
661 self.repo = None |
28326
ea400a4f32e6
chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents:
28325
diff
changeset
|
662 self._inithashstate() |
28536
a979f5b03320
chgserver: invalidate the server if extensions fail to load
Jun Wu <quark@fb.com>
parents:
28535
diff
changeset
|
663 self._checkextensions() |
29433
33770d2b6cf9
py3: conditionalize SocketServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents:
29428
diff
changeset
|
664 class cls(AutoExitMixIn, socketserver.ForkingMixIn, |
33770d2b6cf9
py3: conditionalize SocketServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents:
29428
diff
changeset
|
665 socketserver.UnixStreamServer): |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
666 ui = self.ui |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
667 repo = self.repo |
28328
e00e57d83653
chgserver: pass hashstate and base server address to chgcmdserver
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
668 hashstate = self.hashstate |
e00e57d83653
chgserver: pass hashstate and base server address to chgcmdserver
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
669 baseaddress = self.baseaddress |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
670 self.server = cls(self.address, _requesthandler) |
28223
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
671 self.server.idletimeout = self.ui.configint( |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
672 'chgserver', 'idletimeout', self.server.idletimeout) |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
673 self.server.startautoexitthread() |
28326
ea400a4f32e6
chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents:
28325
diff
changeset
|
674 self._createsymlink() |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
675 |
28326
ea400a4f32e6
chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents:
28325
diff
changeset
|
676 def _inithashstate(self): |
ea400a4f32e6
chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents:
28325
diff
changeset
|
677 self.baseaddress = self.address |
ea400a4f32e6
chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents:
28325
diff
changeset
|
678 if self.ui.configbool('chgserver', 'skiphash', False): |
ea400a4f32e6
chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents:
28325
diff
changeset
|
679 self.hashstate = None |
ea400a4f32e6
chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents:
28325
diff
changeset
|
680 return |
ea400a4f32e6
chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents:
28325
diff
changeset
|
681 self.hashstate = hashstate.fromui(self.ui) |
ea400a4f32e6
chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents:
28325
diff
changeset
|
682 self.address = _hashaddress(self.address, self.hashstate.confighash) |
ea400a4f32e6
chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents:
28325
diff
changeset
|
683 |
28536
a979f5b03320
chgserver: invalidate the server if extensions fail to load
Jun Wu <quark@fb.com>
parents:
28535
diff
changeset
|
684 def _checkextensions(self): |
a979f5b03320
chgserver: invalidate the server if extensions fail to load
Jun Wu <quark@fb.com>
parents:
28535
diff
changeset
|
685 if not self.hashstate: |
a979f5b03320
chgserver: invalidate the server if extensions fail to load
Jun Wu <quark@fb.com>
parents:
28535
diff
changeset
|
686 return |
a979f5b03320
chgserver: invalidate the server if extensions fail to load
Jun Wu <quark@fb.com>
parents:
28535
diff
changeset
|
687 if extensions.notloaded(): |
a979f5b03320
chgserver: invalidate the server if extensions fail to load
Jun Wu <quark@fb.com>
parents:
28535
diff
changeset
|
688 # one or more extensions failed to load. mtimehash becomes |
a979f5b03320
chgserver: invalidate the server if extensions fail to load
Jun Wu <quark@fb.com>
parents:
28535
diff
changeset
|
689 # meaningless because we do not know the paths of those extensions. |
a979f5b03320
chgserver: invalidate the server if extensions fail to load
Jun Wu <quark@fb.com>
parents:
28535
diff
changeset
|
690 # set mtimehash to an illegal hash value to invalidate the server. |
a979f5b03320
chgserver: invalidate the server if extensions fail to load
Jun Wu <quark@fb.com>
parents:
28535
diff
changeset
|
691 self.hashstate.mtimehash = '' |
a979f5b03320
chgserver: invalidate the server if extensions fail to load
Jun Wu <quark@fb.com>
parents:
28535
diff
changeset
|
692 |
28326
ea400a4f32e6
chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents:
28325
diff
changeset
|
693 def _createsymlink(self): |
ea400a4f32e6
chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents:
28325
diff
changeset
|
694 if self.baseaddress == self.address: |
ea400a4f32e6
chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents:
28325
diff
changeset
|
695 return |
ea400a4f32e6
chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents:
28325
diff
changeset
|
696 tempaddress = _tempaddress(self.baseaddress) |
28342
bd05d38a1002
chgserver: use basename for socket symlink
Jun Wu <quark@fb.com>
parents:
28328
diff
changeset
|
697 os.symlink(os.path.basename(self.address), tempaddress) |
28326
ea400a4f32e6
chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents:
28325
diff
changeset
|
698 util.rename(tempaddress, self.baseaddress) |
ea400a4f32e6
chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents:
28325
diff
changeset
|
699 |
28223
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
700 def run(self): |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
701 try: |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
702 self.server.serve_forever() |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
703 finally: |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
704 self.server.unlinksocketfile() |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
705 |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
706 def uisetup(ui): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
707 commandserver._servicemap['chgunix'] = chgunixservice |
28261 | 708 |
709 # CHGINTERNALMARK is temporarily set by chg client to detect if chg will | |
710 # start another chg. drop it to avoid possible side effects. | |
711 if 'CHGINTERNALMARK' in os.environ: | |
712 del os.environ['CHGINTERNALMARK'] |