mercurial/chgserver.py
author Raphaël Gomès <rgomes@octobus.net>
Mon, 28 Nov 2022 12:33:20 +0100
branchstable
changeset 50180 be019ac8c1e4
parent 49275 c6a3243567b6
child 50553 55886050a583
permissions -rw-r--r--
dirstate-v2: don't mmap the data file when on NFS `mmap` on NFS will trigger a SIGBUS when the mmap'ed file is deleted, which wouldn't work in our case. Also, the performance advantage of using mmap on NFS is debatable at best.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
30513
ff7df4bb75de chgserver: make it a core module and drop extension flags
Yuya Nishihara <yuya@tcha.org>
parents: 30512
diff changeset
     8
"""command server extension for cHg
27792
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
'setenv' command
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    20
    replace os.environ completely
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    21
40108
e5fbdc3659fc chgserver: add "setumask2" command which uses correct message frame
Yuya Nishihara <yuya@tcha.org>
parents: 39840
diff changeset
    22
'setumask' command (DEPRECATED)
e5fbdc3659fc chgserver: add "setumask2" command which uses correct message frame
Yuya Nishihara <yuya@tcha.org>
parents: 39840
diff changeset
    23
'setumask2' command
28325
9fec3cb8d128 chgserver: update docs
Jun Wu <quark@fb.com>
parents: 28277
diff changeset
    24
    set umask
9fec3cb8d128 chgserver: update docs
Jun Wu <quark@fb.com>
parents: 28277
diff changeset
    25
28350
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
    26
'validate' command
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
    27
    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
    28
28325
9fec3cb8d128 chgserver: update docs
Jun Wu <quark@fb.com>
parents: 28277
diff changeset
    29
Config
9fec3cb8d128 chgserver: update docs
Jun Wu <quark@fb.com>
parents: 28277
diff changeset
    30
------
9fec3cb8d128 chgserver: update docs
Jun Wu <quark@fb.com>
parents: 28277
diff changeset
    31
9fec3cb8d128 chgserver: update docs
Jun Wu <quark@fb.com>
parents: 28277
diff changeset
    32
::
9fec3cb8d128 chgserver: update docs
Jun Wu <quark@fb.com>
parents: 28277
diff changeset
    33
9fec3cb8d128 chgserver: update docs
Jun Wu <quark@fb.com>
parents: 28277
diff changeset
    34
  [chgserver]
30990
cb899ee133d8 chgserver: move comments in config example
Jun Wu <quark@fb.com>
parents: 30924
diff changeset
    35
  # how long (in seconds) should an idle chg server exit
cb899ee133d8 chgserver: move comments in config example
Jun Wu <quark@fb.com>
parents: 30924
diff changeset
    36
  idletimeout = 3600
cb899ee133d8 chgserver: move comments in config example
Jun Wu <quark@fb.com>
parents: 30924
diff changeset
    37
cb899ee133d8 chgserver: move comments in config example
Jun Wu <quark@fb.com>
parents: 30924
diff changeset
    38
  # whether to skip config or env change checks
cb899ee133d8 chgserver: move comments in config example
Jun Wu <quark@fb.com>
parents: 30924
diff changeset
    39
  skiphash = False
27792
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
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    42
28276
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
    43
import inspect
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    44
import os
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    45
import re
32236
c8b9943c07eb commandserver: move "listen" responsibility from service to handler
Jun Wu <quark@fb.com>
parents: 32208
diff changeset
    46
import socket
36781
ffa3026d4196 cleanup: use stat_result[stat.ST_MTIME] instead of stat_result.st_mtime
Augie Fackler <augie@google.com>
parents: 35582
diff changeset
    47
import stat
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    48
import struct
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
    49
import time
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    50
30513
ff7df4bb75de chgserver: make it a core module and drop extension flags
Yuya Nishihara <yuya@tcha.org>
parents: 30512
diff changeset
    51
from .i18n import _
43089
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43087
diff changeset
    52
from .pycompat import (
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43087
diff changeset
    53
    getattr,
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43087
diff changeset
    54
    setattr,
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43087
diff changeset
    55
)
46113
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 46001
diff changeset
    56
from .node import hex
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    57
30513
ff7df4bb75de chgserver: make it a core module and drop extension flags
Yuya Nishihara <yuya@tcha.org>
parents: 30512
diff changeset
    58
from . import (
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    59
    commandserver,
30635
a150173da1c1 py3: replace os.environ with encoding.environ (part 2 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30619
diff changeset
    60
    encoding,
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    61
    error,
28276
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
    62
    extensions,
30669
10b17ed9b591 py3: replace sys.executable with pycompat.sysexecutable
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30645
diff changeset
    63
    pycompat,
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    64
    util,
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    65
)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    66
37119
d4a2e0d5d042 procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36835
diff changeset
    67
from .utils import (
44060
a61287a95dc3 core: migrate uses of hashlib.sha1 to hashutil.sha1
Augie Fackler <augie@google.com>
parents: 43860
diff changeset
    68
    hashutil,
37119
d4a2e0d5d042 procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36835
diff changeset
    69
    procutil,
41828
bce2356ece68 py3: port things from chgserver.py
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41816
diff changeset
    70
    stringutil,
37119
d4a2e0d5d042 procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36835
diff changeset
    71
)
d4a2e0d5d042 procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36835
diff changeset
    72
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
    73
28262
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    74
def _hashlist(items):
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    75
    """return sha1 hexdigest for a list"""
46113
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 46001
diff changeset
    76
    return hex(hashutil.sha1(stringutil.pprint(items)).digest())
28262
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    77
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
    78
28262
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    79
# sensitive config sections affecting confighash
28478
e6e183687545 chgserver: include [extdiff] in confighash
Jun Wu <quark@fb.com>
parents: 28454
diff changeset
    80
_configsections = [
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    81
    b'alias',  # affects global state commands.table
44616
bdc8a5944d44 chgserver: add merge-tools to sensitive config items
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44612
diff changeset
    82
    b'diff-tools',  # affects whether gui or not in extdiff's uisetup
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    83
    b'eol',  # uses setconfig('eol', ...)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    84
    b'extdiff',  # uisetup will register new commands
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    85
    b'extensions',
44612
bc592059d04f chgserver: add fastannotate config section to sensitive list
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44359
diff changeset
    86
    b'fastannotate',  # affects annotate command and adds fastannonate cmd
44616
bdc8a5944d44 chgserver: add merge-tools to sensitive config items
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44612
diff changeset
    87
    b'merge-tools',  # affects whether gui or not in extdiff's uisetup
44325
5cd2d91eeebd chgserver: spawn new process if schemes change
Yuya Nishihara <yuya@tcha.org>
parents: 44060
diff changeset
    88
    b'schemes',  # extsetup will update global hg.schemes
28478
e6e183687545 chgserver: include [extdiff] in confighash
Jun Wu <quark@fb.com>
parents: 28454
diff changeset
    89
]
28262
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    90
34839
110040e715c9 test-show: make it compatible with chg
Jun Wu <quark@fb.com>
parents: 34485
diff changeset
    91
_configsectionitems = [
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    92
    (b'commands', b'show.aliasprefix'),  # show.py reads it in extsetup
34839
110040e715c9 test-show: make it compatible with chg
Jun Wu <quark@fb.com>
parents: 34485
diff changeset
    93
]
110040e715c9 test-show: make it compatible with chg
Jun Wu <quark@fb.com>
parents: 34485
diff changeset
    94
28262
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    95
# sensitive environment variables affecting confighash
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
    96
_envre = re.compile(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
    97
    br'''\A(?:
28262
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    98
                    CHGHG
32271
6096d27dc119 chgserver: more explicit about sensitive environ variables
Jun Wu <quark@fb.com>
parents: 32237
diff changeset
    99
                    |HG(?:DEMANDIMPORT|EMITWARNINGS|MODULEPOLICY|PROF|RCPATH)?
6096d27dc119 chgserver: more explicit about sensitive environ variables
Jun Wu <quark@fb.com>
parents: 32237
diff changeset
   100
                    |HG(?:ENCODING|PLAIN).*
28262
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
   101
                    |LANG(?:UAGE)?
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
   102
                    |LC_.*
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
   103
                    |LD_.*
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
   104
                    |PATH
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
   105
                    |PYTHON.*
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
   106
                    |TERM(?:INFO)?
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
   107
                    |TZ
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   108
                    )\Z''',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   109
    re.X,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   110
)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   111
28262
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
def _confighash(ui):
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
   114
    """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
   115
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
   116
    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
   117
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
   118
    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
   119
    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
   120
    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
   121
    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
   122
    same time.
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
   123
    """
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
   124
    sectionitems = []
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
   125
    for section in _configsections:
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
   126
        sectionitems.append(ui.configitems(section))
34839
110040e715c9 test-show: make it compatible with chg
Jun Wu <quark@fb.com>
parents: 34485
diff changeset
   127
    for section, item in _configsectionitems:
110040e715c9 test-show: make it compatible with chg
Jun Wu <quark@fb.com>
parents: 34485
diff changeset
   128
        sectionitems.append(ui.config(section, item))
28262
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
   129
    sectionhash = _hashlist(sectionitems)
34887
7bf7544fd6cc chgserver: do not treat HG as sensitive environ when CHGHG is set
Jun Wu <quark@fb.com>
parents: 34839
diff changeset
   130
    # If $CHGHG is set, the change to $HG should not trigger a new chg server
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   131
    if b'CHGHG' in encoding.environ:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   132
        ignored = {b'HG'}
34887
7bf7544fd6cc chgserver: do not treat HG as sensitive environ when CHGHG is set
Jun Wu <quark@fb.com>
parents: 34839
diff changeset
   133
    else:
7bf7544fd6cc chgserver: do not treat HG as sensitive environ when CHGHG is set
Jun Wu <quark@fb.com>
parents: 34839
diff changeset
   134
        ignored = set()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   135
    envitems = [
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   136
        (k, v)
48913
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48903
diff changeset
   137
        for k, v in encoding.environ.items()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   138
        if _envre.match(k) and k not in ignored
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   139
    ]
28262
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
   140
    envhash = _hashlist(sorted(envitems))
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
   141
    return sectionhash[:6] + envhash[:6]
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
   142
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   143
28276
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   144
def _getmtimepaths(ui):
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   145
    """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
   146
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   147
    The list will include:
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   148
    - 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
   149
    - mercurial/__version__.py
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   150
    - python binary
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   151
    """
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   152
    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
   153
    try:
30513
ff7df4bb75de chgserver: make it a core module and drop extension flags
Yuya Nishihara <yuya@tcha.org>
parents: 30512
diff changeset
   154
        from . import __version__
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   155
28276
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   156
        modules.append(__version__)
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   157
    except ImportError:
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   158
        pass
42523
49998d5ba66a pycompat: make fewer assumptions about sys.executable
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 41828
diff changeset
   159
    files = []
49998d5ba66a pycompat: make fewer assumptions about sys.executable
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 41828
diff changeset
   160
    if pycompat.sysexecutable:
49998d5ba66a pycompat: make fewer assumptions about sys.executable
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 41828
diff changeset
   161
        files.append(pycompat.sysexecutable)
28276
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   162
    for m in modules:
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   163
        try:
41816
78027e7bc544 py3: convert return values of inspect.getabsfile() to bytes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41285
diff changeset
   164
            files.append(pycompat.fsencode(inspect.getabsfile(m)))
28276
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   165
        except TypeError:
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   166
            pass
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   167
    return sorted(set(files))
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   168
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   169
28276
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   170
def _mtimehash(paths):
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   171
    """return a quick hash for detecting file changes
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   172
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   173
    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
   174
    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
   175
    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
   176
    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
   177
    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
   178
    some carefully crafted situation.
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   179
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   180
    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
   181
    considered outdated immediately and should no longer provide service.
