• No results found

INGInious Documentation

N/A
N/A
Protected

Academic year: 2022

Share "INGInious Documentation"

Copied!
86
0
0

Loading.... (view fulltext now)

Full text

(1)

INGInious Documentation

Release 0.4

Author

Dec 10, 2017

(2)
(3)

Contents

1 Installation, configuration and upgrade 1

1.1 Installation and deployment . . . 1

1.2 Updating INGInious . . . 7

1.3 Configuration reference . . . 8

1.4 Configuring the LTI frontend . . . 14

1.5 Troubleshooting common problems . . . 16

2 Commands reference 17 2.1 Frontend commands . . . 17

2.2 Backend commands . . . 18

2.3 Task tests commands . . . 20

2.4 Utilities . . . 20

3 Teacher’s documentation 23 3.1 What is INGInious? . . . 23

3.2 Creating a new course . . . 25

3.3 Creating a new task. . . 27

3.4 Creating a new container image . . . 43

3.5 Course administration . . . 44

3.6 Batch containers . . . 48

4 Developer’s documentation 51 4.1 Understand INGInious . . . 51

4.2 Creating plugins . . . 55

4.3 How to extend INGInious . . . 58

4.4 Code documentation . . . 58

5 Indices and tables 75

Python Module Index 77

i

(4)
(5)

CHAPTER 1

Installation, configuration and upgrade

1.1 Installation and deployment

1.1.1 Supported platforms

INGInious is intended to run on Linux (kernel 3.10+), but can also be run on Windows and macOS thanks to the Docker toolbox.

1.1.2 Dependencies setup

INGInious needs:

• Python(with pip) 3.5+

• Docker1.12+

• MongoDB

• Libtidy

• LibZMQ

RHEL/Cent OS 7.0+, Fedora 24+

The previously mentioned dependencies can be installed, for Cent OS 7.0+ :

# curl -fsSL https://get.docker.com/ | sh #This will setup the Docker repo

# yum install -y epel-release https://centos7.iuscommunity.org/ius-release.rpm

# yum install -y git mongodb mongodb-server gcc libtidy python35u python35u-pip

˓→python35u-devel zeromq-devel

Or, for Fedora 24+:

1

(6)

# curl -fsSL https://get.docker.com/ | sh #This will setup the Docker repo

# dnf install -y git mongodb mongodb-server gcc libtidy python3 python3-pip python3-

˓→devel zeromq-devel

You may also add openldap-devel if you want to use the LDAP auth plugin and xmlsec1-openssl-devel libtool-ltdl-develfor the SAML2 auth plugin.

Danger: Due to compatibility issues, it is recommended to disable SELinux on the target machine.

You can now start and enable the mongod and docker services:

# systemctl start mongod

# systemctl enable mongod

# systemctl start docker

# systemctl enable docker

Ubuntu 16.04+

The previously mentioned dependencies can be installed, for Ubuntu 16.04+:

# curl -fsSL https://get.docker.com/ | sh #This will setup the Docker repo

# apt-get install git mongodb gcc tidy python3 python3-pip python3-dev libzmq-dev

You may also add libldap2-dev libsasl2-dev libssl-dev if you want to use the LDAP auth plugin and libxmlsec1-dev libltdl-devfor the SAML2 auth plugin

You can now start and enable the mongod and docker services:

# systemctl start mongodb

# systemctl enable mongodb

# systemctl start docker

# systemctl enable docker

OS X 10.9+

We usebrewto install some packages. Packages are certainly available too via macPorts.

$ brew install mongodb

$ brew install python3

Follow the instruction of brew to enable mongodb.

The next step is to installDocker for Mac.

Windows

Danger: INGInious rely on Docker to run containers. While Docker is supported on Windows 10 (version 1607), INGInious does not provide support for Windows containers yet.

(7)

INGInious Documentation, Release 0.4

The recommended way to run INGInious under Windows is by using a Linux virtual machine, for much more simplic- ity. One can also only run the Docker agent under a Linux virtual machine and run the backend and selected frontend under Windows.

In the later case, you’ll need to install Python 3.5+, MongoDB, LibTidy and LibZMQ.

1.1.3 Installing INGInious

The recommended setup is to install INGInious via pip and the master branch of the INGInious git repository. This allows you to use the latest development version. This version is currently the supported one for issues.

$ pip3 install --upgrade git+https://github.com/UCL-INGI/INGInious.git This will automatically upgrade an existing version.

Note: You may want to enable the LDAP/SAML2 plugin or use (F)CGI instead of the web.py default webserver.

In this case, you have to install more packages: simply add [cgi], [ldap] or [saml2] to the above command, depending on your needs:

$ pip3 install --upgrade git+https://github.com/UCL-INGI/INGInious.git

˓→#egg=INGInious[cgi,ldap]

Some releases are also published on Pipy. However, no support is provided for these versions now. To install the latest previous release:

$ pip3 install --upgrade inginious

1.1.4 Configuring INGInious

INGInious comes with two frontends:

• The LTI frontend, which allows to interface with Learning Management System via theLTIspecification. Any LMS supportingLTIis compatible. This includes Moodle, edX and Coursera, among many others.

• The Web App, a mini-LMS made for on-site courses. It provides statistics, group management, and the INGIn- ious studio, that allows to modify and test your tasks directly in your browser.

You can use one, or both. Each of them have to be configured independently. This can be done automatically with the inginious-installCLI. To configure the LTI frontend:

$ inginious-install lti To configure the Web App frontend:

$ inginious-install webapp

This will help you create the configuration file in the current directory. For manual configuration and details, see Configuration reference.

The detailed inginious-install reference can be found atinginious-install.

1.1. Installation and deployment 3

(8)

1.1.5 Running INGInious

During the configuration step, you were asked to setup either a local or remote backend. In the former case, the frontend will automatically start a local backend and grading agents.

With local backend/agent

To run the frontend(s), please use the inginious-lti or inginious-webapp CLI. This will open a small Python web server and display the url on which it is bind in the console. Some parameters (configuration file, host, port) can be specified. Details are available atinginious-ltiandinginious-webapp.

If you use the LTI frontend, you have to add it to your LMS: follow the instructions inConfiguring the LTI frontend.

With remote backend/agent

To run INInious with a remote backend (and agents), do as follows:

1. On the backend host, launch the backend (seeinginious-backend) :

inginious-backend tcp://backend-host:2001 tcp://backend-host:2000

The agents will connect on tcp://backend-host:2001 and clients on tcp://backend-host:2000 2. Possibly on different hosts, launch the Docker and MCQ agents (see inginious-agent-dockerandinginious-

agent-mcq) :

inginious-agent-docker tcp://backend-host:2001 inginious-agent-mcq tcp://backend-host:2001

3. In you INGInious frontend configuration file (seeConfiguration reference), set backend to : backend: tcp://backend-host:2000

4. Run your preferred frontend usinginginious-ltioringinious-webapp(or both).

1.1.6 Webterm setup

An optional web terminal can be used with INGInious to load the remote SSH debug session. This rely on an external tool.

To install this tool :

$ git clone https://github.com/UCL-INGI/INGInious-xterm

$ cd INGInious-xterm && npm install You can then launch the tool by running:

$ npm start bind_hostname bind_port debug_host:debug_ports

