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

« back to all changes in this revision

Viewing changes to lib/common/console.py

  • Committer: dcoles
  • Date: 2008-08-19 06:44:05 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:1029
Tutorial Service: Ported the tutorial service to the console so that all 
student code should now be run inside the jail. This means that the code will 
also be contrained by trampoline's ulimits and will no longer need to run as 
the webserver (with all the badness that entails).

* TestFramework has been modifed to make eqvivalent calls to the console.
* Tutorial service now starts up a console for each attempt.
* Modifications to python-console script and console module to allow new calls 
needed.
* Added a FakeObject class to util to use to represent things that can not be 
pickled. (Ideally should be in the console module, but the console module can't 
be imported into the jail at the moment - relies on a full lib/conf/conf.py).  
Might be possible to make these fake objects able to call the console too?

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 
22
22
# Mainly refactored out of consoleservice
23
23
 
 
24
import errno
24
25
import cPickle
25
26
import md5
26
27
import os
31
32
import cjson
32
33
 
33
34
import conf
34
 
from common import chat
 
35
from common import (chat, util)
35
36
 
36
 
trampoline_path = os.path.join(conf.ivle_install_dir, "bin/trampoline")
37
 
trampoline_path = os.path.join(conf.ivle_install_dir, "bin/trampoline")
38
 
python_path = "/usr/bin/python"                     # Within jail
39
 
console_dir = "/opt/ivle/scripts"                   # Within jail
40
 
console_path = "/opt/ivle/scripts/python-console"   # Within jail
 
37
# Outside Jail
 
38
trampoline_path = os.path.join(conf.ivle_install_dir, "bin/trampoline")
 
39
# Inside Jail
 
40
python_path = "/usr/bin/python"
 
41
console_dir = "/opt/ivle/scripts"
 
42
console_path = "/opt/ivle/scripts/python-console"
41
43
 
42
44
class ConsoleError(Exception):
43
45
    """ The console failed in some way. This is bad. """
92
94
            # Start the console server (port, magic)
93
95
            # trampoline usage: tramp uid jail_dir working_dir script_path args
94
96
            # console usage:    python-console port magic
95
 
            cmd = ' '.join([trampoline_path, str(self.uid), self.jail_path,
96
 
                            console_dir, python_path, console_path,
97
 
                            str(self.port), str(self.magic), 
98
 
                            self.working_dir])
 
97
            cmd = ' '.join([
 
98
                trampoline_path,
 
99
                str(self.uid),
 
100
                self.jail_path,
 
101
                console_dir,
 
102
                python_path,
 
103
                console_path,
 
104
                str(self.port),
 
105
                str(self.magic),
 
106
                self.working_dir
 
107
                ])
99
108
 
100
109
            res = os.system(cmd)
101
110
 
121
130
            if enumber == errno.ECONNREFUSED:
122
131
                # Timeout
123
132
                raise ConsoleError(
124
 
                    "The IVLE console has timed out due to inactivity")
 
133
                    "Could not establish a connection to the python console")
125
134
            else:
126
135
                # Some other error - probably serious
127
136
                raise socket.error, (enumber, estring)
128
137
        except cjson.DecodeError:
129
138
            # Couldn't decode the JSON
130
139
            raise ConsoleError(
131
 
                "Communication to console process lost")
 
140
                "Could not understand the python console response")
132
141
 
133
142
        # Look for user errors
134
143
        if 'exc' in response:
167
176
            raise ConsoleError("Bad response from console: %s"%str(flush))
168
177
 
169
178
    def call(self, function, *args, **kwargs):
170
 
        """ Calls a function in the python console """
 
179
        """ Calls a function in the python console. Can take in a list of 
 
180
        repr() args and dictionary of repr() values kwargs. These will be 
 
181
        evaluated on the server side.
 
182
        """
171
183
        call_args = {
172
184
            'function': function,
173
185
            'args': args,
174
186
            'kwargs': kwargs}
175
 
        response = self.__chat('call', call_args)
176
 
        if 'output' in response:
177
 
            return response['output']
178
 
        else:
179
 
            raise ConsoleError(
180
 
                "Bad response from console: %s"%str(response))
 
187
        call = self.__chat('call', call_args)
 
188
        
 
189
        # Unpickle any exceptions
 
190
        if 'exception' in call:
 
191
            call['exception']['except'] = \
 
192
                cPickle.loads(call['exception']['except'])
 
193
 
 
194
        return call
181
195
 
182
196
    def inspect(self, code=''):
183
197
        """ Runs a block of code in the python console returning a dictionary 
199
213
                cPickle.loads(inspection['exception']['except'])
200
214
 
201
215
        return inspection
 
216
 
 
217
    def set_vars(self, variables):
 
218
        """ Takes a dictionary of varibles to add to the console's global 
 
219
        space. These are evaluated in the local space so you can't use this to 
 
220
        set a varible to a value to be calculated on the console side.
 
221
        """
 
222
        vars = {}
 
223
        for v in variables:
 
224
            vars[v] = repr(variables[v])
 
225
 
 
226
        set_vars = self.__chat('set_vars', vars)
 
227
 
 
228
        if set_vars.get('response') != 'okay':
 
229
            raise ConsoleError("Could not set variables")
 
230
 
 
231
    def close(self):
 
232
        """ Causes the console process to terminate """
 
233
        self.__chat('restart', None)
202
234
    
203
235