[208797c] | 1 | #!/usr/local/bin/python |
---|
| 2 | |
---|
| 3 | import os,sys |
---|
| 4 | import logging |
---|
| 5 | |
---|
| 6 | from service_error import service_error |
---|
| 7 | from remote_service import xmlrpc_handler, soap_handler, service_caller |
---|
| 8 | |
---|
[d2e86f6] | 9 | from ssh_emulab_segment import ssh_emulab_segment |
---|
[208797c] | 10 | |
---|
| 11 | |
---|
[d2e86f6] | 12 | class protogeni_proxy(ssh_emulab_segment): |
---|
[208797c] | 13 | class ProtoGENIError(Exception): |
---|
| 14 | def __init__(self, op, code, output): |
---|
| 15 | Exception.__init__(self, output) |
---|
| 16 | self.op = op |
---|
| 17 | self.code = code |
---|
| 18 | self.output = output |
---|
| 19 | |
---|
| 20 | def __init__(self, log=None, keyfile=None, debug=False, |
---|
| 21 | ch_url=None, sa_url=None, cm_url=None): |
---|
[d2e86f6] | 22 | ssh_emulab_segment.__init__(self, log=log, keyfile=keyfile, |
---|
| 23 | debug=debug) |
---|
[208797c] | 24 | |
---|
| 25 | self.ProtoGENIError = protogeni_proxy.ProtoGENIError |
---|
| 26 | self.ch_url = ch_url |
---|
| 27 | self.sa_url = sa_url |
---|
| 28 | self.cm_url = cm_url |
---|
| 29 | |
---|
| 30 | self.call_SetValue = service_caller('SetValue') |
---|
| 31 | |
---|
[4c65f67] | 32 | self.debug_fail = [] |
---|
[208797c] | 33 | self.debug_response = { |
---|
| 34 | 'RedeemTicket': ("XML blob1", "XML blob2"), |
---|
[4c65f67] | 35 | 'SliverStatus': { 'status': 'ready' }, |
---|
| 36 | 'Resolve': { |
---|
| 37 | 'creator_urn': 'debugCreatorURN', |
---|
| 38 | 'urn': 'debugURN', |
---|
| 39 | }, |
---|
| 40 | 'GetKeys': [ { 'key': 'k' } ], |
---|
| 41 | 'CreateSliver': 'manifest', |
---|
[208797c] | 42 | } |
---|
| 43 | |
---|
| 44 | |
---|
| 45 | def pg_call(self, url, method, params, context): |
---|
| 46 | max_retries = 5 |
---|
| 47 | retries = 0 |
---|
| 48 | |
---|
| 49 | s = service_caller(method, request_body_name="", strict=False) |
---|
| 50 | if self.log: |
---|
| 51 | self.log.debug("Calling %s %s" % (url, method)) |
---|
| 52 | if not self.debug: |
---|
| 53 | while retries < max_retries: |
---|
| 54 | r = s.call_xmlrpc_service(url, params, context=context) |
---|
| 55 | code = r.get('code', -1) |
---|
| 56 | if code == 0: |
---|
| 57 | # Success leaves the loop here |
---|
| 58 | return r.get('value', None) |
---|
| 59 | elif code == 14 and retries +1 < max_retries: |
---|
| 60 | # Busy resource |
---|
| 61 | retries+= 1 |
---|
| 62 | self.log.info("Resource busy, retrying in 30 secs") |
---|
| 63 | time.sleep(30) |
---|
| 64 | else: |
---|
| 65 | # NB: out of retries falls through to here |
---|
| 66 | raise self.ProtoGENIError(op=method, |
---|
| 67 | code=r.get('code', 'unknown'), |
---|
| 68 | output=r.get('output', 'No output')) |
---|
| 69 | else: |
---|
| 70 | if method in self.debug_fail: |
---|
| 71 | raise self.ProtoGENIError(op=method, code='unknown', |
---|
| 72 | output='No output') |
---|
| 73 | elif self.debug_response.has_key(method): |
---|
| 74 | return self.debug_response[method] |
---|
| 75 | else: |
---|
| 76 | return "%s XML blob" % method |
---|
| 77 | |
---|
| 78 | def clearinghouse_call(self, method, params, context): |
---|
| 79 | return self.pg_call(self.ch_url, method, params, context) |
---|
| 80 | |
---|
| 81 | def slice_authority_call(self, method, params, context): |
---|
| 82 | return self.pg_call(self.sa_url, method, params, context) |
---|
| 83 | |
---|
| 84 | def component_manager_call(self, method, params, context): |
---|
| 85 | return self.pg_call(self.cm_url, method, params, context) |
---|
| 86 | |
---|