Kiln » Kiln Extensions
Clone URL:  
remotestore.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
'''Remote bfile store; the base class for servestore and kilnstore''' from mercurial import util from mercurial.i18n import _ import bfutil import basestore class remotestore(basestore.basestore): """A bfile store accessed over a network""" def __init__(self, ui, repo, url): super(remotestore, self).__init__(ui, repo, url) def put(self, source, hash): if self._verify(hash): return if self.sendfile(source, hash): raise util.Abort( _('remotestore: could not put %s to remote store %s') % (source, self.url)) self.ui.debug( _('remotestore: put %s to remote store %s') % (source, self.url)) def exists(self, hash): return self._verify(hash) def sendfile(self, filename, hash): self.ui.debug('remotestore: sendfile(%s, %s)\n' % (filename, hash)) fd = None try: try: fd = bfutil.httpsendfile(self.ui, filename) except IOError, e: raise util.Abort( _('remotestore: could not open file %s: %s') % (filename, str(e))) return self._put(hash, fd) finally: if fd: fd.close() def _getfile(self, tmpfile, filename, hash): # quit if the bfile isn't there stat = self._stat(hash) if stat: raise util.Abort(_('remotestore: bfile %s is %s') % (hash, stat == 1 and 'invalid' or 'missing')) try: length, infile = self._get(hash) except HTTPError, e: # 401s get converted to util.Aborts; everything else is fine being # turned into a StoreError raise basestore.StoreError(filename, hash, self.url, str(e)) except urllib2.URLError, e: # This usually indicates a connection problem, so don't # keep trying with the other files... they will probably # all fail too. raise util.Abort('%s: %s' % (self.url, str(e.reason))) except IOError, e: raise basestore.StoreError(filename, hash, self.url, str(e)) # Mercurial does not close its SSH connections after writing a stream if length is not None: infile = bfutil.limitreader(infile, length) return bfutil.copyandhash(bfutil.blockstream(infile), tmpfile) def _verify(self, hash): return not self._stat(hash) def _verifyfile(self, cctx, cset, contents, standin, verified): filename = bfutil.splitstandin(standin) if not filename: return False fctx = cctx[standin] key = (filename, fctx.filenode()) if key in verified: return False expect_hash = fctx.data()[0:40] verified.add(key) stat = self._stat(hash) if not stat: return False elif stat == 1: self.ui.warn( _('changeset %s: %s: contents differ\n (%s)\n') % (cset, filename, store_path)) return True # failed elif stat == 2: self.ui.warn( _('changeset %s: %s missing\n (%s)\n') % (cset, filename, store_path)) return True # failed else: raise util.Abort(_('check failed, unexpected response' 'statbfile: %d') % stat) class storeprotonotcapable(BaseException): def __init__(self, storetypes): self.storetypes = storetypes