##// END OF EJS Templates
py3: use util.forcebytestr() to convert IOErrors to bytes...
Pulkit Goyal -
r36580:247e9bf4 default
parent child Browse files
Show More
@@ -1,126 +1,128 b''
1 1 # Copyright 2010-2011 Fog Creek Software
2 2 # Copyright 2010-2011 Unity Technologies
3 3 #
4 4 # This software may be used and distributed according to the terms of the
5 5 # GNU General Public License version 2 or any later version.
6 6
7 7 '''remote largefile store; the base class for wirestore'''
8 8 from __future__ import absolute_import
9 9
10 10 from mercurial.i18n import _
11 11
12 12 from mercurial import (
13 13 error,
14 14 util,
15 15 )
16 16
17 17 from . import (
18 18 basestore,
19 19 lfutil,
20 20 localstore,
21 21 )
22 22
23 23 urlerr = util.urlerr
24 24 urlreq = util.urlreq
25 25
26 26 class remotestore(basestore.basestore):
27 27 '''a largefile store accessed over a network'''
28 28 def __init__(self, ui, repo, url):
29 29 super(remotestore, self).__init__(ui, repo, url)
30 30 self._lstore = None
31 31 if repo is not None:
32 32 self._lstore = localstore.localstore(self.ui, self.repo, self.repo)
33 33
34 34 def put(self, source, hash):
35 35 if self.sendfile(source, hash):
36 36 raise error.Abort(
37 37 _('remotestore: could not put %s to remote store %s')
38 38 % (source, util.hidepassword(self.url)))
39 39 self.ui.debug(
40 40 _('remotestore: put %s to remote store %s\n')
41 41 % (source, util.hidepassword(self.url)))
42 42
43 43 def exists(self, hashes):
44 44 return dict((h, s == 0) for (h, s) in # dict-from-generator
45 45 self._stat(hashes).iteritems())
46 46
47 47 def sendfile(self, filename, hash):
48 48 self.ui.debug('remotestore: sendfile(%s, %s)\n' % (filename, hash))
49 49 try:
50 50 with lfutil.httpsendfile(self.ui, filename) as fd:
51 51 return self._put(hash, fd)
52 52 except IOError as e:
53 53 raise error.Abort(
54 54 _('remotestore: could not open file %s: %s')
55 % (filename, str(e)))
55 % (filename, util.forcebytestr(e)))
56 56
57 57 def _getfile(self, tmpfile, filename, hash):
58 58 try:
59 59 chunks = self._get(hash)
60 60 except urlerr.httperror as e:
61 61 # 401s get converted to error.Aborts; everything else is fine being
62 62 # turned into a StoreError
63 raise basestore.StoreError(filename, hash, self.url, str(e))
63 raise basestore.StoreError(filename, hash, self.url,
64 util.forcebytestr(e))
64 65 except urlerr.urlerror as e:
65 66 # This usually indicates a connection problem, so don't
66 67 # keep trying with the other files... they will probably
67 68 # all fail too.
68 69 raise error.Abort('%s: %s' %
69 70 (util.hidepassword(self.url), e.reason))
70 71 except IOError as e:
71 raise basestore.StoreError(filename, hash, self.url, str(e))
72 raise basestore.StoreError(filename, hash, self.url,
73 util.forcebytestr(e))
72 74
73 75 return lfutil.copyandhash(chunks, tmpfile)
74 76
75 77 def _hashesavailablelocally(self, hashes):
76 78 existslocallymap = self._lstore.exists(hashes)
77 79 localhashes = [hash for hash in hashes if existslocallymap[hash]]
78 80 return localhashes
79 81
80 82 def _verifyfiles(self, contents, filestocheck):
81 83 failed = False
82 84 expectedhashes = [expectedhash
83 85 for cset, filename, expectedhash in filestocheck]
84 86 localhashes = self._hashesavailablelocally(expectedhashes)
85 87 stats = self._stat([expectedhash for expectedhash in expectedhashes
86 88 if expectedhash not in localhashes])
87 89
88 90 for cset, filename, expectedhash in filestocheck:
89 91 if expectedhash in localhashes:
90 92 filetocheck = (cset, filename, expectedhash)
91 93 verifyresult = self._lstore._verifyfiles(contents,
92 94 [filetocheck])
93 95 if verifyresult:
94 96 failed = True
95 97 else:
96 98 stat = stats[expectedhash]
97 99 if stat:
98 100 if stat == 1:
99 101 self.ui.warn(
100 102 _('changeset %s: %s: contents differ\n')
101 103 % (cset, filename))
102 104 failed = True
103 105 elif stat == 2:
104 106 self.ui.warn(
105 107 _('changeset %s: %s missing\n')
106 108 % (cset, filename))
107 109 failed = True
108 110 else:
109 111 raise RuntimeError('verify failed: unexpected response '
110 112 'from statlfile (%r)' % stat)
111 113 return failed
112 114
113 115 def _put(self, hash, fd):
114 116 '''Put file with the given hash in the remote store.'''
115 117 raise NotImplementedError('abstract method')
116 118
117 119 def _get(self, hash):
118 120 '''Get a iterator for content with the given hash.'''
119 121 raise NotImplementedError('abstract method')
120 122
121 123 def _stat(self, hashes):
122 124 '''Get information about availability of files specified by
123 125 hashes in the remote store. Return dictionary mapping hashes
124 126 to return code where 0 means that file is available, other
125 127 values if not.'''
126 128 raise NotImplementedError('abstract method')
General Comments 0
You need to be logged in to leave comments. Login now