1
2
3 import os
4 import sys
5 import socket
6 import time
7
8 from up2date_client import config
9 from up2date_client import clientCaps
10 from up2date_client import up2dateLog
11 from up2date_client import up2dateErrors
12 from up2date_client import up2dateUtils
13
14 from rhn import SSL
15 from rhn import rpclib
16 from rhn.tb import raise_with_tb
17
18 try:
19 import httplib
20 import urllib2
21 import urlparse
22 import xmlrpclib
23 except ImportError:
24 import http.client as httplib
25 import urllib.request as urllib2
26 import urllib.parse as urlparse
27 import xmlrpc.client as xmlrpclib
28
29 import gettext
30 t = gettext.translation('rhn-client-tools', fallback=True)
31
32 if not hasattr(t, 'ugettext'):
33 t.ugettext = t.gettext
34 _ = t.ugettext
35
38
39
42 self.serverList = serverList
43
45 self.log = up2dateLog.initLog()
46 while 1:
47 try:
48 ret = self._request(methodname, params)
49 except rpclib.InvalidRedirectionError:
50 raise
51 except xmlrpclib.Fault:
52 raise
53 except httplib.BadStatusLine:
54 self.log.log_me("Error: Server Unavailable. Please try later.")
55 stdoutMsgCallback(
56 _("Error: Server Unavailable. Please try later."))
57 sys.exit(-1)
58 except:
59 server = self.serverList.next()
60 if server == None:
61
62
63
64 self.serverList.resetServerIndex()
65 raise
66
67 msg = "An error occurred talking to %s:\n" % self._host
68 msg = msg + "%s\n%s\n" % (sys.exc_info()[0], sys.exc_info()[1])
69 msg = msg + "Trying the next serverURL: %s\n" % self.serverList.server()
70 self.log.log_me(msg)
71
72
73
74 parse_res = urlparse.urlsplit(self.serverList.server())
75 typ = parse_res[0]
76 self._host = parse_res[1]
77 self._handler = parse_res[2]
78 typ = typ.lower()
79 if typ not in ("http", "https"):
80 raise_with_tb(rpclib.InvalidRedirectionError(
81 "Redirected to unsupported protocol %s" % typ))
82 self._orig_handler = self._handler
83 self._type = typ
84 self._uri = self.serverList.server()
85 if not self._handler:
86 self._handler = "/RPC2"
87 self._allow_redirect = 1
88 continue
89
90 break
91 return ret
92
93
97
98
99
102 self.serverList = serverlist
103 self.index = 0
104
106 self.serverurl = self.serverList[self.index]
107 return self.serverurl
108
109
111 self.index = self.index + 1
112 if self.index >= len(self.serverList):
113 return None
114 return self.server()
115
118
119
120 -def getServer(refreshCallback=None, serverOverride=None, timeout=None):
121 log = up2dateLog.initLog()
122 cfg = config.initUp2dateConfig()
123
124
125
126
127 ca = cfg["sslCACert"]
128 if not isinstance(ca, list):
129 ca = [ca]
130
131 rhns_ca_certs = ca or ["/usr/share/rhn/RHNS-CA-CERT"]
132 if cfg["enableProxy"]:
133 proxyHost = config.getProxySetting()
134 else:
135 proxyHost = None
136
137 if not serverOverride:
138 serverUrls = config.getServerlURL()
139 else:
140 serverUrls = serverOverride
141 serverList = ServerList(serverUrls)
142
143 proxyUser = None
144 proxyPassword = None
145 if cfg["enableProxyAuth"]:
146 proxyUser = cfg["proxyUser"] or None
147 proxyPassword = cfg["proxyPassword"] or None
148
149 lang = None
150 for env in 'LANGUAGE', 'LC_ALL', 'LC_MESSAGES', 'LANG':
151 if env in os.environ:
152 if not os.environ[env]:
153
154 continue
155 lang = os.environ[env].split(':')[0]
156 lang = lang.split('.')[0]
157 break
158
159
160 s = RetryServer(serverList.server(),
161 refreshCallback=refreshCallback,
162 proxy=proxyHost,
163 username=proxyUser,
164 password=proxyPassword,
165 timeout=timeout)
166 s.addServerList(serverList)
167
168 s.add_header("X-Up2date-Version", up2dateUtils.version())
169
170 if lang:
171 s.setlang(lang)
172
173
174 need_ca = [ True for i in s.serverList.serverList
175 if urlparse.urlparse(i)[0] == 'https']
176 if need_ca:
177 for rhns_ca_cert in rhns_ca_certs:
178 if not os.access(rhns_ca_cert, os.R_OK):
179 msg = "%s: %s" % (_("ERROR: can not find RHNS CA file"),
180 rhns_ca_cert)
181 log.log_me("%s" % msg)
182 raise up2dateErrors.SSLCertificateFileNotFound(msg)
183
184
185 s.add_trusted_cert(rhns_ca_cert)
186
187 clientCaps.loadLocalCaps()
188
189
190 headerlist = clientCaps.caps.headerFormat()
191 for (headerName, value) in headerlist:
192 s.add_header(headerName, value)
193 return s
194
195
196 -def doCall(method, *args, **kwargs):
197 log = up2dateLog.initLog()
198 log.log_debug("rpcServer: Calling XMLRPC %s" % method.__dict__['_Method__name'])
199 cfg = config.initUp2dateConfig()
200 ret = None
201
202 attempt_count = 1
203 try:
204 attempts = int(cfg["networkRetries"])
205 except ValueError:
206 attempts = 1
207 if attempts <= 0:
208 attempts = 1
209
210 while 1:
211 failure = 0
212 ret = None
213 try:
214 ret = method(*args, **kwargs)
215 except KeyboardInterrupt:
216 raise_with_tb(up2dateErrors.CommunicationError(_(
217 "Connection aborted by the user")))
218
219 except (socket.error, SSL.socket_error):
220 log.log_me("A socket error occurred: %s, attempt #%s" % (
221 sys.exc_info()[1], attempt_count))
222 if attempt_count >= attempts:
223 e = sys.exc_info()[1]
224 if len(e.args) > 1:
225 raise_with_tb(up2dateErrors.CommunicationError(e.args[1]))
226 else:
227 raise_with_tb(up2dateErrors.CommunicationError(e.args[0]))
228 else:
229 failure = 1
230 except httplib.IncompleteRead:
231 print("httplib.IncompleteRead")
232 raise_with_tb(up2dateErrors.CommunicationError("httplib.IncompleteRead"))
233
234 except urllib2.HTTPError:
235 e = sys.exc_info()[1]
236 msg = "\nAn HTTP error occurred:\n"
237 msg = msg + "URL: %s\n" % e.filename
238 msg = msg + "Status Code: %s\n" % e.code
239 msg = msg + "Error Message: %s\n" % e.msg
240 log.log_me(msg)
241 raise_with_tb(up2dateErrors.CommunicationError(msg))
242
243 except xmlrpclib.ProtocolError:
244 e = sys.exc_info()[1]
245 log.log_me("A protocol error occurred: %s , attempt #%s," % (
246 e.errmsg, attempt_count))
247 if e.errcode == 404:
248 log.log_me("Could not find URL, %s" % (e.url))
249 log.log_me("Check server name and/or URL, then retry\n");
250
251 (errCode, errMsg) = rpclib.reportError(e.headers)
252 reset = 0
253 if abs(errCode) == 34:
254 log.log_me("Auth token timeout occurred\n errmsg: %s" % errMsg)
255
256
257
258
259 from up2date_client import up2dateAuth
260 up2dateAuth.updateLoginInfo()
261
262
263
264 if abs(errCode) == 51:
265 log.log_me(_("Server has refused connection due to high load"))
266 raise_with_tb(up2dateErrors.CommunicationError(e.errmsg))
267
268
269
270
271
272 if abs(errCode) == 17:
273
274
275 if type(args[0]) == type([]):
276 pkg = args[0]
277 else:
278 pkg=args[1]
279
280 if type(pkg) == type([]):
281 pkgName = "%s-%s-%s.%s" % (pkg[0], pkg[1], pkg[2], pkg[4])
282 else:
283 pkgName = pkg
284 msg = "File Not Found: %s\n%s" % (pkgName, errMsg)
285 log.log_me(msg)
286 raise_with_tb(up2dateErrors.FileNotFoundError(msg))
287
288 if not reset:
289 if attempt_count >= attempts:
290 raise_with_tb(up2dateErrors.CommunicationError(e.errmsg))
291 else:
292 failure = 1
293
294 except xmlrpclib.ResponseError:
295 raise_with_tb(up2dateErrors.CommunicationError(
296 "Broken response from the server."))
297
298 if ret != None:
299 break
300 else:
301 failure = 1
302
303
304 if failure:
305
306 time.sleep(5)
307 attempt_count = attempt_count + 1
308
309 if attempt_count > attempts:
310 raise up2dateErrors.CommunicationError("The data returned from the server was incomplete")
311
312 return ret
313