1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
Installation
============
These instructions assume you are running Debian Jessie. Install dependencies:
apt install apache2 nodejs npm python3 python3-ply python3-psycopg2 python3-termcolor
SWI prolog
----------
To use the correct SWI prolog package (>= 7.3) on Debian, add a custom
repository by creating the file /etc/apt/sources.list.d/prolog.list
containing the following 2 lines:
deb http://ppa.launchpad.net/swi-prolog/devel/ubuntu trusty main
deb-src http://ppa.launchpad.net/swi-prolog/devel/ubuntu trusty main
After that run the following sequence of shell statements to update
the package cache, register the new repository's key, and again refresh
the package cache using the additional key:
apt-get update
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys EF8406856DBFCA18
apt-get update
libseccomp
----------
A new version of libseccomp (≥ 2.2) with Python bindings is needed to sandbox
Python interpreters. This is not available yet in most distributions. You can
download custom-built packages for Debian Jessie at
http://codeq.si/libseccomp2_2.2.3-2_amd64.deb
http://codeq.si/seccomp_2.2.3-2_amd64.deb
and install them using
dpkg --install libseccomp2_2.2.3-2_amd64.deb seccomp_2.2.3-2_amd64.deb
Alternatively, fetch the latest sources with
git clone https://github.com/seccomp/libseccomp
and configure with --enable-python.
nodejs
------
Run "npm install" inside the codeq-server/web directory to install all
dependencies (they will be installed inside the web directory)
sandbox
-------
Go to directory codeq-server/python/runner and run the following commands to
build the sandbox and set appropriate permissions:
make sandbox
sudo setcap cap_setuid,cap_setgid+ep sandbox
Settings
========
Replace $webroot in this section with the path to codeq-web repo. Remember to
grant read access to $webroot to the apache user.
Set environment variables:
CODEQ_PROBLEMS=<path to codeq-problems repo>
CODEQ_WEB_OUTPUT=$webroot/data
CODEQ_DB_HOST=<address of database server>
CODEQ_DB_DATABASE=<database name, default is 'codeq'>
CODEQ_DB_USER=<database user, default is 'codeq'>
CODEQ_DB_PASS=<database password, default is 'c0d3q'>
Set up apache:
a2enmod proxy proxy_http proxy_wstunnel rewrite
Add the following directives to the VirtualHost configuration:
DocumentRoot "$webroot"
<Directory "$webroot">
Require all granted
</Directory>
RewriteEngine on
RewriteCond %{REQUEST_URI} ^/ws/ [NC]
RewriteCond %{QUERY_STRING} transport=websocket [NC]
RewriteRule /(.*) ws://localhost:8083/$1 [P,L]
ProxyPass /ws/ http://localhost:8083/ws/
ProxyPassReverse /ws/ http://localhost:8083/ws/
Running
=======
- first build static JSON data with scripts/build_web_resources.py, read its heading comment for details
- run the prolog interpreter server: swipl prolog/runner/main.pl
- run the session daemon: python3 daemon.py
- run the web server for client communication: node web/main.js
Testing
=======
You can test stuff in a python interpreter:
>>> import server
>>> session = server.user_session.authenticate_and_create_session(<user>, <pass>)
>>> session.get_problem_data('python', 'introduction', 'fahrenheit_to_celsius')
>>> python = session.get_python()
>>> python.test(231, 180, '''print('-17.7')''')
>>> python.hint(231, 180, '''print('-17.7')''')
>>> prolog = session.get_prolog()
>>> prolog.test(231, 96, 'sister(X,Y):- parent(P,X), parent(P,Y), female(X).')
>>> prolog.hint(231, 96, 'sister(X,Y):- parent(P,X), parent(P,Y), female(X).')
Traces
======
Actions and corresponding additional attributes are specified here.
Generic:
- open(time) # when opening the problem page, time = Date.now() on client
- close() # when closing the problem page
- ins(off, txt) # offset, text
- rm(off, txt) # offset, text, was rm(off, len)
- plan()
- hint(feedback) # feedback = list of returned hint objects
- test(feedback) # feedback = list of returned hint objects
Prolog:
- prolog_solve(query) # was slv(qry)
- prolog_next() # was nxt
- prolog_end() # was stp
Python:
- python_run(program)
- python_stop()
- python_input(txt)
Robot:
- robot_run(program)
- robot_stop()
Obsolete actions:
- slva(qry) # "solve all" from tuProlog
- hnt # hint button press
- tst(tot, pas) # test results (total / passed)
|