This will launch the app on http://bind_hostname:bind_port. The debug_host and debug_ports parameters are the debug paramaters on the local (seeConfiguration reference) or remote (seeinginious-agent-docker) Docker agent.

To make the INGInious frontend aware of that application, update your configuration file by setting the webterm field to http://bind_hostname:bind_port (seeConfiguration reference).

(9)

INGInious Documentation, Release 0.4

For more information on this tool, please seeINGInious-xterm. Please note that INGInious-xterm must be launched using SSL if the frontend is launched using SSL.

1.1.7 Webserver configuration

Warning: In configurations below, environment variables accessible to the application must be explicitly repeated.

If you use a local backend with remote Docker daemon, you may need to set the DOCKER_HOST variable. To know the value to set, start a terminal that has access to the docker daemon (the terminal should be able to run docker info), and write echo $DOCKER_HOST. If it returns nothing, just ignore this comment. It is possible that you may need to do the same for the env variable DOCKER_CERT_PATH and DOCKER_TLS_VERIFY too.

Using lighttpd

In production environments, you can use lighttpd in replacement of the built-in Python server. This guide is made for CentOS 7.x.

Install lighttpd with fastcgi:

# yum install lighttpd lighttpd-fastcgi

Add the lighttpd user in the necessary groups, to allow it to launch new containers and to connect to mongodb:

# usermod -aG docker lighttpd

# usermod -aG mongodb lighttpd

Create a folder for INGInious, for example /var/www/INGInious, and change the directory owner to lighttpd:

# mkdir -p /var/www/INGInious

# chown -R lighttpd:lighthttpd /var/www/INGInious

Put your configuration file in that folder, as well as your tasks, backup, download, and temporary (if local backend) directories (seeConfiguring INGIniousfor more details on these folders).

Once this is done, we can configure lighttpd. First, the file /etc/lighttpd/modules.conf, to load these modules:

server.modules = (

"mod_access",

"mod_alias"

)

include "conf.d/compress.conf"

include "conf.d/fastcgi.conf"

You can then replace the content of fastcgi.conf with:

server.modules += ( "mod_fastcgi" ) server.modules += ( "mod_rewrite" ) alias.url = (

"/static/webapp/" => "/usr/lib/python3.5/site-packages/inginious/frontend/webapp/

˓→static/",

"/static/common/" => "/usr/lib/python3.5/site-packages/inginious/frontend/common/

˓→static/"

)

1.1. Installation and deployment 5

(10)

fastcgi.server = ( "/inginious-webapp" =>

(( "socket" => "/tmp/fastcgi.socket",

"bin-path" => "/usr/bin/inginious-webapp",

"max-procs" => 1,

"bin-environment" => (

"INGINIOUS_WEBAPP_HOST" => "0.0.0.0",

"INGINIOUS_WEBAPP_PORT" => "80",

"INGINIOUS_WEBAPP_CONFIG" => "/var/www/INGInious/configuration.yaml",

"REAL_SCRIPT_NAME" => ""

),

"check-local" => "disable"

)) )

url.rewrite-once = (

"^/favicon.ico$" => "/static/common/icons/favicon.ico",

"^/static/(.*)$" => "/static/$1",

"^/(.*)$" => "/inginious-webapp/$1"

)

Replace webapp by lti if you want to use theLTI frontend.

The INGINIOUS_WEBAPP or INGINIOUS_LTI (according to your config) prefixed environment variables are used to replace the default command line parameters. Seeinginious-ltiandinginious-webappfor more details.

The REAL_SCRIPT_NAME environment variable must be specified under lighttpd if you plan to access the application from another path than the specified one. In this case, lighttpd forces to set a non-root path /inginious-webapp, while a root access if wanted, in order to serve static files correctly. Therefore, this environment variable is set to an empty string in addition to the rewrite rule.

Finally, start the server:

# systemctl enable lighttpd

# systemctl start lighttpd

Using Apache

You may also want to use Apache. You should install mod_wsgi. WSGI interfaces are supported through inginious- webappand inginious-lti scripts. This guide is made for CentOS 7.x.

Install the following packages (please note that the Python3.5+ version of mod_wsgi is required):

# yum install httpd httpd-devel

# pip3.5 install mod_wsgi

Add the apache user in the necessary groups, to allow it to launch new containers and to connect to mongodb:

# usermod -aG docker apache

# usermod -aG mongodb apache

Create a folder for INGInious, for example /var/www/INGInious, and change the directory owner to apache:

# mkdir -p /var/www/INGInious

# chown -R apache:apache /var/www/INGInious

(11)

INGInious Documentation, Release 0.4

Put your configuration file in that folder, as well as your tasks, backup, download, and temporary (if local backend) directories (seeConfiguring INGIniousfor more details on these folders).

Set the environment variables used by the INGInious CLI scripts in the Apache service environment file (seelighttpd for more details):

# cat << EOF >> /etc/sysconfig/httpd

INGINIOUS_WEBAPP_CONFIG="/var/www/INGInious/configuration.yaml"

INGINIOUS_WEBAPP_HOST="0.0.0.0"

INGINIOUS_WEBAPP_PORT="80"

EOF

# rm /etc/httpd/conf.d/welcome.conf

Please note that the service environment file /etc/sysconfig/httpd may differ from your distribution and wether it uses systemd or init.

You can then modify your /etc/httpd/conf/httpd.conf file to apply the following rules:

LoadModule wsgi_module /usr/lib64/python3.5/site-packages/mod_wsgi/server/mod_wsgi-

˓→py35.cpython-35m-x86_64-linux-gnu.so

WSGIScriptAlias / "/usr/bin/inginious-webapp"

WSGIScriptReloading On

Alias /static/common /usr/lib/python3.5/site-packages/inginious/frontend/common/

˓→static/

Alias /static/webapp /usr/lib/python3.5/site-packages/inginious/frontend/webapp/

˓→static/

Alias /static/lti /usr/lib/python3.5/site-packages/inginious/frontend/lti/static/

<Directory "/usr/bin">

<Files "inginious-webapp">

Require all granted

</Files>

</Directory>

<DirectoryMatch "/usr/lib/python3.5/site-packages/inginious/frontend/(.+)/static/">

Require all granted

</DirectoryMatch>

Please note that the compiled wsgi module path may differ according to the exact Python version you are running.

1.2 Updating INGInious

1.2.1 Updating the sources

To fetch the latest updates on the Git repository master branch :

$ pip3 install --upgrade git+https://github.com/UCL-INGI/INGInious.git If you installed INGInious via Pipy, you can simply upgrade it using:

$ pip3 install --upgrade inginious

1.2. Updating INGInious 7

(12)

1.2.2 Updating your containers

The provided containers can be automatically updated using:

$ inginious-container-update

For your own or third-party containers, please refer toCreating a new container image.

1.2.3 Updating the configuration

Most of the time, you won’t need to update your configuration. If something goes wrong, backup your existing configuration file(s) and run inginious-install again. For further details, please refer toinginious-installor Configuration reference.

1.3 Configuration reference

Hint: The best way to configure INGInious is to use inginious-install. SeeConfiguring INGInious.

Configuring INGInious is done via a file named configuration.yaml or configuration.lti.yaml. To get started, files named configuration.example.yaml and configuration.lti.example.yaml are provided.

