- Timestamp:
- Jun 18, 2009 9:57:59 AM (15 years ago)
- Branches:
- axis_example, compt_changes, info-ops, master, version-1.30, version-2.00, version-3.01, version-3.02
- Children:
- c7910ac
- Parents:
- 63f3746
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
fedd/fedd_client.py
r63f3746 rcc58813 6 6 import tempfile 7 7 import subprocess 8 import re 9 import xml.parsers.expat 8 10 9 11 from federation import fedid, service_error … … 118 120 default=False, 119 121 help="get output suitable for federation kit install") 122 self.add_option('-G','--gatewaykit', action='store_true', 123 dest='gatewaykit', default=False, 124 help="get output suitable for federation gateway kit install") 120 125 121 126 … … 152 157 help="output image file") 153 158 self.add_option("-F", "--format", dest="format", type="choice", 154 choices=("jpg", "png", "dot"), 159 choices=("jpg", "png", "dot", "svg"), 160 help="Output file format override") 161 self.add_option("-P", "--program", dest="neato", default=None, 162 type="string", 163 help="Program compatible with dot (from graphviz) used to " + \ 164 "render image") 165 166 class fedd_ns_image_opts(fedd_split_opts): 167 def __init__(self, access_keys, add_key_callback=None, 168 add_cert_callback=None): 169 fedd_split_opts.__init__(self, access_keys, add_key_callback, 170 add_cert_callback) 171 self.add_option("-o", "--output", dest="outfile", type="string", 172 help="output image file") 173 self.add_option("-Q", "--format", dest="format", type="choice", 174 choices=("jpg", "png", "dot", "svg"), 155 175 help="Output file format override") 156 176 self.add_option("-P", "--program", dest="neato", default=None, … … 394 414 395 415 396 # Querying experiment data follows the same control flow regardless of the397 # specific data retrieved. This class encapsulates that control flow.398 416 class image(fedd_rpc): 399 def __init__(self ):417 def __init__(self, op): 400 418 """ 401 419 Null constructor 402 420 """ 403 421 404 fedd_rpc.__init__(self, "Vtopo")422 fedd_rpc.__init__(self, op) 405 423 406 424 def gen_image(self, d, file, fmt, neato): … … 430 448 cmd.append(dotname) 431 449 450 nodes = d.get('node',[]) 451 452 if len(nodes) < 10: size = 5 453 elif len(nodes) < 50: size = 10 454 else: size = 18 455 432 456 print >>dotfile, "graph G {" 457 print >>dotfile, '\tgraph [size="%i,%i", ratio=fill];' % (size, size) 433 458 print >>dotfile, '\tnode [fontname=arial,fontsize=9,label="\N"];' 434 print >>dotfile, '\tedge [fontname=arial,fontsize=9 ,label="\N"];\n'459 print >>dotfile, '\tedge [fontname=arial,fontsize=9];\n' 435 460 436 461 for n in d.get('node', []): … … 446 471 v = n['vname'] 447 472 m = n['member'] 473 i = n['ip'] 448 474 if m.find(':') != -1: 449 475 m = m[0:m.find(':')] 450 476 if lans.has_key(v): 451 lans[v].append( m)477 lans[v].append((m, i)) 452 478 elif links.has_key(v): 453 links[v].append( m)479 links[v].append((m, i)) 454 480 if len(links[v]) > 2: 455 481 lans[v] = links[v] 456 482 del links[v] 457 483 else: 458 links[v] = [ m]484 links[v] = [(m, i)] 459 485 460 486 # Encode the lans and the links … … 463 489 print >>dotfile,'\t\tcolor=black,fillcolor="#80c0f8",regular=1]' 464 490 for n in lans[l]: 465 print >>dotfile, '\t%s -- %s ' % (l, n)491 print >>dotfile, '\t%s -- %s [headlabel="%s"]' % (l, n[0], n[1]) 466 492 467 493 for k, l in links.items(): 468 494 if len(l) == 2: 469 print >>dotfile, '\t%s -- %s [label="%s"]' % (l[0], l[1], k) 495 print >>dotfile, \ 496 ('\t%s -- %s [label="%s",taillabel="%s",' + \ 497 'headlabel="%s"]') % \ 498 (l[0][0], l[1][0], k, l[0][1], l[1][1]) 470 499 471 500 print >>dotfile, "}" … … 524 553 elif not opts.format and opts.outfile: 525 554 fmt = opts.outfile[-3:] 526 if fmt not in ("png", "jpg", "dot" ):555 if fmt not in ("png", "jpg", "dot", "svg"): 527 556 sys.exit("Unexpected file type and no format specified") 528 557 file = opts.outfile … … 552 581 if resp_dict.has_key('vtopo'): 553 582 self.gen_image(resp_dict['vtopo'], file, fmt, opts.neato) 583 else: 584 sys.exit("Bad response. %s" % e.message) 585 586 class ns_image(image): 587 def __init__(self, op): 588 """ 589 Null constructor 590 """ 591 592 image.__init__(self, op) 593 594 def generate_topo_dict(self, splitout): 595 class topo_parse: 596 """ 597 Parse the topology XML and create the dats structure. This class 598 is copied from federation.experiment_control. 599 """ 600 def __init__(self): 601 # Typing of the subelements for data conversion 602 self.str_subelements = ('vname', 'vnode', 'ips', 'ip', 'member') 603 self.int_subelements = ( 'bandwidth',) 604 self.float_subelements = ( 'delay',) 605 # The final data structure 606 self.nodes = [ ] 607 self.lans = [ ] 608 self.topo = { \ 609 'node': self.nodes,\ 610 'lan' : self.lans,\ 611 } 612 self.element = { } # Current element being created 613 self.chars = "" # Last text seen 614 615 def end_element(self, name): 616 # After each sub element the contents is added to the current 617 # element or to the appropriate list. 618 if name == 'node': 619 self.nodes.append(self.element) 620 self.element = { } 621 elif name == 'lan': 622 self.lans.append(self.element) 623 self.element = { } 624 elif name in self.str_subelements: 625 self.element[name] = self.chars 626 self.chars = "" 627 elif name in self.int_subelements: 628 self.element[name] = int(self.chars) 629 self.chars = "" 630 elif name in self.float_subelements: 631 self.element[name] = float(self.chars) 632 self.chars = "" 633 634 def found_chars(self, data): 635 self.chars += data.rstrip() 636 637 638 tp = topo_parse(); 639 parser = xml.parsers.expat.ParserCreate() 640 parser.EndElementHandler = tp.end_element 641 parser.CharacterDataHandler = tp.found_chars 642 643 m = re.search('^#\s+Begin\s+Vtopo\s*$(.*)^#\s+End\s+Vtopo', splitout, 644 re.MULTILINE | re.DOTALL) 645 if m: 646 str = m.group(1) 647 else: 648 sys.exit("Badly formatted split") 649 650 parser.Parse(str) 651 652 return tp.topo 653 654 def __call__(self): 655 """ 656 The control flow. Compose the request and print the response. 657 """ 658 access_keys = [] 659 # Process the options using the customized option parser defined above 660 parser = fedd_ns_image_opts(access_keys, self.add_ssh_key, 661 self.add_x509_cert) 662 663 (opts, args) = parser.parse_args() 664 665 if opts.trusted: 666 if ( not os.access(opts.trusted, os.R_OK) ) : 667 sys.exit("Cannot read trusted certificates (%s)" % opts.trusted) 668 669 if opts.debug > 0: opts.tracefile=sys.stderr 670 671 (user, cert) = self.get_user_info([]) 672 673 if opts.cert != None: cert = opts.cert 674 675 if cert == None: 676 sys.exit("No certificate given (--cert) or found") 677 678 if os.access(cert, os.R_OK): 679 fid = fedid(file=cert) 680 else: 681 sys.exit("Cannot read certificate (%s)" % cert) 682 683 if opts.file: 684 exp_desc = "" 685 try: 686 f = open(opts.file, 'r') 687 for line in f: 688 exp_desc += line 689 f.close() 690 except IOError: 691 sys.exit("Cannot read description file (%s)" %opts.file) 692 else: 693 sys.exit("Must specify an experiment description (--file)") 694 695 if not opts.master: 696 opts.master="dummy" 697 698 699 req = { 700 'description': { 'ns2description': exp_desc }, 701 'master': opts.master, 702 'include_fedkit': opts.fedkit, 703 'include_gatewaykit': opts.gatewaykit, 704 } 705 706 707 if opts.format and opts.outfile: 708 fmt = opts.format 709 file = opts.outfile 710 elif not opts.format and opts.outfile: 711 fmt = opts.outfile[-3:] 712 if fmt not in ("png", "jpg", "dot", "svg"): 713 sys.exit("Unexpected file type and no format specified") 714 file = opts.outfile 715 elif opts.format and not opts.outfile: 716 fmt = opts.format 717 file = None 718 else: 719 fmt="dot" 720 file = None 721 722 723 try: 724 resp_dict = self.do_rpc(req, 725 opts.url, opts.transport, cert, opts.trusted, 726 serialize_only=opts.serialize_only, 727 tracefile=opts.tracefile) 728 except self.RPCException, e: 729 exit_with_fault(\ 730 {'desc': e.desc, 'errstr': e.errstr, 'code': e.code}) 731 except RuntimeError, e: 732 print e 733 sys.exit("Error processing RPC: %s" % e) 734 735 736 if resp_dict.has_key('output'): 737 if len(resp_dict['output']) < 1: 738 sys.exit("Bad response: could not split") 739 topo = self.generate_topo_dict(resp_dict['output']) 740 self.gen_image(topo, file, fmt, opts.neato) 554 741 else: 555 742 sys.exit("Bad response. %s" % e.message) … … 738 925 if opts.debug > 0: opts.tracefile=sys.stderr 739 926 927 (user, cert) = self.get_user_info(access_keys) 928 740 929 if opts.cert != None: cert = opts.cert 741 else: cert = None742 930 743 931 if cert == None: … … 772 960 'master': opts.master, 773 961 'include_fedkit': opts.fedkit, 962 'include_gatewaykit': opts.gatewaykit, 774 963 } 775 964 … … 911 1100 'vtopo': exp_data('Vtopo'),\ 912 1101 'vis': exp_data('Vis'),\ 913 'image': image(),\ 1102 'image': image('Vtopo'),\ 1103 'ns_image': ns_image('Ns2Split'),\ 914 1104 'info': exp_data('Info'),\ 915 1105 'terminate': terminate(),\
Note: See TracChangeset
for help on using the changeset viewer.