mercurial/sshserver.py
author Nicolas Dumazet <nicdumz.commits@gmail.com>
Sun, 04 Jul 2010 18:07:30 +0900
changeset 11609 890ad9d6a169
parent 11596 47ca289a3a08
child 11618 83070a9cd526
permissions -rw-r--r--
log: slowpath: do not read the full changelog When in the slowpath, we are examining _all_ changesets in revs. We need to order reads so they happen increasingly for I/O performance. Increasing windows were used to read changelog backwards in a windowed manner, reading the changelog forward inside each window. But since no revision range was specified, it was equivalent to reading the full changelog, even if a single revision was passed to the commandline. When --removed is used, we _need_ to scan all changesets, but if we're only looking for file patterns, this is not necessary and we can stick to the revspec that was given to us.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2399
cc90dcbdf053 fix comment.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2397
diff changeset
     1
# sshserver.py - ssh protocol server support for mercurial
2396
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     2
#
4635
63b9d2deed48 Updated copyright notices and add "and others" to "hg version"
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4258
diff changeset
     3
# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
2859
345bac2bc4ec update copyrights.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2673
diff changeset
     4
# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
2396
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     5
#
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8109
diff changeset
     6
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9742
diff changeset
     7
# GNU General Public License version 2 or any later version.
2396
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     8
3891
6b4127c7d52a Simplify i18n imports
Matt Mackall <mpm@selenic.com>
parents: 3877
diff changeset
     9
from i18n import _
11596
47ca289a3a08 ssh: drop some old imports
Matt Mackall <mpm@selenic.com>
parents: 11594
diff changeset
    10
import util, hook, wireproto
47ca289a3a08 ssh: drop some old imports
Matt Mackall <mpm@selenic.com>
parents: 11594
diff changeset
    11
import os, sys
2396
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    12
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    13
class sshserver(object):
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    14
    def __init__(self, ui, repo):
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    15
        self.ui = ui
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    16
        self.repo = repo
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    17
        self.lock = None
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    18
        self.fin = sys.stdin
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    19
        self.fout = sys.stdout
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    20
5833
323b9c55b328 hook: redirect stdout to stderr for ssh and http servers
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
    21
        hook.redirect(True)
2396
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    22
        sys.stdout = sys.stderr
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    23
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    24
        # Prevent insertion/deletion of CRs
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    25
        util.set_binary(self.fin)
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    26
        util.set_binary(self.fout)
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    27
11579
c19d7e91cc46 protocol: add ssh getargs
Matt Mackall <mpm@selenic.com>
parents: 11442
diff changeset
    28
    def getargs(self, args):
c19d7e91cc46 protocol: add ssh getargs
Matt Mackall <mpm@selenic.com>
parents: 11442
diff changeset
    29
        data = {}
c19d7e91cc46 protocol: add ssh getargs
Matt Mackall <mpm@selenic.com>
parents: 11442
diff changeset
    30
        keys = args.split()
c19d7e91cc46 protocol: add ssh getargs
Matt Mackall <mpm@selenic.com>
parents: 11442
diff changeset
    31
        count = len(keys)
c19d7e91cc46 protocol: add ssh getargs
Matt Mackall <mpm@selenic.com>
parents: 11442
diff changeset
    32
        for n in xrange(len(keys)):
c19d7e91cc46 protocol: add ssh getargs
Matt Mackall <mpm@selenic.com>
parents: 11442
diff changeset
    33
            argline = self.fin.readline()[:-1]
c19d7e91cc46 protocol: add ssh getargs
Matt Mackall <mpm@selenic.com>
parents: 11442
diff changeset
    34
            arg, l = argline.split()
c19d7e91cc46 protocol: add ssh getargs
Matt Mackall <mpm@selenic.com>
parents: 11442
diff changeset
    35
            val = self.fin.read(int(l))
c19d7e91cc46 protocol: add ssh getargs
Matt Mackall <mpm@selenic.com>
parents: 11442
diff changeset
    36
            if arg not in keys:
c19d7e91cc46 protocol: add ssh getargs
Matt Mackall <mpm@selenic.com>
parents: 11442
diff changeset
    37
                raise util.Abort("unexpected parameter %r" % arg)
c19d7e91cc46 protocol: add ssh getargs
Matt Mackall <mpm@selenic.com>
parents: 11442
diff changeset
    38
            if arg == '*':
c19d7e91cc46 protocol: add ssh getargs
Matt Mackall <mpm@selenic.com>
parents: 11442
diff changeset
    39
                star = {}
c19d7e91cc46 protocol: add ssh getargs
Matt Mackall <mpm@selenic.com>
parents: 11442
diff changeset
    40
                for n in xrange(int(l)):
c19d7e91cc46 protocol: add ssh getargs
Matt Mackall <mpm@selenic.com>
parents: 11442
diff changeset
    41
                    arg, l = argline.split()
c19d7e91cc46 protocol: add ssh getargs
Matt Mackall <mpm@selenic.com>
parents: 11442
diff changeset
    42
                    val = self.fin.read(int(l))
c19d7e91cc46 protocol: add ssh getargs
Matt Mackall <mpm@selenic.com>
parents: 11442
diff changeset
    43
                    star[arg] = val
c19d7e91cc46 protocol: add ssh getargs
Matt Mackall <mpm@selenic.com>
parents: 11442
diff changeset
    44
                data['*'] = star
c19d7e91cc46 protocol: add ssh getargs
Matt Mackall <mpm@selenic.com>
parents: 11442
diff changeset
    45
            else:
c19d7e91cc46 protocol: add ssh getargs
Matt Mackall <mpm@selenic.com>
parents: 11442
diff changeset
    46
                data[arg] = val
c19d7e91cc46 protocol: add ssh getargs
Matt Mackall <mpm@selenic.com>
parents: 11442
diff changeset
    47
        return [data[k] for k in keys]
c19d7e91cc46 protocol: add ssh getargs
Matt Mackall <mpm@selenic.com>
parents: 11442
diff changeset
    48
c19d7e91cc46 protocol: add ssh getargs
Matt Mackall <mpm@selenic.com>
parents: 11442
diff changeset
    49
    def getarg(self, name):
c19d7e91cc46 protocol: add ssh getargs
Matt Mackall <mpm@selenic.com>
parents: 11442
diff changeset
    50
        return self.getargs(name)[0]
2396
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    51
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    52
    def respond(self, v):
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    53
        self.fout.write("%d\n" % len(v))
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    54
        self.fout.write(v)
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    55
        self.fout.flush()
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    56
11584
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
    57
    def sendchangegroup(self, changegroup):
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
    58
        while True:
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
    59
            d = changegroup.read(4096)
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
    60
            if not d:
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
    61
                break
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
    62
            self.fout.write(d)
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
    63
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
    64
        self.fout.flush()
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
    65
11585
5d907fbb9703 protocol: unify stream_out command
Matt Mackall <mpm@selenic.com>
parents: 11584
diff changeset
    66
    def sendstream(self, source):
5d907fbb9703 protocol: unify stream_out command
Matt Mackall <mpm@selenic.com>
parents: 11584
diff changeset
    67
        for chunk in source:
5d907fbb9703 protocol: unify stream_out command
Matt Mackall <mpm@selenic.com>
parents: 11584
diff changeset
    68
            self.fout.write(chunk)
5d907fbb9703 protocol: unify stream_out command
Matt Mackall <mpm@selenic.com>
parents: 11584
diff changeset
    69
        self.fout.flush()
5d907fbb9703 protocol: unify stream_out command
Matt Mackall <mpm@selenic.com>
parents: 11584
diff changeset
    70
11593
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
    71
    def getfile(self, fpout):
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
    72
        self.respond('')
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
    73
        count = int(self.fin.readline())
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
    74
        while count:
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
    75
            fpout.write(self.fin.read(count))
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
    76
            count = int(self.fin.readline())
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
    77
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
    78
    def redirect(self):
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
    79
        pass
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
    80
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
    81
    def respondpush(self, ret):
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
    82
        self.respond('')
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
    83
        self.respond(str(ret))
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
    84
