Changeset 65f3f29 for fedd


Ignore:
Timestamp:
Jul 25, 2009 10:52:45 AM (15 years ago)
Author:
Ted Faber <faber@…>
Branches:
axis_example, compt_changes, info-ops, master, version-1.30, version-2.00, version-3.01, version-3.02
Children:
ca489e8
Parents:
d27fd76
Message:

Added multi info functions and some helpers to fedd_client

Location:
fedd
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • fedd/fedd_client.py

    rd27fd76 r65f3f29  
    157157                help="data to extract")
    158158
     159class fedd_multi_exp_data_opts(fedd_client_opts):
     160    def __init__(self):
     161        fedd_client_opts.__init__(self)
     162        self.add_option("--data", dest="data", default=[],
     163                action="append", type="choice",
     164                choices=("id", "federant", "vtopo", "vis", "log", "status"),
     165                help="data to extract")
     166
    159167class fedd_spew_opts(fedd_client_opts):
    160168    def __init__(self):
     
    353361            raise RuntimeError("No body in response??")
    354362
    355 # Querying experiment data follows the same control flow regardless of the
    356 # specific data retrieved.  This class encapsulates that control flow.
    357 class exp_data(fedd_rpc):
    358     def __init__(self):
     363class exp_data_base(fedd_rpc):
     364    def __init__(self, op='Info'):
    359365        """
    360366        Init the various conversions
    361367        """
    362368
    363         fedd_rpc.__init__(self, 'Info')
     369        fedd_rpc.__init__(self, op)
    364370        # List of things one could ask for and what formatting routine is
    365371        # called.
     
    374380            }
    375381
    376 
     382    # Utility functions
    377383    def print_string(self, d, out=sys.stdout):
    378384        print >>out, d
     
    403409            print >>out, str
    404410
     411       
     412
     413# Querying experiment data follows the same control flow regardless of the
     414# specific data retrieved.  This class encapsulates that control flow.
     415class exp_data(exp_data_base):
     416    def __init__(self):
     417        exp_data_base.__init__(self, 'Info')
     418
    405419    def __call__(self):
    406420        """
     
    495509        sys.argv.append('--data=status')
    496510        exp_data.__call__(self)
     511
     512class multi_exp_data(exp_data_base):
     513    def __init__(self):
     514        exp_data_base.__init__(self, 'MultiInfo')
     515
     516
     517    def __call__(self):
     518        """
     519        The control flow.  Compose the request and print the response.
     520        """
     521        # Process the options using the customized option parser defined above
     522        parser = fedd_multi_exp_data_opts()
     523
     524        (opts, args) = parser.parse_args()
     525
     526        if opts.trusted:
     527            if ( not os.access(opts.trusted, os.R_OK) ) :
     528                sys.exit("Cannot read trusted certificates (%s)" % opts.trusted)
     529
     530        if opts.debug > 0: opts.tracefile=sys.stderr
     531
     532        (user, cert) = self.get_user_info([])
     533
     534        if opts.cert != None: cert = opts.cert
     535
     536        if cert == None:
     537            sys.exit("No certificate given (--cert) or found")
     538
     539        if os.access(cert, os.R_OK):
     540            fid = fedid(file=cert)
     541        else:
     542            sys.exit("Cannot read certificate (%s)" % cert)
     543
     544        req = { }
     545
     546        try:
     547            resp_dict = self.do_rpc(req,
     548                    opts.url, opts.transport, cert, opts.trusted,
     549                    serialize_only=opts.serialize_only,
     550                    tracefile=opts.tracefile)
     551        except self.RPCException, e:
     552            exit_with_fault(\
     553                    {'desc': e.desc, 'errstr': e.errstr, 'code': e.code})
     554        except RuntimeError, e:
     555            print e
     556            sys.exit("Error processing RPC: %s" % e)
     557
     558        exps = resp_dict.get('info', [])
     559        if exps:
     560            print '---'
     561            for exp in exps:
     562                for d in opts.data:
     563                    key, output = self.params[d]
     564                    try:
     565                        if exp.has_key(key):
     566                            output(exp[key])
     567                    except RuntimeError, e:
     568                        sys.exit("Bad response. %s" % e.message)
     569                print '---'
     570
     571
     572class multi_status(exp_data_base):
     573    def __init__(self):
     574        exp_data_base.__init__(self, 'MultiInfo')
     575
     576
     577    def __call__(self):
     578        """
     579        The control flow.  Compose the request and print the response.
     580        """
     581        # Process the options using the customized option parser defined above
     582        parser = fedd_client_opts()
     583
     584        (opts, args) = parser.parse_args()
     585
     586        if opts.trusted:
     587            if ( not os.access(opts.trusted, os.R_OK) ) :
     588                sys.exit("Cannot read trusted certificates (%s)" % opts.trusted)
     589
     590        if opts.debug > 0: opts.tracefile=sys.stderr
     591
     592        (user, cert) = self.get_user_info([])
     593
     594        if opts.cert != None: cert = opts.cert
     595
     596        if cert == None:
     597            sys.exit("No certificate given (--cert) or found")
     598
     599        if os.access(cert, os.R_OK):
     600            fid = fedid(file=cert)
     601        else:
     602            sys.exit("Cannot read certificate (%s)" % cert)
     603
     604        req = { }
     605
     606        try:
     607            resp_dict = self.do_rpc(req,
     608                    opts.url, opts.transport, cert, opts.trusted,
     609                    serialize_only=opts.serialize_only,
     610                    tracefile=opts.tracefile)
     611        except self.RPCException, e:
     612            exit_with_fault(\
     613                    {'desc': e.desc, 'errstr': e.errstr, 'code': e.code})
     614        except RuntimeError, e:
     615            print e
     616            sys.exit("Error processing RPC: %s" % e)
     617
     618        for exp in resp_dict.get('info', []):
     619            out = []
     620            for eid in exp.get('experimentID', []):
     621                if eid.has_key('localname'):
     622                    out.append(eid['localname'])
     623                    break
     624            else:
     625                out.append("")
     626            for eid in exp.get('experimentID', []):
     627                if eid.has_key('fedid'):
     628                    out.append("%s" % eid['fedid'])
     629                    break
     630            else:
     631                out.append("")
     632
     633            out.append(exp.get('experimentStatus', ""))
     634
     635            for f in exp.get('federant', []):
     636                if f.get('master', False):
     637                    em = f.get('emulab', None)
     638                    if em:
     639                        project = em.get('project', None)
     640                        if project:
     641                            tb = project.get('testbed', None)
     642                            if tb and tb.has_key('localname'):
     643                                out.append(tb['localname'])
     644                            else:
     645                                out.append("")
     646                            pn = project.get('name', None)
     647                            if pn and pn.has_key('localname'):
     648                                out.append(pn['localname'])
     649                            else:
     650                                out.append("")
     651                        else:
     652                            out.extend(("", ""))
     653                    else:
     654                        out.extend(("", ""))
     655                    break
     656            else:
     657                out.extend(("",""))
     658
     659            print ":".join(out)
    497660
    498661class image(fedd_rpc):
     
    13021465        'vis': vis(),\
    13031466        'info': exp_data(),\
     1467        'multiinfo': multi_exp_data(),\
     1468        'multistatus': multi_status(),\
    13041469        'image': image(),\
    13051470        'ns_image': ns_image(),\
  • fedd/federation/experiment_control.py

    rd27fd76 r65f3f29  
    329329                'Vis': soap_handler('Vis', self.get_vis),
    330330                'Info': soap_handler('Info', self.get_info),
     331                'MultiInfo': soap_handler('MultiInfo', self.get_multi_info),
    331332                'Terminate': soap_handler('Terminate',
    332333                    self.terminate_experiment),
     
    338339                'Vis': xmlrpc_handler('Vis', self.get_vis),
    339340                'Info': xmlrpc_handler('Info', self.get_info),
     341                'MultiInfo': xmlrpc_handler('MultiInfo', self.get_multi_info),
    340342                'Terminate': xmlrpc_handler('Terminate',
    341343                    self.terminate_experiment),
     
    21772179                raise service_error(service_error.req, "No such experiment")
    21782180
     2181    def clean_info_response(self, rv):
     2182        """
     2183        Remove the information in the experiment's state object that is not in
     2184        the info response.
     2185        """
     2186        # Remove the owner info (should always be there, but...)
     2187        if rv.has_key('owner'): del rv['owner']
     2188
     2189        # Convert the log into the allocationLog parameter and remove the
     2190        # log entry (with defensive programming)
     2191        if rv.has_key('log'):
     2192            rv['allocationLog'] = "".join(rv['log'])
     2193            del rv['log']
     2194        else:
     2195            rv['allocationLog'] = ""
     2196
     2197        if rv['experimentStatus'] != 'active':
     2198            if rv.has_key('federant'): del rv['federant']
     2199        else:
     2200            # remove the allocationID info from each federant
     2201            for f in rv.get('federant', []):
     2202                if f.has_key('allocID'): del f['allocID']
     2203
     2204        return rv
     2205
    21792206    def get_info(self, req, fid):
    21802207        """
     
    21862213        if not req:
    21872214            raise service_error(service_error.req,
    2188                     "Bad request format (no VisRequestBody)")
     2215                    "Bad request format (no InfoRequestBody)")
    21892216        exp = req.get('experiment', None)
    21902217        if exp:
     
    22112238
    22122239        if rv:
    2213             # Remove the owner info (should always be there, but...)
    2214             if rv.has_key('owner'): del rv['owner']
    2215 
    2216             # Convert the log into the allocationLog parameter and remove the
    2217             # log entry (with defensive programming)
    2218             if rv.has_key('log'):
    2219                 rv['allocationLog'] = "".join(rv['log'])
    2220                 del rv['log']
    2221             else:
    2222                 rv['allocationLog'] = ""
    2223 
    2224             if rv['experimentStatus'] != 'active':
    2225                 if rv.has_key('federant'): del rv['federant']
    2226             else:
    2227                 # remove the allocationID info from each federant
    2228                 for f in rv.get('federant', []):
    2229                     if f.has_key('allocID'): del f['allocID']
    2230 
    2231             return rv
     2240            return self.clean_info_response(rv)
    22322241        else:
    22332242            raise service_error(service_error.req, "No such experiment")
     2243
     2244    def get_multi_info(self, req, fid):
     2245        """
     2246        Return all the stored info that this fedid can access
     2247        """
     2248        rv = { 'info': [ ] }
     2249
     2250        self.state_lock.acquire()
     2251        for key in [ k for k in self.state.keys() if isinstance(k, fedid)]:
     2252            self.check_experiment_access(fid, key)
     2253
     2254            if self.state.has_key(key):
     2255                e = copy.deepcopy(self.state[key])
     2256                e = self.clean_info_response(e)
     2257                rv['info'].append(e)
     2258        self.state_lock.release()
     2259        return rv
    22342260
    22352261
  • fedd/wsdl/fedd.wsdl

    rd27fd76 r65f3f29  
    6060  </message>
    6161
     62  <message name="MultiInfoRequestMessage">
     63    <part name="MultiInfoRequestBody" type="xsd1:multiInfoRequestType"/>
     64  </message>
     65
     66  <message name="MultiInfoResponseMessage">
     67    <part name="MultiInfoResponseBody" type="xsd1:multiInfoResponseType"/>
     68  </message>
    6269
    6370  <message name="TerminateRequestMessage">
     
    128135      <fault name="VisFeddFault" message="tns:FaultMessage"/>
    129136    </operation>
     137
    130138    <operation name="Info">
    131139      <documentation>
     
    137145      <fault name="InfoFeddFault" message="tns:FaultMessage"/>
    138146    </operation>
     147
     148    <operation name="MultiInfo">
     149      <documentation>
     150        A one-stop request for meta-data on the experiment.  Includes all the
     151        info from a Vtopo and a Vis request.
     152      </documentation>
     153      <input message="tns:MultiInfoRequestMessage"/>
     154      <output message="tns:MultiInfoResponseMessage"/>
     155      <fault name="MultiInfoFeddFault" message="tns:FaultMessage"/>
     156    </operation>
     157
    139158    <operation name="Terminate">
    140159      <documentation>
     
    277296        </output>
    278297        <fault name="InfoFeddFault">
     298          <soap:fault use="literal"  name="tns:FeddFault"
     299            namespace="http://www.isi.edu/faber/fedd.wsdl"
     300            encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
     301        </fault>
     302      </operation>
     303      <operation name="MultiInfo">
     304        <documentation>
     305          The bindings of this operation are straightforward SOAP RPC 1.1.
     306        </documentation>
     307        <soap:operation soapAction="MultiInfo"/>
     308        <input>
     309          <soap:body use="literal" parts="tns:MultiInfoRequestBody"
     310            namespace="http://www.isi.edu/faber/fedd.wsdl"
     311            encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
     312        </input>
     313        <output>
     314          <soap:body use="literal" parts="tns:MultiInfoResponseBody"
     315            namespace="http://www.isi.edu/faber/fedd.wsdl"
     316            encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
     317        </output>
     318        <fault name="MultiInfoFeddFault">
    279319          <soap:fault use="literal"  name="tns:FeddFault"
    280320            namespace="http://www.isi.edu/faber/fedd.wsdl"
  • fedd/wsdl/fedd_types.xsd

    rd27fd76 r65f3f29  
    561561      <xsd:element name="experimentAccess" type="tns:accessType" minOccurs="0"
    562562        maxOccurs="1"/>
     563    </xsd:sequence>
     564  </xsd:complexType>
     565
     566
     567  <xsd:complexType name="multiInfoRequestType">
     568    <xsd:annotation>
     569      <xsd:documentation>
     570        Gets all information that this user can access on this fedd.
     571      </xsd:documentation>
     572    </xsd:annotation>
     573    <xsd:sequence>
     574    </xsd:sequence>
     575  </xsd:complexType>
     576
     577  <xsd:complexType name="multiInfoResponseType">
     578    <xsd:annotation>
     579      <xsd:documentation>
     580        Multi info response.  A list of infoResponses
     581      </xsd:documentation>
     582    </xsd:annotation>
     583    <xsd:sequence>
     584      <xsd:element name="info" type="tns:infoResponseType" minOccurs="0"
     585        maxOccurs="unbounded"/>
    563586    </xsd:sequence>
    564587  </xsd:complexType>
Note: See TracChangeset for help on using the changeset viewer.