mercurial/chgserver.py
author Jun Wu <quark@fb.com>
Sun, 30 Apr 2017 11:21:05 -0700
changeset 32237 1ada3d18e7fb
parent 32236 c8b9943c07eb
child 32271 6096d27dc119
permissions -rw-r--r--
commandserver: move printbanner logic to bindsocket bindsocket now handles listen automatically. "printbanner" seems to be just a part of "bindsocket". This simplifies the interface a bit.
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
28325
9fec3cb8d128 chgserver: update docs
Jun Wu <quark@fb.com>
parents: 28277
diff changeset
    22
'setumask' command
9fec3cb8d128 chgserver: update docs
Jun Wu <quark@fb.com>
parents: 28277
diff changeset
    23
    set umask
9fec3cb8d128 chgserver: update docs
Jun Wu <quark@fb.com>
parents: 28277
diff changeset
    24
28350
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
    25
'validate' command
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
    26
    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
    27
28325
9fec3cb8d128 chgserver: update docs
Jun Wu <quark@fb.com>
parents: 28277
diff changeset
    28
Config
9fec3cb8d128 chgserver: update docs
Jun Wu <quark@fb.com>
parents: 28277
diff changeset
    29
------
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
  [chgserver]
30990
cb899ee133d8 chgserver: move comments in config example
Jun Wu <quark@fb.com>
parents: 30924
diff changeset
    34
  # 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
    35
  idletimeout = 3600
cb899ee133d8 chgserver: move comments in config example
Jun Wu <quark@fb.com>
parents: 30924
diff changeset
    36
cb899ee133d8 chgserver: move comments in config example
Jun Wu <quark@fb.com>
parents: 30924
diff changeset
    37
  # whether to skip config or env change checks
cb899ee133d8 chgserver: move comments in config example
Jun Wu <quark@fb.com>
parents: 30924
diff changeset
    38
  skiphash = False
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    39
"""
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    40
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    41
from __future__ import absolute_import
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    42
29341
0d83ad967bf8 cleanup: replace uses of util.(md5|sha1|sha256|sha512) with hashlib.\1
Augie Fackler <raf@durin42.com>
parents: 29101
diff changeset
    43
import hashlib
28276
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
    44
import inspect
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    45
import os
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    46
import re
32236
c8b9943c07eb commandserver: move "listen" responsibility from service to handler
Jun Wu <quark@fb.com>
parents: 32208
diff changeset
    47
import socket
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 _
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    52
30513
ff7df4bb75de chgserver: make it a core module and drop extension flags
Yuya Nishihara <yuya@tcha.org>
parents: 30512
diff changeset
    53
from . import (
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    54
    commandserver,
30635
a150173da1c1 py3: replace os.environ with encoding.environ (part 2 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30619
diff changeset
    55
    encoding,
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    56
    error,
28276
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
    57
    extensions,
30669
10b17ed9b591 py3: replace sys.executable with pycompat.sysexecutable
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30645
diff changeset
    58
    pycompat,
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    59
    util,
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    60
)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    61
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    62
_log = commandserver.log
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    63
28262
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    64
def _hashlist(items):
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    65
    """return sha1 hexdigest for a list"""
29341
0d83ad967bf8 cleanup: replace uses of util.(md5|sha1|sha256|sha512) with hashlib.\1
Augie Fackler <raf@durin42.com>
parents: 29101
diff changeset
    66
    return hashlib.sha1(str(items)).hexdigest()
28262
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    67
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    68
# sensitive config sections affecting confighash
28478
e6e183687545 chgserver: include [extdiff] in confighash
Jun Wu <quark@fb.com>
parents: 28454
diff changeset
    69
_configsections = [
29101
57a24a85a2bc chgserver: add [alias] to confighash
Jun Wu <quark@fb.com>
parents: 29088
diff changeset
    70
    'alias',  # affects global state commands.table
28478
e6e183687545 chgserver: include [extdiff] in confighash
Jun Wu <quark@fb.com>
parents: 28454
diff changeset
    71
    'extdiff',  # uisetup will register new commands
e6e183687545 chgserver: include [extdiff] in confighash
Jun Wu <quark@fb.com>
parents: 28454
diff changeset
    72
    'extensions',
e6e183687545 chgserver: include [extdiff] in confighash
Jun Wu <quark@fb.com>
parents: 28454
diff changeset
    73
]
28262
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    74
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    75
# sensitive environment variables affecting confighash
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    76
_envre = re.compile(r'''\A(?:
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    77
                    CHGHG
30587
b3643bfc7fcb chg: ignore HG_* in confighash
Jun Wu <quark@fb.com>
parents: 30572
diff changeset
    78
                    |HG(?:[A-Z].*)?
28262
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    79
                    |LANG(?:UAGE)?
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    80
                    |LC_.*
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    81
                    |LD_.*
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    82
                    |PATH
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    83
                    |PYTHON.*
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    84
                    |TERM(?:INFO)?
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    85
                    |TZ
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    86
                    )\Z''', re.X)
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    87
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    88
def _confighash(ui):
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    89
    """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
    90
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    91
    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
    92
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    93
    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
    94
    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
    95
    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
    96
    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
    97
    same time.
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    98
    """
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
    99
    sectionitems = []
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
   100
    for section in _configsections:
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
   101
        sectionitems.append(ui.configitems(section))
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
   102
    sectionhash = _hashlist(sectionitems)
30635
a150173da1c1 py3: replace os.environ with encoding.environ (part 2 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30619
diff changeset
   103
    envitems = [(k, v) for k, v in encoding.environ.iteritems()
a150173da1c1 py3: replace os.environ with encoding.environ (part 2 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30619
diff changeset
   104
                if _envre.match(k)]
28262
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
   105
    envhash = _hashlist(sorted(envitems))
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
   106
    return sectionhash[:6] + envhash[:6]
53dc4aada2d9 chgserver: add utilities to calculate confighash
Jun Wu <quark@fb.com>
parents: 28261
diff changeset
   107
28276
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   108
def _getmtimepaths(ui):
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   109
    """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
   110
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   111
    The list will include:
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   112
    - 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
   113
    - mercurial/__version__.py
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   114
    - python binary
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   115
    """
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   116
    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
   117
    try:
30513
ff7df4bb75de chgserver: make it a core module and drop extension flags
Yuya Nishihara <yuya@tcha.org>
parents: 30512
diff changeset
   118
        from . import __version__
28276
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   119
        modules.append(__version__)
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   120
    except ImportError:
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   121
        pass
30669
10b17ed9b591 py3: replace sys.executable with pycompat.sysexecutable
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30645
diff changeset
   122
    files = [pycompat.sysexecutable]
28276
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   123
    for m in modules:
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   124
        try:
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   125
            files.append(inspect.getabsfile(m))
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   126
        except TypeError:
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   127
            pass
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   128
    return sorted(set(files))
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   129
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   130
def _mtimehash(paths):
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   131
    """return a quick hash for detecting file changes
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   132
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   133
    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
   134
    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
   135
    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
   136
    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
   137
    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
   138
    some carefully crafted situation.
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   139
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   140
    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
   141
    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
   142