2396
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    85
    def serve_forever(self):
8109
496ae1ea4698 switch lock releasing in the core from gc to explicit
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 7875
diff changeset
    86
        try:
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
    87
            while self.serve_one():
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
    88
                pass
8109
496ae1ea4698 switch lock releasing in the core from gc to explicit
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 7875
diff changeset
    89
        finally:
496ae1ea4698 switch lock releasing in the core from gc to explicit
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 7875
diff changeset
    90
            if self.lock is not None:
496ae1ea4698 switch lock releasing in the core from gc to explicit
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 7875
diff changeset
    91
                self.lock.release()
2396
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    92
        sys.exit(0)
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    93
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    94
    def serve_one(self):
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    95
        cmd = self.fin.readline()[:-1]
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents: 11580
diff changeset
    96
        if cmd and not wireproto.dispatch(self.repo, self, cmd):
2396
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    97
            impl = getattr(self, 'do_' + cmd, None)
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
    98
            if impl:
11580
69248b5add46 protocol: move most ssh responses to returns
Matt Mackall <mpm@selenic.com>
parents: 11579
diff changeset
    99
                r = impl()
69248b5add46 protocol: move most ssh responses to returns
Matt Mackall <mpm@selenic.com>
parents: 11579
diff changeset
   100
                if r is not None:
69248b5add46 protocol: move most ssh responses to returns
Matt Mackall <mpm@selenic.com>
parents: 11579
diff changeset
   101
                    self.respond(r)
2397
e9d402506514 merge change to ssh protocol.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2396
diff changeset
   102
            else: self.respond("")
2396
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   103
        return cmd != ''
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   104
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   105
    def do_lock(self):
2439
e8c4f3d3df8c extend network protocol to stop clients from locking servers
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2419
diff changeset
   106
        '''DEPRECATED - allowing remote client to lock repo is not safe'''
e8c4f3d3df8c extend network protocol to stop clients from locking servers
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2419
diff changeset
   107
2396
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   108
        self.lock = self.repo.lock()
11580
69248b5add46 protocol: move most ssh responses to returns
Matt Mackall <mpm@selenic.com>
parents: 11579
diff changeset
   109
        return ""
2396
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   110
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   111
    def do_unlock(self):
2439
e8c4f3d3df8c extend network protocol to stop clients from locking servers
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2419
diff changeset
   112
        '''DEPRECATED'''
e8c4f3d3df8c extend network protocol to stop clients from locking servers
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2419
diff changeset
   113
2396
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   114
        if self.lock:
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   115
            self.lock.release()
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   116
        self.lock = None
11580
69248b5add46 protocol: move most ssh responses to returns
Matt Mackall <mpm@selenic.com>
parents: 11579
diff changeset
   117
        return ""
2396
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   118
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   119
    def do_addchangegroup(self):
2439
e8c4f3d3df8c extend network protocol to stop clients from locking servers
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2419
diff changeset
   120
        '''DEPRECATED'''
e8c4f3d3df8c extend network protocol to stop clients from locking servers
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2419
diff changeset
   121
2396
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   122
        if not self.lock:
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   123
            self.respond("not locked")
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   124
            return
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   125
8d44649df03b refactor ssh server.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   126
        self.respond("")
11593
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   127
        r = self.repo.addchangegroup(self.fin, 'serve', self._client(),
11442
ee1ed6afac21 addchangegroup: pass in lock to release it before changegroup hook is called
Matt Mackall <mpm@selenic.com>
parents: 11369
diff changeset
   128
                                     lock=self.lock)
11580
69248b5add46 protocol: move most ssh responses to returns
Matt Mackall <mpm@selenic.com>
parents: 11579
diff changeset
   129
        return str(r)
2439
e8c4f3d3df8c extend network protocol to stop clients from locking servers
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2419
diff changeset
   130
11593
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   131
    def _client(self):
2673
109a22f5434a hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2622
diff changeset
   132
        client = os.environ.get('SSH_CLIENT', '').split(' ', 1)[0]
109a22f5434a hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2622
diff changeset
   133
        return 'remote:ssh:' + client