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

« back to all changes in this revision

Viewing changes to ivle/console.py

Remove the setup.configure import from setup.

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
 
24
24
import errno
25
25
import cPickle
26
 
import hashlib
 
26
import md5
27
27
import os
28
28
import random
29
29
import socket
30
30
import StringIO
31
31
import uuid
32
32
 
33
 
from ivle import chat, interpret
 
33
import cjson
 
34
 
 
35
import ivle.conf
 
36
from ivle import (chat, util)
 
37
 
 
38
# Outside Jail
 
39
trampoline_path = os.path.join(ivle.conf.lib_path, "trampoline")
 
40
# Inside Jail
 
41
python_path = "/usr/bin/python"
 
42
console_dir = os.path.join(ivle.conf.share_path, 'services')
 
43
console_path = os.path.join(console_dir, 'python-console')
34
44
 
35
45
class ConsoleError(Exception):
36
46
    """ The console failed in some way. This is bad. """
37
 
    pass
 
47
    def __init__(self, value):
 
48
        self.value = value
 
49
    def __str__(self):
 
50
        return repr(self.value)
38
51
 
39
52
class ConsoleException(Exception):
40
53
    """ The code being exectuted on the console returned an exception. 
41
54
    """
42
 
    pass
 
55
    def __init__(self, value):
 
56
        self.value = value
 
57
    def __str__(self):
 
58
        return repr(self.value)
43
59
 
44
60
class TruncateStringIO(StringIO.StringIO):
45
61
    """ A class that wraps around StringIO and truncates the buffer when the 
106
122
class Console(object):
107
123
    """ Provides a nice python interface to the console
108
124
    """
109
 
    def __init__(self, config, user, jail_path, working_dir):
 
125
    def __init__(self, uid, jail_path, working_dir):
110
126
        """Starts up a console service for user uid, inside chroot jail 
111
127
        jail_path with work directory of working_dir
112
128
        """
113
129
        super(Console, self).__init__()
114
130
 
115
 
        self.config = config
116
 
        self.user = user
 
131
        self.uid = uid
117
132
        self.jail_path = jail_path
118
133
        self.working_dir = working_dir
119
134
 
139
154
 
140
155
        # Create magic
141
156
        # TODO
142
 
        self.magic = hashlib.md5(uuid.uuid4().bytes).hexdigest()
 
157
        self.magic = md5.new(uuid.uuid4().bytes).digest().encode('hex')
143
158
 
144
159
        # Try to find a free port on the server.
145
160
        # Just try some random ports in the range [3000,8000)
150
165
        # is (k / N) ** t (e.g. 3.2*10e-9).
151
166
 
152
167
        tries = 0
153
 
        error = None
154
168
        while tries < 5:
155
169
            self.port = int(random.uniform(3000, 8000))
156
170
 
157
 
            python_console = os.path.join(self.config['paths']['share'],
158
 
                        'services/python-console')
159
 
            args = [python_console, str(self.port), str(self.magic)]
 
171
            # Start the console server (port, magic)
 
172
            # trampoline usage: tramp uid jail_dir working_dir script_path args
 
173
            # console usage:    python-console port magic
 
174
            res = os.spawnv(os.P_WAIT, trampoline_path, [
 
175
                trampoline_path,
 
176
                str(self.uid),
 
177
                self.jail_path,
 
178
                console_dir,
 
179
                python_path,
 
180
                console_path,
 
181
                str(self.port),
 
182
                str(self.magic),
 
183
                self.working_dir
 
184
                ])
160
185
 
161
 
            try:
162
 
                interpret.execute_raw(self.config, self.user, self.jail_path,
163
 
                        self.working_dir, "/usr/bin/python", args)
 
186
            if res == 0:
164
187
                # success
165
 
                break
166
 
            except interpret.ExecutionError, e:
167
 
                tries += 1
168
 
                error = e.message
169
 
 
170
 
        # If we can't start the console after 5 attemps (can't find a free 
171
 
        # port during random probing, syntax errors, segfaults) throw an 
172
 
        # exception.
 
188
                break;
 
189
 
 
190
            tries += 1
 
191
 
 
192
        # If we can't start the console after 5 attemps (can't find a free port 
 
193
        # during random probing, syntax errors, segfaults) throw an exception.
173
194
        if tries == 5:
174
 
            raise ConsoleError('Unable to start console service: %s'%error)
 
195
            raise ConsoleError("Unable to start console service!")
175
196
 
176
197
    def __chat(self, cmd, args):
177
198
        """ A wrapper around chat.chat to comunicate directly with the 
188
209
            else:
189
210
                # Some other error - probably serious
190
211
                raise socket.error, (enumber, estring)
191
 
        except ValueError:
 
212
        except cjson.DecodeError:
192
213
            # Couldn't decode the JSON
193
214
            raise ConsoleError(
194
215
                "Could not understand the python console response")
195
 
        except chat.ProtocolError, e:
196
 
            raise ConsoleError(*e.args)
197
216
 
198
217
        return response
199
218
 
247
266
 
248
267
        # Unpickle the globals
249
268
        for g in globals['globals']:
250
 
            globals['globals'][g] = cPickle.loads(str(globals['globals'][g]))
 
269
            globals['globals'][g] = cPickle.loads(globals['globals'][g])
251
270
 
252
271
        return globals['globals']
253
272
        
266
285
        # Unpickle any exceptions
267
286
        if 'exception' in call:
268
287
            call['exception']['except'] = \
269
 
                cPickle.loads(str(call['exception']['except']))
 
288
                cPickle.loads(call['exception']['except'])
270
289
 
271
290
        return call
272
291
 
278
297
              
279
298
        # Unpickle any exceptions
280
299
        if 'exception' in execute:
281
 
            execute['exception'] = cPickle.loads(str(execute['exception']))
282
 
        return execute
 
300
            return cPickle.loads(execute['exception'])
 
301
        else:
 
302
            return execute
283
303
 
284
304
 
285
305
    def set_vars(self, variables):