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