Version: 2.0.3, 2 November 2024
Note: this is a new version, with lots of changes. If you find errors in this document, please email me. My gmail name is trampgeek.
Author: Richard Lobb, University of Canterbury, New Zealand
Contributors: Tim Hunt, Fedor Lyanguzov, Kai-Cheung Leung, Marcus Klang
Jobe (short for Job Engine) is a server that supports running of small compile-and-run jobs in a variety of programming languages. It was developed as a remote sandbox for use by CodeRunner, a Moodle question-type plugin that asks students to write code to some relatively simple specification. However, Jobe servers could be useful in a variety of other contexts, particularly in education.
A job specifies a programming language, the source code, the standard input to the run and an optional list of additional files. Jobe compiles the source code (if compilation is appropriate in the specified language) and runs it with the given input data. It returns a run_result object containing various status information plus the output and error output from the run.
The interface is via a RESTful API, that is documented here.
The languages C, C++, Python3, Python2, Octave, Java, Pascal and PHP are all built-in. Other languages can be added fairly easily although if using Jobe from CodeRunner it is usually even easier to write a Python-based question type that scripts the execution of the required language. See the CodeRunner documentation for an example.
The Computer Science quiz server at the University of Canterbury switched to exclusive use of the Jobe sandbox in early July 2014. Since then it has run many hundreds of thousands of Python3, C, Java and Octave jobs unattended with only a few minor bug fixes and security refinements.
The current version of Jobe implements a subset of the originally documented API, sufficient for use by CodeRunner. It has been used for many years at the University of Canterbury for several years, running many millions of submissions. Jobe is also used by over 600 other CodeRunner sites around the world. It can be considered stable and secure, though it should be run only on a separate appropriately-firewalled server.
With reference to the original API spec, only immediate-mode runs are supported, with run results being returned with the response to the POST of the run requests. Run results are not retained by the server (unless run_spec.debug is true; see the API), so get_run_status always returns 404 not found.
File PUTs are supported but not POSTs. When used by CodeRunner, file IDs are MD5 checksums of the file contents.
Since version 1.6, the Jobe server cleans the file cache whenever available disk space drops below 5% of the disk size. It simply deletes all files that haven't been used for 2 days or more, so the server must have enough free disk space to stay below 95% full for at least two whole days of running. For CodeRunner clients this should not be a problem unless question authors enable large classes of students to attach large files to their submissions. Support files attached by question authors are unlikely to be a problem; a Jobe server at the University of Canterbury serving a large Moodle client with many thousands of questions accumulated only 200 MB of support files over several years.
For sandboxing, Jobe uses the domjudge runguard program to run student jobs with restrictions on resource allocation (memory, processes, cpu time) as a low-privileged user. However it does not restrict any system calls.
Programs may write binary output but the results are returned to the caller JSON-encoded, which requires UTF-8 strings. To avoid crashing the json-encoder, the standard output and standard error output from the program are checked to see if they're valid utf-8. If so, they're returned unchanged. Otherwise, they're taken as 8-bit character streams; characters below '\x20' (the space character) and above '\x7E' are replaced by C-style hexadecimal encodings (e.g. '\x8E') except for newlines which are passed through directly, and tabs and returns which are replaced with '\t' and '\r' respectively.
If Jobe is to correctly handle utf-8 output from programs, the Apache LANG environment variable must be set to a UTF-8 compatible value. See the section Setting the locale below.
Jobe is implemented using codeigniter4.
WARNING Jobe is primarily intended for use on a server that is firewalled to allow connections from authorised client machines only. If you install it on a machine without such firewalling, and do not control access with API keys (see later), anyone will be able to connect to your machine and run their own code on it! CAVEAT EMPTOR!
NOTE: a (rather old) video walkthrough of the process of setting up a Jobe server on a DigitalOcean droplet is here.
Installation on Ubuntu 22.04 systems should be straightforward but installation on other flavours of Linux or on systems with non-standard configurations may require Linux administrator skills.
An alternative approach, and probably the simplest way to get up and running, is to use the JobeInABox Docker image, which should be runnable with a single terminal command on any Linux system that has docker installed. The steps to fire up a Jobe Server on Digital Ocean using JobeInAbox are given below in section Setting up a JobeInAbox Digital Ocean server.
However, for security and performance reasons it it strongly recommended to run Jobe on a dedicated server, even when running it in a container.
Jobe runs only on Linux, which must have the Apache web server
installed and running. PHP must have been compiled with the System V
Semaphone and shared-memory functions enabled
(see here)[http://www.php.net/manual/en/sem.setup.php], but that's the norm.
Access Control Lists (ACLs) must be enabled; they normally are but if the
/home/jobe
directory lands up on a mounted volume, you may need to
explicitly enable ACLs in the mount
command or in /etc/fstab
.
The Python3 and the C development system must also be
installed.
On Ubuntu-22.04, the commands to set up all the necessary web tools plus all currently-supported languages is the following:
sudo apt-get --no-install-recommends install acl apache2 php \
libapache2-mod-php php-cli nodejs git \
php-mbstring nodejs python3 build-essential default-jdk \
octave php-intl python3-pip fp-compiler acl sudo sqlite3
Octave and fp-compiler are required only if you need to run Octave or Pascal programs respectively.
Similar commands should work on other Debian-based Linux distributions, although some differences are inevitable (e.g.: acl is preinstalled in Ubuntu, whereas in debian it must be installed).
A Raspberry Pi user reports that they additionally had to use the command
apt-get install --fix-missing
which may help with broken installs on other systems, too.
Firstly, install pylint for your required version of python (assumed here to be python3) with the command:
sudo apt install pylint
You also need to build the /etc/pylintrc file to set the default options with one of the following commands, which must be run as root (don't just try prefixing the command with sudo, as the output redirection will fail).
Firstly try the command:
pylint --reports=no --score=n --generate-rcfile > /etc/pylintrc
If that gives you an error "no such option: --score" (which happens with older versions of pylint), try instead
pylint --reports=no --generate-rcfile > /etc/pylintrc
Clone the Jobe project in the web root directory WEBROOT
(usually /var/www/html``). Do not clone it elsewhere and attempt to add it to web root with symbolic links. That breaks the installer. In what follows, replace WEBROOT with either
/var/wwwor `/var/www/html
as appropriate.
To clone Jobe:
cd WEBROOT
sudo git clone https://github.com/trampgeek/jobe.git
Installation is performed by the install script, which must be run as root so that it can add the required jobe run users (jobe00, jobe01, etc) and set-up a jobe-sudoers file in /etc/sudoers.d that allows the web server to execute the runguard program as root and to kill any residual jobe processes from the run.
Before running the install script, you might wish to edit the file
/var/www/html/jobe/app/Config/Jobe.php
Find the line
public int $jobe_max_users = 8;
and decide if that value, which sets the maximum number of jobs that can be run at once, is appropriate for your hardware set up. A rule of thumb is to set this to the number of cores on your machine, but if you plan on running lots of partially-I/O-bound jobs, you could consider larger numbers.
Having set that value to your satisfaction:
cd WEBROOT/jobe
sudo ./install
On Centos6 systems (and possibly early Centos7 releases) you should also comment out the line
Defaults requiretty
in /etc/sudoers. This was (reported as a bug)[https://bugzilla.redhat.com/show_bug.cgi?id=1196451] and was fixed in later RHEL releases.
By default, Apache is configured to use the C locale. This means that programs generating, say, UTF-8 output will fail with an error
UnicodeEncodeError: 'ascii' codec can't encode character ...
If you wish to run UTF-8 code (recommended) you should find the line in the Apache envvars file (on Ubuntu systems this is to be found at /etc/apache2/envvars)
export LANG=C
and change it to either C.UTF-8 (which changes the charset to UTF-8 but leaves other locale settings unchanged) or to the required standard locale value, e.g.
export LANG=en_NZ.UTF-8
Make sure that whatever locale you use is installed on the Jobe server.
Then restart apache with the command
sudo service apache2 restart
Note:
The comment in the Apache envvars file suggesting the use of the default locale probably won't work, as this will also just give you ASCII text.
To take advantage of the UTF-8 capabilities in CodeRunner you will need to use Version 3.3 or later.
For people wanting to get a Jobe server up in hurry, the following is probably the simplest approach. This uses a minimal Digital Ocean virtual machine, to run the Docker JobeInAbox image; you should increase memory and core for production servers. Other cloud servers, such as Amazon ECS, can of course also be used.
At this point you have a running Jobe server on port 80. You can check it's working by browsing to
http://<hostname>/jobe/index.php/restapi/languages
You should get presented with a JSON list of installed languages.
And you can connect your CodeRunner plugin to it by setting the new JobeServer IP number in the Admin panel of the plugin. You're in business!
All that remains is to firewall your new server so that only your Moodle server can use it, and so it can't itself open outgoing connections. For example:
sudo apt install ufw
sudo ufw default reject outgoing
sudo sudo ufw allow in 22/tcp
sudo ufw allow in proto tcp to any port 80 from <your moodle server IP>
sudo ufw enable
The program testsubmit.py allows you to test your jobe server. For information on how to use it run this command on the Jobe server:
python3 testsubmit.py --help
To test the installation, first try running the tester with the command
python3 testsubmit.py
The first time you run this command, the initial step of obtaining all the different versions of all language is slow, as it has to test-drive all compilers and interpreters. Be patient. Results are cached in a file in /tmp so subsequent runs will be much faster, at least until the next reboot, when the list is rebuilt.
All going well, you should then be able to copy the testsubmit.py file to any client machine that is allowed to access the jobe server and rerun the command with a line of the form
python3 testsubmit.py --host='jobe.somehow.somewhere' --port=4000
where the host and port are set to reference the jobe server. In the default install, the port number is 80, and the port parameter can be omitted, but will be needed if the port number is mapped to something different, e.g. by changing the default Apache configuration or when testing Jobe in a container.
To test the performance of your new Jobe server, run the testsubmit program on your client machine again, this time with a --perf command line argument, e.g.
python3 testsubmit.py --perf --host='jobe.somehow.somewhere'
The test will print information on the maximum burst of C compile-and-run submissions the server can handle in isolation and the sustained rate of submissions over a 30 second window by default. The figures you get are upper bounds, since the program being used for testing is a minimal 'hello world' program. It's also possible that the Moodle server cannot deliver jobs to the Jobe server at the maximum rate.
Languages like C, PHP and nodejs have similar performance since the communication and server overheads dominate the performance. For slower languages like C++ and particularly Java however, you will much lower throughput. To test Java, for example, type add the argument 'java' to the above command, i.e.
python3 testsubmit.py --perf --host='jobe.somehow.somewhere' java
WARNING: you should not run the performance test on a live production server, as it repeatedly pushes the server into overload, which will result in other users' jobs also receiving server-overload errors.
Usually Jobe is used as a server for Moodle CodeRunner questions. So once jobe
has been installed and tested with testsubmit.py
it can be used by CodeRunner
questions by plugging the Jobe server hostname into the CodeRunner administrator
settings, replacing the default value of jobe2.cosc.canterbury.ac.nz
.
However, Jobe can also be used standalone. The simpletest.py
program shows
how it can be invoked from a Python client.
Note that the POST request payload must a JSON object with a run_spec attribute as specified in the document restapi.pdf. For example, the following POST data runs the classic C "Hello World" program:
{"run_spec": {"language_id": "c", "sourcefilename": "test.c", "sourcecode": "\n#include <stdio.h>\n\nint main() {\n printf(\"Hello world\\n\");\n}\n"}}
The POST request must have the header
Content-type: application/json; charset-utf-8
and should be sent to a URL like
localhost/jobe/index.php/restapi/runs
For example, the following Linux curl
command runs the C Hello World program:
curl -d '{"run_spec": {"language_id": "c", "sourcefilename": "test.c", "sourcecode": "\n#include <stdio.h>\n\nint main() {\n printf(\"Hello world\\n\");\n}\n"}}' -H "Content-type: application/json; charset-utf-8" localhost/jobe/index.php/restapi/runs
If you wish to update an existing version of Jobe to a new one, first put the
the client Moodle server into maintenance mode. Reboot the Jobe server. Then cd
into the Jobe directory, do a git pull
to update the code, then run the
installer with the --purge option, i.e.
sudo ./install --purge
Check that all is well by testing as in the section "Testing the install" above. Lastly take the Moodle server out of maintenance mode again.
If you have problems installing Jobe, here are some things to check.
If the install script fails, check the error message. You should be able to read through the script and figure out what went wrong. Otherwise ...
Check the install went OK:
If the install appears OK but testsubmit.py fails:
app/writable/logs
.app/Config/Logger.php
,
rerun the failed request and again check the log files.app/Config/Jobe.php
. Find
the run in /home/jobe/runs
and try executing the program manually. [When
debugging is turned on, the
run directory contains the source file, the bash command used to run it,
plus the compile output and (if it ran) the stderr and stdout outputs.If you still can't figure it out, email me (Richard Lobb; my gmail name is trampgeek).
[For paranoid sysadmins only].
Submitted jobs can generally write files only into the temporary directory
created for their run within the /home/jobe/runs`` directory. Exceptions to this rule are the
/tmp,
/var/tmp,
/var/crashand
/run/lock` directories all of which
conventionally can be written into by any Linux process.
The temporary working directory and any files in the writable directories mentioned above are deleted on the termination of the run. However, depending on the size of the various partitions and the allowed maximum run time, it might in principle be possible for a rogue process, or a deliberate attacker, to run the system out of disk space in a particular partition (probably /tmp, which is usually relatively small), before the job terminates. That could in turn impact upon other jobs in progress.
This possibility is considered very remote under normal circumstances. With typical
run times of a few seconds, jobs
time out long before they can fill up a main partition such as that housing
/home/jobe. Filling up /tmp is easier but jobs shouldn't generally be using
that directory, so a rogue process that fills it up shouldn't affect other users. In
either case, the space is freed as soon as the job terminates. Certainly this
is not a problem we have ever observed in
practice. However, it should be possible to protect against such an outcome by
setting disk quotas for the users jobe00, jobe01, ... jobe09 [The number
of such user accounts is defined by the parameter jobe_max_users
in
app/Config/Jobe.php
. The default value is 8.]
Instructions for installing the quota
management system and setting quotas are given in various places on the web, e.g.
here.
The precise details will vary from system to system according to how the disk
partitions are set up; quotas should be
set for all jobe users on whatever partitions contain /home/jobe, /tmp, /var/tmp,
/var/crash and /run/lock.
By default, Jobe is expected to run on an Intranet server that is firewalled to permit access only from specific authorised hosts. In this mode, the client is assumed to be trusted and does not need to provide any form of authorisation or authentication. It is also important to prevent the jobe server from opening connections to other machines, so that a student program cannot do nasty things like port-scanning within your Intranet.
Using ufw (Uncomplicated Firewall) a possible command sequence that will restrict outgoing traffic to just a single nominated host ("some useful ip") on ports 80 and 443, allow ssh access (port 22) from anywhere and web access to jobe (assumed to be on port 80) from just one specified client is the following:
ufw default reject outgoing
ufw allow out proto tcp to <some_useful_ip> port 80,443
ufw allow in 22/tcp
ufw allow in proto tcp to any port 80 from <your_client_ip>
ufw enable
In the above, <your_client_ip> is the host that is permitted to send jobs to Jobe (e.g. a Moodle server with CodeRunner). <some_useful_ip> is any server to which Jobe might need to connect in order to run/grade student code. In the absence of such a server, that line should be omitted.
If you wish Jobe to serve multiple clients and do not wish to open a specific port for each one you will need to configure the firewall to allow incoming connections from anywhere. This of course means that anyone anywhere in the world can connect to your Jobe server to run jobs on it. To reduce the risk of abuse, you should also set up one or more API keys (e.g. one per Moodle client). You might also wish to set a per-hour rate limit on the requests coming in from any particular IP number.
To enable API keys and to set throttle rates, edit the app/Config/Jobe.php
to turn on API keys and set desired throttle rates for each API key. A rate
of 0 means no throttling.
If using API-keys, your CodeRunner plugin(s) will need to be configured with API keys matching those on your Jobe server(s).
If running in API-Key mode, you should still firewall the Jobe server to prevent it opening any sockets to other machines.
Jobe is configured to use the standard port 80 for its RESTful protocol. This is convenient because most servers and proxy servers are configured to allow port 80 traffic. However, some school and university IT departments ban use of port 80 because of the security risks when accessing normal web sites in this way. Jobe is not a normal web site and does not have much in the way of interesting data stored in it or flowing in or out. So, most if not all the security concerns of IT departments relating to the use of port 80 with Jobe are unfounded. However, if your IT department policies are too bureaucratic and intractable, you might need to access Jobe via port 443 (SSL) instead.
The easiest way to achieve this is to use a JobeInABox Docker container on your
Jobe server, running on some port like 5000. Then, assuming the Jobe host server
also runs Apache, enable the site 000-default-le-ssl.conf
and edit the VirtualHost entry
to include lines like
# Proxy configuration for /jobe ...
ProxyPass "/jobe" "http://localhost:5000/jobe"
ProxyPassReverse "/jobe" "http://localhost:5000/jobe"
Then, enable mod proxy, mod_proxy_http and mod_ssl with the commands
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod ssl
and restart Apache.
You will then need to configure the CodeRunner plugin settings in your Moodle server to
prefix the Jobe server name with https://
.
The Jobe REST API specification document defines the format of a so-called run_spec, which is the record/object that is encoded within a POST request or a run request to specify the job details. It includes the language_id, the source code, the source file name, any standard input data, a list of required files and a set of job parameters. The job parameters are not defined by the REST API as they are implementation dependent. This section defines the format of the parameters field of a run_spec in this implementation.
The allowable attributes of the parameters field, plus their global default values in parentheses, are:
Individual languages will usually set their own default values for compileargs and interpreterargs.
If any of the above attributes are defined within the run_spec parameters field, the latter is used and the defaults are ignored.
The default values of compileargs and interpreterargs for the currently-implemented languages are as follows. An empty default means the global default is used.
language_id | language | compileargs | interpreterargs | c | C | ["-Wall", "-Werror", "-std=c99", "-x c"] |
---|---|---|---|
cpp | C++ | ["-Wall", "-Werror"] | |
python2 | Python2 | ["-BESs"] | |
python3 | Python3 | ["-BE"] | |
java | Java | ["-Xrs", "-Xss8m", "-Xmx200m"] | |
nodejs | JavaScript (nodejs) | ["--use_strict"] | |
octave | Octave (matlab variant) | ["--norc", "--no-window-system", "--silent", "-H"] | |
php | PHP | ["--no-php-ini"] | |
pascal | Free Pascal | ["-vew", "-Se"] |
This version of jobe is configured for use by Moodle Coderunner. When using Jobe from CodeRunner the various language compile and run options can be changed via the sandbox Parameters field in the question authoring form (using the advanced customisation capabilities) of either the question prototype or within a particular question as suggested by the previous section. For example, if the sandbox Parameters field is set to
{ "compileargs": ["-Wall", "-Werror", "-std=c89"] }
for a C question, the code will be compiled with all warnings enabled, aborting if any warnings are issued and will need to be C89 compliant.
If you wish to change the existing default options within Jobe, or you wish to add new languages, you must edit the source code as follows.
The folder application/libraries contains all the code that executes submitted jobs. The file LanguageTask.php defines an abstract class Task that contains default configuration parameters for things like memory limit, maximum cpu run time, maximum disk output, etc. For each supported language, a subclass with a name of the form <Language>_Task resides in a file named <language>_task.php. For example, c_task.php contains all the parameters specific to running C tasks, octave_task.php contains parameters for running Octave tasks, etc. To add a new language to Jobe you just drop in a new <language>_task.php file; its presence is autodetected by the Restapi constructor and the language will be available immediately.
Each subclass of LanguageTask typically defines at least the following three methods:
__construct(). This is the constructor. It should generally call the parent constructor then set any language-specific default compile and/or interpret and/or run options.
getVersion(). This returns a string defining what version of the language, compiler etc is supported. It's not actually used by CodeRunner but is available via the rest API.
compile(). Calling this method must result in the file named $this->sourceFileName being compiled, with an executable output file being placed in the current working directory. If compilation succeeds the name of the executable must be returned in $this->executableFileName; alternatively $this->cmpinfo should be set to an appropriate error message; any non-empty string is taken as a compile error. Interpreted languages might do nothing or might copy the program.
getRunCommand(). This method must return an array of strings that, when joined with a space separator, make a bash command to execute the program resulting from the compile(). Execution parameters like the Java heap size are set in this function. The output from this function is passed to the RunguardSandbox, after addition of standard I/O redirection plus other sandbox parameters (see getParam below).
Additionally the subclass may define:
filteredStderr(). This takes $this->stderr and returns a filtered version, which might be necessary in some languages to remove extraneous text or remove special characters like form-feed or tab in order to make the result more appropriate for subsequent use, e.g. for display to students in a CodeRunner result table.
filteredStdout(). This performs the same task as filteredStderr() except it filters stdout, available to the function as $this->stdout.
The following performance measurements were made on a physical 8-core 16GB Intel i5 CPU @1.60GHz Jobe server.
Burst sizes are measured by sending a burst of submissions as fast as possible to the server and then observing whether or not they all run successfully. If so, the burst size is doubled and the test repeated. Thus burst sizes might be low by a factor of 2. Apart from that, however, all figures should be regarded as upper-bounds on performance since the test jobs are of minimal size with minimal communication overhead.
Performance figures on 8-core virtualised servers on enterprise server systems could be 2 or more times higher, depending on the server infrastructure.
Language | Language id | Max burst size (jobs) | Max sustained throughput (jobs/sec) |
---|---|---|---|
C | c | 128 | 18 |
Python3 | python3 | 128 | 18 |
JavaScript | nodejs | 64 | 13 |
C++ | cpp | 32 | 5 |
Java | java | 16 | 2 |
Fixed bug with Java when correct source file name supplied in the request (rename of file to itself was failing). Thanks Paul Denny. Replaced uses of Moodle coding_exception with generic exception. Again thanks Paul Denny.
Fixed bug in C++ task - invalid language type being passed to compiler.
Updated CodeIgniter Rest Server to latest version.
Added code to load limit data from a config file "per_method_limits.php" to support per-API-key limits on the number of calls that can be made to the restapi's POST and PUT entry points per hour. Updated the documentation to explain how to turn on API-key authorisation and per-method limits.
Added code to support CORS (Cross Origin Resource Sharing), i.e., in-browser JavaScript requests from arbitrary domains.
Fixed bug in how Java class names (and hence source file names) were inferred from the source code (main classes that implemented an interface or extended a subclass were not handled correctly). Also the filename field in the REST API runspec is now optional; if provided, it is trusted and used as-is, but if not supplied or if an empty string is supplied, Jobe now calls a language-specific function to provide a filename from the sourcecode. [Usually this is just something generic like prog.cpp, prog.py etc]
Fixed issue with runguard that prevented use of pthreads library in C programs.,
Pascal support added by Fedor Lyanguzov (thanks Fedor)
Good luck!
Minor patches to ensure PHP7 compability. Install instruction in readme.md still relate to PHP5, however.
Change Java config parameters to allow Java 8 to run (more memory and more processes).
Remove inline declaration of readoptarg in runguard.c (causing compile errors with most recent gcc versions). Documentation tweaks.
Fix serious security flaw in runguard + my use of it.
Thanks Kai-Cheung Leung for the first two of those additions.
Thanks Tim Hunt for most of the work in this addition.
Bug fix: Jobe server overload was being incorrectly reported as a Runguard error ("No user jobe-1").
Fix bug in testsubmit.php when used with latest pylint3.
Document dependency script for Ubuntu 18.04 plus limitations due to missing mcrypt.
Add a configuration parameter to config.php to allow users to adjust the maximum time Jobe will wait for a free worker thread before aborting the execution and returning a server-overload response.
Alter the testsubmit program to workaround differences in the way RedHat servers handle process limits, particularly in containerised versions of Jobe.
Add performance measurement code to the testsubmit program.
Add several command-line arguments to make the testsubmit.py program more user-friendly.
Increase memory allocation for Python as jobs continue to grow in memory demand.
Add HTTP return code to the error message on invalid sourcefilename.
Ensure PHP 8.2 compatibility by allowing dynamic properties in the CodeIgniter core and by adding property declarations to Jobe classes.
Increase the backoff from 1 sec to 5 secs when starting the sustained load testing. Otherwise, the first test could fail.
Fix long-standing bug that always applied a compile parameter setting if this was greater than the requested value, even when it wasn't a compile. Hopefully won't break anyone's code (they'd have to have been using very low parameter values).
Bug fix: purge fails if num_jobe_users has been reduced in the config file since the install was run.
Upgrade install to include option to set range of UIDs for Jobe and workers. This should provide a workaround for JobeInABox installs on systems running nginx, which resulted in a UID conflict with the host. Also include a --uninstall option.
Add various tuning parameters for Java to config file. Thanks Marcus Klang.
Ensure that install updates runguard config to allow for a large number of Jobe users (> 20). Thanks Marcus Klang.
Add a main_class parameter to Java task. Thanks Peter Seibel.
Increase default per-run memory allocation from 200 MB to 400 MB. Needed for NodeJS in particular but everything is getting greedier.
This version is a major rewrite, using CodeIgniter version 4 as the framework. The code is very difference but should be functionally mostly the same.
Known differences in functionality.
Configuration is very different, mostly involving editing the file
/var/www/html/jobe/app/Config/Jobe.php
.
python2 is not longer supported.
Rate limiting when using API keys is on a per-IP basis, not world-wide. It uses CodeIgniter 4's 'leaky bucket' algorithm, where the per-hour submission rate limit isn't a simple rate checked each hour but some sort of 'average submission rate' that also allows bursts of up to the maximum per-hour rate in one burst provided there are very long gaps before and after.
Some extra PHP modules are required - see install instructions.
Some minor bug fixes (e.g. bad error message when language unknown) and documentation tweaks. Most significantly, this is when the JobeV2 branch was finally merged into master. Anyone still wanting the old version can clone the JobeV1 branch.
Two bug fixes: use of the 'debugging' configuration parameter was not working and jobe server overloads were generating an erroneous Jobe\Exception not found error.
Minor enhancement: the python3_version config parameter now allows a full path specification rather than requiring that the python interpreter be installed at /usr/bin.
Bug fix: The Language Cache file was getting rebuilt on every task, reducing throughput.
Bug fix: Under some configurations of python3 when using the python3_version config parameter, the current Python version was being incorrectly reported.