The different entries are :

tasks_directory The path to the directory that contains all the task definitions, grouped by courses. (seeCreat- ing a new task)

backend The link to the backend used. You can either set it to local or indicate the address of your manually- managed backend.

• local. In this mode, which is the default, you have to ensure the docker daemon is local to your machine, or, at least, share the same directory structure. This is typically the case if you use Linux and have a local Docker daemon, or if you use Docker for Mac/Windows, or even docker-machine with local machines.

This is the configuration described in this tutorial. You will need a running docker daemon on your machine for this to work. If you can use any Docker client command, like docker info, INGInious should run flawlessly.

In this mode, a supplementary config option is available, local-config.

• tcp://xxx.yyy.zzz.aaa:bbbb, udp://xxx.yyy.zzz.aaa:bbbb or ipc:///path/to/

your/sock, where the adresses are the ip/socket path of the backend you started manually. This is for advanced users only. See commands inginious-backend and inginious-agent for more information.

local-config These configuration options are available only if you set backend:local.

concurrency Number of concurrent task that can be run by INGInious. By default, it is the number of CPU in your host.

debug_host Host to which the users should connect in order to access to the debug ssh for containers. Most of the time, just do not indicate this option: the address will be automatically guessed.

debug_ports Range of port, in the form 64100-64200, to which INGInious can bind SSH debug contain- ers, to allow remote debugging. By default, it is 64100-64200.

(13)

INGInious Documentation, Release 0.4

tmp_dir A directory whose absolute path must be available by the docker daemon and INGInious at the same time. By default, it is ./agent_tmp.

mongo_opt MongoDB client configuration.

host MongoDB server address. If your database is user/password-protected, use the following syntax:

mongodb://USER:PASSWORD@HOSTNAME/DB_NAME

database You can change the database name if you want multiple instances or in the case of conflict.

log_level Can be set to INFO, WARN, or DEBUG. Specifies the logging verbosity.

use_minified_js Set to true to use the minified version of Javascript scripts, false otherwise.

webterm Link to the INGInious xterm app with the following syntax: http[s]://host:port. If set, it allows to use in-browser task debug via ssh. (See _webterm_setup for more information)

plugins A list of plugin modules together with configuration options. SeePluginsfor detailed information on available plugins, including their configuration. Please note that the usage of at least one authentication plugin is mandatory for the webapp.

1.3.1 Webapp-specific configuration

superadmins A list of super-administrators who have admin access on the whole stored content.

maintenance Set to true if the webapp must be disabled.

backup_directory Path to the directory where are courses backup are stored in cases of data wiping.

smtp Mails can be sent by batch containers at the end of the job execution, or by plugins.

sendername Email sender name, e.g. : INGInious <[email protected]>

host SMTP server.

port SMTP port.

username SMTP username.

password SMTP password.

starttls Set to true if TLS is needed.

1.3.2 LTI-specific configuration

The LTI interface uses most of the same configuration options as the webapp as well as the following:

lti A list of LTI consumer key and secret values.

lti_user_name The LTI field used to identify the user. By default this is user_id, which for many LMS system would be the numeric ID of the user. It can be set to ext_user_username which is often a unique username.

download_directory The path to the directory where downloads are stored temporarily during the archive is being prepared.

1.3.3 Plugins

Several plugins are available to complete the INGInious feature set. Some of them are only compatible with the webapp, while others are compatible with both webapp and LTI application.

1.3. Configuration reference 9

(14)

Auth plugins (webapp)

You need at least one auth plugin activated.

demo_auth

Provides a simple authentification method, mainly for demo purposes, with username/password pairs stored directly in the config file.

To enable this plugin, add to your configuration file:

plugins:

- plugin_module: inginious.frontend.webapp.plugins.auth.demo_auth users:

username1: "password1"

username2: "password2"

username3: "password3"

Each key/value pair in the users field corresponds to a new username/password user.

ldap_auth

Uses an LDAP server to authenticate users.

To enable this plugin, add to your configuration file:

plugins:

- plugin_module: inginious.frontend.webapp.plugins.auth.ldap_auth host: "your.ldap.server.com"

encryption: "ssl" #can be tls or none

base_dn: "ou=People,dc=info,dc=ucl,dc=ac,dc=be"

request: "uid={}", prefix: "",

name: "INGI Login", require_cert: true

Most of the parameters are self-explaining, but:

request is the request made to the LDAP server to search the user to authentify. “{}” is replaced by the username indicated by the user.

prefix a prefix that will be added in the internal username used in INGInious. Useful if you have multiple auth methods with usernames used in more than one method.

saml2_auth

Uses a SAML2-compliant identity provider (such as Shibboleth IdP) to authenticate users.

To enable this plugin, add to your configuration file:

plugins:

- plugin_module: inginious.frontend.webapp.plugins.auth.saml2_auth strict: true

sp:

entityId: "<your_entity_id>"

x509cert: "<your_cert>"

(15)

INGInious Documentation, Release 0.4

privateKey: "<your_private_key>"

idp:

entityId: "https://idp.testshib.org/idp/shibboleth"

singleSignOnService:

url: "https://idp.testshib.org/idp/profile/SAML2/Redirect/SSO"

binding: "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"

x509cert: "<idp_cert>"

additionalX509certs:

- "<idp_cert>"

security:

metadataValidUntil: ""

metadataCacheDuration: ""

attributes:

cn: "urn:oid:2.5.4.3"

email: "urn:oid:1.3.6.1.4.1.5923.1.1.1.6"

uid: "urn:oid:0.9.2342.19200300.100.1.1"

Your IdP is required to provide at least attributes corresponding to the username, the complete name and the email address. Use the attributes entry for the mapping. The additionalX509certs is a plugin-specific entry to specify several certificates in case your IdP is able to use more than one.

This plugin mainly relies onpython3-samlpackage and configuration parameters are interoperable. Please refer to the package documentation for more detailed configuration parameters. The SP Attribute Consuming Service (ACS) is automatically configured by the plugin.

db_auth

Uses the MongoDB database to authenticate users. Provides a basic email-verification based registration and password recovery. It does not support manual user management yet. The superadmin has to register the same way other users do.

To enable this plugin, add to your configuration file:

plugins:

- plugin_module: inginious.frontend.webapp.plugins.auth.db_auth allow_deletion: true

For mails to be sent by the registration module, you need to configure the smtp parameter of your configuration file.

allow_deletionparameter can be used to specify if users can delete their accounts from INGInious.

Scoreboard plugin (webapp)

This plugin allows to generate course/tasks scoreboards. To enable the plugin, add to your configuration file:

plugins:

- plugin_module: inginious.frontend.webapp.plugins.scoreboard

To define a new scoreboard, an additional field scoreboard must be defined in the course.yaml file associated to a course (SeeCreating a new course). For instance:

scoreboard:

- content: ["taskid1"]

name: "Scoreboard task 1"

- content: ["taskid2", "taskid3"] # sum of both score is taken as overall score name: "Scoreboard for task 2 and 3"

1.3. Configuration reference 11

(16)

- content: {"taskid4": 2, "taskid5": 3} # overall score is 2*score of taskid4 +

˓→3*score of taskid5

