~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-08-13 07:26:44 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:1017
Console: Refactored a lot of the console stuff into a class to make calls to 
the console from Python a lot nicer. Eventually it should even be able to be 
used by consoleservice but needs a little more work (at the moment it's only 
used for starting the console).
Also added in a few Tutorial specific functions to console such as 'inspect' 
which gives a summary of the the evaluated code block and flush to clear and 
optionally set globals.

Listmake will need to be rerun after this revision due to the new 
lib/common/console.py

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
 
30
30
import cjson
31
31
 
32
 
from common import (util, studpath, chat)
 
32
from common import (util, studpath, chat, console)
33
33
import conf
34
34
import errno
35
35
 
36
 
trampoline_path = os.path.join(conf.ivle_install_dir, "bin/trampoline")
37
 
python_path = "/usr/bin/python"                     # Within jail
38
 
console_dir = "/opt/ivle/scripts"                   # Within jail
39
 
console_path = "/opt/ivle/scripts/python-console"   # Within jail
40
 
 
41
36
def handle(req):
42
37
    """Handler for the Console Service AJAX backend application."""
43
38
    if len(req.path) > 0 and req.path[-1] == os.sep:
55
50
        handle_chat(req)
56
51
    elif req.path == "block":
57
52
        handle_chat(req, kind="block")
 
53
    elif req.path == "flush":
 
54
        handle_chat(req, kind="flush")
58
55
    elif req.path == "inspect":
59
56
        handle_chat(req, kind="inspect")
60
57
    else:
82
79
 
83
80
    # Start the server
84
81
    jail_path = os.path.join(conf.jail_base, req.user.login)
85
 
    (host, port, magic) = start_console(uid, jail_path, working_dir)
 
82
    cons = console.Console(uid, jail_path, working_dir)
86
83
 
87
84
    # Assemble the key and return it.
88
 
    key = cjson.encode({"host": host, "port": port, "magic": magic})
 
85
    key = cjson.encode(
 
86
        {"host": cons.host, "port": cons.port, "magic": cons.magic})
89
87
    req.write(cjson.encode(key.encode("hex")))
90
88
 
91
89
def handle_chat(req, kind = "chat"):
142
140
    req.content_type = "text/plain"
143
141
    req.write(response)
144
142
 
145
 
def start_console(uid, jail_path, working_dir):
146
 
    """Starts up a console service for user uid, inside chroot jail jail_path 
147
 
    with work directory of working_dir
148
 
    Returns a tupple (host, port, magic)
149
 
    """
150
 
 
151
 
    # TODO: Figure out the host name the console server is running on.
152
 
    host = socket.gethostname()
153
 
 
154
 
    # Create magic
155
 
    # TODO
156
 
    magic = md5.new(uuid.uuid4().bytes).digest().encode('hex')
157
 
 
158
 
    # Try to find a free port on the server.
159
 
    # Just try some random ports in the range [3000,8000)
160
 
    # until we either succeed, or give up. If you think this
161
 
    # sounds risky, it isn't:
162
 
    # For N ports (e.g. 5000) with k (e.g. 100) in use, the
163
 
    # probability of failing to find a free port in t (e.g. 5) tries
164
 
    # is (k / N) ** t (e.g. 3.2*10e-9).
165
 
 
166
 
    tries = 0
167
 
    while tries < 5:
168
 
        port = int(random.uniform(3000, 8000))
169
 
 
170
 
        # Start the console server (port, magic)
171
 
        # trampoline usage: tramp uid jail_dir working_dir script_path args
172
 
        # console usage:    python-console port magic
173
 
        cmd = ' '.join([trampoline_path, str(uid), jail_path,
174
 
                            console_dir, python_path, console_path,
175
 
                            str(port), str(magic), working_dir])
176
 
 
177
 
        res = os.system(cmd)
178
 
 
179
 
        if res == 0:
180
 
            # success
181
 
            break;
182
 
 
183
 
        tries += 1
184
 
 
185
 
    # If we can't start the console after 5 attemps (can't find a free port 
186
 
    # during random probing, syntax errors, segfaults) throw an exception.
187
 
    if tries == 5:
188
 
        raise Exception, "unable to start console service!"
189
 
 
190
 
    return (host, port, magic)
191
 
 
192
143
def restart_console(uid, jail_path, working_dir, reason):
193
144
    """Tells the client that it must be issued a new console since the old 
194
145
    console is no longer availible. The client must accept the new key.
195
146
    Returns the JSON response to be given to the client.
196
147
    """
197
148
    # Start a new console server console
198
 
    (host, port, magic) = start_console(uid, jail_path, working_dir)
 
149
    cons = console.Console(uid, jail_path, working_dir)
199
150
 
200
151
    # Make a JSON object to tell the browser to restart its console client
201
 
    new_key = cjson.encode({"host": host, "port": port, "magic": magic})
 
152
    new_key = cjson.encode(
 
153
        {"host": cons.host, "port": cons.port, "magic": cons.magic})
202
154
    json_restart = {
203
155
        "restart": reason,
204
156
        "key": new_key.encode("hex"),
205
157
    }
206
158
    
207
159
    return cjson.encode(json_restart)
208