Mercurial > hg
annotate hgext/chgserver.py @ 29360:4cbe62ab5c97
rebase: move local variable 'skipped' to the RR class
author | Kostia Balytskyi <ikostia@fb.com> |
---|---|
date | Mon, 13 Jun 2016 22:40:59 +0100 |
parents | 0d83ad967bf8 |
children | 247ea0dfdb94 |
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 SocketServer |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
44 import errno |
28553
5346e9b910fc
chgserver: add an explicit gc to trigger __del__
Jun Wu <quark@fb.com>
parents:
28537
diff
changeset
|
45 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
|
46 import hashlib |
28276
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
47 import inspect |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
48 import os |
28770
97c8da2f89f9
chgserver: change random state after fork
Jun Wu <quark@fb.com>
parents:
28768
diff
changeset
|
49 import random |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
50 import re |
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 |
27793
8c9bbf5cd349
chgserver: mark as a built-in extension
Yuya Nishihara <yuya@tcha.org>
parents:
27792
diff
changeset
|
70 # 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
|
71 # 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
|
72 # 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
|
73 # leave the attribute unspecified. |
8c9bbf5cd349
chgserver: mark as a built-in extension
Yuya Nishihara <yuya@tcha.org>
parents:
27792
diff
changeset
|
74 testedwith = 'internal' |
8c9bbf5cd349
chgserver: mark as a built-in extension
Yuya Nishihara <yuya@tcha.org>
parents:
27792
diff
changeset
|
75 |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
76 _log = commandserver.log |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
77 |
28262
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
78 def _hashlist(items): |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
79 """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
|
80 return hashlib.sha1(str(items)).hexdigest() |
28262
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
81 |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
82 # sensitive config sections affecting confighash |
28478
e6e183687545
chgserver: include [extdiff] in confighash
Jun Wu <quark@fb.com>
parents:
28454
diff
changeset
|
83 _configsections = [ |
29101
57a24a85a2bc
chgserver: add [alias] to confighash
Jun Wu <quark@fb.com>
parents:
29088
diff
changeset
|
84 'alias', # affects global state commands.table |
28478
e6e183687545
chgserver: include [extdiff] in confighash
Jun Wu <quark@fb.com>
parents:
28454
diff
changeset
|
85 'extdiff', # uisetup will register new commands |
e6e183687545
chgserver: include [extdiff] in confighash
Jun Wu <quark@fb.com>
parents:
28454
diff
changeset
|
86 'extensions', |
e6e183687545
chgserver: include [extdiff] in confighash
Jun Wu <quark@fb.com>
parents:
28454
diff
changeset
|
87 ] |
28262
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
88 |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
89 # sensitive environment variables affecting confighash |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
90 _envre = re.compile(r'''\A(?: |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
91 CHGHG |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
92 |HG.* |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
93 |LANG(?:UAGE)? |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
94 |LC_.* |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
95 |LD_.* |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
96 |PATH |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
97 |PYTHON.* |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
98 |TERM(?:INFO)? |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
99 |TZ |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
100 )\Z''', re.X) |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
101 |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
102 def _confighash(ui): |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
103 """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
|
104 |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
105 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
|
106 |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
107 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
|
108 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
|
109 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
|
110 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
|
111 same time. |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
112 """ |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
113 sectionitems = [] |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
114 for section in _configsections: |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
115 sectionitems.append(ui.configitems(section)) |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
116 sectionhash = _hashlist(sectionitems) |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
117 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
|
118 envhash = _hashlist(sorted(envitems)) |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
119 return sectionhash[:6] + envhash[:6] |
53dc4aada2d9
chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents:
28261
diff
changeset
|
120 |
28276
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
121 def _getmtimepaths(ui): |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
122 """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
|
123 |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
124 The list will include: |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
125 - 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
|
126 - mercurial/__version__.py |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
127 - python binary |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
128 """ |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
129 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
|
130 try: |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
131 from mercurial import __version__ |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
132 modules.append(__version__) |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
133 except ImportError: |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
134 pass |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
135 files = [sys.executable] |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
136 for m in modules: |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
137 try: |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
138 files.append(inspect.getabsfile(m)) |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
139 except TypeError: |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
140 pass |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
141 return sorted(set(files)) |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
142 |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
143 def _mtimehash(paths): |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
144 """return a quick hash for detecting file changes |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
145 |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
146 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
|
147 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
|
148 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
|
149 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
|
150 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
|
151 some carefully crafted situation. |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
152 |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
153 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
|
154 considered outdated immediately and should no longer provide service. |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
155 """ |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
156 def trystat(path): |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
157 try: |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
158 st = os.stat(path) |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
159 return (st.st_mtime, st.st_size) |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
160 except OSError: |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
161 # 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
|
162 pass |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
163 return _hashlist(map(trystat, paths))[:12] |
b4ceadb2c439
chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents:
28264
diff
changeset
|
164 |
28277
cdc6319f6a7d
chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents:
28276
diff
changeset
|
165 class hashstate(object): |
cdc6319f6a7d
chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents:
28276
diff
changeset
|
166 """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
|
167 def __init__(self, confighash, mtimehash, mtimepaths): |
cdc6319f6a7d
chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents:
28276
diff
changeset
|
168 self.confighash = confighash |
cdc6319f6a7d
chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents:
28276
diff
changeset
|
169 self.mtimehash = mtimehash |
cdc6319f6a7d
chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents:
28276
diff
changeset
|
170 self.mtimepaths = mtimepaths |
cdc6319f6a7d
chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents:
28276
diff
changeset
|
171 |
cdc6319f6a7d
chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents:
28276
diff
changeset
|
172 @staticmethod |
cdc6319f6a7d
chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents:
28276
diff
changeset
|
173 def fromui(ui, mtimepaths=None): |
cdc6319f6a7d
chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents:
28276
diff
changeset
|
174 if mtimepaths is None: |
cdc6319f6a7d
chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents:
28276
diff
changeset
|
175 mtimepaths = _getmtimepaths(ui) |
cdc6319f6a7d
chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents:
28276
diff
changeset
|
176 confighash = _confighash(ui) |
cdc6319f6a7d
chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents:
28276
diff
changeset
|
177 mtimehash = _mtimehash(mtimepaths) |
cdc6319f6a7d
chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents:
28276
diff
changeset
|
178 _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
|
179 return hashstate(confighash, mtimehash, mtimepaths) |
cdc6319f6a7d
chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents:
28276
diff
changeset
|
180 |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
181 # copied from hgext/pager.py:uisetup() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
182 def _setuppagercmd(ui, options, cmd): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
183 if not ui.formatted(): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
184 return |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
185 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
186 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
|
187 usepager = False |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
188 always = util.parsebool(options['pager']) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
189 auto = options['pager'] == 'auto' |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
190 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
191 if not p: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
192 pass |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
193 elif always: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
194 usepager = True |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
195 elif not auto: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
196 usepager = False |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
197 else: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
198 attended = ['annotate', 'cat', 'diff', 'export', 'glog', 'log', 'qdiff'] |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
199 attend = ui.configlist('pager', 'attend', attended) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
200 ignore = ui.configlist('pager', 'ignore') |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
201 cmds, _ = cmdutil.findcmd(cmd, commands.table) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
202 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
203 for cmd in cmds: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
204 var = 'attend-%s' % cmd |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
205 if ui.config('pager', var): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
206 usepager = ui.configbool('pager', var) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
207 break |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
208 if (cmd in attend or |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
209 (cmd not in ignore and not attend)): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
210 usepager = True |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
211 break |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
212 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
213 if usepager: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
214 ui.setconfig('ui', 'formatted', ui.formatted(), 'pager') |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
215 ui.setconfig('ui', 'interactive', False, 'pager') |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
216 return p |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
217 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
218 def _newchgui(srcui, csystem): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
219 class chgui(srcui.__class__): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
220 def __init__(self, src=None): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
221 super(chgui, self).__init__(src) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
222 if src: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
223 self._csystem = getattr(src, '_csystem', csystem) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
224 else: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
225 self._csystem = csystem |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
226 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
227 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
|
228 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
|
229 # 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
|
230 # 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
|
231 # (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
|
232 # 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
|
233 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
|
234 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
|
235 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
|
236 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
|
237 errprefix) |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
238 # copied from mercurial/util.py:system() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
239 self.flush() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
240 def py2shell(val): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
241 if val is None or val is False: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
242 return '0' |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
243 if val is True: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
244 return '1' |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
245 return str(val) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
246 env = os.environ.copy() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
247 if environ: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
248 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
|
249 env['HG'] = util.hgexecutable() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
250 rc = self._csystem(cmd, env, cwd) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
251 if rc and onerr: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
252 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
|
253 util.explainexit(rc)[0]) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
254 if errprefix: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
255 errmsg = '%s: %s' % (errprefix, errmsg) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
256 raise onerr(errmsg) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
257 return rc |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
258 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
259 return chgui(srcui) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
260 |
28602
83127a9fe76e
chgserver: drop old hack to recreate ui on HGPLAIN change
Yuya Nishihara <yuya@tcha.org>
parents:
28599
diff
changeset
|
261 def _loadnewui(srcui, args): |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
262 newui = srcui.__class__() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
263 for a in ['fin', 'fout', 'ferr', 'environ']: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
264 setattr(newui, a, getattr(srcui, a)) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
265 if util.safehasattr(srcui, '_csystem'): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
266 newui._csystem = srcui._csystem |
28264
3682e201cce6
chgserver: make _renewui load repo and command line configs
Jun Wu <quark@fb.com>
parents:
28262
diff
changeset
|
267 |
3682e201cce6
chgserver: make _renewui load repo and command line configs
Jun Wu <quark@fb.com>
parents:
28262
diff
changeset
|
268 # internal config: extensions.chgserver |
3682e201cce6
chgserver: make _renewui load repo and command line configs
Jun Wu <quark@fb.com>
parents:
28262
diff
changeset
|
269 newui.setconfig('extensions', 'chgserver', |
3682e201cce6
chgserver: make _renewui load repo and command line configs
Jun Wu <quark@fb.com>
parents:
28262
diff
changeset
|
270 srcui.config('extensions', 'chgserver'), '--config') |
3682e201cce6
chgserver: make _renewui load repo and command line configs
Jun Wu <quark@fb.com>
parents:
28262
diff
changeset
|
271 |
3682e201cce6
chgserver: make _renewui load repo and command line configs
Jun Wu <quark@fb.com>
parents:
28262
diff
changeset
|
272 # command line args |
28767
73bfd9a54a5c
chgserver: move args copying logic to the correct place
Jun Wu <quark@fb.com>
parents:
28603
diff
changeset
|
273 args = args[:] |
28264
3682e201cce6
chgserver: make _renewui load repo and command line configs
Jun Wu <quark@fb.com>
parents:
28262
diff
changeset
|
274 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
|
275 |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
276 # stolen from tortoisehg.util.copydynamicconfig() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
277 for section, name, value in srcui.walkconfig(): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
278 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
|
279 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
|
280 # path:line or command line |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
281 continue |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
282 if source == 'none': |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
283 # ui.configsource returns 'none' by default |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
284 source = '' |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
285 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
|
286 |
0e7a929754aa
chgserver: use global ui instead of repo ui for dispatch.request.ui
Jun Wu <quark@fb.com>
parents:
28586
diff
changeset
|
287 # 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
|
288 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
|
289 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
|
290 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
|
291 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
|
292 |
0e7a929754aa
chgserver: use global ui instead of repo ui for dispatch.request.ui
Jun Wu <quark@fb.com>
parents:
28586
diff
changeset
|
293 return (newui, newlui) |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
294 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
295 class channeledsystem(object): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
296 """Propagate ui.system() request in the following format: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
297 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
298 payload length (unsigned int), |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
299 cmd, '\0', |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
300 cwd, '\0', |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
301 envkey, '=', val, '\0', |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
302 ... |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
303 envkey, '=', val |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
304 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
305 and waits: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
306 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
307 exitcode length (unsigned int), |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
308 exitcode (int) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
309 """ |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
310 def __init__(self, in_, out, channel): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
311 self.in_ = in_ |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
312 self.out = out |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
313 self.channel = channel |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
314 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
315 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
|
316 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
|
317 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
|
318 data = '\0'.join(args) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
319 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
|
320 self.out.write(data) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
321 self.out.flush() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
322 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
323 length = self.in_.read(4) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
324 length, = struct.unpack('>I', length) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
325 if length != 4: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
326 raise error.Abort(_('invalid response')) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
327 rc, = struct.unpack('>i', self.in_.read(4)) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
328 return rc |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
329 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
330 _iochannels = [ |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
331 # server.ch, ui.fp, mode |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
332 ('cin', 'fin', 'rb'), |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
333 ('cout', 'fout', 'wb'), |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
334 ('cerr', 'ferr', 'wb'), |
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 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
337 class chgcmdserver(commandserver.server): |
28328
e00e57d83653
chgserver: pass hashstate and base server address to chgcmdserver
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
338 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
|
339 super(chgcmdserver, self).__init__( |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
340 _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
|
341 self.clientsock = sock |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
342 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
|
343 self.hashstate = hashstate |
e00e57d83653
chgserver: pass hashstate and base server address to chgcmdserver
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
344 self.baseaddress = baseaddress |
28350
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
345 if hashstate is not None: |
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
346 self.capabilities = self.capabilities.copy() |
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
347 self.capabilities['validate'] = chgcmdserver.validate |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
348 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
349 def cleanup(self): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
350 # 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
|
351 # handled by dispatch._dispatch() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
352 self.ui.flush() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
353 self._restoreio() |
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 attachio(self): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
356 """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
|
357 channels except cresult will no longer be used |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
358 """ |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
359 # 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
|
360 # 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
|
361 self.clientsock.sendall(struct.pack('>cI', 'I', 1)) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
362 clientfds = osutil.recvfds(self.clientsock.fileno()) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
363 _log('received fds: %r\n' % clientfds) |
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 ui = self.ui |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
366 ui.flush() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
367 first = self._saveio() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
368 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
|
369 assert fd > 0 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
370 fp = getattr(ui, fn) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
371 os.dup2(fd, fp.fileno()) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
372 os.close(fd) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
373 if not first: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
374 continue |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
375 # 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
|
376 # 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
|
377 # 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
|
378 # 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
|
379 if fn == 'ferr': |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
380 newfp = fp |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
381 else: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
382 # 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
|
383 # 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
|
384 if fp.isatty(): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
385 bufsize = 1 # line buffered |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
386 else: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
387 bufsize = -1 # system default |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
388 newfp = os.fdopen(fp.fileno(), mode, bufsize) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
389 setattr(ui, fn, newfp) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
390 setattr(self, cn, newfp) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
391 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
392 self.cresult.write(struct.pack('>i', len(clientfds))) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
393 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
394 def _saveio(self): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
395 if self._oldios: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
396 return False |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
397 ui = self.ui |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
398 for cn, fn, _mode in _iochannels: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
399 ch = getattr(self, cn) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
400 fp = getattr(ui, fn) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
401 fd = os.dup(fp.fileno()) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
402 self._oldios.append((ch, fp, fd)) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
403 return True |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
404 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
405 def _restoreio(self): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
406 ui = self.ui |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
407 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
|
408 newfp = getattr(ui, fn) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
409 # 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
|
410 # would be closed when newfp is deleted |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
411 if newfp is not fp: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
412 newfp.close() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
413 # restore original fd: fp is open again |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
414 os.dup2(fd, fp.fileno()) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
415 os.close(fd) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
416 setattr(self, cn, ch) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
417 setattr(ui, fn, fp) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
418 del self._oldios[:] |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
419 |
28350
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
420 def validate(self): |
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
421 """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
|
422 |
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
423 Read a list of '\0' separated arguments. |
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
424 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
|
425 if the list is empty. |
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
426 An instruction string could be either: |
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
427 - "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
|
428 outdated server. |
28535
aa082a8125da
chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents:
28516
diff
changeset
|
429 - "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
|
430 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
|
431 "reconnect". |
28516
3bf2892f685f
chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents:
28514
diff
changeset
|
432 - "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
|
433 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
|
434 - "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
|
435 reconnect. |
aa082a8125da
chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents:
28516
diff
changeset
|
436 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
|
437 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
|
438 the instructions. |
28350
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
439 """ |
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
440 args = self._readlist() |
28516
3bf2892f685f
chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents:
28514
diff
changeset
|
441 try: |
28599
0e7a929754aa
chgserver: use global ui instead of repo ui for dispatch.request.ui
Jun Wu <quark@fb.com>
parents:
28586
diff
changeset
|
442 self.ui, lui = _loadnewui(self.ui, args) |
28516
3bf2892f685f
chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents:
28514
diff
changeset
|
443 except error.ParseError as inst: |
3bf2892f685f
chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents:
28514
diff
changeset
|
444 dispatch._formatparse(self.ui.warn, inst) |
3bf2892f685f
chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents:
28514
diff
changeset
|
445 self.ui.flush() |
3bf2892f685f
chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents:
28514
diff
changeset
|
446 self.cresult.write('exit 255') |
3bf2892f685f
chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents:
28514
diff
changeset
|
447 return |
28599
0e7a929754aa
chgserver: use global ui instead of repo ui for dispatch.request.ui
Jun Wu <quark@fb.com>
parents:
28586
diff
changeset
|
448 newhash = hashstate.fromui(lui, self.hashstate.mtimepaths) |
28350
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
449 insts = [] |
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
450 if newhash.mtimehash != self.hashstate.mtimehash: |
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
451 addr = _hashaddress(self.baseaddress, self.hashstate.confighash) |
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
452 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
|
453 # 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
|
454 # 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
|
455 if self.hashstate.mtimehash: |
a979f5b03320
chgserver: invalidate the server if extensions fail to load
Jun Wu <quark@fb.com>
parents:
28535
diff
changeset
|
456 insts.append('reconnect') |
28350
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
457 if newhash.confighash != self.hashstate.confighash: |
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
458 addr = _hashaddress(self.baseaddress, newhash.confighash) |
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
459 insts.append('redirect %s' % addr) |
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
460 _log('validate: %s\n' % insts) |
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
461 self.cresult.write('\0'.join(insts) or '\0') |
8f9661d1637b
chgserver: implement validate command
Jun Wu <quark@fb.com>
parents:
28342
diff
changeset
|
462 |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
463 def chdir(self): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
464 """Change current directory |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
465 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
466 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
|
467 It does not affect --config parameter. |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
468 """ |
28158
7cc57a531f0c
chgserver: use _readlist and _readstr
Jun Wu <quark@fb.com>
parents:
28014
diff
changeset
|
469 path = self._readstr() |
7cc57a531f0c
chgserver: use _readlist and _readstr
Jun Wu <quark@fb.com>
parents:
28014
diff
changeset
|
470 if not path: |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
471 return |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
472 _log('chdir to %r\n' % path) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
473 os.chdir(path) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
474 |
28159 | 475 def setumask(self): |
476 """Change umask""" | |
477 mask = struct.unpack('>I', self._read(4))[0] | |
478 _log('setumask %r\n' % mask) | |
479 os.umask(mask) | |
480 | |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
481 def getpager(self): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
482 """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
|
483 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
484 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
|
485 does not allow to write empty data. |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
486 """ |
28158
7cc57a531f0c
chgserver: use _readlist and _readstr
Jun Wu <quark@fb.com>
parents:
28014
diff
changeset
|
487 args = self._readlist() |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
488 try: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
489 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
|
490 args) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
491 except (error.Abort, error.AmbiguousCommand, error.CommandError, |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
492 error.UnknownCommand): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
493 cmd = None |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
494 options = {} |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
495 if not cmd or 'pager' not in options: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
496 self.cresult.write('\0') |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
497 return |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
498 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
499 pagercmd = _setuppagercmd(self.ui, options, cmd) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
500 if pagercmd: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
501 self.cresult.write(pagercmd) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
502 else: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
503 self.cresult.write('\0') |
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 def setenv(self): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
506 """Clear and update os.environ |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
507 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
508 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
|
509 """ |
28158
7cc57a531f0c
chgserver: use _readlist and _readstr
Jun Wu <quark@fb.com>
parents:
28014
diff
changeset
|
510 l = self._readlist() |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
511 try: |
28158
7cc57a531f0c
chgserver: use _readlist and _readstr
Jun Wu <quark@fb.com>
parents:
28014
diff
changeset
|
512 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
|
513 except ValueError: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
514 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
|
515 _log('setenv: %r\n' % sorted(newenv.keys())) |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
516 os.environ.clear() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
517 os.environ.update(newenv) |
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 capabilities = commandserver.server.capabilities.copy() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
520 capabilities.update({'attachio': attachio, |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
521 'chdir': chdir, |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
522 'getpager': getpager, |
28159 | 523 'setenv': setenv, |
524 'setumask': setumask}) | |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
525 |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
526 # copied from mercurial/commandserver.py |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
527 class _requesthandler(SocketServer.StreamRequestHandler): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
528 def handle(self): |
28014
83fc0c055664
chgserver: create new process group after fork (issue5051)
Jun Wu <quark@fb.com>
parents:
27793
diff
changeset
|
529 # 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
|
530 # 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
|
531 # SIGTSTP, SIGTTIN, SIGTTOU are not ignored. |
83fc0c055664
chgserver: create new process group after fork (issue5051)
Jun Wu <quark@fb.com>
parents:
27793
diff
changeset
|
532 os.setpgid(0, 0) |
28770
97c8da2f89f9
chgserver: change random state after fork
Jun Wu <quark@fb.com>
parents:
28768
diff
changeset
|
533 # 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
|
534 # same state inherited from parent. |
97c8da2f89f9
chgserver: change random state after fork
Jun Wu <quark@fb.com>
parents:
28768
diff
changeset
|
535 random.seed() |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
536 ui = self.server.ui |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
537 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
|
538 sv = None |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
539 try: |
28511
ff5f923fca3c
cmdserver: write early exception to 'e' channel in 'unix' mode
Yuya Nishihara <yuya@tcha.org>
parents:
28482
diff
changeset
|
540 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
|
541 self.server.hashstate, self.server.baseaddress) |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
542 try: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
543 sv.serve() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
544 # 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
|
545 # known exceptions are caught by dispatch. |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
546 except error.Abort as inst: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
547 ui.warn(_('abort: %s\n') % inst) |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
548 except IOError as inst: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
549 if inst.errno != errno.EPIPE: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
550 raise |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
551 except KeyboardInterrupt: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
552 pass |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
553 finally: |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
554 sv.cleanup() |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
555 except: # re-raises |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
556 # 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
|
557 # 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
|
558 if sv: |
ff5f923fca3c
cmdserver: write early exception to 'e' channel in 'unix' mode
Yuya Nishihara <yuya@tcha.org>
parents:
28482
diff
changeset
|
559 cerr = sv.cerr |
ff5f923fca3c
cmdserver: write early exception to 'e' channel in 'unix' mode
Yuya Nishihara <yuya@tcha.org>
parents:
28482
diff
changeset
|
560 else: |
ff5f923fca3c
cmdserver: write early exception to 'e' channel in 'unix' mode
Yuya Nishihara <yuya@tcha.org>
parents:
28482
diff
changeset
|
561 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
|
562 traceback.print_exc(file=cerr) |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
563 raise |
28553
5346e9b910fc
chgserver: add an explicit gc to trigger __del__
Jun Wu <quark@fb.com>
parents:
28537
diff
changeset
|
564 finally: |
5346e9b910fc
chgserver: add an explicit gc to trigger __del__
Jun Wu <quark@fb.com>
parents:
28537
diff
changeset
|
565 # 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
|
566 gc.collect() |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
567 |
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
|
568 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
|
569 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
|
570 |
28326
ea400a4f32e6
chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents:
28325
diff
changeset
|
571 def _hashaddress(address, hashstr): |
ea400a4f32e6
chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents:
28325
diff
changeset
|
572 return '%s-%s' % (address, hashstr) |
ea400a4f32e6
chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents:
28325
diff
changeset
|
573 |
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
|
574 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
|
575 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
|
576 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
|
577 |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
578 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
|
579 # 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
|
580 # 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
|
581 # 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
|
582 # 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
|
583 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
|
584 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
|
585 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
|
586 |
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 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
|
588 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
|
589 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
|
590 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
|
591 _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
|
592 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
|
593 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
|
594 _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
|
595 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
|
596 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
|
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 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
|
599 self.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
|
600 return SocketServer.ForkingMixIn.process_request( |
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 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
|
602 |
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 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
|
604 # 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
|
605 # 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
|
606 tempaddress = _tempaddress(self.server_address) |
28768
2461f33c9f97
chgserver: use relative path at socket.bind
Jun Wu <quark@fb.com>
parents:
28767
diff
changeset
|
607 # 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
|
608 # 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
|
609 # platforms (see sys/un.h) |
2461f33c9f97
chgserver: use relative path at socket.bind
Jun Wu <quark@fb.com>
parents:
28767
diff
changeset
|
610 dirname, basename = os.path.split(tempaddress) |
2461f33c9f97
chgserver: use relative path at socket.bind
Jun Wu <quark@fb.com>
parents:
28767
diff
changeset
|
611 bakwdfd = None |
2461f33c9f97
chgserver: use relative path at socket.bind
Jun Wu <quark@fb.com>
parents:
28767
diff
changeset
|
612 if dirname: |
2461f33c9f97
chgserver: use relative path at socket.bind
Jun Wu <quark@fb.com>
parents:
28767
diff
changeset
|
613 bakwdfd = os.open('.', os.O_DIRECTORY) |
2461f33c9f97
chgserver: use relative path at socket.bind
Jun Wu <quark@fb.com>
parents:
28767
diff
changeset
|
614 os.chdir(dirname) |
2461f33c9f97
chgserver: use relative path at socket.bind
Jun Wu <quark@fb.com>
parents:
28767
diff
changeset
|
615 self.socket.bind(basename) |
2461f33c9f97
chgserver: use relative path at socket.bind
Jun Wu <quark@fb.com>
parents:
28767
diff
changeset
|
616 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
|
617 # 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
|
618 # 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
|
619 util.rename(basename, self.server_address) |
2461f33c9f97
chgserver: use relative path at socket.bind
Jun Wu <quark@fb.com>
parents:
28767
diff
changeset
|
620 if bakwdfd: |
2461f33c9f97
chgserver: use relative path at socket.bind
Jun Wu <quark@fb.com>
parents:
28767
diff
changeset
|
621 os.fchdir(bakwdfd) |
2461f33c9f97
chgserver: use relative path at socket.bind
Jun Wu <quark@fb.com>
parents:
28767
diff
changeset
|
622 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
|
623 |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
624 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
|
625 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
|
626 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
|
627 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
|
628 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
|
629 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
|
630 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
|
631 |
0a853dc9b306
chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents:
28159
diff
changeset
|
632 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
|
633 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
|
634 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
|
635 # 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
|
636 # 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
|
637 # 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
|
638 # 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
|
639 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
|
640 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
|
641 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
|
642 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
|
643 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
|
644 |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
645 class chgunixservice(commandserver.unixservice): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
646 def init(self): |
28603
f467073cd798
chgserver: drop bundle.mainreporoot config
Jun Wu <quark@fb.com>
parents:
28602
diff
changeset
|
647 if self.repo: |
f467073cd798
chgserver: drop bundle.mainreporoot config
Jun Wu <quark@fb.com>
parents:
28602
diff
changeset
|
648 # one chgserver can serve multiple repos. drop repo infomation |
f467073cd798
chgserver: drop bundle.mainreporoot config
Jun Wu <quark@fb.com>
parents:
28602
diff
changeset
|
649 self.ui.setconfig('bundle', 'mainreporoot', '', 'repo') |
f467073cd798
chgserver: drop bundle.mainreporoot config
Jun Wu <quark@fb.com>
parents:
28602
diff
changeset
|
650 self.repo = None |
28326
ea400a4f32e6
chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents:
28325
diff
changeset
|
651 self._inithashstate() |
28536
a979f5b03320
chgserver: invalidate the server if extensions fail to load
Jun Wu <quark@fb.com>
parents:
28535
diff
changeset
|
652 self._checkextensions() |
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
|
653 class cls(AutoExitMixIn, SocketServer.ForkingMixIn, |
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 SocketServer.UnixStreamServer): |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
655 ui = self.ui |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
656 repo = self.repo |
28328
e00e57d83653
chgserver: pass hashstate and base server address to chgcmdserver
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
657 hashstate = self.hashstate |
e00e57d83653
chgserver: pass hashstate and base server address to chgcmdserver
Jun Wu <quark@fb.com>
parents:
28327
diff
changeset
|
658 baseaddress = self.baseaddress |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
659 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
|
660 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
|
661 '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
|
662 self.server.startautoexitthread() |
28326
ea400a4f32e6
chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents:
28325
diff
changeset
|
663 self._createsymlink() |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
664 |
28326
ea400a4f32e6
chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents:
28325
diff
changeset
|
665 def _inithashstate(self): |
ea400a4f32e6
chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents:
28325
diff
changeset
|
666 self.baseaddress = self.address |
ea400a4f32e6
chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents:
28325
diff
changeset
|
667 if self.ui.configbool('chgserver', 'skiphash', False): |
ea400a4f32e6
chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents:
28325
diff
changeset
|
668 self.hashstate = None |
ea400a4f32e6
chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents:
28325
diff
changeset
|
669 return |
ea400a4f32e6
chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents:
28325
diff
changeset
|
670 self.hashstate = hashstate.fromui(self.ui) |
ea400a4f32e6
chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents:
28325
diff
changeset
|
671 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
|
672 |
28536
a979f5b03320
chgserver: invalidate the server if extensions fail to load
Jun Wu <quark@fb.com>
parents:
28535
diff
changeset
|
673 def _checkextensions(self): |
a979f5b03320
chgserver: invalidate the server if extensions fail to load
Jun Wu <quark@fb.com>
parents:
28535
diff
changeset
|
674 if not self.hashstate: |
a979f5b03320
chgserver: invalidate the server if extensions fail to load
Jun Wu <quark@fb.com>
parents:
28535
diff
changeset
|
675 return |
a979f5b03320
chgserver: invalidate the server if extensions fail to load
Jun Wu <quark@fb.com>
parents:
28535
diff
changeset
|
676 if extensions.notloaded(): |
a979f5b03320
chgserver: invalidate the server if extensions fail to load
Jun Wu <quark@fb.com>
parents:
28535
diff
changeset
|
677 # 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
|
678 # 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
|
679 # 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
|
680 self.hashstate.mtimehash = '' |
a979f5b03320
chgserver: invalidate the server if extensions fail to load
Jun Wu <quark@fb.com>
parents:
28535
diff
changeset
|
681 |
28326
ea400a4f32e6
chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents:
28325
diff
changeset
|
682 def _createsymlink(self): |
ea400a4f32e6
chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents:
28325
diff
changeset
|
683 if self.baseaddress == self.address: |
ea400a4f32e6
chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents:
28325
diff
changeset
|
684 return |
ea400a4f32e6
chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents:
28325
diff
changeset
|
685 tempaddress = _tempaddress(self.baseaddress) |
28342
bd05d38a1002
chgserver: use basename for socket symlink
Jun Wu <quark@fb.com>
parents:
28328
diff
changeset
|
686 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
|
687 util.rename(tempaddress, self.baseaddress) |
ea400a4f32e6
chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents:
28325
diff
changeset
|
688 |
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
|
689 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
|
690 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
|
691 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
|
692 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
|
693 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
|
694 |
27792
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
695 def uisetup(ui): |
980957333cfa
chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
696 commandserver._servicemap['chgunix'] = chgunixservice |
28261 | 697 |
698 # CHGINTERNALMARK is temporarily set by chg client to detect if chg will | |
699 # start another chg. drop it to avoid possible side effects. | |
700 if 'CHGINTERNALMARK' in os.environ: | |
701 del os.environ['CHGINTERNALMARK'] |