36
from ivle import (chat, util)
39
trampoline_path = os.path.join(ivle.conf.lib_path, "trampoline")
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')
33
from ivle import chat, interpret
45
35
class ConsoleError(Exception):
46
36
""" The console failed in some way. This is bad. """
47
def __init__(self, value):
50
return repr(self.value)
52
39
class ConsoleException(Exception):
53
40
""" The code being exectuted on the console returned an exception.
55
def __init__(self, value):
58
return repr(self.value)
60
44
class TruncateStringIO(StringIO.StringIO):
61
45
""" A class that wraps around StringIO and truncates the buffer when the
122
106
class Console(object):
123
107
""" Provides a nice python interface to the console
125
def __init__(self, uid, jail_path, working_dir):
109
def __init__(self, config, user, jail_path, working_dir):
126
110
"""Starts up a console service for user uid, inside chroot jail
127
111
jail_path with work directory of working_dir
129
113
super(Console, self).__init__()
132
117
self.jail_path = jail_path
133
118
self.working_dir = working_dir
157
self.magic = md5.new(uuid.uuid4().bytes).digest().encode('hex')
142
self.magic = hashlib.md5(uuid.uuid4().bytes).hexdigest()
159
144
# Try to find a free port on the server.
160
145
# Just try some random ports in the range [3000,8000)
165
150
# is (k / N) ** t (e.g. 3.2*10e-9).
169
155
self.port = int(random.uniform(3000, 8000))
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, [
178
ivle.conf.jail_src_base,
179
ivle.conf.jail_system,
157
python_console = os.path.join(self.config['paths']['share'],
158
'services/python-console')
159
args = [python_console, str(self.port), str(self.magic)]
162
interpret.execute_raw(self.config, self.user, self.jail_path,
163
self.working_dir, "/usr/bin/python", args)
195
# If we can't start the console after 5 attemps (can't find a free port
196
# during random probing, syntax errors, segfaults) throw an exception.
166
except interpret.ExecutionError, e:
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
198
raise ConsoleError("Unable to start console service!")
174
raise ConsoleError('Unable to start console service: %s'%error)
200
176
def __chat(self, cmd, args):
201
177
""" A wrapper around chat.chat to comunicate directly with the
213
189
# Some other error - probably serious
214
190
raise socket.error, (enumber, estring)
215
except cjson.DecodeError:
216
192
# Couldn't decode the JSON
217
193
raise ConsoleError(
218
194
"Could not understand the python console response")
195
except chat.ProtocolError, e:
196
raise ConsoleError(*e.args)
301
279
# Unpickle any exceptions
302
280
if 'exception' in execute:
303
return cPickle.loads(execute['exception'])
281
execute['exception'] = cPickle.loads(str(execute['exception']))
308
285
def set_vars(self, variables):