name: "Another scoreboard"

reverse: True

This defines three scoreboards for the course. The first one will create a scoreboard for task id taskid1 and will be displayed as Scoreboard task 1. The second one will create a scoreboard for taskid2 and taskid3 where both scores are added. The last one is more complex and will create a reversed scoreboard for task taskid4 and taskid5where both scores are wieghted by factor 2 and 3, respectively.

The score used by this plugin for each task must be generated via a key/value custom feedback (seefeedback-custom) using the score key. Only the succeeded tasks are taken into account.

Contests plugin (webapp)

This plugin allows to manage an ACM/ICPC like contest inside a course between students. To enable the plugin, add to your configuration file:

plugins:

- plugin_module: inginious.frontend.webapp.plugins.contests

A new configuration page named Contest appears on the administration page. To enable the contest mode, check the Enable contest pluginbox on the appropriate course. Please note that the plugin will override the task accessibility dates.

Simple grader plugin (webapp, lti)

This simple grader allows anonymous POST requests without storing submissions in database.

To enable the plugin, add to your configuration file:

plugins:

- plugin_module: inginious.frontend.webapp.plugins.simple_grader courseid : "external"

page_pattern: "/external"

return_fields: "^(result|text|problems)$"

• courseid is the course id you want to expose to the simple grader.

• page_pattern is the URL at which you want to make the simple grader available.

• return_fields is a regular expression matching the submission fields that can be returned via the simple grader.

A demonstration POST form will be available at the page_pattern specified URL.

New synchronized job

External submissions must take the form of a POST request on the url defined by page_pattern. This POST must contains two data field:

• taskid: the task id of the task

• input: the input for the task, in JSON. The input is a dictionary filled with problemid:problem_answer pairs.

(17)

INGInious Documentation, Release 0.4

The return value will contains the standard return fields of an INGInious inginious.backend job plus a “status” field that will contain “ok”.

If an internal error occurs, it will return a dictionary containing {

"status": "error",

"status_message": "A message containing a simple description of the error"

}

New asynchronous job

This POST request allows new jobs to be treated asynchronously. It must contains three data fields:

• taskid: the task id of the task

• input: the input for the task, in JSON. The input is a dictionary filled with problemid:problem_answer pairs.

• async: field that indicate that the job must be launched asynchronously. Only have to be present, content is not read.

The return value will be a dictionnary containing:

{

"status": "done",

"jobid": "the jobid of the async job. Will be needed to get the results."

} or {

"status": "error",

"status_message": "A message describing the error"

}

Get status of asynchronous job

Given a jobid in input (as field of the POST request) and will return either:

{

"status": "waiting"

} or {

"status": "error",

"status_message": "A message describing the error"

} or {

"status": "done",

"...":"..."

}

1.3. Configuration reference 13

(18)

where ... are the results of the job, as defined in the return_fields configuration value.

Git Repo plugin (webapp, lti)

This plugin allows saving submissions history in a Git repository, according to the following path pattern : courseid/taskid/username. The version kept in the head of branch is the latest submission made.

To enable this plugin, add to your configuration file:

plugins:

- plugin_module: inginious.frontend.webapp.plugins.git_repo repo_directory: "./repo_submissions"

The repo_directory parameter specify the path to the repository that must be initialized before configuration.

Task file readers plugin (webapp, lti)

It is possible to store task files in other formats than YAML. However, these plugins are provided for retro- compatibility with previous supported formats, which are deprecated. You therefore use these plugins at your own risks.

JSON

To enable the JSON task file format:

plugins:

- plugin_module: inginious.frontend.webapp.plugins.task_file_readers.json_reader

RST

To enable the reStructuredText task file format:

plugins:

- plugin_module: inginious.frontend.webapp.plugins.task_file_readers.rst_reader

1.4 Configuring the LTI frontend

In order to use the LTI frontend with your favorite LMS, you first have to define your LTI keys (consumer key and secret), then installing them on your LMS.

1.4.1 Defining your LTI keys

The LTI keys are defined in the configuration file of the LTI frontend, usually configuration.lti.yaml. Here is an example of configuration:

lti:

consumer_key_1:

secret: a_very_secret_password consumer_key_2:

(19)

INGInious Documentation, Release 0.4

secret: wow_such_secret courses:

- my_course

This obviously defines two LTI keys, consumer_key_1 and consumer_key_2, with passwords a_very_secret_passwordand wow_such_secret.

By default, consumer keys allow accessing all courses data from the consumer. If you want a consumer to be restricted to only one course data, use the courses field and specify the list of courses to give access to. This is illustrated in the example with consumer_key_2.

1.4.2 Setting up your LMS

Setting up (Open) edX

edX providesa good tutorial on how to install LTI components.

When it asks for the LTI passport, you have to enter it in the format

an_id_that_you_define:consumer_key:password. A good example, taking values from the start of this document, would be

inginious:consumer_key_1:a_very_secret_password

The launch url is, if your server is located at https://HOST:PORT/, and you want to load the task task_id from the course course_id:

https://HOST:PORT/launch/course_id/task_id

Please note that, for now, official edX needs https. You also need to set the LTI activity to accept a score back from INGInious, without which the activity won’t launch.

Setting up Moodle

Under edition mode, select add an activity, choose external tool, and confirm.

Directly click on Show more.... Fill in the activity name.

The Launch URL is, if your server is located at https://HOST:PORT/, and you want to load the task task_id from the course course_id:

https://HOST:PORT/launch/course_id/task_id

For the field Launch Container, the best value is “Embded without block”. Consumer key and Consumer secretare the LTI key you defined earlier. In the Privacy fieldset, verify that accept grades from the toolis checked. Leave the other fields blank (or modify them as you want).

Save, and it should work.

Setting up other LMS

INGInious has only been tested with edX and Moodle, but it should work out-of-the-box with any LMS that respects LTI 1.1. You are on your own for the configuration, though; but with the LTI keys and the launch URL, it should be enough to configure anything.

1.4. Configuring the LTI frontend 15

(20)

1.5 Troubleshooting common problems

1.5.1 Solving problems hangs, on OS X with docker-machine or VirtualBox to run Docker

There is a known problem with VirtualBox shared folders: it is impossible for the VM to create a unix socket inside (for strange reasons). To solve this, you can mount instead your /Users directory using docker-machine-nfs:

1.5.2 LTI grades are not pushed back using LetsEncrypt

INGInious uses PyLTI which uses oauth, oauth2 and libhttp2. The list of certificate authorities known to libhttp2 may be out of day with your host operating system. In particular, as of August 2016, it does not include the LetsEncrypt CA, and thus websites protected with a LetsEncrypt certificate won’t work (you won’t be able to push grades back).

1.5.3 LTI frontend keeps on OAuth errors

LTI uses OAuth which uses time-based replay prevention. You need to insure that your webserver (LTI consumer) and LTI producer have reasonably synchronous clocks.

1.5.4 Impossible to get the LTI frontend work

You may find http://ltiapps.net/test/tp.php and http://ltiapps.net/test/t.php useful when debugging producers and con- sumers.

(21)

CHAPTER 2

Commands reference

2.1 Frontend commands

2.1.1 inginious-install

Assistant to create a complete configuration file for the specified frontend.

Read and follow screen instructions.

