~azzar1/unity/add-show-desktop-key

« back to all changes in this revision

Viewing changes to www/apps/consoleservice/__init__.py

  • Committer: dcoles
  • Date: 2008-04-18 06:05:17 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:737
Console: The consoleservice is now able to work out when a console has timed 
out and automatically start a new console. This looks much better than the old 
"A console error has occured"
    a/c/__init__.py: Catches refused connections (no server waiting anymore), 
    starts a new console and alerts the browser that the console has been 
    reset.
    m/c/console.js: Detects reset, displays message in terminal and updates the 
    console settings to the new console server.

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
 
32
32
from common import (util, studpath, chat)
33
33
import conf
 
34
import errno
34
35
 
35
36
trampoline_path = os.path.join(conf.ivle_install_dir, "bin/trampoline")
36
37
python_path = "/usr/bin/python"                     # Within jail
66
67
    req.content_type = "text/plain"
67
68
    req.write_html_head_foot = False
68
69
 
 
70
    # Start the server
 
71
    (host, port, magic) = start_console(uid, jail_path, working_dir)
 
72
 
 
73
    # Assemble the key and return it.
 
74
    key = cjson.encode({"host": host, "port": port, "magic": magic})
 
75
    req.write(cjson.encode(key.encode("hex")))
 
76
 
 
77
def handle_chat(req, kind = "chat"):
 
78
    # The request *should* have the following four fields:
 
79
    # host, port, magic: Host and port where the console server lives,
 
80
    # and the secret to use to digitally sign the communication with the
 
81
    # console server.
 
82
    # text: Fields to pass along to the console server
 
83
    # It simply acts as a proxy to the console server
 
84
    if req.method != "POST":
 
85
        req.throw_error(req.HTTP_BAD_REQUEST)
 
86
    fields = req.get_fieldstorage()
 
87
    try:
 
88
        key = cjson.decode(fields.getfirst("key").value.decode("hex"))
 
89
        host = key['host']
 
90
        port = key['port']
 
91
        magic = key['magic']
 
92
    except AttributeError:
 
93
        # Any of the getfirsts returned None
 
94
        req.throw_error(req.HTTP_BAD_REQUEST)
 
95
    # If text is None, it was probably just an empty line
 
96
    try:
 
97
        text = fields.getfirst("text").value
 
98
    except AttributeError:
 
99
        text = ""
 
100
 
 
101
    msg = {'cmd':kind, 'text':text}
 
102
    try:
 
103
        response = chat.chat(host, port, msg, magic, decode = False)
 
104
    except socket.error, (enumber, estring):
 
105
        if enumber == errno.ECONNREFUSED:
 
106
            # Timeout: Restart the session
 
107
            jail_path = os.path.join(conf.jail_base, req.user.login)
 
108
            working_dir = os.path.join("/home", req.user.login)   # Within jail
 
109
            
 
110
            # Get the UID of the logged-in user
 
111
            uid = req.user.unixid
 
112
 
 
113
            # Start the console
 
114
            (host, port, magic) = start_console(uid, jail_path, working_dir)
 
115
 
 
116
            # Make a JSON object to tell the browser to restart its console 
 
117
            # client
 
118
            new_key = cjson.encode(
 
119
                {"host": host, "port": port, "magic": magic})
 
120
            json_restart = {
 
121
                "restart": "The IVLE console has timed out due to inactivity",
 
122
                "key": new_key.encode("hex"),
 
123
            }
 
124
            response = cjson.encode(json_restart)
 
125
        else:
 
126
            # Some other error - probably serious
 
127
            raise socket.error, (enumber, estring)
 
128
 
 
129
    req.content_type = "text/plain"
 
130
    req.write(response)
 
131
 
 
132
def start_console(uid, jail_path, working_dir):
 
133
    """Starts up a console service for user uid, inside chroot jail jail_path 
 
134
    with work directory of working_dir
 
135
    Returns a tupple (host, port, magic)
 
136
    """
 
137
 
69
138
    # TODO: Figure out the host name the console server is running on.
70
139
    host = socket.gethostname()
71
140
 
103
172
    if tries == 5:
104
173
        raise Exception, "unable to find a free port!"
105
174
 
106
 
    # Assemble the key and return it.
107
 
    key = cjson.encode({"host": host, "port": port, "magic": magic})
108
 
    req.write(cjson.encode(key.encode("hex")))
109
 
 
110
 
def handle_chat(req, kind = "chat"):
111
 
    # The request *should* have the following four fields:
112
 
    # host, port, magic: Host and port where the console server lives,
113
 
    # and the secret to use to digitally sign the communication with the
114
 
    # console server.
115
 
    # text: Fields to pass along to the console server
116
 
    # It simply acts as a proxy to the console server
117
 
    if req.method != "POST":
118
 
        req.throw_error(req.HTTP_BAD_REQUEST)
119
 
    fields = req.get_fieldstorage()
120
 
    try:
121
 
        key = cjson.decode(fields.getfirst("key").value.decode("hex"))
122
 
        host = key['host']
123
 
        port = key['port']
124
 
        magic = key['magic']
125
 
    except AttributeError:
126
 
        # Any of the getfirsts returned None
127
 
        req.throw_error(req.HTTP_BAD_REQUEST)
128
 
    # If text is None, it was probably just an empty line
129
 
    try:
130
 
        text = fields.getfirst("text").value
131
 
    except AttributeError:
132
 
        text = ""
133
 
 
134
 
    msg = {'cmd':kind, 'text':text}
135
 
    response = chat.chat(host, port, msg, magic, decode = False)
136
 
    req.content_type = "text/plain"
137
 
    req.write(response)
 
175
    return (host, port, magic)
138
176