29462
71ed5a3ef8a9 chgserver: document why we don't merge mtimehash and confighash
Jun Wu <quark@fb.com>
parents: 29433
diff changeset
   182
71ed5a3ef8a9 chgserver: document why we don't merge mtimehash and confighash
Jun Wu <quark@fb.com>
parents: 29433
diff changeset
   183
    mtimehash is not included in confighash because we only know the paths of
71ed5a3ef8a9 chgserver: document why we don't merge mtimehash and confighash
Jun Wu <quark@fb.com>
parents: 29433
diff changeset
   184
    extensions after importing them (there is imp.find_module but that faces
71ed5a3ef8a9 chgserver: document why we don't merge mtimehash and confighash
Jun Wu <quark@fb.com>
parents: 29433
diff changeset
   185
    race conditions). We need to calculate confighash without importing.
28276
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   186
    """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   187
28276
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   188
    def trystat(path):
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   189
        try:
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   190
            st = os.stat(path)
36781
ffa3026d4196 cleanup: use stat_result[stat.ST_MTIME] instead of stat_result.st_mtime
Augie Fackler <augie@google.com>
parents: 35582
diff changeset
   191
            return (st[stat.ST_MTIME], st.st_size)
28276
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   192
        except OSError:
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   193
            # 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
   194
            pass
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   195
42818
0cbe17335857 py3: use pycompat.maplist() in chgserver
Martin von Zweigbergk <martinvonz@google.com>
parents: 42523
diff changeset
   196
    return _hashlist(pycompat.maplist(trystat, paths))[:12]
28276
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   197
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   198
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
   199
class hashstate:
28277
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   200
    """a structure storing confighash, mtimehash, paths used for mtimehash"""
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   201
28277
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   202
    def __init__(self, confighash, mtimehash, mtimepaths):
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   203
        self.confighash = confighash
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   204
        self.mtimehash = mtimehash
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   205
        self.mtimepaths = mtimepaths
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   206
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   207
    @staticmethod
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   208
    def fromui(ui, mtimepaths=None):
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   209
        if mtimepaths is None:
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   210
            mtimepaths = _getmtimepaths(ui)
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   211
        confighash = _confighash(ui)
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   212
        mtimehash = _mtimehash(mtimepaths)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   213
        ui.log(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   214
            b'cmdserver',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   215
            b'confighash = %s mtimehash = %s\n',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   216
            confighash,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   217
            mtimehash,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   218
        )
28277
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   219
        return hashstate(confighash, mtimehash, mtimepaths)
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   220
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   221
30740
493935e0327a chgserver: implement chgui._runpager
Jun Wu <quark@fb.com>
parents: 30739
diff changeset
   222
def _newchgui(srcui, csystem, attachio):
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   223
    class chgui(srcui.__class__):
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   224
        def __init__(self, src=None):
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   225
            super(chgui, self).__init__(src)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   226
            if src:
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   227
                self._csystem = getattr(src, '_csystem', csystem)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   228
            else:
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   229
                self._csystem = csystem
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   230
31108
3f8f53190d6a chg: deduplicate error handling of ui.system()
Yuya Nishihara <yuya@tcha.org>
parents: 31107
diff changeset
   231
        def _runsystem(self, cmd, environ, cwd, out):
39808
1b9be0b26511 chgserver: update comment describing when to fall back to core _runsystem()
Yuya Nishihara <yuya@tcha.org>
parents: 37120
diff changeset
   232
            # fallback to the original system method if
1b9be0b26511 chgserver: update comment describing when to fall back to core _runsystem()
Yuya Nishihara <yuya@tcha.org>
parents: 37120
diff changeset
   233
            #  a. the output stream is not stdout (e.g. stderr, cStringIO),
41285
cf8677cd7286 ui: proxy protect/restorestdio() calls to update internal flag
Yuya Nishihara <yuya@tcha.org>
parents: 40875
diff changeset
   234
            #  b. or stdout is redirected by protectfinout(),
39808
1b9be0b26511 chgserver: update comment describing when to fall back to core _runsystem()
Yuya Nishihara <yuya@tcha.org>
parents: 37120
diff changeset
   235
            # because the chg client is not aware of these situations and
1b9be0b26511 chgserver: update comment describing when to fall back to core _runsystem()
Yuya Nishihara <yuya@tcha.org>
parents: 37120
diff changeset
   236
            # will behave differently (i.e. write to stdout).
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   237
            if (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   238
                out is not self.fout
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   239
                or not util.safehasattr(self.fout, b'fileno')
39809
23a00bc90a3c chgserver: do not send system() back to client if stdio redirected (issue5992)
Yuya Nishihara <yuya@tcha.org>
parents: 39808
diff changeset
   240
                or self.fout.fileno() != procutil.stdout.fileno()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   241
                or self._finoutredirected
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   242
            ):
37120
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37119
diff changeset
   243
                return procutil.system(cmd, environ=environ, cwd=cwd, out=out)
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   244
            self.flush()
37120
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37119
diff changeset
   245
            return self._csystem(cmd, procutil.shellenviron(environ), cwd)
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   246
31954
e518192d6bac pager: set some environment variables if they're not set
Jun Wu <quark@fb.com>
parents: 31695
diff changeset
   247
        def _runpager(self, cmd, env=None):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   248
            self._csystem(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   249
                cmd,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   250
                procutil.shellenviron(env),
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   251
                type=b'pager',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   252
                cmdtable={b'attachio': attachio},
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   253
            )
31690
2d11d278279a ui: defer setting pager related properties until the pager has spawned
Matt Harbison <matt_harbison@yahoo.com>
parents: 31545
diff changeset
   254
            return True
30740
493935e0327a chgserver: implement chgui._runpager
Jun Wu <quark@fb.com>
parents: 30739
diff changeset
   255
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   256
    return chgui(srcui)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   257
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   258
40824
82210d88d814 commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents: 40729
diff changeset
   259
def _loadnewui(srcui, args, cdebug):
30513
ff7df4bb75de chgserver: make it a core module and drop extension flags
Yuya Nishihara <yuya@tcha.org>
parents: 30512
diff changeset
   260
    from . import dispatch  # avoid cycle
30512
cc374292a561 chgserver: delay importing commands and dispatch modules
Yuya Nishihara <yuya@tcha.org>
parents: 30511
diff changeset
   261
30572
cfb227016d01 chgserver: call "load" for new ui objects
Jun Wu <quark@fb.com>
parents: 30513
diff changeset
   262
    newui = srcui.__class__.load()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   263
    for a in [b'fin', b'fout', b'ferr', b'environ']:
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   264
        setattr(newui, a, getattr(srcui, a))
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   265
    if util.safehasattr(srcui, b'_csystem'):
27792
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
    # command line args
35224
6e6d0a5b88e6 dispatch: replace _earlyreq*() with new fancyopts-based parser
Yuya Nishihara <yuya@tcha.org>
parents: 35170
diff changeset
   269
    options = dispatch._earlyparseopts(newui, args)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   270
    dispatch._parseconfig(newui, options[b'config'])
28264
3682e201cce6 chgserver: make _renewui load repo and command line configs
Jun Wu <quark@fb.com>
parents: 28262
diff changeset
   271
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   272
    # stolen from tortoisehg.util.copydynamicconfig()
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   273
    for section, name, value in srcui.walkconfig():
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   274
        source = srcui.configsource(section, name)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   275
        if b':' in source or source == b'--config' or source.startswith(b'$'):
31695
d73490957d61 chgserver: do not copy configs set by environment variables
Jun Wu <quark@fb.com>
parents: 31690
diff changeset
   276
            # path:line or command line, or environ
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   277
            continue
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   278
        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
   279
0e7a929754aa chgserver: use global ui instead of repo ui for dispatch.request.ui
Jun Wu <quark@fb.com>
parents: 28586
diff changeset
   280
    # load wd and repo config, copied from dispatch.py
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   281
    cwd = options[b'cwd']
35170
c9740b69b9b7 dispatch: add HGPLAIN=+strictflags to restrict early parsing of global options
Yuya Nishihara <yuya@tcha.org>
parents: 35033
diff changeset
   282
    cwd = cwd and os.path.realpath(cwd) or None
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   283
    rpath = options[b'repository']
28599
0e7a929754aa chgserver: use global ui instead of repo ui for dispatch.request.ui
Jun Wu <quark@fb.com>
parents: 28586
diff changeset
   284
    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
   285
40729
c93d046d4300 extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents: 40110
diff changeset
   286
    extensions.populateui(newui)
40824
82210d88d814 commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents: 40729
diff changeset
   287
    commandserver.setuplogging(newui, fp=cdebug)
40729
c93d046d4300 extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents: 40110
diff changeset
   288
    if newui is not newlui:
c93d046d4300 extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents: 40110
diff changeset
   289
        extensions.populateui(newlui)
40824
82210d88d814 commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents: 40729
diff changeset
   290
        commandserver.setuplogging(newlui, fp=cdebug)
40729
c93d046d4300 extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents: 40110
diff changeset
   291
28599
0e7a929754aa chgserver: use global ui instead of repo ui for dispatch.request.ui
Jun Wu <quark@fb.com>
parents: 28586
diff changeset
   292
    return (newui, newlui)
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   293
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   294
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
   295
class channeledsystem:
27792
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),
30726
dd897eb1699e chg: send type information via S channel (BC)
Jun Wu <quark@fb.com>
parents: 30669
diff changeset
   299
    type, '\0',
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   300
    cmd, '\0',
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   301
    cwd, '\0',
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   302
    envkey, '=', val, '\0',
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   303
    ...
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   304
    envkey, '=', val
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   305
30726
dd897eb1699e chg: send type information via S channel (BC)
Jun Wu <quark@fb.com>
parents: 30669
diff changeset
   306
    if type == 'system', waits for:
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   307
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   308
    exitcode length (unsigned int),
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   309
    exitcode (int)
30739
815e1cefd082 chgserver: make S channel support pager request
Jun Wu <quark@fb.com>
parents: 30737
diff changeset
   310
815e1cefd082 chgserver: make S channel support pager request
Jun Wu <quark@fb.com>
parents: 30737
diff changeset
   311
    if type == 'pager', repetitively waits for a command name ending with '\n'
815e1cefd082 chgserver: make S channel support pager request
Jun Wu <quark@fb.com>
parents: 30737
diff changeset
   312
    and executes it defined by cmdtable, or exits the loop if the command name
815e1cefd082 chgserver: make S channel support pager request
Jun Wu <quark@fb.com>
parents: 30737
diff changeset
   313
    is empty.
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   314
    """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   315
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   316
    def __init__(self, in_, out, channel):
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   317
        self.in_ = in_
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   318
        self.out = out
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   319
        self.channel = channel
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   320
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   321
    def __call__(self, cmd, environ, cwd=None, type=b'system', cmdtable=None):