71ed5a3ef8a9 chgserver: document why we don't merge mtimehash and confighash
Jun Wu <quark@fb.com>
parents: 29433
diff changeset
   143
    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
   144
    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
   145
    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
   146
    """
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   147
    def trystat(path):
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   148
        try:
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   149
            st = os.stat(path)
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   150
            return (st.st_mtime, st.st_size)
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   151
        except OSError:
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   152
            # 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
   153
            pass
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   154
    return _hashlist(map(trystat, paths))[:12]
b4ceadb2c439 chgserver: add utilities to calculate mtimehash
Jun Wu <quark@fb.com>
parents: 28264
diff changeset
   155
28277
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   156
class hashstate(object):
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   157
    """a structure storing confighash, mtimehash, paths used for mtimehash"""
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   158
    def __init__(self, confighash, mtimehash, mtimepaths):
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   159
        self.confighash = confighash
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   160
        self.mtimehash = mtimehash
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   161
        self.mtimepaths = mtimepaths
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   162
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   163
    @staticmethod
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   164
    def fromui(ui, mtimepaths=None):
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   165
        if mtimepaths is None:
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   166
            mtimepaths = _getmtimepaths(ui)
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   167
        confighash = _confighash(ui)
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   168
        mtimehash = _mtimehash(mtimepaths)
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   169
        _log('confighash = %s mtimehash = %s\n' % (confighash, mtimehash))
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   170
        return hashstate(confighash, mtimehash, mtimepaths)
cdc6319f6a7d chgserver: add a structure for confighash and mtimehash
Jun Wu <quark@fb.com>
parents: 28276
diff changeset
   171
30740
493935e0327a chgserver: implement chgui._runpager
Jun Wu <quark@fb.com>
parents: 30739
diff changeset
   172
def _newchgui(srcui, csystem, attachio):
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   173
    class chgui(srcui.__class__):
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   174
        def __init__(self, src=None):
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   175
            super(chgui, self).__init__(src)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   176
            if src:
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   177
                self._csystem = getattr(src, '_csystem', csystem)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   178
            else:
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   179
                self._csystem = csystem
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   180
31108
3f8f53190d6a chg: deduplicate error handling of ui.system()
Yuya Nishihara <yuya@tcha.org>
parents: 31107
diff changeset
   181
        def _runsystem(self, cmd, environ, cwd, out):
28586
82cee85d5274 chgserver: use old ui.system if fout is not stdout or needs to be captured
Jun Wu <quark@fb.com>
parents: 28553
diff changeset
   182
            # fallback to the original system method if the output needs to be
82cee85d5274 chgserver: use old ui.system if fout is not stdout or needs to be captured
Jun Wu <quark@fb.com>
parents: 28553
diff changeset
   183
            # captured (to self._buffers), or the output stream is not stdout
82cee85d5274 chgserver: use old ui.system if fout is not stdout or needs to be captured
Jun Wu <quark@fb.com>
parents: 28553
diff changeset
   184
            # (e.g. stderr, cStringIO), because the chg client is not aware of
82cee85d5274 chgserver: use old ui.system if fout is not stdout or needs to be captured
Jun Wu <quark@fb.com>
parents: 28553
diff changeset
   185
            # these situations and will behave differently (write to stdout).
31107
fbce78c58f1e chg: refactor ui.system() to be partly overridden
Yuya Nishihara <yuya@tcha.org>
parents: 30990
diff changeset
   186
            if (out is not self.fout
28586
82cee85d5274 chgserver: use old ui.system if fout is not stdout or needs to be captured
Jun Wu <quark@fb.com>
parents: 28553
diff changeset
   187
                or not util.safehasattr(self.fout, 'fileno')
30473
39d13b8c101d py3: bulk replace sys.stdin/out/err by util's
Yuya Nishihara <yuya@tcha.org>
parents: 30332
diff changeset
   188
                or self.fout.fileno() != util.stdout.fileno()):
31108
3f8f53190d6a chg: deduplicate error handling of ui.system()
Yuya Nishihara <yuya@tcha.org>
parents: 31107
diff changeset
   189
                return util.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
   190
            self.flush()
31108
3f8f53190d6a chg: deduplicate error handling of ui.system()
Yuya Nishihara <yuya@tcha.org>
parents: 31107
diff changeset
   191
            return self._csystem(cmd, util.shellenviron(environ), cwd)
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   192
31954
e518192d6bac pager: set some environment variables if they're not set
Jun Wu <quark@fb.com>
parents: 31695
diff changeset
   193
        def _runpager(self, cmd, env=None):
e518192d6bac pager: set some environment variables if they're not set
Jun Wu <quark@fb.com>
parents: 31695
diff changeset
   194
            self._csystem(cmd, util.shellenviron(env), type='pager',
30740
493935e0327a chgserver: implement chgui._runpager
Jun Wu <quark@fb.com>
parents: 30739
diff changeset
   195
                          cmdtable={'attachio': attachio})
31690
2d11d278279a ui: defer setting pager related properties until the pager has spawned
Matt Harbison <matt_harbison@yahoo.com>
parents: 31545
diff changeset
   196
            return True
30740
493935e0327a chgserver: implement chgui._runpager
Jun Wu <quark@fb.com>
parents: 30739
diff changeset
   197
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   198
    return chgui(srcui)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   199
28602
83127a9fe76e chgserver: drop old hack to recreate ui on HGPLAIN change
Yuya Nishihara <yuya@tcha.org>
parents: 28599
diff changeset
   200
def _loadnewui(srcui, args):
30513
ff7df4bb75de chgserver: make it a core module and drop extension flags
Yuya Nishihara <yuya@tcha.org>
parents: 30512
diff changeset
   201
    from . import dispatch  # avoid cycle
30512
cc374292a561 chgserver: delay importing commands and dispatch modules
Yuya Nishihara <yuya@tcha.org>
parents: 30511
diff changeset
   202
30572
cfb227016d01 chgserver: call "load" for new ui objects
Jun Wu <quark@fb.com>
parents: 30513
diff changeset
   203
    newui = srcui.__class__.load()
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   204
    for a in ['fin', 'fout', 'ferr', 'environ']:
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   205
        setattr(newui, a, getattr(srcui, a))
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   206
    if util.safehasattr(srcui, '_csystem'):
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   207
        newui._csystem = srcui._csystem
28264
3682e201cce6 chgserver: make _renewui load repo and command line configs
Jun Wu <quark@fb.com>
parents: 28262
diff changeset
   208
3682e201cce6 chgserver: make _renewui load repo and command line configs
Jun Wu <quark@fb.com>
parents: 28262
diff changeset
   209
    # command line args
28767
73bfd9a54a5c chgserver: move args copying logic to the correct place
Jun Wu <quark@fb.com>
parents: 28603
diff changeset
   210
    args = args[:]
28264
3682e201cce6 chgserver: make _renewui load repo and command line configs
Jun Wu <quark@fb.com>
parents: 28262
diff changeset
   211
    dispatch._parseconfig(newui, dispatch._earlygetopt(['--config'], args))
3682e201cce6 chgserver: make _renewui load repo and command line configs
Jun Wu <quark@fb.com>
parents: 28262
diff changeset
   212
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   213
    # stolen from tortoisehg.util.copydynamicconfig()
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   214
    for section, name, value in srcui.walkconfig():
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   215
        source = srcui.configsource(section, name)
31695
d73490957d61 chgserver: do not copy configs set by environment variables
Jun Wu <quark@fb.com>
parents: 31690
diff changeset
   216
        if ':' in source or source == '--config' or source.startswith('$'):
d73490957d61 chgserver: do not copy configs set by environment variables
Jun Wu <quark@fb.com>
parents: 31690
diff changeset
   217
            # path:line or command line, or environ
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   218
            continue
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   219
        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
   220
0e7a929754aa chgserver: use global ui instead of repo ui for dispatch.request.ui
Jun Wu <quark@fb.com>
parents: 28586
diff changeset
   221
    # load wd and repo config, copied from dispatch.py
0e7a929754aa chgserver: use global ui instead of repo ui for dispatch.request.ui
Jun Wu <quark@fb.com>
parents: 28586
diff changeset
   222
    cwds = dispatch._earlygetopt(['--cwd'], args)
0e7a929754aa chgserver: use global ui instead of repo ui for dispatch.request.ui
Jun Wu <quark@fb.com>
parents: 28586
diff changeset
   223
    cwd = cwds and os.path.realpath(cwds[-1]) or None
0e7a929754aa chgserver: use global ui instead of repo ui for dispatch.request.ui
Jun Wu <quark@fb.com>
parents: 28586
diff changeset
   224
    rpath = dispatch._earlygetopt(["-R", "--repository", "--repo"], args)
0e7a929754aa chgserver: use global ui instead of repo ui for dispatch.request.ui
Jun Wu <quark@fb.com>
parents: 28586
diff changeset
   225
    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
   226
0e7a929754aa chgserver: use global ui instead of repo ui for dispatch.request.ui
Jun Wu <quark@fb.com>
parents: 28586
diff changeset
   227
    return (newui, newlui)
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   228
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   229
class channeledsystem(object):
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   230
    """Propagate ui.system() request in the following format:
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   231
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   232
    payload length (unsigned int),
