blob: bff976f219e7075072a5245e0455ec630285e351 [file] [log] [blame]
Jon Hall69b2b982016-05-11 12:04:59 -07001"Functions for using the SimpleHTTPServer python module"
2import re
3
4class Server():
5
6 def __init__( self ):
7 self.default = ''
8 self.PID = -1
9 self.component = None
10 self.rootDir = None
11
12 def __del__( self ):
13 self.stop()
14
15 def start( self, component, rootDir, port=8000, logDir=None ):
16 """
17 Start SimpleHTTPServer as a background process from rootDir on the
18 given component. The webserver will listen on port and if specified,
19 output will be redirected to logDir.
20
21 Arguments:
22 - component = The TestON component handle to start the webserver on
23 - rootDir = The root directory for the web content
24 - port = The port number for the webserver to listen on. Defaults to 8000
25 - logDir = If specified, the output of the webserver will be redirected
26 to this file. Note that this should be either an absolute path
27 or relative to rootDir.
28 Returns:
29 main.TRUE if the command succedes or main.FALSE if there is an error.
30 """
31 retValue = main.TRUE
32 self.rootDir = rootDir
33 try:
34 # Save component for this instance so other functions can use it
35 self.component = component
36 main.log.info( "Starting SimpleHTTPServer on " + component.name )
37 if component.handle:
38 handle = component.handle
39 # cd to rootDir
40 handle.sendline( "cd " + str( rootDir ) )
41 handle.expect( "\$" )
42 # Start server
43 cmd = "python -m SimpleHTTPServer {}".format( port )
44 if logDir:
45 cmd += " &> {}".format( logDir ) # pipe all output to a file
46 else:
47 cmd += "&> {dev/null}" # Throw away all output
48 cmd += " &"
49 handle.sendline( cmd )
50 handle.expect( "\$" )
51 response = handle.before
52 # Return to home dir
53 handle.sendline( "cd " + component.home )
54 handle.expect( "\$" )
55 response += handle.before
56 if "Exit" in response:
57 main.log.error( "Error starting server. Check server log for details" )
58 main.log.debug( handle.before )
59 retValue = main.FALSE
60 # capture PID for later use
61 # EX: [1] 67987
62 match = re.search( "\[\d\] (?P<PID>\d+)", response )
63 if match:
64 self.PID = match.group( "PID" )
65 else:
66 main.log.warn( "Could not find PID" )
67 else:
68 main.log.error( "Component handle is not set" )
69 retValue = main.FALSE
70 except Exception:
71 main.log.exception( "Error starting web server" )
72 retValue = main.FALSE
73 return retValue
74
75 def stop( self ):
76 """
77 Kills the process of the server. Note that this function must be run
78 from the same instance of the server class that the server was started
79 on.
80 """
81 retValue = main.TRUE
82 try:
83 main.log.info( "Stopping Server." )
84 assert self.component, "Component not specified"
85 assert self.PID, "PID not found"
86 if self.component.handle:
87 handle = self.component.handle
88 cmd = "sudo kill {}".format( self.PID )
89 handle.sendline( cmd )
90 handle.expect( "\$" )
91 # TODO: What is bad output? cannot sudo?
92 else:
93 main.log.error( "Component handle is not set" )
94 retValue = main.FALSE
95 except Exception:
96 main.log.exception( "Error stopping web server" )
97 retValue = main.FALSE
98 return retValue
99
100 def generateFile( self, nodes, equal=False, filename="cluster.json" ):
101 """
102 Generate custom metadata file in the root directory using the custom
103 onos-gen-partitions file which should also be located in the root
104 directory.
105
106 Note that this function needs to be run after the start function has
107 been called for this instance.
108
109 Arguments:
110 - nodes = The number of ONOS nodes to include in the cluster. Will
111 include nodes in ascending order, I.E. OC1, OC2, etc
112
113 Optional Arguments:
114 - equal = Specifies whether all nodes should participate in every
115 partition. Defaults to False.
116 - filename = The name of the file to save the cluster metadata to.
117 Defaults to "cluster.json".
118 Returns:
119 main.TRUE if the command succedes or main.FALSE if there is an error.
120 """
121 retValue = main.TRUE
122 try:
123 if self.component.handle:
124 assert self.component, "Component not specified. Please start the server first"
125 assert self.rootDir, "Root directory not found"
126 handle = self.component.handle
127 # cd to rootDir
128 handle.sendline( "cd " + str( self.rootDir ) )
129 handle.expect( "\$" )
130 cmd = "./onos-gen-partitions {} {} ".format( filename, nodes )
131 if equal:
132 cmd += "-e"
133 handle.sendline( cmd )
134 handle.expect( "\$" )
135 response = handle.before
136 # Return to home dir
137 handle.sendline( "cd " + self.component.home )
138 handle.expect( "\$" )
139 response += handle.before
140 if "Traceback" in response:
141 main.log.error( handle.before )
142 retValue = main.FALSE
143 else:
144 main.log.error( "Component handle is not set" )
145 retValue = main.FALSE
146 except Exception:
147 main.log.exception( "Error generating metadata file" )
148 return retValue