inginious-install [-h] [--file FILE] {lti,webapp}

--file

Specify the configuration file to use. By default, it is configuration.yaml or configuration.lti.yaml, depending on which backend you use

-h, --help

Display the help message.

lti, webapp

The frontend to install

2.1.2 inginious-webapp

Starts the Web App Frontend. This command can run a standalone web server (see --host and --port options), but also as a FastCGI backend.

inginious-webapp [-h] [--config CONFIG] [--host HOST] [--port PORT]

--config

Specify the configuration file to use. By default, it is configuration.yaml or configuration.json, depending on which is found first. This can also be specified via the INGINIOUS_WEBAPP_CONFIG environment variable.

17

(22)

--host HOST

Specify the host to which to bind to. By default, it is localhost. This can also be specified via the INGINIOUS_WEBAPP_HOSTenvironment variable.

--port PORT

Specify the port to which to bind to. By default, it is 8080. This can also be specified via the INGINIOUS_WEBAPP_PORTenvironment variable.

-h, --help

Display the help message.

2.1.3 inginious-lti

Starts the LTI Frontend. This command can run a standalone web server (see --host and --port options), but also as a FastCGI backend.

inginious-lti [-h] [--config CONFIG] [--host HOST] [--port PORT]

--config

Specify the configuration file to use. By default, it is configuration.lti.yaml. This can also be specified via the INGINIOUS_LTI_CONFIGenvironment variable.

--host HOST

Specify the host to which to bind to. By default, it is localhost. This can also be specified via the INGINIOUS_LTI_HOSTenvironment variable.

--port PORT

Specify the port to which to bind to. By default, it is 8080. This can also be specified via the INGINIOUS_LTI_PORTenvironment variable.

-h, --help

Display the help message.

2.2 Backend commands

2.2.1 inginious-agent-docker

Start a Docker grading agent. This is typically only used when running the INGInious backend remotely. If you configured INGInious to use a local backend, it is automatically run by inginious-webapp or inginious-lti.

inginious-agent-docker [-h] [--debug-host DEBUG_HOST]

[--debug-ports DEBUG_PORTS] [--tmpdir TMPDIR]

[--tasks TASKS] [--concurrency CONCURRENCY] [-v]

backend -h, --help

Display the help message.

--debug-host DEBUG_HOST

The agent hostname for SSH debug. If not specified, the agent autodiscover the public IP address.

--debug-ports DEBUG_PORTS

Range of port for job remote debugging. By default it is 64120-64130 --tmpdir TMPDIR

Path to a directory where the agent can store information, such as caches. Defaults to ./agent_data

(23)

INGInious Documentation, Release 0.4

--tasks TASKS

The path to the directory containing the courses. Default to ./tasks.

--concurrency CONCURRENCY

Maximal number of jobs that can run concurrently on this agent. By default, it is the two times the number of cores available.

-v, --verbose

Increase output verbosity: logging level to DEBUG.

backend

The backend port, using the following syntax : protocol://host:port. E.g. tcp://127.0.0.

1:2001. The agent will connect to the backend listening on that port.

2.2.2 inginious-agent-mcq

Start a MCQ grading agent. This is typically only used when running the INGInious backend remotely. If you configured INGInious to use a local backend, it is automatically run by inginious-webapp or inginious-lti.

inginious-agent-mcq [-h] [--tasks TASKS] [-v] backend -h, --help

Display the help message.

--tasks TASKS

The path to the directory containing the courses. Default to ./tasks.

-v, --verbose

Increase output verbosity: logging level to DEBUG.

backend

The backend port, using the following syntax : protocol://host:port. E.g. tcp://127.0.0.

1:2001. The agent will connect to the backend listening on that port.

2.2.3 inginious-backend

Start an INGInious backend. This is typically only used when running the INGInious backend remotely. If you configured INGInious to use a local backend, it is automatically run by inginious-webapp or inginious-lti.

inginious-backend [-h] [-v] agent client -h, --help

Display the help message.

-v, --verbose

Increase output verbosity: logging level to DEBUG.

agent

The agents port, using the following syntax : protocol://host:port. E.g. tcp://127.0.0.1:2001.

The backend will listen for grading agents on that port.

client

The clients port, using the following syntax : protocol://host:port. E.g. tcp://127.0.0.

1:2000. The backend will listen for client frontend on that port.

2.2. Backend commands 19

(24)

2.3 Task tests commands

2.3.1 inginious-check-task

Verify the syntax and the parameters of a course/task file.

inginious-check-task [-h] [--taskdir TASKDIR] course task -h, --help

Display the help message.

--taskdir TASKDIR

The path to the directory containing the courses. Default to ./tasks.

course

The course id to test --port PORT

The task id to test

2.3.2 inginious-test-task

Replay a task with the set of .test files available in the task folder and checks if results are identical. If results differ, detailed information are printed on the terminal.

The .test files can be obtained by downloading a valid submission and storing the .test file found in the downloaded archive in the task folder.

inginious-test-task [-h] [-c CONFIG] [-v] courseid taskid -h, --help

Display the help message.

-c, --config

Specify the INGInious config file to use. If not specified, looks for a configuration file in the current directory -v, --verbose

Increase output verbosity: display entire stdout/stderr.

courseid

The course id corresponding to the task to test.

taskid

The task id corresponding to the task to test.

2.4 Utilities

2.4.1 inginious-synchronize

Synchronization tool for INGInious Git repos. Each repository is suppposed to content the files required for a course.

When run, the tool pulls the modifications done remotely and force-merge the the local version if conflicts cannot be resolved automatically.

(25)

INGInious Documentation, Release 0.4

A configuration file synchronize.json must be provided or specified using environment variable INGINIOUS_SYNC_CONFIG. This file contains the main task directory as well as the course identifier, private key for pulls and repo url, as follows:

{

"maindir":"../tasks",

"repos":

[ {

"course":"TEST0000",

"keyfile":"TEST0000.key",

"url":"[email protected]:user/TEST0000.git"

}, {

"course":"TEST0001",

"keyfile":"TEST0001.key",

"url":"[email protected]:user/TEST0001.git"

} ] }

For more compatibility, please run this command in an ssh-agent session.

Before adding in crontab, add the following lines to .ssh/config for user who runs the scripts : Host *

StrictHostKeyChecking no

This tells SSH not to check host keys, we always trust the remote servers

2.4.2 inginious-old-task-converter

Convert old tasks (in .json or .rst format) to the newer format, .yaml. You will probably not need this command.

inginious-old-task-converter [-h] [--delete-html] [--convert-yaml] tasks -h, --help

Display the help message.

--delete-html

Delete*IsHTML fields. Default to false --conver-yaml

Force conversion to YAML. Default to false tasks

The path to the directory containing the courses.

2.4.3 inginious-containers-update

Update all the containers created and/or maintained by the INGInious team.

Takes no argument, but needs a properly configured Docker environment. If you use a remote Docker instance, please check the DOCKER_HOST environment variable.

2.4. Utilities 21

(26)
(27)

CHAPTER 3

Teacher’s documentation

Contents:

3.1 What is INGInious?

