/autofeedback

Unix-y tools for submission and feedback on/of assessed work

Primary LanguageC

This is autofeedback, a somewhat generic submission and feedback system 
originally developed by Stephen Kell for CO557 at the University of 
Kent. It is gradually becomine slightly more institution-generic, but
that is a work in progress.

A build of the system produces a single statically linked binary 
invokable as 'feedback' or 'submit', into which have been compiled 
details of the module.

A module is assumed to consist of one or more numbered `projects', which 
map to individual assessments or parts thereof. A project is submitted 
in the form of a directory named by the student. So the student runs 
commands like:

/courses/co557/submit   1 ~/my-proj1-attempt   # submit proj 1 of CO557
/courses/co557/feedback 1 ~/my-proj1-attempt   # ... or just get feedback
/courses/co557/submit   2 ~/my-proj2-attempt   # etc

In this example, submissions are written to /courses/coNNN/submissions/. 
Submissions are tar files obeying a particular naming convention: 
%d-%s-XXXXXX.tar (where %d is the project number, %s is the student 
login ID, and XXXXXX are random characters for uniqueness).

Details of the module are compiled into a library. In principle you can 
hand-write this library in C. However, a generic implementation is 
provided which securely calls out to a script that can be written in any 
convenient language (shell, Python, etc).

Important files are:

- src/submit.c -- the submission and feedback program. This is generic 
(module-agnostic) and handles the setuid/setgid logic, file handling, 
and all other security-sensitive stuff. You shouldn't have to touch 
this.

- libcoNNN/libcoNNN.a -- a library that contains knowledge of how to 
generate feedback on submissions for a given module. It is linked into 
the eventual module-*specific* static binary. The library consists of an 
array of structures, one per project, each defining three callbacks that 
are invoked by the submission program: check_sanity, write_feedback, 
finalise_submission.

- libcoNNN/scripts/write-feedback -- you can auto-generate (see below) 
a libcoNNN library which simply calls this script to write feedback, and 
does no-ops for the other two callbacks (check_sanity and 
finalise_submission). In that case, this script is the only thing you 
have to write. It can be any executable file, and is invoked with a 
bunch of file descriptors open:

0 (stdin): the submission tar file on stdin
1 (stdout): write feedback here
2 (stderr): stderr
7: the directory of the submission (open as a file descriptor)
8: the audit log (where you can write messages about what's happening)

The workflow for using it for a new module is something like:

- From this directory i.e. /path/to/autofeedback:

./generate-module-lib.sh COnnn

This generates an initial per-module libraries, and sets up a local git 
branch for that module. The idea is to merge this with a per-institution 
local branch, while still allowing generic changes to the main 
autofeedback to the 'main' branch.

- From a directory named after your module, or with MODULE set,
  do 'make -f /path/to/autofeedback/Makefile'. This will generate a 
'submit' binary in the current directory.

- Now you have your submit binary. I recommend symlinking it from the 
relevant place at your institution (at Kent: on raptor, 
/courses/coNNN/submit and /courses/coNNN/feedback).

Since statically linked binaries can't reliably use NSS functions in some
system configs (e.g. using LDAP), the submission code does not use these,
and provides a fake version of getpwnam() for libtar's benefit. The
submitting user's name is taken from the USER environment variable,
used to name submission files and the like. Spoofing this is harmless and
easily detectable.