47623
227bbb078c2c windows: use abspath in chgserver
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47293
diff changeset
   322
        args = [type, cmd, util.abspath(cwd or b'.')]
48913
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48903
diff changeset
   323
        args.extend(b'%s=%s' % (k, v) for k, v in environ.items())
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   324
        data = b'\0'.join(args)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   325
        self.out.write(struct.pack(b'>cI', self.channel, len(data)))
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   326
        self.out.write(data)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   327
        self.out.flush()
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   328
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   329
        if type == b'system':
30727
18eb63ec8475 chgserver: check type passed to S channel
Jun Wu <quark@fb.com>
parents: 30726
diff changeset
   330
            length = self.in_.read(4)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   331
            (length,) = struct.unpack(b'>I', length)
30727
18eb63ec8475 chgserver: check type passed to S channel
Jun Wu <quark@fb.com>
parents: 30726
diff changeset
   332
            if length != 4:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   333
                raise error.Abort(_(b'invalid response'))
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   334
            (rc,) = struct.unpack(b'>i', self.in_.read(4))
30727
18eb63ec8475 chgserver: check type passed to S channel
Jun Wu <quark@fb.com>
parents: 30726
diff changeset
   335
            return rc
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   336
        elif type == b'pager':
30739
815e1cefd082 chgserver: make S channel support pager request
Jun Wu <quark@fb.com>
parents: 30737
diff changeset
   337
            while True:
815e1cefd082 chgserver: make S channel support pager request
Jun Wu <quark@fb.com>
parents: 30737
diff changeset
   338
                cmd = self.in_.readline()[:-1]
815e1cefd082 chgserver: make S channel support pager request
Jun Wu <quark@fb.com>
parents: 30737
diff changeset
   339
                if not cmd:
815e1cefd082 chgserver: make S channel support pager request
Jun Wu <quark@fb.com>
parents: 30737
diff changeset
   340
                    break
815e1cefd082 chgserver: make S channel support pager request
Jun Wu <quark@fb.com>
parents: 30737
diff changeset
   341
                if cmdtable and cmd in cmdtable:
815e1cefd082 chgserver: make S channel support pager request
Jun Wu <quark@fb.com>
parents: 30737
diff changeset
   342
                    cmdtable[cmd]()
815e1cefd082 chgserver: make S channel support pager request
Jun Wu <quark@fb.com>
parents: 30737
diff changeset
   343
                else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   344
                    raise error.Abort(_(b'unexpected command: %s') % cmd)