INGInious provides a simple and secure way to execute and test untrusted code. It has been developed by theINGI department (Université catholique de Louvain) to automatic grading of programming assignments. The whole tool is written inPython(version 3.5+) and relies onDockerto provide secure execution environments and onMongoDBto keep track of submissions.

INGInious is completely language-agnostic and is able to run anything. Currently, this is limited to Linux programs as only Linux containers are provided and supported.

INGInious also provides anLTImodule, allowing its integration to your existing (Open)edX,Moodle,... courses.

3.1.1 How does INGInious work?

INGInious is based on the concept of tasks (see Creating a new task). A task is a set of one or more related (sub)questions. For each task, an infinite number of submissions is allowed, but a user must wait for the result of its current submission before trying a new one.

For simplicity, tasks are grouped by courses (seeCreating a new course). Usually, an INGInious course has one task per assignment.

A submission is a set of deliverables (chunks of code, files, archives, etc.) that correspond each to one of the (sub)questions of the task. These files are made available to the run file (see Run file), a special script provided by the task. That script is responsible for providing feedback on the submission by compiling, executing or applying any form of checking and testing to the deliverables. In its simplest form, the feedback consists of either success or failed.

This run file is run inside a container (precisely, a grading container), that completely jails the execution of the script, because even teachers and assistants are never fully trusted. Grading containers are able to start sub-containers, called student containers, that runs the scripts that the students sent with their submission, in another jailed environment.

23

(28)

This separation in two step of the grading is mandatory to ensure a complete security for the server hosting INGInious and a complete security of the grading process, making impossible for the student to interact “badly” with the run script.

These containers are created/described by very simple files called Dockerfile. They allow to create containers for anything that runs on Linux. For details about to create new containers and add new languages to INGInious, see Creating a new container image.

Architecture

INGInious comes with three distinct parts, the backend (and its agent) and a frontend.

The backend (see ../dev_doc/backend) receives the code of the students and sends it to its agent (see ../dev_doc/agent), which is then responsible to send it to a Dockercontainer, and interact with the request made by the container.

That container then makes some verifications on the submission and returns one of the following four possible status : success, crash, timeout, or failed.

INGInious also provides a frontend (see ../dev_doc/frontend). Made with MongoDB as database, the frontend is in fact an extension of the backend and allows students to work directly on a website. This frontend also provides statistics and management tools for the teachers.

Most of these functionalities can be extended through plugins.

For a more advanced view of the architecture of INGInious, seeUnderstand INGInious.

Docker containers

Docker containers are small virtual operating systems that providesisolationbetween the processes and resources of the host operating system. Docker allow to create and ship any software on any free Linux distribution.

As there are no hypervisor, the processes launched in the container are in fact directly run by the host operating system, which allows applications to be amazingly fast.

Docker allow teachers to build new containers easily, to add new dependencies to the tests applied on the student’s code (seeCreating a new container image)

Isolation

Isolation allows teachers and system administrators to stop worrying about the code that the students provides.

For example, if a student provides a forkbomb instead of a good code for the test, the forkbomb will be contained inside the container. The host operating system (the computer that runs INGInious) won’t be affected.

The same thing occurs with memory consumption and disk flood. The running time of a code is also limited.

3.1.2 Compatibility

INGInious provides two compatibility layers with Pythia v0 and v1. Except the task description file which has to be updated, everything is 100% compatible with INGInious.

(29)

INGInious Documentation, Release 0.4

3.2 Creating a new course

Courses are defined by subdirectories found in the tasks directory, which has been specified in the configuration. See Configuration reference. These subdirectories are composed of a course.yaml file describing the course parameters and other subdirectories corresponding to tasks (SeeCreating a new task).

Here is an example of the content of a tasks folder:

tasks/

course_id_1/

course.yaml task_id_1/

task.yaml run ...

...

...

Ideally, you should only give permissions to a course folder to the course administrator if needed. The webapp task editor should not require you to give this access. If needed, several methods exist. Seeinginious-synchronizefor Git repository synchronization.

3.2.1 Tutorial

Creating courses is reserved to the super-administrators (SeeConfiguration reference). Course administrators are then able to configure the course by themselves.

Note: Demonstration tasks are made available for downloadhere. They can also be downloaded and installed automatically via theinginious-installscript.

Using the webapp

1. As a super-administrator, go to the bottom of the course list and enter a new course id, for instance demo, and click on Create new course. A newly created hidden course named demo appears on the list.

2. Click on that course, and then on Course administration to change the course parameters, add course adminis- trators and tasks.

Please note that, if you give access to the course directory to course administrators, you still have to do some manual work for this to be effective.

Manually

The course description is a YAML file containing all the course parameters used by INGInious. Here is a simple course description. Put this file with the name course.yaml in a newly created demo folder in your tasks directory.

name: "[DEMO] Demonstration course"

admins:

- demouser

This elementary course description file will make a new publicly visible course with id demo appear as [DEMO]

Demonstration courseon the course list.

3.2. Creating a new course 25

(30)

3.2.2 Course description files

Inside the task folder, courses are identified by subdirectories name by their course id and containing a course.yaml file. For instance, this file, for a course with id courseid1, should be placed in a courseid1 subdirectory.

course.yamlis a YAML file containing the course configuration.

admins:

- demouser

name: "[DEMO] Demonstration course"

tutors: []

groups_student_choice: false use_classrooms: true

accessible: true registration: true

registration_password: null registration_ac: null

While the course.yaml file must be present at the course root dir, all the fields inside are actually only used by the webapp. Here are the possible fields to set:

• name Displayed name of the course on the course list.

• admins List of administrators usernames. These users will have complete administrations right on the course.

• tutors List of tutors usernames (restricted-rights teaching assistants). These users will have read-only rights on the course content. They cannot change course parameters nor tasks, cannot replay submissions, launch batch operations or wipe the course data. However, they can manage the classroom composition and download all the student submissions.

• accessible When this field is defined, the course is only visible if within the defined period. A course is always accessible to its admins, and is only hidden to normal users, even if they are registered to the course.

This field can contain theses values:

true the task is always accessible;

false the task is never accessible;

"<start>/<end>" where <start> and <end> are either empty or valid dates like “2014-05-10 10:11:12” or

“2014-06-18”. The task is only accessible between <start> and <end>. If one of the values is empty, the corresponding limit does not apply.

Dates are always considered as a precise instant (to te lowest resolution of the clock). For example, “2014- 05-21” is expanded to “2014-05-21 00:00:00”. This means that start limits are inclusive, while end limits are exclusive.

Some examples:

"2014-05-21 / 2014-05-28"

"/ 2014-01-01 " # (strictly) before january the first

"2030-01-01 /" # opens in 2030

"/" # Always open

"/ 2013-12-31 23:59:59" # closes one minute before "/ 2014-01-01"

• registration When this field is defined, users can only register to the course between the defined period. It takes the same arguments as accessible.

• allow_unregister If this field is defined and set to false, then students are not allowed to auto-unregister from the course.

• registration_password A password that is asked upon registration to the course. If empty or not defined, no password will be asked.

(31)

INGInious Documentation, Release 0.4

• registration_ac Access control (AC) method. Can be null (anyone can register), username (filter by username), realname (filter by real name) or email (filter by email address). If AC is activated, the allowed values for the filter should be set in the registration_ac_list key.

