Ignore:
Timestamp:
Jul 24, 2009 7:11:35 PM (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:
d27fd76
Parents:
a74ea78
Message:

Pretty big overhaul. Make info actually useful and create the spewlog that
will incrementally retrieve the log from a starting experiment.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • fedd/fedd_client.py

    ra74ea78 r281c0ca  
    88import re
    99import xml.parsers.expat
     10import time
    1011
    1112from federation import fedid, service_error
     
    8889                type="string", help="output certificate file")
    8990        self.add_option("-E", "--experiment_name", dest="exp_name",
    90                 type="string", help="output certificate file")
     91                type="string", help="Suggested experiment name")
    9192        self.add_option("-F","--useFedid", action="store_true",
    9293                dest="use_fedid", default=False,
     
    148149        fedd_client_opts.__init__(self)
    149150        self.add_option("-e", "--experiment_cert", dest="exp_certfile",
    150                 type="string", help="output certificate file")
     151                type="string", help="experiment certificate file")
    151152        self.add_option("-E", "--experiment_name", dest="exp_name",
    152                 type="string", help="output certificate file")
     153                type="string", help="human readable experiment name")
     154        self.add_option("--data", dest="data", default=[],
     155                action="append", type="choice",
     156                choices=("id", "federant", "vtopo", "vis", "log", "status"),
     157                help="data to extract")
     158
     159class fedd_spew_opts(fedd_client_opts):
     160    def __init__(self):
     161        fedd_client_opts.__init__(self)
     162        self.add_option("-e", "--experiment_cert", dest="exp_certfile",
     163                type="string", help="experiment name certificate file")
     164        self.add_option("-E", "--experiment_name", dest="exp_name",
     165                type="string", help="human readable experiment name")
     166        self.add_option("--logfile", dest="logfile", default=None,
     167                help="File to write log to")
     168        self.add_option('--update_time', dest='update', type='int', default=10,
     169                help='how often to update the printed log')
    153170
    154171class fedd_image_opts(fedd_exp_data_opts):
     
    339356# specific data retrieved.  This class encapsulates that control flow.
    340357class exp_data(fedd_rpc):
    341     def __init__(self, op):
    342         """
    343         Specialize the class for the type of data requested (op)
    344         """
    345 
    346         fedd_rpc.__init__(self, op)
    347         if op =='Vtopo':
    348             self.key="vtopo"
    349             self.xml='experiment'
    350         elif op == 'Vis':
    351             self.key="vis"
    352             self.xml='vis'
    353         elif op == 'Info': pass
    354         else:
    355             raise TypeError("Bad op: %s" % op)
    356 
    357     def print_xml(self, d, out=sys.stdout):
     358    def __init__(self):
     359        """
     360        Init the various conversions
     361        """
     362
     363        fedd_rpc.__init__(self, 'Info')
     364        # List of things one could ask for and what formatting routine is
     365        # called.
     366        self.params = {
     367                'vis': ('vis', self.print_xml('vis')),
     368                'vtopo': ('vtopo', self.print_xml('vtopo')),
     369                'federant': ('federant', self.print_xml),
     370                'id': ('experimentID', self.print_id),
     371                'status': ('experimentStatus', self.print_string),
     372                'log': ('allocationLog', self.print_string),
     373                'access': ('experimentAccess', self.print_string),
     374            }
     375
     376
     377    def print_string(self, d, out=sys.stdout):
     378        print >>out, d
     379
     380    def print_id(self, d, out=sys.stdout):
     381        if d:
     382            for id in d:
     383                for k in id.keys():
     384                    print >>out, "%s: %s" % (k, id[k])
     385
     386    class print_xml:
    358387        """
    359388        Print the retrieved data is a simple xml representation of the dict.
    360389        """
    361         str = "<%s>\n" % self.xml
    362         for t in ('node', 'lan'):
    363             if d.has_key(t):
    364                 for x in d[t]:
    365                     str += "<%s>" % t
    366                     for k in x.keys():
    367                         str += "<%s>%s</%s>" % (k, x[k],k)
    368                     str += "</%s>\n" % t
    369         str+= "</%s>" % self.xml
    370         print >>out, str
     390        def __init__(self, top):
     391            self.xml = top
     392
     393        def __call__(self, d, out=sys.stdout):
     394            str = "<%s>\n" % self.xml
     395            for t in ('node', 'lan'):
     396                if d.has_key(t):
     397                    for x in d[t]:
     398                        str += "<%s>" % t
     399                        for k in x.keys():
     400                            str += "<%s>%s</%s>" % (k, x[k],k)
     401                        str += "</%s>\n" % t
     402            str+= "</%s>" % self.xml
     403            print >>out, str
    371404
    372405    def __call__(self):
     
    421454            sys.exit("Error processing RPC: %s" % e)
    422455
    423         if getattr(self, 'key', None):
     456        for d in opts.data:
     457            key, output = self.params[d]
    424458            try:
    425                 if resp_dict.has_key(self.key):
    426                     self.print_xml(resp_dict[self.key])
     459                if resp_dict.has_key(key):
     460                    output(resp_dict[key])
    427461            except RuntimeError, e:
    428462                sys.exit("Bad response. %s" % e.message)
    429         else:
    430             print resp_dict
    431 
    432 
    433 # Querying experiment data follows the same control flow regardless of the
    434 # specific data retrieved.  This class encapsulates that control flow.
    435 class simple_info(fedd_rpc):
    436     def __init__(self):
    437         """
    438         Specialize the class for the type of data requested (op)
    439         """
    440 
    441         fedd_rpc.__init__(self, 'Info')
    442 
    443     def print_xml(self, d, out=sys.stdout):
    444         """
    445         Print the retrieved data is a simple xml representation of the dict.
    446         """
    447         str = "<%s>\n" % self.xml
    448         for t in ('node', 'lan'):
    449             if d.has_key(t):
    450                 for x in d[t]:
    451                     str += "<%s>" % t
    452                     for k in x.keys():
    453                         str += "<%s>%s</%s>" % (k, x[k],k)
    454                     str += "</%s>\n" % t
    455         str+= "</%s>" % self.xml
    456         print >>out, str
    457 
     463
     464class vtopo(exp_data):
     465    """
     466    vtopo is just an info --data=vtopo request, so this adds that parameter to
     467    the arguments and executes exp_info when called.
     468    """
     469    def __init__(self):
     470        exp_data.__init__(self)
    458471    def __call__(self):
    459         """
    460         The control flow.  Compose the request and print the response.
    461         """
    462         # Process the options using the customized option parser defined above
    463         parser = fedd_exp_data_opts()
    464 
    465         (opts, args) = parser.parse_args()
    466 
    467         if opts.trusted:
    468             if ( not os.access(opts.trusted, os.R_OK) ) :
    469                 sys.exit("Cannot read trusted certificates (%s)" % opts.trusted)
    470 
    471         if opts.debug > 0: opts.tracefile=sys.stderr
    472 
    473         (user, cert) = self.get_user_info([])
    474 
    475         if opts.cert != None: cert = opts.cert
    476 
    477         if cert == None:
    478             sys.exit("No certificate given (--cert) or found")
    479 
    480         if os.access(cert, os.R_OK):
    481             fid = fedid(file=cert)
    482         else:
    483             sys.exit("Cannot read certificate (%s)" % cert)
    484 
    485         if opts.exp_name and opts.exp_certfile:
    486             sys.exit("Only one of --experiment_cert and " +\
    487                     "--experiment_name permitted");
    488 
    489         if opts.exp_certfile:
    490             exp_id = { 'fedid': fedid(file=opts.exp_certfile) }
    491 
    492         if opts.exp_name:
    493             exp_id = { 'localname' : opts.exp_name }
    494 
    495         req = { 'experiment': exp_id }
    496 
    497         status = "active"
    498         try:
    499             resp_dict = self.do_rpc(req,
    500                     opts.url, opts.transport, cert, opts.trusted,
    501                     serialize_only=opts.serialize_only,
    502                     tracefile=opts.tracefile)
    503         except self.RPCException, e:
    504             if e.code == 5:
    505                 status = "swapping"
    506             elif e.code == 1:
    507                 status = "inactive"
    508             else:
    509                 status = "unknown"
    510         except RuntimeError, e:
    511             print e
    512             sys.exit("Error processing RPC: %s" % e)
    513 
    514         print status
    515 
     472        sys.argv.append('--data=vtopo')
     473        exp_data.__call__(self)
     474
     475
     476class vis(exp_data):
     477    """
     478    vis is just an info --data=vis request, so this adds that parameter to
     479    the arguments and executes exp_info when called.
     480    """
     481    def __init__(self):
     482        exp_data.__init__(self)
     483    def __call__(self):
     484        sys.argv.append('--data=vis')
     485        exp_data.__call__(self)
     486
     487class status(exp_data):
     488    """
     489    status is just an info --data=status request, so this adds that parameter
     490    to the arguments and executes exp_info when called.
     491    """
     492    def __init__(self):
     493        exp_data.__init__(self)
     494    def __call__(self):
     495        sys.argv.append('--data=status')
     496        exp_data.__call__(self)
    516497
    517498class image(fedd_rpc):
    518     def __init__(self, op):
     499    def __init__(self, op='Vtopo'):
    519500        """
    520501        Null constructor
    521502        """
    522503
    523         fedd_rpc.__init__(self, op)
     504        fedd_rpc.__init__(self, 'Vtopo')
    524505
    525506    def gen_image(self, d, file, fmt, neato, labels, pix=None):
     
    709690
    710691class ns_image(image):
    711     def __init__(self, op):
     692    def __init__(self, op='Ns2Split'):
    712693        """
    713694        Null constructor
    714695        """
    715696
    716         image.__init__(self, op)
     697        image.__init__(self, 'Ns2Split')
    717698
    718699    def generate_topo_dict(self, splitout):
     
    10321013                for k in id.keys():
    10331014                    print "%s: %s" % (k, id[k])
     1015        st = resp_dict.get('experimentStatus', None)
     1016        if st:
     1017            print "status: %s" % st
    10341018
    10351019class split(fedd_rpc):
     
    12191203        self.print_response_as_testbed(resp_dict, opts.label)
    12201204
     1205# Keep requesting experiment status and printing updates to the log until the
     1206# experiment is done being created.
     1207class spew_log(fedd_rpc):
     1208    def __init__(self):
     1209        """
     1210        Init the superclass
     1211        """
     1212
     1213        fedd_rpc.__init__(self, 'Info')
     1214
     1215    def __call__(self):
     1216        """
     1217        The control flow.  Compose the request and print the response.
     1218        """
     1219        # Process the options using the customized option parser defined above
     1220        parser = fedd_spew_opts()
     1221
     1222        (opts, args) = parser.parse_args()
     1223
     1224        if opts.trusted:
     1225            if ( not os.access(opts.trusted, os.R_OK) ) :
     1226                sys.exit("Cannot read trusted certificates (%s)" % opts.trusted)
     1227
     1228        if opts.debug > 0: opts.tracefile=sys.stderr
     1229
     1230        (user, cert) = self.get_user_info([])
     1231
     1232        if opts.cert != None: cert = opts.cert
     1233
     1234        if cert == None:
     1235            sys.exit("No certificate given (--cert) or found")
     1236
     1237        if os.access(cert, os.R_OK):
     1238            fid = fedid(file=cert)
     1239        else:
     1240            sys.exit("Cannot read certificate (%s)" % cert)
     1241
     1242        if opts.exp_name and opts.exp_certfile:
     1243            sys.exit("Only one of --experiment_cert and " +\
     1244                    "--experiment_name permitted");
     1245
     1246        if opts.exp_certfile:
     1247            exp_id = { 'fedid': fedid(file=opts.exp_certfile) }
     1248
     1249        if opts.exp_name:
     1250            exp_id = { 'localname' : opts.exp_name }
     1251
     1252        if opts.logfile:
     1253            try:
     1254                out = open(opts.logfile, "w")
     1255            except IOError,e:
     1256                sys.exit("Cannot open logfile: %s" %e)
     1257        else:
     1258            out = sys.stdout
     1259
     1260        req = { 'experiment': exp_id }
     1261
     1262        status = "starting"
     1263        log = ""
     1264        log_offset = 0
     1265        update = opts.update
     1266        while status == 'starting':
     1267            try:
     1268                resp_dict = self.do_rpc(req,
     1269                        opts.url, opts.transport, cert, opts.trusted,
     1270                        serialize_only=opts.serialize_only,
     1271                        tracefile=opts.tracefile)
     1272            except self.RPCException, e:
     1273                exit_with_fault(\
     1274                        {'desc': e.desc, 'errstr': e.errstr, 'code': e.code})
     1275            except RuntimeError, e:
     1276                sys.exit("Error processing RPC: %s" % e)
     1277
     1278            status = resp_dict.get('experimentStatus', None)
     1279            log = resp_dict.get('allocationLog', None)
     1280            if not status:
     1281                sys.exit("No status in Info response??")
     1282            if not log:
     1283                sys.exit("No log in Info response??")
     1284
     1285            if len(log) > log_offset:
     1286                print >>out, log[log_offset:],
     1287                out.flush()
     1288                log_offset = len(log)
     1289            time.sleep(update)
     1290
     1291        print >>out
     1292        print >>out, status
     1293        out.close()
     1294
     1295
    12211296cmds = {\
    12221297        'create': create(),\
    12231298        'split': split(),\
    12241299        'access': access(),\
    1225         'vtopo': exp_data('Vtopo'),\
    1226         'vis': exp_data('Vis'),\
    1227         'image': image('Vtopo'),\
    1228         'ns_image': ns_image('Ns2Split'),\
    1229         'info': exp_data('Info'),\
    1230         'status': simple_info(),\
     1300        'vtopo': vtopo(),\
     1301        'vis': vis(),\
     1302        'info': exp_data(),\
     1303        'image': image(),\
     1304        'ns_image': ns_image(),\
     1305        'status': status(),\
    12311306        'terminate': terminate(),\
     1307        'spewlog': spew_log(),
    12321308    }
    12331309
Note: See TracChangeset for help on using the changeset viewer.