##// END OF EJS Templates
hg-ssh: use %s for printing paths in error messages...
Mads Kiilerich -
r16606:19379226 stable
parent child Browse files
Show More
@@ -1,57 +1,57 b''
1 1 #!/usr/bin/env python
2 2 #
3 3 # Copyright 2005-2007 by Intevation GmbH <intevation@intevation.de>
4 4 #
5 5 # Author(s):
6 6 # Thomas Arendsen Hein <thomas@intevation.de>
7 7 #
8 8 # This software may be used and distributed according to the terms of the
9 9 # GNU General Public License version 2 or any later version.
10 10
11 11 """
12 12 hg-ssh - a wrapper for ssh access to a limited set of mercurial repos
13 13
14 14 To be used in ~/.ssh/authorized_keys with the "command" option, see sshd(8):
15 15 command="hg-ssh path/to/repo1 /path/to/repo2 ~/repo3 ~user/repo4" ssh-dss ...
16 16 (probably together with these other useful options:
17 17 no-port-forwarding,no-X11-forwarding,no-agent-forwarding)
18 18
19 19 This allows pull/push over ssh from/to the repositories given as arguments.
20 20
21 21 If all your repositories are subdirectories of a common directory, you can
22 22 allow shorter paths with:
23 23 command="cd path/to/my/repositories && hg-ssh repo1 subdir/repo2"
24 24
25 25 You can use pattern matching of your normal shell, e.g.:
26 26 command="cd repos && hg-ssh user/thomas/* projects/{mercurial,foo}"
27 27 """
28 28
29 29 # enable importing on demand to reduce startup time
30 30 from mercurial import demandimport; demandimport.enable()
31 31
32 32 from mercurial import dispatch
33 33
34 34 import sys, os, shlex
35 35
36 36 cwd = os.getcwd()
37 37 allowed_paths = [os.path.normpath(os.path.join(cwd, os.path.expanduser(path)))
38 38 for path in sys.argv[1:]]
39 39 orig_cmd = os.getenv('SSH_ORIGINAL_COMMAND', '?')
40 40 try:
41 41 cmdargv = shlex.split(orig_cmd)
42 42 except ValueError, e:
43 sys.stderr.write("Illegal command %r: %s\n" % (orig_cmd, e))
43 sys.stderr.write('Illegal command "%s": %s\n' % (orig_cmd, e))
44 44 sys.exit(-1)
45 45
46 46 if cmdargv[:2] == ['hg', '-R'] and cmdargv[3:] == ['serve', '--stdio']:
47 47 path = cmdargv[2]
48 48 repo = os.path.normpath(os.path.join(cwd, os.path.expanduser(path)))
49 49 if repo in allowed_paths:
50 50 dispatch.dispatch(dispatch.request(['-R', repo, 'serve', '--stdio']))
51 51 else:
52 sys.stderr.write("Illegal repository %r\n" % repo)
52 sys.stderr.write('Illegal repository "%s"\n' % repo)
53 53 sys.exit(-1)
54 54 else:
55 sys.stderr.write("Illegal command %r\n" % orig_cmd)
55 sys.stderr.write('Illegal command "%s"\n' % orig_cmd)
56 56 sys.exit(-1)
57 57
@@ -1,318 +1,320 b''
1 1
2 2
3 3 This test tries to exercise the ssh functionality with a dummy script
4 4
5 5 creating 'remote' repo
6 6
7 7 $ hg init remote
8 8 $ cd remote
9 9 $ echo this > foo
10 10 $ echo this > fooO
11 11 $ hg ci -A -m "init" foo fooO
12 12 $ cat <<EOF > .hg/hgrc
13 13 > [server]
14 14 > uncompressed = True
15 15 >
16 16 > [hooks]
17 17 > changegroup = python "$TESTDIR"/printenv.py changegroup-in-remote 0 ../dummylog
18 18 > EOF
19 19 $ cd ..
20 20
21 21 repo not found error
22 22
23 23 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/nonexistent local
24 24 remote: abort: There is no Mercurial repository here (.hg not found)!
25 25 abort: no suitable response from remote hg!
26 26 [255]
27 27
28 28 non-existent absolute path
29 29
30 30 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy//`pwd`/nonexistent local
31 31 remote: abort: There is no Mercurial repository here (.hg not found)!
32 32 abort: no suitable response from remote hg!
33 33 [255]
34 34
35 35 clone remote via stream
36 36
37 37 $ hg clone -e "python \"$TESTDIR/dummyssh\"" --uncompressed ssh://user@dummy/remote local-stream
38 38 streaming all changes
39 39 4 files to transfer, 392 bytes of data
40 40 transferred 392 bytes in * seconds (*/sec) (glob)
41 41 updating to branch default
42 42 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
43 43 $ cd local-stream
44 44 $ hg verify
45 45 checking changesets
46 46 checking manifests
47 47 crosschecking files in changesets and manifests
48 48 checking files
49 49 2 files, 1 changesets, 2 total revisions
50 50 $ cd ..
51 51
52 52 clone remote via pull
53 53
54 54 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote local
55 55 requesting all changes
56 56 adding changesets
57 57 adding manifests
58 58 adding file changes
59 59 added 1 changesets with 2 changes to 2 files
60 60 updating to branch default
61 61 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
62 62
63 63 verify
64 64
65 65 $ cd local
66 66 $ hg verify
67 67 checking changesets
68 68 checking manifests
69 69 crosschecking files in changesets and manifests
70 70 checking files
71 71 2 files, 1 changesets, 2 total revisions
72 72 $ echo '[hooks]' >> .hg/hgrc
73 73 $ echo 'changegroup = python "$TESTDIR"/printenv.py changegroup-in-local 0 ../dummylog' >> .hg/hgrc
74 74
75 75 empty default pull
76 76
77 77 $ hg paths
78 78 default = ssh://user@dummy/remote
79 79 $ hg pull -e "python \"$TESTDIR/dummyssh\""
80 80 pulling from ssh://user@dummy/remote
81 81 searching for changes
82 82 no changes found
83 83
84 84 local change
85 85
86 86 $ echo bleah > foo
87 87 $ hg ci -m "add"
88 88
89 89 updating rc
90 90
91 91 $ echo "default-push = ssh://user@dummy/remote" >> .hg/hgrc
92 92 $ echo "[ui]" >> .hg/hgrc
93 93 $ echo "ssh = python \"$TESTDIR/dummyssh\"" >> .hg/hgrc
94 94
95 95 find outgoing
96 96
97 97 $ hg out ssh://user@dummy/remote
98 98 comparing with ssh://user@dummy/remote
99 99 searching for changes
100 100 changeset: 1:a28a9d1a809c
101 101 tag: tip
102 102 user: test
103 103 date: Thu Jan 01 00:00:00 1970 +0000
104 104 summary: add
105 105
106 106
107 107 find incoming on the remote side
108 108
109 109 $ hg incoming -R ../remote -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/local
110 110 comparing with ssh://user@dummy/local
111 111 searching for changes
112 112 changeset: 1:a28a9d1a809c
113 113 tag: tip
114 114 user: test
115 115 date: Thu Jan 01 00:00:00 1970 +0000
116 116 summary: add
117 117
118 118
119 119 find incoming on the remote side (using absolute path)
120 120
121 121 $ hg incoming -R ../remote -e "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/`pwd`"
122 122 comparing with ssh://user@dummy/$TESTTMP/local
123 123 searching for changes
124 124 changeset: 1:a28a9d1a809c
125 125 tag: tip
126 126 user: test
127 127 date: Thu Jan 01 00:00:00 1970 +0000
128 128 summary: add
129 129
130 130
131 131 push
132 132
133 133 $ hg push
134 134 pushing to ssh://user@dummy/remote
135 135 searching for changes
136 136 remote: adding changesets
137 137 remote: adding manifests
138 138 remote: adding file changes
139 139 remote: added 1 changesets with 1 changes to 1 files
140 140 $ cd ../remote
141 141
142 142 check remote tip
143 143
144 144 $ hg tip
145 145 changeset: 1:a28a9d1a809c
146 146 tag: tip
147 147 user: test
148 148 date: Thu Jan 01 00:00:00 1970 +0000
149 149 summary: add
150 150
151 151 $ hg verify
152 152 checking changesets
153 153 checking manifests
154 154 crosschecking files in changesets and manifests
155 155 checking files
156 156 2 files, 2 changesets, 3 total revisions
157 157 $ hg cat -r tip foo
158 158 bleah
159 159 $ echo z > z
160 160 $ hg ci -A -m z z
161 161 created new head
162 162
163 163 test pushkeys and bookmarks
164 164
165 165 $ cd ../local
166 166 $ hg debugpushkey --config ui.ssh="python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote namespaces
167 167 bookmarks
168 168 phases
169 169 namespaces
170 170 $ hg book foo -r 0
171 171 $ hg out -B
172 172 comparing with ssh://user@dummy/remote
173 173 searching for changed bookmarks
174 174 foo 1160648e36ce
175 175 $ hg push -B foo
176 176 pushing to ssh://user@dummy/remote
177 177 searching for changes
178 178 no changes found
179 179 exporting bookmark foo
180 180 [1]
181 181 $ hg debugpushkey --config ui.ssh="python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote bookmarks
182 182 foo 1160648e36cec0054048a7edc4110c6f84fde594
183 183 $ hg book -f foo
184 184 $ hg push --traceback
185 185 pushing to ssh://user@dummy/remote
186 186 searching for changes
187 187 no changes found
188 188 updating bookmark foo
189 189 [1]
190 190 $ hg book -d foo
191 191 $ hg in -B
192 192 comparing with ssh://user@dummy/remote
193 193 searching for changed bookmarks
194 194 foo a28a9d1a809c
195 195 $ hg book -f -r 0 foo
196 196 $ hg pull -B foo
197 197 pulling from ssh://user@dummy/remote
198 198 no changes found
199 199 updating bookmark foo
200 200 importing bookmark foo
201 201 $ hg book -d foo
202 202 $ hg push -B foo
203 203 pushing to ssh://user@dummy/remote
204 204 searching for changes
205 205 no changes found
206 206 deleting remote bookmark foo
207 207 [1]
208 208
209 209 a bad, evil hook that prints to stdout
210 210
211 211 $ cat <<EOF > $TESTTMP/badhook
212 212 > import sys
213 213 > sys.stdout.write("KABOOM\n")
214 214 > EOF
215 215
216 216 $ echo '[hooks]' >> ../remote/.hg/hgrc
217 217 $ echo "changegroup.stdout = python $TESTTMP/badhook" >> ../remote/.hg/hgrc
218 218 $ echo r > r
219 219 $ hg ci -A -m z r
220 220
221 221 push should succeed even though it has an unexpected response
222 222
223 223 $ hg push
224 224 pushing to ssh://user@dummy/remote
225 225 searching for changes
226 226 note: unsynced remote changes!
227 227 remote: adding changesets
228 228 remote: adding manifests
229 229 remote: adding file changes
230 230 remote: added 1 changesets with 1 changes to 1 files
231 231 remote: KABOOM
232 232 $ hg -R ../remote heads
233 233 changeset: 3:1383141674ec
234 234 tag: tip
235 235 parent: 1:a28a9d1a809c
236 236 user: test
237 237 date: Thu Jan 01 00:00:00 1970 +0000
238 238 summary: z
239 239
240 240 changeset: 2:6c0482d977a3
241 241 parent: 0:1160648e36ce
242 242 user: test
243 243 date: Thu Jan 01 00:00:00 1970 +0000
244 244 summary: z
245 245
246 246
247 247 clone bookmarks
248 248
249 249 $ hg -R ../remote bookmark test
250 250 $ hg -R ../remote bookmarks
251 251 * test 2:6c0482d977a3
252 252 $ hg clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote local-bookmarks
253 253 requesting all changes
254 254 adding changesets
255 255 adding manifests
256 256 adding file changes
257 257 added 4 changesets with 5 changes to 4 files (+1 heads)
258 258 updating to branch default
259 259 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
260 260 $ hg -R local-bookmarks bookmarks
261 261 test 2:6c0482d977a3
262 262
263 263 passwords in ssh urls are not supported
264 264 (we use a glob here because different Python versions give different
265 265 results here)
266 266
267 267 $ hg push ssh://user:erroneouspwd@dummy/remote
268 268 pushing to ssh://user:*@dummy/remote (glob)
269 269 abort: password in URL not supported!
270 270 [255]
271 271
272 272 $ cd ..
273 273
274 274 Test remote paths with spaces (issue2983):
275 275
276 276 $ hg init --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
277 277 $ hg -R 'a repo' tag tag
278 278 $ hg id --ssh "python \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
279 279 3fb238f49e8c
280 280
281 281 Test hg-ssh:
282 282
283 283 $ SSH_ORIGINAL_COMMAND="'hg' -R 'a repo' serve --stdio" hg id --ssh "python \"$TESTDIR\"/../contrib/hg-ssh \"$TESTTMP/a repo\"" "ssh://user@dummy/a repo"
284 284 3fb238f49e8c
285
285 286 $ SSH_ORIGINAL_COMMAND="'hg' -R 'a repo' serve --stdio" hg id --ssh "python \"$TESTDIR\"/../contrib/hg-ssh \"$TESTTMP\"" "ssh://user@dummy/a repo"
286 remote: Illegal repository '$TESTTMP/a repo' (glob)
287 remote: Illegal repository "$TESTTMP/a repo" (glob)
287 288 abort: no suitable response from remote hg!
288 289 [255]
290
289 291 $ SSH_ORIGINAL_COMMAND="'hg' -R 'a'repo' serve --stdio" hg id --ssh "python \"$TESTDIR\"/../contrib/hg-ssh \"$TESTTMP\"" "ssh://user@dummy/a repo"
290 292 remote: Illegal command "'hg' -R 'a'repo' serve --stdio": No closing quotation
291 293 abort: no suitable response from remote hg!
292 294 [255]
293 295
294 296 $ cat dummylog
295 297 Got arguments 1:user@dummy 2:hg -R nonexistent serve --stdio
296 298 Got arguments 1:user@dummy 2:hg -R /$TESTTMP/nonexistent serve --stdio
297 299 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
298 300 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
299 301 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
300 302 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
301 303 Got arguments 1:user@dummy 2:hg -R local serve --stdio
302 304 Got arguments 1:user@dummy 2:hg -R $TESTTMP/local serve --stdio
303 305 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
304 306 changegroup-in-remote hook: HG_NODE=a28a9d1a809cab7d4e2fde4bee738a9ede948b60 HG_SOURCE=serve HG_URL=remote:ssh:127.0.0.1
305 307 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
306 308 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
307 309 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
308 310 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
309 311 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
310 312 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
311 313 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
312 314 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
313 315 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
314 316 changegroup-in-remote hook: HG_NODE=1383141674ec756a6056f6a9097618482fe0f4a6 HG_SOURCE=serve HG_URL=remote:ssh:127.0.0.1
315 317 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
316 318 Got arguments 1:user@dummy 2:hg init 'a repo'
317 319 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
318 320 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
General Comments 0
You need to be logged in to leave comments. Login now