• registration_ac_list If AC is activated, registration_ac_list should contain a list of values for the filter.

• nofrontend If this field is defined and set to true, then the course won’t be displayed on the webapp course list.

• groups_student_choice If this field is defined and set to true and if collaborative work is activated for a given task, students will be invited to register by themselves for a group or team before submitting.

• use_classrooms If this field is set to true, the classroom model will be used, otherwise, the team model will be used. The default value for this field is true. (SeeClassrooms and teams)

3.3 Creating a new task

3.3.1 Tutorial

In this document we will describe how to create a simple task, that checks that a code in Python returns “Hello World!”.

Note: Demonstration tasks are made available for downloadhere. They can also be downloaded and installed automatically via theinginious-installscript.

Creating the task description Using the webapp

If you are using the webapp, this procedure can be done using the graphical interface:

1. Go to the Course administration/Tasks page, enter helloworld as a new task id and click on Create new task.

2. In the Basic settings tab, set the task name to Hello World! and put some context and author name. Con- tainer setup can be left with default parameters.

3. In the Subproblems tab, add a new code-type problem with problem id question1.

4. Set some problem name and context, and set language to python.

5. Save changes and go to Task files tab.

Manually

This is only possible if the administrator has given access to the course directory to the course administrator.

The task description is a YAML file describing everything that INGInious needs to know to verify the input of the student. Here is a simple task description. Put this file with the name task.yaml in a newly created helloworld folder in your course directory.

author: "The INGInious authors"

accessible: true name: "Hello World!"

context: "In this task, you will have to write a python script that displays 'Hello

˓→World!'."

3.3. Creating a new task 27

(32)

problems:

question1:

name: "Let's print it"

header: "def func():"

type: "code"

language: "python"

limits:

time: 10 memory: 50 output: 1000 environment: default

Most of the fields are self-explanatory. Some remarks:

• The field problems is a dictionary of problems. Each problem must have an unique id, for example here question1.

• Problem question1 have its type field that equals to code, which means the student must enter some code to answer the question. Other types exists, such as multiple-choice.

• The field limits are the limits that the task cannot exceed. The time is in seconds, and memory and output are in MB.

• The environment field is intended to change the environment where the tasks run. The available environ- ments are those you downloaded during installation or those you created by creating a grading container. Please seeCreating a new container image.

More documentation is available here:Creating a new task.

Creating the run file

In your task folder, you will put every file needed to test the input of the student. This folder content can be shown in the webapp in the Task files tab of the Edit task page.

1. Create a template file template.py, where we will put the code of the student.

def func():

@ @question1@@

func()

The syntax is very simple: put a first @ on the line where you want to put the code of the student. Then indent the line and write a second @. Now write the problem id of the problem you want to take the input from (question1) then write another @, write a possible suffix (not used here), and then finish the line with a last

@.

2. Create the run file. This file will be the script that is launched when the task is started. Here we will create a bashscript, that parses the template and verifies its content.

#! /bin/bash

# This line parses the template and put the result in studentcode.py parsetemplate --output student/studentcode.py template.py

# Verify the output of the code...

output=$(run_student python student/studentcode.py) if [ "$output" = "Hello World!" ]; then

# The student succeeded

(33)

INGInious Documentation, Release 0.4

feedback-result success

feedback-msg -m "You solved this difficult task!"

else

# The student failed feedback-result failed

feedback-msg -m "Your output is $output"

fi

Here we use three commands provided by INGInious, parsetemplate, run_student and feedback.

The code is self-explanatory; just notice the usage of run_student that ask INGInious (precisely the Docker agent) to start a new student container and run inside the command python studentcode.py.

Please note that the run_student command is fully configurable: you can change the environment on which you run the task, define new timeouts, memory limits, ... Seerun_studentfor more details.

3. If not using the webapp, don’t forget to give the run file the execution rights:

$ chmod +x helloworld/run More documentation is available here:Run file.

3.3.2 Task reference

Task description files

Inside a course folder (seeCreating a new course), tasks are identified by subdirectories named by their task id and containing a task.yaml file. For instance, this file, for a task with id taskid1, should be placed in a taskid1 subdirectory.

task.yamlis a YAML file containing information about the task.

author: Your name context: |-

The context of this task. Explain here what the students have to do.

order: 1 groups: false

name: The complete name of this task accessible: true

problems:

a_problem_id:

name: The title of this question header: A header for this question type: code

language: c limits

time: 30 memory: 128 environment: default network_grading: False

• author, context, order, name, language and header are only needed if you use the frontend.

contextand header are parsed using restructuredText.

• order is an integer, used by the frontend to sort the task list. Task are sorted in increasing value of order.

• weight is a decimal value indicating the weight of the task score to use to compute the total course score.

3.3. Creating a new task 29

(34)

• accessible describes when the task is accessible to student. This field is not mandatory (by default, the task is visible) and can contain the following values:

true the task is always accessible false the task is never accessible

"START" where START is a valid date, like “2014-05-10 10:11:12”, or “2014-06-18”. The task is only acces- sible after START.

"/END" where END is a valid date, like “2014-05-10 10:11:12”, or “2014-06-18”. The task is only accessible before END.

"START/END" where START and END are valid dates, like “2014-05-10 10:11:12”, or “2014-06-18”. The task is only accessible between START and END.

• problems describes sub-problems of this task. This field is mandatory and must contain at least one problem.

Problem types are described in the following sectionProblem types. Each problem must have an id which is alphanumeric and unique.

• limits contains the limits that will be applied on the grading container. time is the CPU timeout in seconds, and hard_time is the timeout in real time.

By default, hard_time is defined to be to 3*‘‘time‘‘. This can leads to problems when INGInious is under heavy load, but allow to detect processes that do too much system interruptions (sleep calls or IO)

memoryis the maximum memory allowed to the container.

Please note that the limits of the student containers (container that you start inside the grading container) will use these limits by default.

• environment is the name of the Docker container in which the grading code will run. This field is only needed if there is code to correct; a multiple-choice question does not need it. This environment will be used by default for the student containers.

• groups allows to indicate if the submission is to be done individually or per groups/teams. (see Classrooms and Teams).

• network_grading indicates if the grading container should have access to the net. This is not the case by default.

• evaluate indicates the submission that must be used for evaluation. This can be either:

best This is the default value. In this case, the best submission is used.

last In this case, the last submission is used.

student In this case, the student can select the submission for evaluation. This allows student to select the submission for evaluation without submitting it again or if submission replays are planned. This feature is not available in the LTI module due to LTI specifications limitations, and will be considered as best submission.

• submission_limit indicates the amount of submissions a student can make within a certain period of time.

It is composed of two fields:

– amount is an integer value indicating the amount of submission. A value of -1 corresponds to an infinite amount of submissions.

– period is an integer value indicating the length of the submission period in hours. A value of -1 corre- sponds to an infinite period. At the end of this period, the student can submit amount submissions again during period hours.

• stored_submissions indicates the amount of submissions that must be saved in the submission history. A value of 0 keeps all the submissions.

(35)

INGInious Documentation, Release 0.4

Problem types Code problems

type: codeproblems allows students to submit their code. The code is then sent to a container where a script made by the teaching team corrects it.

Here is a simple example for a code problem type: code

language: c header: |-

Hello dear student!

