diff options
-rwxr-xr-x | images/Thumbs.db | bin | 590336 -> 601088 bytes | |||
-rw-r--r-- | images/icons/selected_tab_bg.png | bin | 0 -> 124 bytes | |||
-rw-r--r-- | images/icons/toggle.png | bin | 0 -> 135 bytes | |||
-rwxr-xr-x | trex_book.asciidoc | 1 | ||||
-rw-r--r-- | trex_rpc_server_spec-docinfo.html | 6 | ||||
-rwxr-xr-x | trex_rpc_server_spec.asciidoc | 1 | ||||
-rwxr-xr-x | trex_stateless.asciidoc | 2 | ||||
-rw-r--r-- | trex_toc.asciidoc | 221 | ||||
-rw-r--r-- | trex_vm_manual-docinfo.html | 6 | ||||
-rwxr-xr-x | trex_vm_manual.asciidoc | 19 | ||||
-rw-r--r-- | ws_main.py | 225 | ||||
-rwxr-xr-x | wscript | 3 |
12 files changed, 463 insertions, 21 deletions
diff --git a/images/Thumbs.db b/images/Thumbs.db Binary files differindex a7cb4a90..893347af 100755 --- a/images/Thumbs.db +++ b/images/Thumbs.db diff --git a/images/icons/selected_tab_bg.png b/images/icons/selected_tab_bg.png Binary files differnew file mode 100644 index 00000000..16bb5d61 --- /dev/null +++ b/images/icons/selected_tab_bg.png diff --git a/images/icons/toggle.png b/images/icons/toggle.png Binary files differnew file mode 100644 index 00000000..84380cd0 --- /dev/null +++ b/images/icons/toggle.png diff --git a/trex_book.asciidoc b/trex_book.asciidoc index 2326f3ec..f13c63ae 100755 --- a/trex_book.asciidoc +++ b/trex_book.asciidoc @@ -10,6 +10,7 @@ TRex :toclevels: 4 include::trex_ga.asciidoc[] +include::trex_toc.asciidoc[] == Introduction diff --git a/trex_rpc_server_spec-docinfo.html b/trex_rpc_server_spec-docinfo.html new file mode 100644 index 00000000..6fb66a5e --- /dev/null +++ b/trex_rpc_server_spec-docinfo.html @@ -0,0 +1,6 @@ + + + + + + diff --git a/trex_rpc_server_spec.asciidoc b/trex_rpc_server_spec.asciidoc index 7df63553..1663830b 100755 --- a/trex_rpc_server_spec.asciidoc +++ b/trex_rpc_server_spec.asciidoc @@ -10,6 +10,7 @@ The TRex RPC Server :toclevels: 4 include::trex_ga.asciidoc[] +include::trex_toc.asciidoc[] == Change log diff --git a/trex_stateless.asciidoc b/trex_stateless.asciidoc index 303de5c5..4aad01e6 100755 --- a/trex_stateless.asciidoc +++ b/trex_stateless.asciidoc @@ -22,6 +22,8 @@ ifdef::backend-xhtml11[] endif::backend-xhtml11[] include::trex_ga.asciidoc[] +include::trex_toc.asciidoc[] + == Audience diff --git a/trex_toc.asciidoc b/trex_toc.asciidoc new file mode 100644 index 00000000..664370b9 --- /dev/null +++ b/trex_toc.asciidoc @@ -0,0 +1,221 @@ + +ifdef::backend-xhtml11[] +++++ + <div id="toggle"><img src="images\icons\toggle.png" title="click to toggle table of contents"></div> + + <div id="toc"> + <div id="toctitle"> + Table of Contents + </div> + + <div id="nav-tree"> + + </div> + </div> + + + <!-- load the theme CSS file --> + <link href="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/themes/default/style.min.css" rel="stylesheet"/> + + <link href="http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css" rel="stylesheet" /> + + <!-- include the jQuery library --> + <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.1/jquery.min.js"> + </script> + + <!-- include the jQuery UI library --> + <script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"> + </script> + + <!-- include the minified jstree source --> + <script src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/jstree.min.js"> + </script> + + <style type="text/css"> + + #toc { + margin-bottom: 2.5em; + } + + #toctitle { + color: #527bbd; + font-size: 1.1em; + font-weight: bold; + margin-top: 1.0em; + margin-bottom: 0.1em; + } + + @media screen { + body { + max-width: 50em; /* approximately 80 characters wide */ + margin-left: 20em; + } + + #toc { + position: fixed; + top: 0; + left: 0; + bottom: 0; + width: 18em; + padding-bottom: 1.5em; + margin: 0; + overflow-x: auto; + overflow-y: hidden; + border-right: solid 2px #cfcfcf; + background-color: #FAFAFA; + white-space: nowrap; + } + + #toctitle { + font-size: 17px !important; + color: #4d4d4d !important; + margin-top: 0px; + height: 36px; + line-height: 36px; + background-color: #e4e2e2; + padding: 8px 0px 7px 45px; + white-space: nowrap; + } + + #toc .toclevel1 { + margin-top: 0.5em; + } + + #toc .toclevel2 { + margin-top: 0.25em; + display: list-item; + color: #aaaaaa; + } + + } + + + /* Custom for Nave Tree */ + #nav-tree{ + margin-left: 10px !important; + } + + #nav-tree ul > li { + color: #000 !important; + } + + .jstree-wholerow.jstree-wholerow-clicked { + background-image: url('images\icons\selected_tab_bg.png'); + background-repeat: repeat-x; + color: #fff !important; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); + } + + .jstree-anchor { + font-size: 12px !important; + color: #91A501 !important; + } + + /* For side bar */ + .ui-resizable-e{ + width: 10px !important; + } + + .jstree-clicked{ + color: green !important; + } + + .jstree-default .jstree-themeicon{ + display: none !important; + } + + #toggle { + position: fixed; + top: 14px; + left: 10px; + z-index: 10; + } + + #toggle img { + opacity:0.3; + } + + #toggle img:hover { + opacity:0.9; + } + + </style> + + + +<script> + + $(document).ready(function(){ + + // Initialize NavTree + initializeNavTree(); + // Drag TOC left and right + initResizable(); + // Toggle TOC whe clicking on the menu icon + toggleTOC(); + + function initializeNavTree() { + $('#nav-tree').jstree({ + 'core' : { + "animation" :false, + "themes" : { "stripes" : false }, + 'data' : { + "url" : "./input_replace_me.json", + "dataType" : "json" // needed only if you do not supply JSON headers + } + } + , + "plugins" : [ "wholerow" ] + }); + + $('#nav-tree').on("changed.jstree", function (e, data) { + window.location.href = data.instance.get_selected(true)[0].original.link; + }); + } + + function initResizable() { + var toc = $("#toc"); + var bodyLeftMargin = $("body"); + $("#toc").resizable({ + resize: function(e, ui) { + var tocWidth = $("#toc").outerWidth(); + bodyLeftMargin.css({"marginLeft":parseInt(tocWidth)+20+"px"}); + }, + handles: 'e' + }); + } + + + function toggleTOC(){ + var isOpen = true; + $( "#toggle" ).click(function() { + if ( isOpen ) { + // Close it + $("#toc").hide("slide", 500); + // Show the show/hide button + $("#toggle").css("right", "-40px"); + // $("body").css("margin-left", "20px"); + $("body").animate({ + "margin-left": "50px" + }, 500); + } else { + // Open it + $("#toc").show("slide", 500); + // Show the show/hide button + $("#toggle").css("right", "15px"); + // $("body").css("margin-left", $(toc).outerWidth()+20+"px"); + $("body").animate({ + "margin-left": $(toc).outerWidth()+20+"px" + }, 500); + } + isOpen = !isOpen; + }); + } + + } + ) + +</script> +++++ +endif::backend-xhtml11[] + diff --git a/trex_vm_manual-docinfo.html b/trex_vm_manual-docinfo.html new file mode 100644 index 00000000..6fb66a5e --- /dev/null +++ b/trex_vm_manual-docinfo.html @@ -0,0 +1,6 @@ + + + + + + diff --git a/trex_vm_manual.asciidoc b/trex_vm_manual.asciidoc index 7e22d54a..ec4c39c5 100755 --- a/trex_vm_manual.asciidoc +++ b/trex_vm_manual.asciidoc @@ -8,6 +8,8 @@ TRex Virtual Machine setup and basic usage include::trex_ga.asciidoc[] +include::trex_toc.asciidoc[] + == Introduction @@ -276,12 +278,14 @@ Once we have TRex up and running, we can enjoy the benefit of having live monito This can be easily done by following these steps: - 0. Download the latest version of TrexViewer application and install it using http://trex-tgn.cisco.com/trex/client_gui/setup.exe[this link]. - 1. Start the application and fill in the following: + +1. Download the latest version of TrexViewer application and install it using http://trex-tgn.cisco.com/trex/client_gui/setup.exe[this link]. + + +2. Start the application and fill in the following: + - Trex ip: `127.0.0.1:4500` - 2. Click the play button. +3. Click the play button. ifdef::backend-docbook[] image::images/trex_motinor_config.png[title="TRex viewer start screen",align="center",width=400,link="images/trex_motinor_config.png"] @@ -291,9 +295,7 @@ ifdef::backend-xhtml11[] image::images/trex_motinor_config.png[title="TRex viewer start screen",align="center",width=900,link="images/trex_motinor_config.png"] endif::backend-xhtml11[] - - - 3. **That's it!** + +**That's it!** + Now the live data from TRex will be displayed on the screen. ifdef::backend-docbook[] @@ -328,3 +330,8 @@ The VM runs TRex with single client and single server port. The traffic generate TRex identifies only the packets which were dedicately sent by one of those traffic ports and receives them in the other port. Hence, packets generated by client port will be received by the server port and vice versa. Ontop, network adapter #4 used to [underline]#listen# to all traffic generated by both of TRex's ports, therefore it is very useful in providing live data of the generated flows over the network. + + + + + @@ -12,11 +12,155 @@ APPNAME='wafdocs' import os, re, shutil import shlex import subprocess +import json + top = '.' out = 'build' +from HTMLParser import HTMLParser + +class CTocNode: + def __init__ (self): + self.name="root" + self.level=1; # 1,2,3,4 + self.parent=None + self.childs=[]; # link to CTocNode + + def get_link (self): + name=self.name + l=name.split('.'); + l=l[-1].lower() + s=''; + for c in l: + if c.isalpha() or c.isspace(): + s+=c + + return '#_'+'_'.join(s.lower().split()); + + + def add_new_child (self,name,level): + n=CTocNode(); + n.name=name; + n.level=level; + n.parent=self; + self.childs.append(n); + return n + + def to_json_childs (self): + l=[] + for obj in self.childs: + l.append(obj.to_json()); + return (l); + + def to_open (self): + if self.level <3: + return True + else: + return False + + + def to_json (self): + d={"text" : self.name, + "link" : self.get_link(), + "state" : { + "opened" : self.to_open() + } + } + if len(self.childs)>0 : + d["children"]= self.to_json_childs() + return d + + + +class TocHTMLParser(HTMLParser): + + def __init__ (self): + HTMLParser.__init__(self); + self.state=0; + self.root=CTocNode() + self.root.parent=self.root + self.level=2; + self.d={}; + self.last_level=1 + self.set_level(1,self.root) + + + def set_level (self,level,node): + assert(node!=None); + assert(isinstance(node,CTocNode)==True); + self.d[str(level)]=node + + # in case we change from high to low level remove the higher level + if level<self.last_level: + for l in range(level+1,self.last_level+1): + self.d.pop(str(l),None) + + + + def _get_level (self,level): + k=str(level) + if self.d.has_key(k): + n=self.d[k] + assert(n!=None); + return n + else: + return None + + def get_level (self,level): + for l in range(level,0,-1): + n=self._get_level(l) + if n != None: + return n + assert(0); + + + def is_header (self,tag): + if len(tag)==2 and tag[0]=='h' and tag[1].isdigit() and (int(tag[1])>1): + return (True); + + def handle_starttag(self, tag, attrs): + if self.is_header (tag): + self.state=True; + self.level=int(tag[1]); + + def handle_endtag(self, tag): + if self.is_header (tag): + self.state=False; + + + def handle_data(self, data): + if self.state: + level=self.level + + cnode=self.get_level(level-1) + + n=cnode.add_new_child(data,level); + assert(n!=None); + self.set_level(level,n) + self.last_level=level + + def dump_as_json (self): + return json.dumps(self.root.to_json_childs(), sort_keys=False, indent=4) + + + + +def create_toc_json (input_file,output_file): + f = open (input_file) + l=f.readlines() + f.close(); + html_input = ''.join(l) + parser = TocHTMLParser() + parser.feed(html_input); + f = open (output_file,'w') + f.write(parser.dump_as_json()); + f.close(); + + + + re_xi = re.compile('''^(include|image)::([^.]*.(asciidoc|\\{PIC\\}))\[''', re.M) def ascii_doc_scan(self): p = self.inputs[0].parent @@ -96,6 +240,47 @@ def convert_to_pdf(task): os.system('a2x --no-xmllint -v -f pdf -d article %s -D %s ' %(task.inputs[0].abspath(),out_dir ) ) return (0) + + +def toc_fixup_file (input_file, + out_file, + json_file_name + ): + + file = open(input_file) + contents = file.read() + replaced_contents = contents.replace('input_replace_me.json', json_file_name) + file = open(out_file,'w') + file.write(replaced_contents) + file.close(); + + + +def convert_to_html_toc_book(task): + + input_file = task.inputs[0].abspath() + + json_out_file = os.path.splitext(task.outputs[0].abspath())[0]+'.json' + tmp = os.path.splitext(task.outputs[0].abspath())[0]+'.tmp' + json_out_file_short = os.path.splitext(task.outputs[0].name)[0]+'.json' + + cmd='{0} -a stylesheet={1} -a icons=true -a docinfo -d book -a max-width=55em -o {2} {3}'.format( + task.env['ASCIIDOC'], + task.inputs[1].abspath(), + tmp, + task.inputs[0].abspath()); + + os.system( cmd ) + + create_toc_json(tmp,json_out_file) + + toc_fixup_file(tmp,task.outputs[0].abspath(),json_out_file_short); + + os.system('rm {0}'.format(tmp)); + + + + def convert_to_pdf_book(task): input_file = task.outputs[0].abspath() out_dir = task.outputs[0].parent.get_bld().abspath() @@ -209,6 +394,14 @@ def build_cp(bld,dir,root,callback): + + + + + + + + def build(bld): bld(rule=my_copy, target='symbols.lang') @@ -252,13 +445,6 @@ def build(bld): bld(rule='${ASCIIDOC} -a stylesheet=${SRC[1].abspath()} -a icons=true -a max-width=55em -o ${TGT} ${SRC[0].abspath()}', source='release_notes.asciidoc waf.css', target='release_notes.html', scan=ascii_doc_scan) - - bld(rule='${ASCIIDOC} -a docinfo -a stylesheet=${SRC[1].abspath()} -a icons=true -a toc2 -a max-width=55em -d book -o ${TGT} ${SRC[0].abspath()}', - source='trex_book.asciidoc waf.css', target='trex_manual.html', scan=ascii_doc_scan) - - bld(rule='${ASCIIDOC} -a docinfo -a stylesheet=${SRC[1].abspath()} -a icons=true -a toc2 -a max-width=55em -d book -o ${TGT} ${SRC[0].abspath()}', - source='trex_stateless.asciidoc waf.css', target='trex_stateless.html', scan=ascii_doc_scan) - bld(rule='${ASCIIDOC} -a docinfo -a stylesheet=${SRC[1].abspath()} -a icons=true -a toc2 -a max-width=55em -d book -o ${TGT} ${SRC[0].abspath()}', source='draft_trex_stateless.asciidoc waf.css', target='draft_trex_stateless.html', scan=ascii_doc_scan) @@ -277,17 +463,26 @@ def build(bld): bld(rule=convert_to_pdf_book, source='trex_control_plane_design_phase1.asciidoc waf.css', target='trex_control_plane_design_phase1.pdf', scan=ascii_doc_scan) - bld(rule='${ASCIIDOC} -a stylesheet=${SRC[1].abspath()} -a icons=true -a toc2 -a max-width=55em -o ${TGT} ${SRC[0].abspath()}', - source='trex_vm_manual.asciidoc waf.css', target='trex_vm_manual.html', scan=ascii_doc_scan) + # with nice TOC + bld(rule=convert_to_html_toc_book, + source='trex_vm_manual.asciidoc waf.css', target='trex_vm_manual.html',scan=ascii_doc_scan) + + bld(rule=convert_to_html_toc_book, + source='trex_stateless.asciidoc waf.css', target='trex_stateless.html',scan=ascii_doc_scan); + + bld(rule=convert_to_html_toc_book, + source='trex_book.asciidoc waf.css', target='trex_manual.html',scan=ascii_doc_scan); + + bld(rule=convert_to_html_toc_book, + source='trex_rpc_server_spec.asciidoc waf.css', target='trex_rpc_server_spec.html',scan=ascii_doc_scan); + + bld(rule='${ASCIIDOC} -a stylesheet=${SRC[1].abspath()} -a icons=true -a toc2 -a max-width=55em -o ${TGT} ${SRC[0].abspath()}', source='vm_doc.asciidoc waf.css', target='vm_doc.html', scan=ascii_doc_scan) bld(rule='${ASCIIDOC} -a stylesheet=${SRC[1].abspath()} -a icons=true -a toc2 -a max-width=55em -o ${TGT} ${SRC[0].abspath()}', source='packet_builder_yaml.asciidoc waf.css', target='packet_builder_yaml.html', scan=ascii_doc_scan) - - bld(rule='${ASCIIDOC} -a stylesheet=${SRC[1].abspath()} -a icons=true -a toc2 -a max-width=55em -o ${TGT} ${SRC[0].abspath()}', - source='trex_rpc_server_spec.asciidoc waf.css', target='trex_rpc_server_spec.html', scan=ascii_doc_scan) bld(rule='${ASCIIDOC} -a stylesheet=${SRC[1].abspath()} -a icons=true -a toc2 -a max-width=55em -o ${TGT} ${SRC[0].abspath()}', source='trex_control_plane_design_phase1.asciidoc waf.css', target='trex_control_plane_design_phase1.html', scan=ascii_doc_scan) @@ -367,18 +562,18 @@ def release(bld): def publish(bld): # copy all the files to our web server remote_dir = "%s:%s" % ( Env().get_local_web_server(), Env().get_remote_release_path ()+'../doc/') - os.system('rsync -av --rsh=ssh build/ %s' % (remote_dir)) + os.system('rsync -av --del --rsh=ssh build/ %s' % (remote_dir)) def publish_ext(bld): from_ = 'build/' - os.system('rsync -avz -e "ssh -i %s" --rsync-path=/usr/bin/rsync %s %s@%s:%s/doc/' % (Env().get_trex_ex_web_key(),from_, Env().get_trex_ex_web_user(),Env().get_trex_ex_web_srv(),Env().get_trex_ex_web_path() ) ) + os.system('rsync -avz --del -e "ssh -i %s" --rsync-path=/usr/bin/rsync %s %s@%s:%s/doc/' % (Env().get_trex_ex_web_key(),from_, Env().get_trex_ex_web_user(),Env().get_trex_ex_web_srv(),Env().get_trex_ex_web_path() ) ) def publish_test(bld): # copy all the files to our web server remote_dir = "%s:%s" % ( Env().get_local_web_server(), Env().get_remote_release_path ()+'../test/') - os.system('rsync -av --rsh=ssh build/ %s' % (remote_dir)) + os.system('rsync -av --del --rsh=ssh build/ %s' % (remote_dir)) @@ -24,6 +24,9 @@ def configure(conf): ws_main.configure(conf) +def create_toc (bld): + ws_main.create_toc(bld) + def build(bld): ws_main.build(bld) |