7
7
8
8
try :
9
9
import click
10
+ import os
11
+ import pexpect
10
12
import re
11
13
import subprocess
12
14
from tabulate import tabulate
15
17
16
18
@click .group ()
17
19
def consutil ():
18
- """consutil - Command-line utility for interacting with switchs via console device"""
20
+ """consutil - Command-line utility for interacting with switches via console device"""
19
21
20
22
if os .geteuid () != 0 :
21
23
print "Root privileges are required for this operation"
@@ -28,7 +30,7 @@ def show():
28
30
devices = getAllDevices ()
29
31
busyDevices = getBusyDevices ()
30
32
31
- header = ["Line" , "Baud" , "PID" , "Start Time" ]
33
+ header = ["Line" , "Actual/Configured Baud" , "PID" , "Start Time" ]
32
34
body = []
33
35
for device in devices :
34
36
lineNum = device [11 :]
@@ -38,10 +40,13 @@ def show():
38
40
if lineNum in busyDevices :
39
41
pid , date = busyDevices [lineNum ]
40
42
busy = "*"
41
- baud = getBaud (lineNum )
43
+ actBaud , confBaud , _ = getConnectionInfo (lineNum )
44
+ # repeated "~" will be replaced by spaces - hacky way to align the "/"s
45
+ baud = "{}/{}{}" .format (actBaud , confBaud , "~" * (15 - len (confBaud )))
42
46
body .append ([busy + lineNum , baud , pid , date ])
43
47
44
- click .echo (tabulate (body , header , stralign = "right" ))
48
+ # replace repeated "~" with spaces - hacky way to align the "/"s
49
+ click .echo (tabulate (body , header , stralign = "right" ).replace ('~' , ' ' ))
45
50
46
51
# 'clear' subcommand
47
52
@consutil .command ()
@@ -62,10 +67,42 @@ def clear(linenum):
62
67
63
68
# 'connect' subcommand
64
69
@consutil .command ()
65
- @click .argument ('linenum' )
66
- def connect (linenum ):
67
- """Connect to switch via console device"""
68
- click .echo ("connect linenum" )
70
+ @click .argument ('target' )
71
+ @click .option ('--devicename' , '-d' , is_flag = True , help = "connect by name - if flag is set, interpret linenum as device name instead" )
72
+ def connect (target , devicename ):
73
+ """Connect to switch via console device - TARGET is line number or device name of switch"""
74
+ lineNumber = getLineNumber (target , devicename )
75
+ checkDevice (lineNumber )
76
+ lineNumber = str (lineNumber )
77
+
78
+ # build and start picocom command
79
+ actBaud , _ , flowBool = getConnectionInfo (lineNumber )
80
+ flowCmd = "h" if flowBool else "n"
81
+ quietCmd = "-q" if QUIET else ""
82
+ cmd = "sudo picocom -b {} -f {} {} {}{}" .format (actBaud , flowCmd , quietCmd , DEVICE_PREFIX , lineNumber )
83
+ proc = pexpect .spawn (cmd )
84
+ proc .send ("\n " )
85
+
86
+ if QUIET :
87
+ readyMsg = DEV_READY_MSG
88
+ else :
89
+ readyMsg = "Terminal ready" # picocom ready message
90
+ busyMsg = "Resource temporarily unavailable" # picocom busy message
91
+
92
+ # interact with picocom or print error message, depending on pexpect output
93
+ index = proc .expect ([readyMsg , busyMsg , pexpect .EOF , pexpect .TIMEOUT ], timeout = TIMEOUT_SEC )
94
+ if index == 0 : # terminal ready
95
+ click .echo ("Successful connection to line {}\n Press ^A ^X to disconnect" .format (lineNumber ))
96
+ if QUIET :
97
+ # prints picocom output up to and including readyMsg
98
+ click .echo (proc .before + proc .match .group (0 ), nl = False )
99
+ proc .interact ()
100
+ if QUIET :
101
+ click .echo ("\n Terminating..." )
102
+ elif index == 1 : # resource is busy
103
+ click .echo ("Cannot connect: line {} is busy" .format (lineNumber ))
104
+ else : # process reached EOF or timed out
105
+ click .echo ("Cannot connect: unable to open picocom process" )
69
106
70
107
if __name__ == '__main__' :
71
108
consutil ()
0 commit comments