30727
18eb63ec8475 chgserver: check type passed to S channel
Jun Wu <quark@fb.com>
parents: 30726
diff changeset
   345
        else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   346
            raise error.ProgrammingError(b'invalid S channel type: %s' % type)
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   347
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   348
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   349
_iochannels = [
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   350
    # server.ch, ui.fp, mode
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43106
diff changeset
   351
    (b'cin', b'fin', 'rb'),
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43106
diff changeset
   352
    (b'cout', b'fout', 'wb'),
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43106
diff changeset
   353
    (b'cerr', b'ferr', 'wb'),
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   354
]
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   355
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   356
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   357
class chgcmdserver(commandserver.server):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   358
    def __init__(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   359
        self, ui, repo, fin, fout, sock, prereposetups, hashstate, baseaddress
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   360
    ):
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   361
        super(chgcmdserver, self).__init__(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   362
            _newchgui(ui, channeledsystem(fin, fout, b'S'), self.attachio),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   363
            repo,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   364
            fin,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   365
            fout,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   366
            prereposetups,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   367
        )
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   368
        self.clientsock = sock
39738
a93fe297dfb3 chgserver: add separate flag to remember if stdio fds are replaced
Yuya Nishihara <yuya@tcha.org>
parents: 37120
diff changeset
   369
        self._ioattached = False
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   370
        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
   371
        self.hashstate = hashstate
e00e57d83653 chgserver: pass hashstate and base server address to chgcmdserver
Jun Wu <quark@fb.com>
parents: 28327
diff changeset
   372
        self.baseaddress = baseaddress
28350
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   373
        if hashstate is not None:
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   374
            self.capabilities = self.capabilities.copy()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   375
            self.capabilities[b'validate'] = chgcmdserver.validate
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   376
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   377
    def cleanup(self):
29512
538d0003c9e0 commandserver: promote .cleanup() hook from chgserver
Yuya Nishihara <yuya@tcha.org>
parents: 29511
diff changeset
   378
        super(chgcmdserver, self).cleanup()
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   379
        # 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
   380
        # handled by dispatch._dispatch()
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   381
        self.ui.flush()
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   382
        self._restoreio()
39738
a93fe297dfb3 chgserver: add separate flag to remember if stdio fds are replaced
Yuya Nishihara <yuya@tcha.org>
parents: 37120
diff changeset
   383
        self._ioattached = False
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   384
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   385
    def attachio(self):
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   386
        """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
   387
        channels except cresult will no longer be used
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   388
        """
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   389
        # 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
   390
        # distinctive from "attachio\n" command consumed by client.read()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   391
        self.clientsock.sendall(struct.pack(b'>cI', b'I', 1))
49275
c6a3243567b6 chg: replace mercurial.util.recvfds() by simpler pure Python implementation
Manuel Jacob <me@manueljacob.de>
parents: 49244
diff changeset
   392
c6a3243567b6 chg: replace mercurial.util.recvfds() by simpler pure Python implementation
Manuel Jacob <me@manueljacob.de>
parents: 49244
diff changeset
   393
        data, ancdata, msg_flags, address = self.clientsock.recvmsg(1, 256)
c6a3243567b6 chg: replace mercurial.util.recvfds() by simpler pure Python implementation
Manuel Jacob <me@manueljacob.de>
parents: 49244
diff changeset
   394
        assert len(ancdata) == 1
c6a3243567b6 chg: replace mercurial.util.recvfds() by simpler pure Python implementation
Manuel Jacob <me@manueljacob.de>
parents: 49244
diff changeset
   395
        cmsg_level, cmsg_type, cmsg_data = ancdata[0]
c6a3243567b6 chg: replace mercurial.util.recvfds() by simpler pure Python implementation
Manuel Jacob <me@manueljacob.de>
parents: 49244
diff changeset
   396
        assert cmsg_level == socket.SOL_SOCKET
c6a3243567b6 chg: replace mercurial.util.recvfds() by simpler pure Python implementation
Manuel Jacob <me@manueljacob.de>
parents: 49244
diff changeset
   397
        assert cmsg_type == socket.SCM_RIGHTS
c6a3243567b6 chg: replace mercurial.util.recvfds() by simpler pure Python implementation
Manuel Jacob <me@manueljacob.de>
parents: 49244
diff changeset
   398
        # memoryview.cast() was added in typeshed 61600d68772a, but pytype
c6a3243567b6 chg: replace mercurial.util.recvfds() by simpler pure Python implementation
Manuel Jacob <me@manueljacob.de>
parents: 49244
diff changeset
   399
        # still complains
c6a3243567b6 chg: replace mercurial.util.recvfds() by simpler pure Python implementation
Manuel Jacob <me@manueljacob.de>
parents: 49244
diff changeset
   400
        # pytype: disable=attribute-error
c6a3243567b6 chg: replace mercurial.util.recvfds() by simpler pure Python implementation
Manuel Jacob <me@manueljacob.de>
parents: 49244
diff changeset
   401
        clientfds = memoryview(cmsg_data).cast('i').tolist()
c6a3243567b6 chg: replace mercurial.util.recvfds() by simpler pure Python implementation
Manuel Jacob <me@manueljacob.de>
parents: 49244
diff changeset
   402
        # pytype: enable=attribute-error
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   403
        self.ui.log(b'chgserver', b'received fds: %r\n', clientfds)
27792
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
        ui = self.ui
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   406
        ui.flush()
39738
a93fe297dfb3 chgserver: add separate flag to remember if stdio fds are replaced
Yuya Nishihara <yuya@tcha.org>
parents: 37120
diff changeset
   407
        self._saveio()
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   408
        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
   409
            assert fd > 0
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   410
            fp = getattr(ui, fn)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   411
            os.dup2(fd, fp.fileno())
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   412
            os.close(fd)
39738
a93fe297dfb3 chgserver: add separate flag to remember if stdio fds are replaced
Yuya Nishihara <yuya@tcha.org>
parents: 37120
diff changeset
   413
            if self._ioattached:
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   414
                continue
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   415
            # 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
   416
            # 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
   417
            # 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
   418
            # be unbuffered no matter if it is a tty or not.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   419
            if fn == b'ferr':
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   420
                newfp = fp
48902
1ba11c8f3430 chgserver: remove Python 2 branch
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   421
            else:
45852
b56feaa9b520 chgserver: backport py3 buffered I/O workarounds from procutil
Yuya Nishihara <yuya@tcha.org>
parents: 45682
diff changeset
   422
                # On Python 3, the standard library doesn't offer line-buffered
b56feaa9b520 chgserver: backport py3 buffered I/O workarounds from procutil
Yuya Nishihara <yuya@tcha.org>
parents: 45682
diff changeset
   423
                # binary streams, so wrap/unwrap it.
b56feaa9b520 chgserver: backport py3 buffered I/O workarounds from procutil
Yuya Nishihara <yuya@tcha.org>
parents: 45682
diff changeset
   424
                if fp.isatty():
b56feaa9b520 chgserver: backport py3 buffered I/O workarounds from procutil
Yuya Nishihara <yuya@tcha.org>
parents: 45682
diff changeset
   425
                    newfp = procutil.make_line_buffered(fp)
b56feaa9b520 chgserver: backport py3 buffered I/O workarounds from procutil
Yuya Nishihara <yuya@tcha.org>
parents: 45682
diff changeset
   426
                else:
b56feaa9b520 chgserver: backport py3 buffered I/O workarounds from procutil
Yuya Nishihara <yuya@tcha.org>
parents: 45682
diff changeset
   427
                    newfp = procutil.unwrap_line_buffered(fp)
b56feaa9b520 chgserver: backport py3 buffered I/O workarounds from procutil
Yuya Nishihara <yuya@tcha.org>
parents: 45682
diff changeset
   428
            if newfp is not fp:
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   429
                setattr(ui, fn, newfp)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   430
            setattr(self, cn, newfp)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   431
39738
a93fe297dfb3 chgserver: add separate flag to remember if stdio fds are replaced
Yuya Nishihara <yuya@tcha.org>
parents: 37120
diff changeset
   432
        self._ioattached = True
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   433
        self.cresult.write(struct.pack(b'>i', len(clientfds)))
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   434
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   435
    def _saveio(self):
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   436
        if self._oldios:
39738
a93fe297dfb3 chgserver: add separate flag to remember if stdio fds are replaced
Yuya Nishihara <yuya@tcha.org>
parents: 37120
diff changeset
   437
            return
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   438
        ui = self.ui
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   439
        for cn, fn, _mode in _iochannels:
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   440
            ch = getattr(self, cn)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   441
            fp = getattr(ui, fn)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   442
            fd = os.dup(fp.fileno())
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   443
            self._oldios.append((ch, fp, fd))
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   444
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   445
    def _restoreio(self):