I'm a multiline header!

name: A name optional: false

header and language are only needed when using the frontend and are not mandatory. This description typically displays on the frontend a box where student can put their code.

optionalis an optional field, that defaults to false, that indicates if this problem is mandatory or not.

Code problem input’s are available in the run script (seeRun file) directly with the id of the problem.

Single code line problems

type: code-single-lineis simply a code box that allows a single line as input.

type: code-single-line language: c

header: |-

Hello dear student!

I'm another multiline header, parsed with *RST*!

name: Another problem optional: false

Single line code problem input’s are available in the run script (seeRun file) directly with the id of the problem.

Advanced code problem

Advanced code problems are available:

type: code

header: some text

name: And again, another name boxes:

boxId1:

type: text

content: Some additional text boxId2:

type: input-text maxChars: 10 optional: true boxId3:

type: multiline

3.3. Creating a new task 31

(36)

maxChars: 1000 lines: 8 language: java

Boxes are displayable (on the frontend) input fields that allows the student to fill more than one entry per prob- lem. Different box types are available, all of them are demonstrated above. Every configuration in the boxes (max- Chars,*lines*,*language*) is not mandatory, except content if the box type is text, and the field optional (default to false), that indicates if the box is mandatory or not.

In the run file (seeRun file), boxes input are available with the name problem_id/box_id

Match problems

Match problem are input that allows a single-line input from the student and that returns if the student entered exactly the text given in the “answer” field.

name: The answer type: match

header: some text describing this problem answer: 42

Match problem input’s are available in the run script (seeRun file) directly with the id of the problem.

Multiple choice problems

name: An exercice type: multiple-choice

header: The answer to life, the universe and any other things is multiple: true

limit: 2

error_message: "Wrong answer. Don't panic, and read Hitchhiker's Guide to the Galaxy."

success_message: "You're right! But don't forget to always take your towel with you."

choices:

- text: It is, of course, 42!

valid: true

- text: It should be *42*

valid: true - text: 43!

feedback: "43 isn't the answer. Maybe can you try to substract one?"

- text: 41?

feedback: "41 isn't the answer. Maybe can you try to add one?"

Choices are described in the choices section of the YAML. Each choice must have a text field (on the frontend) that will be parsed in restructuredText. Valid choices must have a valid: truefield. The field feedback is a message that will be displayed when the student check the choice.

multipleindicates if the student may (or not) select more than one response.

Choices are chosen randomly in the list. If the limit field is set, the number of choices taken equals to the limit.

There is always a valid answer in the chosen choices.

error_messageand success_message are messages that will be displayed on error/success. They are parsed in RST and are not mandatory.

Multiple choice problem input’s are available in the run script (seeRun file) directly with the id of the problem. The input can be either an array of integer if multiple is true or an integer. Choices are numbered sequentially from 0.

(37)

INGInious Documentation, Release 0.4

Run file

When the student have submit his/her code, INGInious starts a new Docker container with the right environment for the task (as given in the .task file). Inside this container is launched a script, called run, that you have to provide in the directory of your task.

Here is a simple example of a run file, compatible with the default environment, that simply returns that the student’s code is OK:

#!/bin/bash

feedback-result success

The run script is simply an executable application (a bash script, a python script, or a compiled executable runnable by the container). INGInious’ default containers provides commands (also available as python libraries) to interact with the backend.

By default, the script is run inside the container in the /task directory, by a non-root user. You can modify the container to change this (and everything else).

Feedback commands

feedback (obsolete since v0.4)

The feedback command allows you to set the result of your tests. Every argument is optional.

-r, --result STATUS set the result to STATUS. STATUS can be - success (the student succeeded the task), - failed (there are error in the student answer), - timeout (the tests timed out), - overflow (there was a memory/disk overflow) or - crash (the tests crashed) -e, --escape interprets the space-like escape chars.

-f, --feedback MSG set the feedback message to MSG. It is possible to set different messages for each problems. You can use -i to change the problem to which you assign the message -i, --id PROBLEMID set the problem id to which the message from the -f option is assigned. Unused

if -f is not set.

-g, --grade GRADE the grade. Should be a floating point number between 0(no points) and 100(all points) (bonuses, up to 200, are allowed).

-c, --custom CUSTOM add a value VAL to the “custom” dictionnary, with key KEY, where CUSTOM is KEY:VAL, which is stored in DB. Useful for plugins.

-j, --custom-json CUSTOM same as `--custom` but VAL is a json-encoded dictionnary The feedback command can be called multiple times.

feedback --result success --feedback "You're right, the answer is 42!"

feedback-result

The feedback-result command sets the submission result of a task, or a problem, and uses the following syntax : feedback-result [-i|--id PROBLEM_ID] RESULT

The execution result can be of different types:

• success : the student succeeded the task

3.3. Creating a new task 33

(38)

• failed : there are error in the student answer

• timeout : the tests timed out

• overflow :there was a memory/disk overflow

• crash : the tests crashed

For instance, the following command will inform that the student succeeded:

feedback-result success

In Python : the equivalent command can be directly obtained with:

from inginious import feedback

feedback.set_global_result("success") # Set global result to success

feedback.set_problem_result("failed", "q1") # Set 'q1' subproblem result to failed

feedback-grade

The feedback-grade command sets the submission grade and uses the following syntax:

feedback-grade GRADE

If no grade is specified, the result score will be binary. This means that a failed submission will give a 0.0% score to the student, while a successful submission will give a 100.0% score to the student. For instance, the following command will give an 87.8% grade to the student:

feedback-grade 87.8

In Python : the equivalent command can be directly obtained with:

from inginious import feedback

feedback.set_grade(87.8) # Set the grade to 87.8%

feedback-msg

The feedback-msg command sets the feedback message associated to the task or a subproblem. It has several optional parameters:

-a, --append append to current feedback, if not specified, replace the current feedback.

-i, --id PROBLEM_ID problem id to which associate the feedback, leave empty for the whole task.

-e, --escape interprets backslash escapes -m, --message MESSAGE feedback message

If the message is not specified, the feedback message is read from stdin. For instance, the command can be used as follows:

feedback-msg -ae -m "This is the correct answer.\n\nWell done!"

In Python : the equivalent command can be directly obtained with:

References

Related documents

Findings from three empirical studies of the recent revival of the Dutch beer brewing industry suggest that renewal is more likely in industries that (1) provide actors with a

Intended learning outcomes At the end of this course students: • are familiar with, and can reproduce the concepts of law, justice and morality as well as the relationship

The connector elements are configured in Tomcat’s server.xml file using the &lt;Connector&gt; XML element.. The &lt;Connector&gt; XML element is defined as a nested element within

This bonus is paid only during the consultant’s Fast Start period (enrollment month plus the next three full months) and is paid in addition to any other selling bonuses

Ektrasi fitur GLCM dan ektrasi fitur Geometri adalah metode pengklasifikasian yang terbukti membantu dalam proses perhitungan jarak dari tiap sample karena metode tersebut

[r]

Social inequalities, the widening gulf between the rich and the poor, exploitation by the higher castes in Andhra Pradesh and more importantly the loss of self-respect by

In order to verify identity information provided by a person applying for an igovt ID (and to keep the information about the igovt ID accurate and up to date), an information