1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 import os
18 import stat
19 try:
20
21 import cStringIO
22 except ImportError:
23
24 import io as cStringIO
25 import sys
26 from rhn import rpclib
27
28 from spacewalk.common import usix
29 from spacewalk.common import rhn_rpm
30
31
32 from spacewalk.common import rhnFlags
33 from spacewalk.common.rhnLog import log_debug
34 from spacewalk.common.rhnLib import rfc822time
35 from spacewalk.common.rhnException import rhnException, rhnFault, rhnNotFound
36 from spacewalk.common.RPC_Base import RPC_Base
42
43 """ Shared repository class, inherited by both the proxy and server specific
44 Repository classes.
45 """
46
48 log_debug(2, channelName)
49 RPC_Base.__init__(self)
50 self.channelName = channelName
51
52 self.compress_headers = 1
53 self.functions = [
54 'getPackage',
55 'getPackageHeader',
56 'getPackageSource',
57 'i18n',
58 'media_1'
59 ]
60
62 self.compress_headers = val
63
65 self.channelName = None
66 self.functions = None
67
69 """Returns the path to a package.
70 OVERLOAD this in server and proxy rhnRepository.
71 I.e.: they construct the path differently.
72 """
73
74 raise rhnException("This function should be overloaded.")
75
76 @staticmethod
78 """OVERLOAD this in server and proxy rhnRepository.
79 I.e.: they construct the path differently.
80 """
81 raise rhnException("This function should be overloaded.")
82
84 """Returns the path to a package.
85 OVERLOAD this in server and proxy rhnRepository.
86 I.e.: they construct the path differently.
87 """
88
89 raise rhnException("This function should be overloaded.")
90
92 """ Get rpm package. """
93 log_debug(3, pkgFilename)
94 if args:
95 pkg_spec = [pkgFilename] + list(args)
96 else:
97 pkg_spec = pkgFilename
98
99 redirectsSupported = 0
100
101
102
103 proxyVersionString = rhnFlags.get('x-rhn-proxy-version')
104 if proxyVersionString:
105 redirectsSupported = 1
106 else:
107
108
109 transport_cap = rhnFlags.get('x-rhn-transport-capability')
110 if transport_cap:
111 transport_cap_list = transport_cap.split('=')
112 redirectsSupported = transport_cap_list[0] == 'follow-redirects' and transport_cap_list[1] >= 2
113
114 if redirectsSupported:
115 log_debug(3, "Client supports redirects.")
116 filePath = self.getPackagePath(pkg_spec, 1)
117 else:
118
119 filePath = self.getPackagePath(pkg_spec)
120
121 return self._getFile(filePath)
122
123 @staticmethod
124 - def i18n(_translation, *_args):
125 """ Translations files for Ubuntu. E.g. Translation-en_US.bz2
126
127 We do not support it so just return 404. But do not fail with
128 traceback.
129 """
130 raise rhnNotFound()
131
132 @staticmethod
141
143 """ Get srpm packrge. """
144 log_debug(3, pkgFilename)
145
146 l = pkgFilename.split('.')
147
148 if l[-2] != "nosrc":
149 l[-2] = 'src'
150 pkgFilename = '.'.join(l)
151 filePath = self.getSourcePackagePath(pkgFilename)
152 return self._getFile(filePath)
153
155 """ Get rpm header.
156 XXX: stock 8.0 clients could not compress headers, we need to either
157 change the function name, or version the protocol
158 """
159 log_debug(3, pkgFilename)
160 pkg = pkgFilename.split('.')
161
162 if pkg[-1] not in ["hdr", 'rpm']:
163 raise rhnFault(21, "'%s' not a valid RPM header name" % pkgFilename)
164
165 pkgFilename = ".".join(pkg[:-1]) + '.rpm'
166 filePath = self.getPackagePath(pkgFilename)
167 data = self._getHeaderFromFile(filePath)
168
169
170 return rpclib.transports.File(cStringIO.StringIO(data), len(data))
171
172
173
174
175
176
177
178
180 """ Returns xmlrpclib file object to any file given a path to it.
181 IN: filePath: path to any file.
182 OUT: XMLed rpm or source rpm, or an xmlrpc file object.
183 """
184 log_debug(3, filePath)
185 features = self._fileFeatures(filePath)
186 filePath = features['path']
187 length = features['length']
188 lastModified = features['lastModified']
189 self._set_last_modified(lastModified)
190 return rpclib.transports.File(open(filePath, "rb"), length, name=filePath)
191
193 """ Utility function to extract a header from an rpm.
194 If stat_info was already passed, don't re-stat the file
195 """
196 log_debug(3, filePath)
197 if stat_info:
198 s = stat_info
199 else:
200 s = None
201 try:
202 s = os.stat(filePath)
203 except:
204 usix.raise_with_tb(rhnFault(17, "Unable to read package %s"
205 % os.path.basename(filePath)), sys.exc_info()[2])
206
207 lastModified = s[stat.ST_MTIME]
208 del s
209
210
211
212 fd = os.open(filePath, os.O_RDONLY)
213 h = rhn_rpm.get_package_header(fd=fd)
214 os.close(fd)
215 if h is None:
216 raise rhnFault(17, "Invalid RPM %s" % os.path.basename(filePath))
217 stringIO = cStringIO.StringIO()
218
219 stringIO.write(h.unload())
220 del h
221
222 pkgFilename = os.path.basename(filePath)
223 pkg = pkgFilename.split('.')
224
225 pkg[-1] = "hdr"
226 pkgFilename = ".".join(pkg)
227 extra_headers = {
228 'X-RHN-Package-Header': pkgFilename,
229 }
230 self._set_last_modified(lastModified, extra_headers=extra_headers)
231 rhnFlags.set("AlreadyEncoded", 1)
232 return stringIO.getvalue()
233
234 @staticmethod
250
251 @staticmethod
253 """ From a filepath, construct a dictionary of file features. """
254
255 log_debug(3, filePath)
256 if not filePath:
257 raise rhnFault(17, "While looking for file: `%s'"
258 % os.path.basename(filePath))
259 try:
260 s = os.stat(filePath)
261 except:
262 s = None
263 if not s:
264 l = 0
265 lastModified = 0
266 else:
267 l = s[stat.ST_SIZE]
268 lastModified = s[stat.ST_MTIME]
269 del s
270
271
272 result = {}
273 result['name'] = os.path.basename(filePath)
274 result['length'] = l
275 result['path'] = filePath
276 if lastModified:
277 result['lastModified'] = rfc822time(lastModified)
278 else:
279 result['lastModified'] = None
280 return result
281