45185
a17454a189d1 chgserver: discard buffered output before restoring fds (issue6207)
Yuya Nishihara <yuya@tcha.org>
parents: 45035
diff changeset
   446
        if not self._oldios:
a17454a189d1 chgserver: discard buffered output before restoring fds (issue6207)
Yuya Nishihara <yuya@tcha.org>
parents: 45035
diff changeset
   447
            return
a17454a189d1 chgserver: discard buffered output before restoring fds (issue6207)
Yuya Nishihara <yuya@tcha.org>
parents: 45035
diff changeset
   448
        nullfd = os.open(os.devnull, os.O_WRONLY)
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   449
        ui = self.ui
45185
a17454a189d1 chgserver: discard buffered output before restoring fds (issue6207)
Yuya Nishihara <yuya@tcha.org>
parents: 45035
diff changeset
   450
        for (ch, fp, fd), (cn, fn, mode) in zip(self._oldios, _iochannels):
45035
3862de62d5cf chg: suppress OSError in _restoreio() and add some logging (issue6330)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44867
diff changeset
   451
            try:
48951
cf99c4af1079 chgserver: remove Python 2 file descriptor logic
Yuya Nishihara <yuya@tcha.org>
parents: 48946
diff changeset
   452
                if 'w' in mode:
45185
a17454a189d1 chgserver: discard buffered output before restoring fds (issue6207)
Yuya Nishihara <yuya@tcha.org>
parents: 45035
diff changeset
   453
                    # Discard buffered data which couldn't be flushed because
a17454a189d1 chgserver: discard buffered output before restoring fds (issue6207)
Yuya Nishihara <yuya@tcha.org>
parents: 45035
diff changeset
   454
                    # of EPIPE. The data should belong to the current session
a17454a189d1 chgserver: discard buffered output before restoring fds (issue6207)
Yuya Nishihara <yuya@tcha.org>
parents: 45035
diff changeset
   455
                    # and should never persist.
a17454a189d1 chgserver: discard buffered output before restoring fds (issue6207)
Yuya Nishihara <yuya@tcha.org>
parents: 45035
diff changeset
   456
                    os.dup2(nullfd, fp.fileno())
a17454a189d1 chgserver: discard buffered output before restoring fds (issue6207)
Yuya Nishihara <yuya@tcha.org>
parents: 45035
diff changeset
   457
                    fp.flush()
45035
3862de62d5cf chg: suppress OSError in _restoreio() and add some logging (issue6330)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44867
diff changeset
   458
                os.dup2(fd, fp.fileno())
49240
201222849987 chg: ignore already closed fds when cleaning up
Raphaël Gomès <rgomes@octobus.net>
parents: 48486
diff changeset
   459
                os.close(fd)
45035
3862de62d5cf chg: suppress OSError in _restoreio() and add some logging (issue6330)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44867
diff changeset
   460
            except OSError as err:
3862de62d5cf chg: suppress OSError in _restoreio() and add some logging (issue6330)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44867
diff changeset
   461
                # According to issue6330, running chg on heavy loaded systems
3862de62d5cf chg: suppress OSError in _restoreio() and add some logging (issue6330)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44867
diff changeset
   462
                # can lead to EBUSY. [man dup2] indicates that, on Linux,
3862de62d5cf chg: suppress OSError in _restoreio() and add some logging (issue6330)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44867
diff changeset
   463
                # EBUSY comes from a race condition between open() and dup2().
3862de62d5cf chg: suppress OSError in _restoreio() and add some logging (issue6330)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44867
diff changeset
   464
                # However it's not clear why open() race occurred for
3862de62d5cf chg: suppress OSError in _restoreio() and add some logging (issue6330)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44867
diff changeset
   465
                # newfd=stdin/out/err.
3862de62d5cf chg: suppress OSError in _restoreio() and add some logging (issue6330)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44867
diff changeset
   466
                self.ui.log(
3862de62d5cf chg: suppress OSError in _restoreio() and add some logging (issue6330)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44867
diff changeset
   467
                    b'chgserver',
3862de62d5cf chg: suppress OSError in _restoreio() and add some logging (issue6330)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44867
diff changeset
   468
                    b'got %s while duplicating %s\n',
3862de62d5cf chg: suppress OSError in _restoreio() and add some logging (issue6330)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44867
diff changeset
   469
                    stringutil.forcebytestr(err),
3862de62d5cf chg: suppress OSError in _restoreio() and add some logging (issue6330)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44867
diff changeset
   470
                    fn,
3862de62d5cf chg: suppress OSError in _restoreio() and add some logging (issue6330)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44867
diff changeset
   471
                )
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   472
            setattr(self, cn, ch)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   473
            setattr(ui, fn, fp)
45185
a17454a189d1 chgserver: discard buffered output before restoring fds (issue6207)
Yuya Nishihara <yuya@tcha.org>
parents: 45035
diff changeset
   474
        os.close(nullfd)
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   475
        del self._oldios[:]
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   476
28350
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   477
    def validate(self):
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   478
        """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
   479
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   480
        Read a list of '\0' separated arguments.
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   481
        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
   482
        if the list is empty.
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   483
        An instruction string could be either:
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   484
            - "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
   485
              outdated server.
28535
aa082a8125da chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents: 28516
diff changeset
   486
            - "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
   487
              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
   488
              "reconnect".
28516
3bf2892f685f chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents: 28514
diff changeset
   489
            - "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
   490
              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
   491
            - "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
   492
              reconnect.
aa082a8125da chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents: 28516
diff changeset
   493
        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
   494
        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
   495
        the instructions.
28350
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   496
        """
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   497
        args = self._readlist()
46001
aab70f05d6ec chgserver: catch RepoError while loading configuration
Pulkit Goyal <7895pulkit@gmail.com>
parents: 45887
diff changeset
   498
        errorraised = False
46143
dadca47e3d4d errors: respect ui.detailed-exit-code in chg
Martin von Zweigbergk <martinvonz@google.com>
parents: 46113
diff changeset
   499
        detailed_exit_code = 255
28516
3bf2892f685f chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents: 28514
diff changeset
   500
        try:
40824
82210d88d814 commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents: 40729
diff changeset
   501
            self.ui, lui = _loadnewui(self.ui, args, self.cdebug)
46001
aab70f05d6ec chgserver: catch RepoError while loading configuration
Pulkit Goyal <7895pulkit@gmail.com>
parents: 45887
diff changeset
   502
        except error.RepoError as inst:
aab70f05d6ec chgserver: catch RepoError while loading configuration
Pulkit Goyal <7895pulkit@gmail.com>
parents: 45887
diff changeset
   503
            # RepoError can be raised while trying to read shared source
aab70f05d6ec chgserver: catch RepoError while loading configuration
Pulkit Goyal <7895pulkit@gmail.com>
parents: 45887
diff changeset
   504
            # configuration
aab70f05d6ec chgserver: catch RepoError while loading configuration
Pulkit Goyal <7895pulkit@gmail.com>
parents: 45887
diff changeset
   505
            self.ui.error(_(b"abort: %s\n") % stringutil.forcebytestr(inst))
aab70f05d6ec chgserver: catch RepoError while loading configuration
Pulkit Goyal <7895pulkit@gmail.com>
parents: 45887
diff changeset
   506
            if inst.hint:
aab70f05d6ec chgserver: catch RepoError while loading configuration
Pulkit Goyal <7895pulkit@gmail.com>
parents: 45887
diff changeset
   507
                self.ui.error(_(b"(%s)\n") % inst.hint)
aab70f05d6ec chgserver: catch RepoError while loading configuration
Pulkit Goyal <7895pulkit@gmail.com>
parents: 45887
diff changeset
   508
            errorraised = True
47293
7a769ac49637 errors: catch the new Error class in scmutil and chgserver
Martin von Zweigbergk <martinvonz@google.com>
parents: 47289
diff changeset
   509
        except error.Error as inst:
47289
33c0c25d0b0f errors: let each Abort subclass define its error code
Martin von Zweigbergk <martinvonz@google.com>
parents: 46145
diff changeset
   510
            if inst.detailed_exit_code is not None:
33c0c25d0b0f errors: let each Abort subclass define its error code
Martin von Zweigbergk <martinvonz@google.com>
parents: 46145
diff changeset
   511
                detailed_exit_code = inst.detailed_exit_code
45885
600aec73f309 errors: format "abort: " text in a new Abort.format() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 45884
diff changeset
   512
            self.ui.error(inst.format())
