Mercurial > hg-stable
annotate mercurial/sshserver.py @ 11594:67863f9d805f
protocol: unify server-side capabilities functions
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Thu, 15 Jul 2010 13:56:52 -0500 |
parents | d054cc5c7737 |
children | 47ca289a3a08 |
rev | line source |
---|---|
2399 | 1 # sshserver.py - ssh protocol server support for mercurial |
2396 | 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 | 4 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com> |
2396 | 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 | 7 # GNU General Public License version 2 or any later version. |
2396 | 8 |
3891 | 9 from i18n import _ |
6211
f89fd07fc51d
Expand import * to allow Pyflakes to find problems
Joel Rosdahl <joel@rosdahl.net>
parents:
5833
diff
changeset
|
10 from node import bin, hex |
11581
4530b3307fb9
protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
11580
diff
changeset
|
11 import streamclone, util, hook, pushkey, wireproto |
9713
d193cc97c4e8
hgweb/sshserver: extract capabilities for easier modification
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
9198
diff
changeset
|
12 import os, sys, tempfile, urllib, copy |
2396 | 13 |
14 class sshserver(object): | |
15 def __init__(self, ui, repo): | |
16 self.ui = ui | |
17 self.repo = repo | |
18 self.lock = None | |
19 self.fin = sys.stdin | |
20 self.fout = sys.stdout | |
21 | |
5833
323b9c55b328
hook: redirect stdout to stderr for ssh and http servers
Matt Mackall <mpm@selenic.com>
parents:
4635
diff
changeset
|
22 hook.redirect(True) |
2396 | 23 sys.stdout = sys.stderr |
24 | |
25 # Prevent insertion/deletion of CRs | |
26 util.set_binary(self.fin) | |
27 util.set_binary(self.fout) | |
28 | |
11579 | 29 def getargs(self, args): |
30 data = {} | |
31 keys = args.split() | |
32 count = len(keys) | |
33 for n in xrange(len(keys)): | |
34 argline = self.fin.readline()[:-1] | |
35 arg, l = argline.split() | |
36 val = self.fin.read(int(l)) | |
37 if arg not in keys: | |
38 raise util.Abort("unexpected parameter %r" % arg) | |
39 if arg == '*': | |
40 star = {} | |
41 for n in xrange(int(l)): | |
42 arg, l = argline.split() | |
43 val = self.fin.read(int(l)) | |
44 star[arg] = val | |
45 data['*'] = star | |
46 else: | |
47 data[arg] = val | |
48 return [data[k] for k in keys] | |
49 | |
50 def getarg(self, name): | |
51 return self.getargs(name)[0] | |
2396 | 52 |
53 def respond(self, v): | |
54 self.fout.write("%d\n" % len(v)) | |
55 self.fout.write(v) | |
56 self.fout.flush() | |
57 | |
11584
1af96b090116
protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents:
11581
diff
changeset
|
58 def sendchangegroup(self, changegroup): |
1af96b090116
protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents:
11581
diff
changeset
|
59 while True: |
1af96b090116
protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents:
11581
diff
changeset
|
60 d = changegroup.read(4096) |
1af96b090116
protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents:
11581
diff
changeset
|
61 if not d: |
1af96b090116
protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents:
11581
diff
changeset
|
62 break |
1af96b090116
protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents:
11581
diff
changeset
|
63 self.fout.write(d) |
1af96b090116
protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents:
11581
diff
changeset
|
64 |
1af96b090116
protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents:
11581
diff
changeset
|
65 self.fout.flush() |
1af96b090116
protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents:
11581
diff
changeset
|
66 |
11585
5d907fbb9703
protocol: unify stream_out command
Matt Mackall <mpm@selenic.com>
parents:
11584
diff
changeset
|
67 def sendstream(self, source): |
5d907fbb9703
protocol: unify stream_out command
Matt Mackall <mpm@selenic.com>
parents:
11584
diff
changeset
|
68 for chunk in source: |
5d907fbb9703
protocol: unify stream_out command
Matt Mackall <mpm@selenic.com>
parents:
11584
diff
changeset
|
69 self.fout.write(chunk) |
5d907fbb9703
protocol: unify stream_out command
Matt Mackall <mpm@selenic.com>
parents:
11584
diff
changeset
|
70 self.fout.flush() |
5d907fbb9703
protocol: unify stream_out command
Matt Mackall <mpm@selenic.com>
parents:
11584
diff
changeset
|
71 |
11593
d054cc5c7737
protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents:
11585
diff
changeset
|
72 def getfile(self, fpout): |
d054cc5c7737
protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents:
11585
diff
changeset
|
73 self.respond('') |
d054cc5c7737
protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents:
11585
diff
changeset
|
74 count = int(self.fin.readline()) |
d054cc5c7737
protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents:
11585
diff
changeset
|
75 while count: |
d054cc5c7737
protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents:
11585
diff
changeset
|
76 fpout.write(self.fin.read(count)) |
d054cc5c7737
protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents:
11585
diff
changeset
|
77 count = int(self.fin.readline()) |
d054cc5c7737
protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents:
11585
diff
changeset
|
78 |
d054cc5c7737
protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents:
11585
diff
changeset
|
79 def redirect(self): |
d054cc5c7737
protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents:
11585
diff
changeset
|
80 pass |
d054cc5c7737
protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents:
11585
diff
changeset
|
81 |
d054cc5c7737
protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents:
11585
diff
changeset
|
82 def respondpush(self, ret): |
d054cc5c7737
protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents:
11585
diff
changeset
|
83 self.respond('') |
d054cc5c7737
protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents:
11585
diff
changeset
|
84 self.respond(str(ret)) |
d054cc5c7737
protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents:
11585
diff
changeset
|
85 |
2396 | 86 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
|
87 try: |
10282
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10263
diff
changeset
|
88 while self.serve_one(): |
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10263
diff
changeset
|
89 pass |
8109
496ae1ea4698
switch lock releasing in the core from gc to explicit
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
7875
diff
changeset
|
90 finally: |
496ae1ea4698
switch lock releasing in the core from gc to explicit
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
7875
diff
changeset
|
91 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
|
92 self.lock.release() |
2396 | 93 sys.exit(0) |
94 | |
95 def serve_one(self): | |
96 cmd = self.fin.readline()[:-1] | |
11581
4530b3307fb9
protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
11580
diff
changeset
|
97 if cmd and not wireproto.dispatch(self.repo, self, cmd): |
2396 | 98 impl = getattr(self, 'do_' + cmd, None) |
10282
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10263
diff
changeset
|
99 if impl: |
11580
69248b5add46
protocol: move most ssh responses to returns
Matt Mackall <mpm@selenic.com>
parents:
11579
diff
changeset
|
100 r = impl() |
69248b5add46
protocol: move most ssh responses to returns
Matt Mackall <mpm@selenic.com>
parents:
11579
diff
changeset
|
101 if r is not None: |
69248b5add46
protocol: move most ssh responses to returns
Matt Mackall <mpm@selenic.com>
parents:
11579
diff
changeset
|
102 self.respond(r) |
2397
e9d402506514
merge change to ssh protocol.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2396
diff
changeset
|
103 else: self.respond("") |
2396 | 104 return cmd != '' |
105 | |
106 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
|
107 '''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
|
108 |
2396 | 109 self.lock = self.repo.lock() |
11580
69248b5add46
protocol: move most ssh responses to returns
Matt Mackall <mpm@selenic.com>
parents:
11579
diff
changeset
|
110 return "" |
2396 | 111 |
112 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
|
113 '''DEPRECATED''' |
e8c4f3d3df8c
extend network protocol to stop clients from locking servers
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2419
diff
changeset
|
114 |
2396 | 115 if self.lock: |
116 self.lock.release() | |
117 self.lock = None | |
11580
69248b5add46
protocol: move most ssh responses to returns
Matt Mackall <mpm@selenic.com>
parents:
11579
diff
changeset
|
118 return "" |
2396 | 119 |
120 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
|
121 '''DEPRECATED''' |
e8c4f3d3df8c
extend network protocol to stop clients from locking servers
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2419
diff
changeset
|
122 |
2396 | 123 if not self.lock: |
124 self.respond("not locked") | |
125 return | |
126 | |
127 self.respond("") | |
11593
d054cc5c7737
protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents:
11585
diff
changeset
|
128 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
|
129 lock=self.lock) |
11580
69248b5add46
protocol: move most ssh responses to returns
Matt Mackall <mpm@selenic.com>
parents:
11579
diff
changeset
|
130 return str(r) |
2439
e8c4f3d3df8c
extend network protocol to stop clients from locking servers
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2419
diff
changeset
|
131 |
11593
d054cc5c7737
protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents:
11585
diff
changeset
|
132 def _client(self): |
2673
109a22f5434a
hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2622
diff
changeset
|
133 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
|
134 return 'remote:ssh:' + client |