30726
dd897eb1699e chg: send type information via S channel (BC)
Jun Wu <quark@fb.com>
parents: 30669
diff changeset
   233
    type, '\0',
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   234
    cmd, '\0',
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   235
    cwd, '\0',
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   236
    envkey, '=', val, '\0',
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   237
    ...
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   238
    envkey, '=', val
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   239
30726
dd897eb1699e chg: send type information via S channel (BC)
Jun Wu <quark@fb.com>
parents: 30669
diff changeset
   240
    if type == 'system', waits for:
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   241
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   242
    exitcode length (unsigned int),
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   243
    exitcode (int)
30739
815e1cefd082 chgserver: make S channel support pager request
Jun Wu <quark@fb.com>
parents: 30737
diff changeset
   244
815e1cefd082 chgserver: make S channel support pager request
Jun Wu <quark@fb.com>
parents: 30737
diff changeset
   245
    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
   246
    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
   247
    is empty.
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   248
    """
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   249
    def __init__(self, in_, out, channel):
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   250
        self.in_ = in_
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   251
        self.out = out
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   252
        self.channel = channel
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   253
30739
815e1cefd082 chgserver: make S channel support pager request
Jun Wu <quark@fb.com>
parents: 30737
diff changeset
   254
    def __call__(self, cmd, environ, cwd=None, type='system', cmdtable=None):
30726
dd897eb1699e chg: send type information via S channel (BC)
Jun Wu <quark@fb.com>
parents: 30669
diff changeset
   255
        args = [type, util.quotecommand(cmd), os.path.abspath(cwd or '.')]
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   256
        args.extend('%s=%s' % (k, v) for k, v in environ.iteritems())
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   257
        data = '\0'.join(args)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   258
        self.out.write(struct.pack('>cI', self.channel, len(data)))
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   259
        self.out.write(data)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   260
        self.out.flush()
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   261
30727
18eb63ec8475 chgserver: check type passed to S channel
Jun Wu <quark@fb.com>
parents: 30726
diff changeset
   262
        if type == 'system':
18eb63ec8475 chgserver: check type passed to S channel
Jun Wu <quark@fb.com>
parents: 30726
diff changeset
   263
            length = self.in_.read(4)
18eb63ec8475 chgserver: check type passed to S channel
Jun Wu <quark@fb.com>
parents: 30726
diff changeset
   264
            length, = struct.unpack('>I', length)
18eb63ec8475 chgserver: check type passed to S channel
Jun Wu <quark@fb.com>
parents: 30726
diff changeset
   265
            if length != 4:
18eb63ec8475 chgserver: check type passed to S channel
Jun Wu <quark@fb.com>
parents: 30726
diff changeset
   266
                raise error.Abort(_('invalid response'))
18eb63ec8475 chgserver: check type passed to S channel
Jun Wu <quark@fb.com>
parents: 30726
diff changeset
   267
            rc, = struct.unpack('>i', self.in_.read(4))
18eb63ec8475 chgserver: check type passed to S channel
Jun Wu <quark@fb.com>
parents: 30726
diff changeset
   268
            return rc
30739
815e1cefd082 chgserver: make S channel support pager request
Jun Wu <quark@fb.com>
parents: 30737
diff changeset
   269
        elif type == 'pager':
815e1cefd082 chgserver: make S channel support pager request
Jun Wu <quark@fb.com>
parents: 30737
diff changeset
   270
            while True:
815e1cefd082 chgserver: make S channel support pager request
Jun Wu <quark@fb.com>
parents: 30737
diff changeset
   271
                cmd = self.in_.readline()[:-1]
815e1cefd082 chgserver: make S channel support pager request
Jun Wu <quark@fb.com>
parents: 30737
diff changeset
   272
                if not cmd:
815e1cefd082 chgserver: make S channel support pager request
Jun Wu <quark@fb.com>
parents: 30737
diff changeset
   273
                    break
815e1cefd082 chgserver: make S channel support pager request
Jun Wu <quark@fb.com>
parents: 30737
diff changeset
   274
                if cmdtable and cmd in cmdtable:
815e1cefd082 chgserver: make S channel support pager request
Jun Wu <quark@fb.com>
parents: 30737
diff changeset
   275
                    _log('pager subcommand: %s' % cmd)
815e1cefd082 chgserver: make S channel support pager request
Jun Wu <quark@fb.com>
parents: 30737
diff changeset
   276
                    cmdtable[cmd]()
815e1cefd082 chgserver: make S channel support pager request
Jun Wu <quark@fb.com>
parents: 30737
diff changeset
   277
                else:
815e1cefd082 chgserver: make S channel support pager request
Jun Wu <quark@fb.com>
parents: 30737
diff changeset
   278
                    raise error.Abort(_('unexpected command: %s') % cmd)
30727
18eb63ec8475 chgserver: check type passed to S channel
Jun Wu <quark@fb.com>
parents: 30726
diff changeset
   279
        else:
18eb63ec8475 chgserver: check type passed to S channel
Jun Wu <quark@fb.com>
parents: 30726
diff changeset
   280
            raise error.ProgrammingError('invalid S channel type: %s' % type)
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   281
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   282
_iochannels = [
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   283
    # server.ch, ui.fp, mode
30924
48dea083f66d py3: convert the mode argument of os.fdopen to unicodes (1 of 2)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30750
diff changeset
   284
    ('cin', 'fin', pycompat.sysstr('rb')),
48dea083f66d py3: convert the mode argument of os.fdopen to unicodes (1 of 2)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30750
diff changeset
   285
    ('cout', 'fout', pycompat.sysstr('wb')),
48dea083f66d py3: convert the mode argument of os.fdopen to unicodes (1 of 2)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30750
diff changeset
   286
    ('cerr', 'ferr', pycompat.sysstr('wb')),
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   287
]
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   288
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   289
class chgcmdserver(commandserver.server):
28328
e00e57d83653 chgserver: pass hashstate and base server address to chgcmdserver
Jun Wu <quark@fb.com>
parents: 28327
diff changeset
   290
    def __init__(self, ui, repo, fin, fout, sock, hashstate, baseaddress):
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   291
        super(chgcmdserver, self).__init__(
30740
493935e0327a chgserver: implement chgui._runpager
Jun Wu <quark@fb.com>
parents: 30739
diff changeset
   292
            _newchgui(ui, channeledsystem(fin, fout, 'S'), self.attachio),
493935e0327a chgserver: implement chgui._runpager
Jun Wu <quark@fb.com>
parents: 30739
diff changeset
   293
            repo, fin, fout)
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   294
        self.clientsock = sock
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   295
        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
   296
        self.hashstate = hashstate
e00e57d83653 chgserver: pass hashstate and base server address to chgcmdserver
Jun Wu <quark@fb.com>
parents: 28327
diff changeset
   297
        self.baseaddress = baseaddress
28350
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   298
        if hashstate is not None:
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   299
            self.capabilities = self.capabilities.copy()
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   300
            self.capabilities['validate'] = chgcmdserver.validate
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   301
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   302
    def cleanup(self):
29512
538d0003c9e0 commandserver: promote .cleanup() hook from chgserver
Yuya Nishihara <yuya@tcha.org>
parents: 29511
diff changeset
   303
        super(chgcmdserver, self).cleanup()
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   304
        # 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
   305
        # handled by dispatch._dispatch()
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   306
        self.ui.flush()
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   307
        self._restoreio()
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   308
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   309
    def attachio(self):
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   310
        """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
   311
        channels except cresult will no longer be used
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   312
        """
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   313
        # 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
   314
        # distinctive from "attachio\n" command consumed by client.read()
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   315
        self.clientsock.sendall(struct.pack('>cI', 'I', 1))
32208
d74b0cff94a9 osutil: proxy through util (and platform) modules (API)
Yuya Nishihara <yuya@tcha.org>
parents: 31954
diff changeset
   316
        clientfds = util.recvfds(self.clientsock.fileno())
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   317
        _log('received fds: %r\n' % clientfds)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   318
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   319
        ui = self.ui
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   320
        ui.flush()
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   321
        first = self._saveio()
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   322
        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
   323
            assert fd > 0
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   324
            fp = getattr(ui, fn)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   325
            os.dup2(fd, fp.fileno())
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   326
            os.close(fd)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   327
            if not first:
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   328
                continue
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   329
            # 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
   330
            # 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
   331
            # 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
   332
            # be unbuffered no matter if it is a tty or not.
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   333
            if fn == 'ferr':
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   334
                newfp = fp
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   335
            else:
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   336
                # make it line buffered explicitly because the default is
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   337
                # decided on first write(), where fout could be a pager.
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   338
                if fp.isatty():
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   339
                    bufsize = 1  # line buffered
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   340
                else:
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   341
                    bufsize = -1  # system default
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   342
                newfp = os.fdopen(fp.fileno(), mode, bufsize)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   343
                setattr(ui, fn, newfp)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   344
            setattr(self, cn, newfp)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   345
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   346
        self.cresult.write(struct.pack('>i', len(clientfds)))
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   347
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   348
    def _saveio(self):
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   349
        if self._oldios:
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   350
            return False
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   351
        ui = self.ui
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   352
        for cn, fn, _mode in _iochannels:
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   353
            ch = getattr(self, cn)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   354
            fp = getattr(ui, fn)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   355
            fd = os.dup(fp.fileno())
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   356
            self._oldios.append((ch, fp, fd))
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   357
        return True
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   358
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   359
    def _restoreio(self):
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   360
        ui = self.ui
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   361
        for (ch, fp, fd), (cn, fn, _mode) in zip(self._oldios, _iochannels):
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   362
            newfp = getattr(ui, fn)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   363
            # close newfp while it's associated with client; otherwise it
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   364
            # would be closed when newfp is deleted
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   365
            if newfp is not fp:
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   366
                newfp.close()
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   367
            # restore original fd: fp is open again
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   368
            os.dup2(fd, fp.fileno())
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   369
            os.close(fd)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   370
            setattr(self, cn, ch)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   371
            setattr(ui, fn, fp)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   372
        del self._oldios[:]
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   373
28350
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   374
    def validate(self):
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   375
        """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
   376
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   377
        Read a list of '\0' separated arguments.
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   378
        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
   379
        if the list is empty.
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   380
        An instruction string could be either:
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   381
            - "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
   382
              outdated server.