46001
aab70f05d6ec chgserver: catch RepoError while loading configuration
Pulkit Goyal <7895pulkit@gmail.com>
parents: 45887
diff changeset
   513
            errorraised = True
aab70f05d6ec chgserver: catch RepoError while loading configuration
Pulkit Goyal <7895pulkit@gmail.com>
parents: 45887
diff changeset
   514
aab70f05d6ec chgserver: catch RepoError while loading configuration
Pulkit Goyal <7895pulkit@gmail.com>
parents: 45887
diff changeset
   515
        if errorraised:
40110
d1338b4e39d0 chgserver: catch Abort while parsing early args to shut down cleanly
Yuya Nishihara <yuya@tcha.org>
parents: 40108
diff changeset
   516
            self.ui.flush()
46143
dadca47e3d4d errors: respect ui.detailed-exit-code in chg
Martin von Zweigbergk <martinvonz@google.com>
parents: 46113
diff changeset
   517
            exit_code = 255
dadca47e3d4d errors: respect ui.detailed-exit-code in chg
Martin von Zweigbergk <martinvonz@google.com>
parents: 46113
diff changeset
   518
            if self.ui.configbool(b'ui', b'detailed-exit-code'):
dadca47e3d4d errors: respect ui.detailed-exit-code in chg
Martin von Zweigbergk <martinvonz@google.com>
parents: 46113
diff changeset
   519
                exit_code = detailed_exit_code
dadca47e3d4d errors: respect ui.detailed-exit-code in chg
Martin von Zweigbergk <martinvonz@google.com>
parents: 46113
diff changeset
   520
            self.cresult.write(b'exit %d' % exit_code)
40110
d1338b4e39d0 chgserver: catch Abort while parsing early args to shut down cleanly
Yuya Nishihara <yuya@tcha.org>
parents: 40108
diff changeset
   521
            return
28599
0e7a929754aa chgserver: use global ui instead of repo ui for dispatch.request.ui
Jun Wu <quark@fb.com>
parents: 28586
diff changeset
   522
        newhash = hashstate.fromui(lui, self.hashstate.mtimepaths)
28350
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   523
        insts = []
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   524
        if newhash.mtimehash != self.hashstate.mtimehash:
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   525
            addr = _hashaddress(self.baseaddress, self.hashstate.confighash)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   526
            insts.append(b'unlink %s' % addr)
28536
a979f5b03320 chgserver: invalidate the server if extensions fail to load
Jun Wu <quark@fb.com>
parents: 28535
diff changeset
   527
            # 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
   528
            # 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
   529
            if self.hashstate.mtimehash:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   530
                insts.append(b'reconnect')
28350
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   531
        if newhash.confighash != self.hashstate.confighash:
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   532
            addr = _hashaddress(self.baseaddress, newhash.confighash)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   533
            insts.append(b'redirect %s' % addr)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   534
        self.ui.log(b'chgserver', b'validate: %s\n', stringutil.pprint(insts))
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   535
        self.cresult.write(b'\0'.join(insts) or b'\0')
28350
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   536
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   537
    def chdir(self):
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   538
        """Change current directory
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   539
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   540
        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
   541
        It does not affect --config parameter.
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   542
        """
28158
7cc57a531f0c chgserver: use _readlist and _readstr
Jun Wu <quark@fb.com>
parents: 28014
diff changeset
   543
        path = self._readstr()
7cc57a531f0c chgserver: use _readlist and _readstr
Jun Wu <quark@fb.com>
parents: 28014
diff changeset
   544
        if not path:
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   545
            return
43621
975e517451a6 py3: replace "%r" by"'%s'% for py3-compatible (and clearer) quoting in chg
Martin von Zweigbergk <martinvonz@google.com>
parents: 43506
diff changeset
   546
        self.ui.log(b'chgserver', b"chdir to '%s'\n", path)
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   547
        os.chdir(path)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   548
28159
d2d04d1d2f92 chgserver: add setumask method
Jun Wu <quark@fb.com>
parents: 28158
diff changeset
   549
    def setumask(self):
40108
e5fbdc3659fc chgserver: add "setumask2" command which uses correct message frame
Yuya Nishihara <yuya@tcha.org>
parents: 39840
diff changeset
   550
        """Change umask (DEPRECATED)"""
e5fbdc3659fc chgserver: add "setumask2" command which uses correct message frame
Yuya Nishihara <yuya@tcha.org>
parents: 39840
diff changeset
   551
        # BUG: this does not follow the message frame structure, but kept for
e5fbdc3659fc chgserver: add "setumask2" command which uses correct message frame
Yuya Nishihara <yuya@tcha.org>
parents: 39840
diff changeset
   552
        # backward compatibility with old chg clients for some time
e5fbdc3659fc chgserver: add "setumask2" command which uses correct message frame
Yuya Nishihara <yuya@tcha.org>
parents: 39840
diff changeset
   553
        self._setumask(self._read(4))
e5fbdc3659fc chgserver: add "setumask2" command which uses correct message frame
Yuya Nishihara <yuya@tcha.org>
parents: 39840
diff changeset
   554
e5fbdc3659fc chgserver: add "setumask2" command which uses correct message frame
Yuya Nishihara <yuya@tcha.org>
parents: 39840
diff changeset
   555
    def setumask2(self):
28159
d2d04d1d2f92 chgserver: add setumask method
Jun Wu <quark@fb.com>
parents: 28158
diff changeset
   556
        """Change umask"""
40108
e5fbdc3659fc chgserver: add "setumask2" command which uses correct message frame
Yuya Nishihara <yuya@tcha.org>
parents: 39840
diff changeset
   557
        data = self._readstr()
e5fbdc3659fc chgserver: add "setumask2" command which uses correct message frame
Yuya Nishihara <yuya@tcha.org>
parents: 39840
diff changeset
   558
        if len(data) != 4:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   559
            raise ValueError(b'invalid mask length in setumask2 request')
40108
e5fbdc3659fc chgserver: add "setumask2" command which uses correct message frame
Yuya Nishihara <yuya@tcha.org>
parents: 39840
diff changeset
   560
        self._setumask(data)
e5fbdc3659fc chgserver: add "setumask2" command which uses correct message frame
Yuya Nishihara <yuya@tcha.org>
parents: 39840
diff changeset
   561
e5fbdc3659fc chgserver: add "setumask2" command which uses correct message frame
Yuya Nishihara <yuya@tcha.org>
parents: 39840
diff changeset
   562
    def _setumask(self, data):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   563
        mask = struct.unpack(b'>I', data)[0]
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   564
        self.ui.log(b'chgserver', b'setumask %r\n', mask)
44629
d37975386798 chgserver: update the umask cache before each run
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44616
diff changeset
   565
        util.setumask(mask)
28159
d2d04d1d2f92 chgserver: add setumask method
Jun Wu <quark@fb.com>
parents: 28158
diff changeset
   566
30644
2bb8c53be961 chgserver: override runcommand
Jun Wu <quark@fb.com>
parents: 30643
diff changeset
   567
    def runcommand(self):
39739
7cdd47d9ccf8 chgserver: restore pager fds attached within runcommand session
Yuya Nishihara <yuya@tcha.org>
parents: 39738
diff changeset
   568
        # pager may be attached within the runcommand session, which should
7cdd47d9ccf8 chgserver: restore pager fds attached within runcommand session
Yuya Nishihara <yuya@tcha.org>
parents: 39738
diff changeset
   569
        # be detached at the end of the session. otherwise the pager wouldn't
7cdd47d9ccf8 chgserver: restore pager fds attached within runcommand session
Yuya Nishihara <yuya@tcha.org>
parents: 39738
diff changeset
   570
        # receive EOF.
7cdd47d9ccf8 chgserver: restore pager fds attached within runcommand session
Yuya Nishihara <yuya@tcha.org>
parents: 39738
diff changeset
   571
        globaloldios = self._oldios
7cdd47d9ccf8 chgserver: restore pager fds attached within runcommand session
Yuya Nishihara <yuya@tcha.org>
parents: 39738
diff changeset
   572
        self._oldios = []
7cdd47d9ccf8 chgserver: restore pager fds attached within runcommand session
Yuya Nishihara <yuya@tcha.org>
parents: 39738
diff changeset
   573
        try:
7cdd47d9ccf8 chgserver: restore pager fds attached within runcommand session
Yuya Nishihara <yuya@tcha.org>
parents: 39738
diff changeset
   574
            return super(chgcmdserver, self).runcommand()
7cdd47d9ccf8 chgserver: restore pager fds attached within runcommand session
Yuya Nishihara <yuya@tcha.org>
parents: 39738
diff changeset
   575
        finally:
7cdd47d9ccf8 chgserver: restore pager fds attached within runcommand session
Yuya Nishihara <yuya@tcha.org>
parents: 39738
diff changeset
   576
            self._restoreio()
7cdd47d9ccf8 chgserver: restore pager fds attached within runcommand session
Yuya Nishihara <yuya@tcha.org>
parents: 39738
diff changeset
   577
            self._oldios = globaloldios
30644
2bb8c53be961 chgserver: override runcommand
Jun Wu <quark@fb.com>
parents: 30643
diff changeset
   578
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   579
    def setenv(self):
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   580
        """Clear and update os.environ
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   581
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   582
        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
   583
        """
28158
7cc57a531f0c chgserver: use _readlist and _readstr
Jun Wu <quark@fb.com>
parents: 28014
diff changeset
   584
        l = self._readlist()
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   585
        try:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   586
            newenv = dict(s.split(b'=', 1) for s in l)
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   587
        except ValueError:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   588
            raise ValueError(b'unexpected value in setenv request')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   589
        self.ui.log(b'chgserver', b'setenv: %r\n', sorted(newenv.keys()))
43860
5e0f6451e2d2 chg: fix chg to work with py3.7+ "coercing" the locale
Kyle Lippincott <spectral@google.com>
parents: 43621
diff changeset
   590
