Statistics
| Branch: | Tag: | Revision:

mininet / mininet / term.py @ ab8c4e91

History | View | Annotate | Download (2.71 KB)

1
"""
2
Terminal creation and cleanup.
3
Utility functions to run a terminal (connected via socat(1)) on each host.
4

5
Requires socat(1) and xterm(1).
6
Optionally uses gnome-terminal.
7
"""
8

    
9
from os import environ
10

    
11
from mininet.log import error
12
from mininet.util import quietRun, errRun
13

    
14
def tunnelX11( node, display=None):
15
    """Create an X11 tunnel from node:6000 to the root host
16
       display: display on root host (optional)
17
       returns: node $DISPLAY, Popen object for tunnel"""
18
    if display is None and 'DISPLAY' in environ:
19
        display = environ[ 'DISPLAY' ]
20
    if display is None:
21
        error( "Error: Cannot connect to display\n" )
22
        return None, None
23
    host, screen = display.split( ':' )
24
    # Unix sockets should work
25
    if not host or host == 'unix':
26
        # GDM3 doesn't put credentials in .Xauthority,
27
        # so allow root to just connect
28
        quietRun( 'xhost +si:localuser:root' )
29
        return display, None
30
    else:
31
        # Create a tunnel for the TCP connection
32
        port = 6000 + int( float( screen ) )
33
        connection = r'TCP\:%s\:%s' % ( host, port )
34
        cmd = [ "socat", "TCP-LISTEN:%d,fork,reuseaddr" % port,
35
                "EXEC:'mnexec -a 1 socat STDIO %s'" % connection ]
36
    return 'localhost:' + screen, node.popen( cmd )
37

    
38
def makeTerm( node, title='Node', term='xterm', display=None, cmd='bash'):
39
    """Create an X11 tunnel to the node and start up a terminal.
40
       node: Node object
41
       title: base title
42
       term: 'xterm' or 'gterm'
43
       returns: two Popen objects, tunnel and terminal"""
44
    title = '"%s: %s"' % ( title, node.name )
45
    if not node.inNamespace:
46
        title += ' (root)'
47
    cmds = {
48
        'xterm': [ 'xterm', '-title', title, '-display' ],
49
        'gterm': [ 'gnome-terminal', '--title', title, '--display' ]
50
    }
51
    if term not in cmds:
52
        error( 'invalid terminal type: %s' % term )
53
        return
54
    display, tunnel = tunnelX11( node, display )
55
    if display is None:
56
        return []
57
    term = node.popen( cmds[ term ] +
58
                       [ display, '-e', 'env TERM=ansi %s' % cmd ] )
59
    return [ tunnel, term ] if tunnel else [ term ]
60

    
61
def runX11( node, cmd ):
62
    "Run an X11 client on a node"
63
    _display, tunnel = tunnelX11( node )
64
    if _display is None:
65
        return []
66
    popen = node.popen( cmd )
67
    return [ tunnel, popen ]
68

    
69
def cleanUpScreens():
70
    "Remove moldy socat X11 tunnels."
71
    errRun( "pkill -9 -f mnexec.*socat" )
72

    
73
def makeTerms( nodes, title='Node', term='xterm' ):
74
    """Create terminals.
75
       nodes: list of Node objects
76
       title: base title for each
77
       returns: list of created tunnel/terminal processes"""
78
    terms = []
79
    for node in nodes:
80
        terms += makeTerm( node, title, term )
81
    return terms