28535
aa082a8125da chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents: 28516
diff changeset
   383
            - "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
   384
              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
   385
              "reconnect".
28516
3bf2892f685f chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents: 28514
diff changeset
   386
            - "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
   387
              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
   388
            - "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
   389
              reconnect.
aa082a8125da chgserver: add an explicit "reconnect" instruction to validate
Jun Wu <quark@fb.com>
parents: 28516
diff changeset
   390
        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
   391
        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
   392
        the instructions.
28350
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   393
        """
30513
ff7df4bb75de chgserver: make it a core module and drop extension flags
Yuya Nishihara <yuya@tcha.org>
parents: 30512
diff changeset
   394
        from . import dispatch  # avoid cycle
30512
cc374292a561 chgserver: delay importing commands and dispatch modules
Yuya Nishihara <yuya@tcha.org>
parents: 30511
diff changeset
   395
28350
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   396
        args = self._readlist()
28516
3bf2892f685f chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents: 28514
diff changeset
   397
        try:
28599
0e7a929754aa chgserver: use global ui instead of repo ui for dispatch.request.ui
Jun Wu <quark@fb.com>
parents: 28586
diff changeset
   398
            self.ui, lui = _loadnewui(self.ui, args)
28516
3bf2892f685f chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents: 28514
diff changeset
   399
        except error.ParseError as inst:
3bf2892f685f chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents: 28514
diff changeset
   400
            dispatch._formatparse(self.ui.warn, inst)
3bf2892f685f chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents: 28514
diff changeset
   401
            self.ui.flush()
3bf2892f685f chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents: 28514
diff changeset
   402
            self.cresult.write('exit 255')
3bf2892f685f chgserver: handle ParseError during validate
Jun Wu <quark@fb.com>
parents: 28514
diff changeset
   403
            return
28599
0e7a929754aa chgserver: use global ui instead of repo ui for dispatch.request.ui
Jun Wu <quark@fb.com>
parents: 28586
diff changeset
   404
        newhash = hashstate.fromui(lui, self.hashstate.mtimepaths)
28350
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   405
        insts = []
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   406
        if newhash.mtimehash != self.hashstate.mtimehash:
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   407
            addr = _hashaddress(self.baseaddress, self.hashstate.confighash)
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   408
            insts.append('unlink %s' % addr)
28536
a979f5b03320 chgserver: invalidate the server if extensions fail to load
Jun Wu <quark@fb.com>
parents: 28535
diff changeset
   409
            # 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
   410
            # 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
   411
            if self.hashstate.mtimehash:
a979f5b03320 chgserver: invalidate the server if extensions fail to load
Jun Wu <quark@fb.com>
parents: 28535
diff changeset
   412
                insts.append('reconnect')
28350
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   413
        if newhash.confighash != self.hashstate.confighash:
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   414
            addr = _hashaddress(self.baseaddress, newhash.confighash)
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   415
            insts.append('redirect %s' % addr)
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   416
        _log('validate: %s\n' % insts)
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   417
        self.cresult.write('\0'.join(insts) or '\0')
8f9661d1637b chgserver: implement validate command
Jun Wu <quark@fb.com>
parents: 28342
diff changeset
   418
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   419
    def chdir(self):
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   420
        """Change current directory
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   421
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   422
        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
   423
        It does not affect --config parameter.
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   424
        """
28158
7cc57a531f0c chgserver: use _readlist and _readstr
Jun Wu <quark@fb.com>
parents: 28014
diff changeset
   425
        path = self._readstr()
7cc57a531f0c chgserver: use _readlist and _readstr
Jun Wu <quark@fb.com>
parents: 28014
diff changeset
   426
        if not path:
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   427
            return
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   428
        _log('chdir to %r\n' % path)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   429
        os.chdir(path)
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   430
28159
d2d04d1d2f92 chgserver: add setumask method
Jun Wu <quark@fb.com>
parents: 28158
diff changeset
   431
    def setumask(self):
d2d04d1d2f92 chgserver: add setumask method
Jun Wu <quark@fb.com>
parents: 28158
diff changeset
   432
        """Change umask"""
d2d04d1d2f92 chgserver: add setumask method
Jun Wu <quark@fb.com>
parents: 28158
diff changeset
   433
        mask = struct.unpack('>I', self._read(4))[0]
d2d04d1d2f92 chgserver: add setumask method
Jun Wu <quark@fb.com>
parents: 28158
diff changeset
   434
        _log('setumask %r\n' % mask)
d2d04d1d2f92 chgserver: add setumask method
Jun Wu <quark@fb.com>
parents: 28158
diff changeset
   435
        os.umask(mask)
d2d04d1d2f92 chgserver: add setumask method
Jun Wu <quark@fb.com>
parents: 28158
diff changeset
   436
30644
2bb8c53be961 chgserver: override runcommand
Jun Wu <quark@fb.com>
parents: 30643
diff changeset
   437
    def runcommand(self):
2bb8c53be961 chgserver: override runcommand
Jun Wu <quark@fb.com>
parents: 30643
diff changeset
   438
        return super(chgcmdserver, self).runcommand()
2bb8c53be961 chgserver: override runcommand
Jun Wu <quark@fb.com>
parents: 30643
diff changeset
   439
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   440
    def setenv(self):
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   441
        """Clear and update os.environ
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   442
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   443
        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
   444
        """
28158
7cc57a531f0c chgserver: use _readlist and _readstr
Jun Wu <quark@fb.com>
parents: 28014
diff changeset
   445
        l = self._readlist()
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   446
        try:
28158
7cc57a531f0c chgserver: use _readlist and _readstr
Jun Wu <quark@fb.com>
parents: 28014
diff changeset
   447
            newenv = dict(s.split('=', 1) for s in l)
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   448
        except ValueError:
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   449
            raise ValueError('unexpected value in setenv request')
28602
83127a9fe76e chgserver: drop old hack to recreate ui on HGPLAIN change
Yuya Nishihara <yuya@tcha.org>
parents: 28599
diff changeset
   450
        _log('setenv: %r\n' % sorted(newenv.keys()))
30635
a150173da1c1 py3: replace os.environ with encoding.environ (part 2 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30619
diff changeset
   451
        encoding.environ.clear()
a150173da1c1 py3: replace os.environ with encoding.environ (part 2 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30619
diff changeset
   452
        encoding.environ.update(newenv)
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   453
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   454
    capabilities = commandserver.server.capabilities.copy()
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   455
    capabilities.update({'attachio': attachio,
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   456
                         'chdir': chdir,
30644
2bb8c53be961 chgserver: override runcommand
Jun Wu <quark@fb.com>
parents: 30643
diff changeset
   457
                         'runcommand': runcommand,
28159
d2d04d1d2f92 chgserver: add setumask method
Jun Wu <quark@fb.com>
parents: 28158
diff changeset
   458
                         'setenv': setenv,
d2d04d1d2f92 chgserver: add setumask method
Jun Wu <quark@fb.com>
parents: 28158
diff changeset
   459
                         'setumask': setumask})
27792
980957333cfa chgserver: import background server extension from cHg
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
   460
32208
d74b0cff94a9 osutil: proxy through util (and platform) modules (API)
Yuya Nishihara <yuya@tcha.org>
parents: 31954
diff changeset
   461
    if util.safehasattr(util, 'setprocname'):
30750
378686afca52 chgserver: add the setprocname interface
Jun Wu <quark@fb.com>
parents: 30741
diff changeset
   462
        def setprocname(self):
378686afca52 chgserver: add the setprocname interface
Jun Wu <quark@fb.com>
parents: 30741
diff changeset
   463
            """Change process title"""
378686afca52 chgserver: add the setprocname interface
Jun Wu <quark@fb.com>
parents: 30741
diff changeset
   464
            name = self._readstr()
378686afca52 chgserver: add the setprocname interface
Jun Wu <quark@fb.com>
parents: 30741
diff changeset
   465
            _log('setprocname: %r\n' % name)
32208
d74b0cff94a9 osutil: proxy through util (and platform) modules (API)
Yuya Nishihara <yuya@tcha.org>
parents: 31954
diff changeset
   466
            util.setprocname(name)
30750
378686afca52 chgserver: add the setprocname interface
Jun Wu <quark@fb.com>
parents: 30741
diff changeset
   467
        capabilities['setprocname'] = setprocname
378686afca52 chgserver: add the setprocname interface
Jun Wu <quark@fb.com>
parents: 30741
diff changeset
   468
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
   469
def _tempaddress(address):
0a853dc9b306 chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents: 28159
diff changeset
   470
    return '%s.%d.tmp' % (address, os.getpid())
0a853dc9b306 chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents: 28159
diff changeset
   471
28326
ea400a4f32e6 chgserver: mangle server address to include confighash
Jun Wu <quark@fb.com>
parents: 28325
diff changeset
   472
def _hashaddress(address, hashstr):
30619
88efb4fb1975 chgserver: truncate base address at "." for hash address
Jun Wu <quark@fb.com>
parents: 30618
diff changeset
   473
    # 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
   474
    # 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
   475
    # 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
   476
    dirname, basename = os.path.split(address)
88efb4fb1975 chgserver: truncate base address at "." for hash address
Jun Wu <quark@fb.com>
parents: 30618
diff changeset
   477
    basename = basename.split('.', 1)[0]
88efb4fb1975 chgserver: truncate base address at "." for hash address
Jun Wu <quark@fb.com>
parents: 30618
diff changeset
   478
    return '%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
   479
29547
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   480
class chgunixservicehandler(object):
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   481
    """Set of operations for chg services"""
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   482
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   483
    pollinterval = 1  # [sec]
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   484
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   485
    def __init__(self, ui):
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   486
        self.ui = ui
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   487
        self._idletimeout = ui.configint('chgserver', 'idletimeout', 3600)
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   488
        self._lastactive = time.time()
29547
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   489
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   490
    def bindsocket(self, sock, address):
29597
581c0c7cb258 chgserver: refactor initialization of real/base addresses
Yuya Nishihara <yuya@tcha.org>
parents: 29596
diff changeset
   491
        self._inithashstate(address)
29545
28aca3fafc2a chgserver: reorder service classes to make future patches readable
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
   492
        self._checkextensions()
29547
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   493
        self._bind(sock)
29545
28aca3fafc2a chgserver: reorder service classes to make future patches readable
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
   494
        self._createsymlink()
32237
1ada3d18e7fb commandserver: move printbanner logic to bindsocket
Jun Wu <quark@fb.com>
parents: 32236
diff changeset
   495
        # 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
   496
29597
581c0c7cb258 chgserver: refactor initialization of real/base addresses
Yuya Nishihara <yuya@tcha.org>
parents: 29596
diff changeset
   497
    def _inithashstate(self, address):
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   498
        self._baseaddress = address
29545
28aca3fafc2a chgserver: reorder service classes to make future patches readable
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
   499
        if self.ui.configbool('chgserver', 'skiphash', False):
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   500
            self._hashstate = None
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   501
            self._realaddress = address
29545
28aca3fafc2a chgserver: reorder service classes to make future patches readable
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
   502
            return
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   503
        self._hashstate = hashstate.fromui(self.ui)
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   504
        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
   505
28aca3fafc2a chgserver: reorder service classes to make future patches readable
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
   506
    def _checkextensions(self):
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   507
        if not self._hashstate:
29545
28aca3fafc2a chgserver: reorder service classes to make future patches readable
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
   508
            return
28aca3fafc2a chgserver: reorder service classes to make future patches readable
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
   509
        if extensions.notloaded():
28aca3fafc2a chgserver: reorder service classes to make future patches readable
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
   510
            # 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
   511
            # 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
   512
            # set mtimehash to an illegal hash value to invalidate the server.
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   513
            self._hashstate.mtimehash = ''
29545
28aca3fafc2a chgserver: reorder service classes to make future patches readable
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
   514
29547
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   515
    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
   516
        # 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
   517
        # check later
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   518
        tempaddress = _tempaddress(self._realaddress)
29547
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   519
        util.bindunixsocket(sock, tempaddress)
29529
02de1dbd4f6e chgserver: narrow scope of chdir() to socket.bind()
Yuya Nishihara <yuya@tcha.org>
parents: 29513
diff changeset
   520
        self._socketstat = os.stat(tempaddress)
32236
c8b9943c07eb commandserver: move "listen" responsibility from service to handler
Jun Wu <quark@fb.com>
parents: 32208
diff changeset
   521
        sock.listen(socket.SOMAXCONN)
29529
02de1dbd4f6e chgserver: narrow scope of chdir() to socket.bind()
Yuya Nishihara <yuya@tcha.org>
parents: 29513
diff changeset
   522
        # 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
   523
        # 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
   524
        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
   525
29596
71c197d82b7e chgserver: reorder functions in chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29595
diff changeset
   526
    def _createsymlink(self):
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   527
        if self._baseaddress == self._realaddress:
29596
71c197d82b7e chgserver: reorder functions in chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29595
diff changeset
   528
            return
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   529
        tempaddress = _tempaddress(self._baseaddress)
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   530
        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
   531
        util.rename(tempaddress, self._baseaddress)
29596
71c197d82b7e chgserver: reorder functions in chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29595
diff changeset
   532
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   533
    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
   534
        try:
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   535
            stat = os.stat(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
   536
            return (stat.st_ino == self._socketstat.st_ino and
0a853dc9b306 chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents: 28159
diff changeset
   537
                    stat.st_mtime == self._socketstat.st_mtime)
0a853dc9b306 chgserver: auto exit after being idle for too long or lose the socket file
Jun Wu <quark@fb.com>
parents: 28159
diff changeset
   538
        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
   539
            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
   540
29547
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   541
    def unlinksocket(self, address):
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   542
        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
   543
            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
   544
        # 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
   545
        # 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
   546
        # 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
   547
        # the client will start a new server on demand.
31545
82b3ec04b652 chgserver: use tryunlink
Ryan McElroy <rmcelroy@fb.com>
parents: 31108
diff changeset
   548
        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
   549
29596
71c197d82b7e chgserver: reorder functions in chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29595
diff changeset
   550
    def shouldexit(self):
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   551
        if not self._issocketowner():
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   552
            self.ui.debug('%s is not owned, exiting.\n' % self._realaddress)
29596
71c197d82b7e chgserver: reorder functions in chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29595
diff changeset
   553
            return True
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   554
        if time.time() - self._lastactive > self._idletimeout:
29596
71c197d82b7e chgserver: reorder functions in chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29595
diff changeset
   555
            self.ui.debug('being idle too long. exiting.\n')
71c197d82b7e chgserver: reorder functions in chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29595
diff changeset
   556
            return True
71c197d82b7e chgserver: reorder functions in chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29595
diff changeset
   557
        return False
71c197d82b7e chgserver: reorder functions in chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29595
diff changeset
   558
71c197d82b7e chgserver: reorder functions in chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29595
diff changeset
   559
    def newconnection(self):
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   560
        self._lastactive = time.time()
29596
71c197d82b7e chgserver: reorder functions in chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29595
diff changeset
   561
29547
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   562
    def createcmdserver(self, repo, conn, fin, fout):
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   563
        return chgcmdserver(self.ui, repo, fin, fout, conn,
29598
a67398726747 chgserver: rename private functions and variables of chgunixservicehandler
Yuya Nishihara <yuya@tcha.org>
parents: 29597
diff changeset
   564
                            self._hashstate, self._baseaddress)
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
   565
29546
a7513390a9db chgserver: extract stub factory of service object
Yuya Nishihara <yuya@tcha.org>
parents: 29545
diff changeset
   566
def chgunixservice(ui, repo, opts):
30511
1873563e1ede chgserver: drop CHGINTERNALMARK by chgunixservice()
Yuya Nishihara <yuya@tcha.org>
parents: 30507
diff changeset
   567
    # CHGINTERNALMARK is temporarily set by chg client to detect if chg will
1873563e1ede chgserver: drop CHGINTERNALMARK by chgunixservice()
Yuya Nishihara <yuya@tcha.org>
parents: 30507
diff changeset
   568
    # start another chg. drop it to avoid possible side effects.
30635
a150173da1c1 py3: replace os.environ with encoding.environ (part 2 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30619
diff changeset
   569
    if 'CHGINTERNALMARK' in encoding.environ:
a150173da1c1 py3: replace os.environ with encoding.environ (part 2 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30619
diff changeset
   570
        del encoding.environ['CHGINTERNALMARK']
30511
1873563e1ede chgserver: drop CHGINTERNALMARK by chgunixservice()
Yuya Nishihara <yuya@tcha.org>
parents: 30507
diff changeset
   571
29546
a7513390a9db chgserver: extract stub factory of service object
Yuya Nishihara <yuya@tcha.org>
parents: 29545
diff changeset
   572
    if repo:
30332
318a24b52eeb spelling: fixes of non-dictionary words
Mads Kiilerich <madski@unity3d.com>
parents: 29841
diff changeset
   573
        # one chgserver can serve multiple repos. drop repo information
29546
a7513390a9db chgserver: extract stub factory of service object
Yuya Nishihara <yuya@tcha.org>
parents: 29545
diff changeset
   574
        ui.setconfig('bundle', 'mainreporoot', '', 'repo')
29547
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   575
    h = chgunixservicehandler(ui)
300318b7d66d chgserver: switch to new forking service
Yuya Nishihara <yuya@tcha.org>
parents: 29546
diff changeset
   576
    return commandserver.unixforkingservice(ui, repo=None, opts=opts, handler=h)