30635
a150173da1c1 py3: replace os.environ with encoding.environ (part 2 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30619
diff changeset
   591
        encoding.environ.clear()
a150173da1c1 py3: replace os.environ with encoding.environ (part 2 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30619
diff changeset
   592
        encoding.environ.update(newenv)
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   593
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   594
    capabilities = commandserver.server.capabilities.copy()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   595
    capabilities.update(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   596
        {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   597
            b'attachio': attachio,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   598
            b'chdir': chdir,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   599
            b'runcommand': runcommand,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   600
            b'setenv': setenv,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   601
            b'setumask': setumask,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   602
            b'setumask2': setumask2,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   603
        }
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   604
    )
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   605
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   606
    if util.safehasattr(procutil, b'setprocname'):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   607
30750
378686afca52 chgserver: add the setprocname interface
Jun Wu <quark@fb.com>
parents: 30741
diff changeset
   608
        def setprocname(self):
378686afca52 chgserver: add the setprocname interface
Jun Wu <quark@fb.com>
parents: 30741
diff changeset
   609
            """Change process title"""
378686afca52 chgserver: add the setprocname interface
Jun Wu <quark@fb.com>
parents: 30741
diff changeset
   610
            name = self._readstr()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   611
            self.ui.log(b'chgserver', b'setprocname: %r\n', name)
37120
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37119
diff changeset
   612
            procutil.setprocname(name)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   613
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   614
        capabilities[b'setprocname'] = setprocname
30750
378686afca52 chgserver: add the setprocname interface
Jun Wu <quark@fb.com>
parents: 30741
diff changeset
   615
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   616
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
def _tempaddress(address):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   618
    return b'%s.%d.tmp' % (address, os.getpid())
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
   619
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   620
28326
ea400a4f32e6 chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents: 28325
diff changeset
   621
def _hashaddress(address, hashstr):
30619
88efb4fb1975 chgserver: truncate base address at "." for hash address
Jun Wu <quark@fb.com>
parents: 30618
diff changeset
   622
    # if the basename of address contains '.', use only the left part. this
88efb4fb1975 chgserver: truncate base address at "." for hash address
Jun Wu <quark@fb.com>
parents: 30618
diff changeset
   623
    # makes it possible for the client to pass 'server.tmp$PID' and follow by
88efb4fb1975 chgserver: truncate base address at "." for hash address
Jun Wu <quark@fb.com>
parents: 30618
diff changeset
   624
    # an atomic rename to avoid locking when spawning new servers.
88efb4fb1975 chgserver: truncate base address at "." for hash address
Jun Wu <quark@fb.com>
parents: 30618
diff changeset
   625
    dirname, basename = os.path.split(address)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   626
    basename = basename.split(b'.', 1)[0]
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   627
    return b'%s-%s' % (os.path.join(dirname, basename), hashstr)
28326
ea400a4f32e6 chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents: 28325
diff changeset
   628
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   629
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
   630
class chgunixservicehandler:
29547
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   631
    """Set of operations for chg services"""
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   632
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   633
    pollinterval = 1  # [sec]
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   634
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   635
    def __init__(self, ui):
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   636
        self.ui = ui
48486
7caaefa48794 pytype: stop excluding chgserver.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 47623
diff changeset
   637
7caaefa48794 pytype: stop excluding chgserver.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 47623
diff changeset
   638
        # TODO: use PEP 526 syntax (`_hashstate: hashstate` at the class level)
7caaefa48794 pytype: stop excluding chgserver.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 47623
diff changeset
   639
        #  when 3.5 support is dropped.
7caaefa48794 pytype: stop excluding chgserver.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 47623
diff changeset
   640
        self._hashstate = None  # type: hashstate
7caaefa48794 pytype: stop excluding chgserver.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 47623
diff changeset
   641
        self._baseaddress = None  # type: bytes
7caaefa48794 pytype: stop excluding chgserver.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 47623
diff changeset
   642
        self._realaddress = None  # type: bytes
7caaefa48794 pytype: stop excluding chgserver.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 47623
diff changeset
   643
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   644
        self._idletimeout = ui.configint(b'chgserver', b'idletimeout')
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   645
        self._lastactive = time.time()
29547
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   646
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   647
    def bindsocket(self, sock, address):
29597
581c0c7cb258 chgserver: refactor initialization of real/base addresses
Yuya Nishihara <yuya@tcha.org>
parents: 29596
diff changeset
   648
        self._inithashstate(address)
29545
28aca3fafc2a chgserver: reorder service classes to make future patches readable
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
   649
        self._checkextensions()
29547
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   650
        self._bind(sock)
29545
28aca3fafc2a chgserver: reorder service classes to make future patches readable
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
   651
        self._createsymlink()
32237
1ada3d18e7fb commandserver: move printbanner logic to bindsocket
Jun Wu <quark@fb.com>
parents: 32236
diff changeset
   652
        # no "listening at" message should be printed to simulate hg behavior
29545
28aca3fafc2a chgserver: reorder service classes to make future patches readable
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
   653
29597
581c0c7cb258 chgserver: refactor initialization of real/base addresses
Yuya Nishihara <yuya@tcha.org>
parents: 29596
diff changeset
   654
    def _inithashstate(self, address):
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   655
        self._baseaddress = address
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   656
        if self.ui.configbool(b'chgserver', b'skiphash'):
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   657
            self._hashstate = None
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   658
            self._realaddress = address
29545
28aca3fafc2a chgserver: reorder service classes to make future patches readable
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
   659
            return
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   660
        self._hashstate = hashstate.fromui(self.ui)
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   661
        self._realaddress = _hashaddress(address, self._hashstate.confighash)
29545
28aca3fafc2a chgserver: reorder service classes to make future patches readable
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
   662
28aca3fafc2a chgserver: reorder service classes to make future patches readable
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
   663
    def _checkextensions(self):
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   664
        if not self._hashstate:
29545
28aca3fafc2a chgserver: reorder service classes to make future patches readable
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
   665
            return
28aca3fafc2a chgserver: reorder service classes to make future patches readable
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
   666
        if extensions.notloaded():
28aca3fafc2a chgserver: reorder service classes to make future patches readable
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
   667
            # one or more extensions failed to load. mtimehash becomes
28aca3fafc2a chgserver: reorder service classes to make future patches readable
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
   668
            # meaningless because we do not know the paths of those extensions.
28aca3fafc2a chgserver: reorder service classes to make future patches readable
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
   669
            # set mtimehash to an illegal hash value to invalidate the server.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   670
            self._hashstate.mtimehash = b''
29545
28aca3fafc2a chgserver: reorder service classes to make future patches readable
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
   671
29547
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   672
    def _bind(self, sock):
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
   673
        # 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
   674
        # check later
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   675
        tempaddress = _tempaddress(self._realaddress)
29547
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   676
        util.bindunixsocket(sock, tempaddress)
29529
02de1dbd4f6e chgserver: narrow scope of chdir() to socket.bind()
Yuya Nishihara <yuya@tcha.org>
parents: 29513
diff changeset
   677
        self._socketstat = os.stat(tempaddress)
32236
c8b9943c07eb commandserver: move "listen" responsibility from service to handler
Jun Wu <quark@fb.com>
parents: 32208
diff changeset
   678
        sock.listen(socket.SOMAXCONN)
29529
02de1dbd4f6e chgserver: narrow scope of chdir() to socket.bind()
Yuya Nishihara <yuya@tcha.org>
parents: 29513
diff changeset
   679
        # rename will replace the old socket file if exists atomically. the
02de1dbd4f6e chgserver: narrow scope of chdir() to socket.bind()
Yuya Nishihara <yuya@tcha.org>
parents: 29513
diff changeset
   680
        # old server will detect ownership change and exit.
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   681
        util.rename(tempaddress, self._realaddress)
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
   682
29596
71c197d82b7e chgserver: reorder functions in chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29595
diff changeset
   683
    def _createsymlink(self):
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   684
        if self._baseaddress == self._realaddress:
29596
71c197d82b7e chgserver: reorder functions in chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29595
diff changeset
   685
            return
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   686
        tempaddress = _tempaddress(self._baseaddress)
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   687
        os.symlink(os.path.basename(self._realaddress), tempaddress)
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   688
        util.rename(tempaddress, self._baseaddress)
29596
71c197d82b7e chgserver: reorder functions in chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29595
diff changeset
   689
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   690
    def _issocketowner(self):
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
   691
        try:
36781
ffa3026d4196 cleanup: use stat_result[stat.ST_MTIME] instead of stat_result.st_mtime
Augie Fackler <augie@google.com>
parents: 35582
diff changeset
   692
            st = os.stat(self._realaddress)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   693
            return (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   694
                st.st_ino == self._socketstat.st_ino
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   695
                and st[stat.ST_MTIME] == self._socketstat[stat.ST_MTIME]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   696
            )
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
   697
        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
   698
            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
   699
29547
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   700
    def unlinksocket(self, address):
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   701
        if not self._issocketowner():
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
   702
            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
   703
        # 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
   704
        # 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
   705
        # 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
   706
        # the client will start a new server on demand.
31545
82b3ec04b652 chgserver: use tryunlink
Ryan McElroy <rmcelroy@fb.com>
parents: 31108
diff changeset
   707
        util.tryunlink(self._realaddress)
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
   708
29596
71c197d82b7e chgserver: reorder functions in chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29595
diff changeset
   709
    def shouldexit(self):
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   710
        if not self._issocketowner():
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   711
            self.ui.log(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   712
                b'chgserver', b'%s is not owned, exiting.\n', self._realaddress
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   713
            )
29596
71c197d82b7e chgserver: reorder functions in chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29595
diff changeset
   714
            return True
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   715
        if time.time() - self._lastactive > self._idletimeout:
40828
25e9089c7686 commandserver: turn server debug messages into logs
Yuya Nishihara <yuya@tcha.org>
parents: 40825
diff changeset
   716
            self.ui.log(b'chgserver', b'being idle too long. exiting.\n')
29596
71c197d82b7e chgserver: reorder functions in chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29595
diff changeset
   717
            return True
71c197d82b7e chgserver: reorder functions in chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29595
diff changeset
   718
        return False
71c197d82b7e chgserver: reorder functions in chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29595
diff changeset
   719
71c197d82b7e chgserver: reorder functions in chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29595
diff changeset
   720
    def newconnection(self):
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   721
        self._lastactive = time.time()
29596
71c197d82b7e chgserver: reorder functions in chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29595
diff changeset
   722
40875
e7110f44ee2d commandserver: pass around option to hook repo instance creation
Yuya Nishihara <yuya@tcha.org>
parents: 40828
diff changeset
   723
    def createcmdserver(self, repo, conn, fin, fout, prereposetups):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   724
        return chgcmdserver(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   725
            self.ui,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   726
            repo,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   727
            fin,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   728
            fout,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   729
            conn,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   730
            prereposetups,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   731
            self._hashstate,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   732
            self._baseaddress,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   733
        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42818
diff changeset
   734
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
   735
29546
a7513390a9db chgserver: extract stub factory of service object
Yuya Nishihara <yuya@tcha.org>
parents: 29545
diff changeset
   736
def chgunixservice(ui, repo, opts):
33860
3cfc9070245f demandimport: disable if chg is being used
Jun Wu <quark@fb.com>
parents: 33499
diff changeset
   737
    # CHGINTERNALMARK is set by chg client. It is an indication of things are
3cfc9070245f demandimport: disable if chg is being used
Jun Wu <quark@fb.com>
parents: 33499
diff changeset
   738
    # started by chg so other code can do things accordingly, like disabling
3cfc9070245f demandimport: disable if chg is being used
Jun Wu <quark@fb.com>
parents: 33499
diff changeset
   739
    # demandimport or detecting chg client started by chg client. When executed
3cfc9070245f demandimport: disable if chg is being used
Jun Wu <quark@fb.com>
parents: 33499
diff changeset
   740
    # here, CHGINTERNALMARK is no longer useful and hence dropped to make
3cfc9070245f demandimport: disable if chg is being used
Jun Wu <quark@fb.com>
parents: 33499
diff changeset
   741
    # environ cleaner.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   742
    if b'CHGINTERNALMARK' in encoding.environ:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   743
        del encoding.environ[b'CHGINTERNALMARK']
44261
04a3ae7aba14 chg: force-set LC_CTYPE on server start to actual value from the environment
Kyle Lippincott <spectral@google.com>
parents: 44060
diff changeset
   744
    # Python3.7+ "coerces" the LC_CTYPE environment variable to a UTF-8 one if
04a3ae7aba14 chg: force-set LC_CTYPE on server start to actual value from the environment
Kyle Lippincott <spectral@google.com>
parents: 44060
diff changeset
   745
    # it thinks the current value is "C". This breaks the hash computation and
04a3ae7aba14 chg: force-set LC_CTYPE on server start to actual value from the environment
Kyle Lippincott <spectral@google.com>
parents: 44060
diff changeset
   746
    # causes chg to restart loop.
04a3ae7aba14 chg: force-set LC_CTYPE on server start to actual value from the environment
Kyle Lippincott <spectral@google.com>
parents: 44060
diff changeset
   747
    if b'CHGORIG_LC_CTYPE' in encoding.environ:
04a3ae7aba14 chg: force-set LC_CTYPE on server start to actual value from the environment
Kyle Lippincott <spectral@google.com>
parents: 44060
diff changeset
   748
        encoding.environ[b'LC_CTYPE'] = encoding.environ[b'CHGORIG_LC_CTYPE']
04a3ae7aba14 chg: force-set LC_CTYPE on server start to actual value from the environment
Kyle Lippincott <spectral@google.com>
parents: 44060
diff changeset
   749
        del encoding.environ[b'CHGORIG_LC_CTYPE']
04a3ae7aba14 chg: force-set LC_CTYPE on server start to actual value from the environment
Kyle Lippincott <spectral@google.com>
parents: 44060
diff changeset
   750
    elif b'CHG_CLEAR_LC_CTYPE' in encoding.environ:
04a3ae7aba14 chg: force-set LC_CTYPE on server start to actual value from the environment
Kyle Lippincott <spectral@google.com>
parents: 44060
diff changeset
   751
        if b'LC_CTYPE' in encoding.environ:
04a3ae7aba14 chg: force-set LC_CTYPE on server start to actual value from the environment
Kyle Lippincott <spectral@google.com>
parents: 44060
diff changeset
   752
            del encoding.environ[b'LC_CTYPE']
04a3ae7aba14 chg: force-set LC_CTYPE on server start to actual value from the environment
Kyle Lippincott <spectral@google.com>
parents: 44060
diff changeset
   753
        del encoding.environ[b'CHG_CLEAR_LC_CTYPE']
30511
1873563e1ede chgserver: drop CHGINTERNALMARK by chgunixservice()
Yuya Nishihara <yuya@tcha.org>
parents: 30507
diff changeset
   754
29546
a7513390a9db chgserver: extract stub factory of service object
Yuya Nishihara <yuya@tcha.org>
parents: 29545
diff changeset
   755
    if repo:
30332
318a24b52eeb spelling: fixes of non-dictionary words
Mads Kiilerich <madski@unity3d.com>
parents: 29841
diff changeset
   756
        # one chgserver can serve multiple repos. drop repo information
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   757
        ui.setconfig(b'bundle', b'mainreporoot', b'', b'repo')
29547
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   758
    h = chgunixservicehandler(ui)
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   759
    return commandserver.unixforkingservice(ui, repo=None, opts=opts, handler=h)