Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • master
1 result

Target

Select target project
  • nthiery/wims-info
  • medimegh/wims-info
  • ventos/wims-info
  • bokaris/wims-info
4 results
Select Git revision
  • master
1 result
Show changes
Showing
with 986 additions and 0 deletions
type=first
textarea="data explain"
:Remettre en bon ordre des objets donnés, glisser-déposer.
On présente une liste d'objets, et il faut les trier selon l'ordre précisé
en les tirant vers les cases prévues avec la souris.
<p>
Pour construire un exercice avec ce modèle, il suffit d'entrer la liste
d'objets à trier et changer le texte explicatif.
<p>
Avec une petite modification, une variante de ce modèle peut accepter des
images comme objets.
<p>
Auteur du modèle : Gang Xiao <qualite@wimsedu.info>
:%%%%%%%%%%%%%%%%% ATTENTION %%%%%%%%%%%%%%%%%%%%
Enlevez l'en-tête ci-dessus si vous détruisez les balises pour le modèle !
(Ce sont les lignes qui commencent par un ':'.)
Sinon l'exercice risque de ne pas pouvoir repasser sous Createxo.
:%%%%%%%% Paramètres d'exemples à redéfinir %%%%%%%%%%%%%%%%%
:\title{Complexité}
:\author{Viviane, Pons}
:\email{viviane.pons@lri.fr}
:\credits{}
:Nombre d'objets à trier par exercice. Jusqu'à 20.
Si ce nombre est plus petit que les objets disponibles, une partie tirée au
hasard des objets seront présentés. <p>
Si ce nombre est plus grand que les objets disponibles, il sera ramené au
nombre d'objets.
\integer{tot=4}
:La taille des objets à glisser, en pixels, x fois y.
Pensez aux gens qui augmentent la taille de polices de leurs navigateurs !
Ne mettez pas les cases trop petites.
\text{size=80x40}
:La liste d'objets à réordonner
Ecrivez les objets dans le bon ordre, séparés par des virgules.
\text{data=log(n),n,nlog(n),n^2,n^3,2^n}
:Le texte qui explique ce qu'il faut faire.
\text{explain=Ordonner ces complexités de la plus rapide (à gauche) à la plus lente (à droite) pour n grand.}
:Mise en aléatoire par des accolades emboitables
help
\text{accolade=item(1,1 oui, 2 non)}
:%%%%%%%%%%%%%% Rien à modifier avant l'énoncé %%%%%%%%%%%%%%%%
\text{accolade=wims(word 1 of \accolade)}
\text{data=\accolade=1 ? wims(embraced randitem \data)}
\integer{datacnt=items(\data)}
\integer{tot=min(20,min(\tot,\datacnt))}
\if{\tot<\datacnt}{
\text{sh=shuffle(\datacnt)}
\text{sh=wims(sort numeric items \sh[1..\tot])}
\text{data=item(\sh,\data)}
}
\text{st=wims(makelist r x for x=1 to \tot)}
\steps{\st}
:%%%%%%%%%%%%% Maintenant l'énoncé en code html. %%%%%%%%%%%%%%%%%%%%
::Vous n'avez pas besoin de modifier ceci en général.
\statement{\explain
<table class="wimsnoborder"><tr>
\for{k=1 to \tot}{<td>\embed{r\k,\size}</td>}
</tr></table>}
:%%%%%%%%%%%%% Rien à modifier ci-après. %%%%%%%%%%%%%%%%%5
\answer{1}{\data[1]}{type=dragfill}
\answer{2}{\data[2]}{type=dragfill}
\answer{3}{\data[3]}{type=dragfill}
\answer{4}{\data[4]}{type=dragfill}
\answer{5}{\data[5]}{type=dragfill}
\answer{6}{\data[6]}{type=dragfill}
\answer{7}{\data[7]}{type=dragfill}
\answer{8}{\data[8]}{type=dragfill}
\answer{9}{\data[9]}{type=dragfill}
\answer{10}{\data[10]}{type=dragfill}
\answer{11}{\data[11]}{type=dragfill}
\answer{12}{\data[12]}{type=dragfill}
\answer{13}{\data[13]}{type=dragfill}
\answer{14}{\data[14]}{type=dragfill}
\answer{15}{\data[15]}{type=dragfill}
\answer{16}{\data[16]}{type=dragfill}
\answer{17}{\data[17]}{type=dragfill}
\answer{18}{\data[18]}{type=dragfill}
\answer{19}{\data[19]}{type=dragfill}
\answer{20}{\data[20]}{type=dragfill}
type=first
textarea="datatrue datafalse explain"
:Une question choix multiples avec permutation alatoire des choix.
Voici un modle de question choix multiples. L'ordre des choix est alatoire,
ainsi que les choix s'il y en a suffisamment qui sont dfinis.
Quand il y a plusieurs bons choix, il suffit d'en choisir un, peu importe lequel.
<p>
Le texte n'est pas alatoire. Un autre modle <b>QCM la suite</b>
permet d'avoir aussi un texte alatoire.
<p>Auteur du modle : Gang Xiao <qualite@wimsedu.info></p>
:%%%%%%%%%%%%%%%%% ATTENTION %%%%%%%%%%%%%%%%%%%%
Enlevez l'en-tte ci-dessus si vous dtruisez les balises pour le modle !
(Ce sont les lignes qui commencent par un ':'.)
Sinon l'exercice risque de ne pas pouvoir repasser sous Createxo.
:%%%%%%%% Paramtres d'exemples redfinir %%%%%%%%%%%%%%%%%
:\title{Appel de fonctions}
:\author{Viviane Pons}
:\email{viviane.pons@upsud.fr}
:\credits{}
:Nombre de choix prsenter. Au plus 10.
Vous devez dfinir suffisamment de choix. Sinon l'exercice affichera seulement ce qui est disponible.
\integer{tot=4}
:Le nombre de bons choix dans chaque exercice. Ne doit pas depasser le total.
\integer{givetrue=1}
:Nombre de mauvais choix "obligatoires".
Par exemple si ce nombre est 2, les deux premiers mauvais choix dans la liste seront toujours prsents dans les exercices gnrs.
<p> Dans le doute, mettez 0.</p>
\integer{minfalse=0}
:Le texte qui explique ce qu'il faut faire.
help
\text{explain=Slectionner un appel correct pour la fonction dont la signature est
<pre>int max(int a, int b)</pre>}
:Le(s) bon(s) choix, un par ligne.
On peut en placer plusieurs (un par ligne) pour tirer au hasard.
Evitez les phrases trop longues ! Aucun point-virgule dans la phrase.
help
\matrix{datatrue=max(3,4)
max(-1,5)
max(6,2)
max(max(1,2),3)}
:Les mauvais choix, un par ligne.
Vous pouvez en donner plus que ce qu'il faut tirer au hasard.
Evitez les phrases trop longues ! Aucun point-virgule dans la phrase.
help
\matrix{datafalse=max(2.5,3)
max("abab","bcbc")
max(5)
max(8)
max(5,4,2,9)
max(1.2,5.3)
max(4,4,"hop")
min(2,5)
Max(3,3)}
:Mots d'option : <span class="tt wims_code_words">checkbox</span>, <span class="tt wims_code_words">split</span>.
Ajouter le mot <span class="tt wims_code_words">checkbox</span> s'il y a plusieurs bonnes rponses et si l'lve doit choisir toutes les bonnes rponses (au lieu d'une seule).
Dans ce cas, ajouter aussi le mot <span class="tt wims_code_words">split</span> si on autorise une note partielle quand seulement une partie des bonnes rponses sont choisies.
\text{option=}
:Feedback Gnral
Ce texte s'affichera aprs la rponse de l'apprenant, qu'elle soit juste ou fausse.
\text{feedback_general=}
:Feedback en cas de bonne rponse
Ce texte s'affichera aprs la rponse de l'apprenant, en cas de bonne reponse ou de reponse partielle.
\text{feedback_bon=}
:Feedback en cas de mauvaise rponse
Ce texte s'affichera aprs la rponse de l'apprenant, s'il a coch au moins une mauvaise rponse.
\text{feedback_mauvais=}
:Mise en alatoire par des accolades emboitables
help
\text{accolade=item(1,1 oui, 2 non)}
:%%%%%%%%%%%%%% Rien modifier avant l'nonc %%%%%%%%%%%%%%%%
\text{accolade=wims(word 1 of \accolade)}
\text{empty=}
\if{\feedback_general != \empty}{
\text{feedback_general=<p class="feedback">\feedback_general</p>}
}
\if{\feedback_bon != \empty}{
\text{feedback_bon=<p class="feedback good_answer">\feedback_bon</p>}
}
\if{\feedback_mauvais != \empty}{
\text{feedback_mauvais=<p class="feedback bad_answer">\feedback_mauvais</p>}
}
\text{datatrue=wims(nonempty rows \datatrue)}
\text{datafalse=wims(nonempty rows \datafalse)}
\integer{truecnt=rows(\datatrue)}
\integer{falsecnt=rows(\datafalse)}
\integer{givetrue=\givetrue<1?1}
\integer{givetrue=\givetrue>\truecnt?\truecnt}
\integer{tot=\tot > \falsecnt+\givetrue?\falsecnt+\givetrue}
\integer{givetrue=\givetrue>\tot-1?\tot-1}
\integer{minfalse=\minfalse>\tot-\givetrue?\tot-\givetrue}
\text{tsh=shuffle(\truecnt)}
\text{true=row(\tsh,\datatrue)}
\if{\minfalse>0}{
\text{false1=row(1..\minfalse,\datafalse);}
\text{false2=row(\minfalse+1..\falsecnt,\datafalse)}
}{
\integer{minfalse=0}
\text{false1=}
\text{false2=\datafalse}
}
\text{fsh=shuffle(\falsecnt)}
\text{false2=row(\fsh,\false2)}
\text{pick=row(1..\givetrue,\true);\false1 row(1..\tot-\givetrue-\minfalse,\false2)}
\text{ind=wims(makelist 1 for x=1 to \givetrue),wims(makelist 0 for x=1 to \tot-\givetrue)}
\text{sh=shuffle(\tot)}
\text{ind=item(\sh,\ind)}
\text{pick=row(\sh,\pick)}
\text{pick=\accolade=1 ? wims(embraced randitem \pick)}
\text{explain=\accolade=1 ? wims(embraced randitem \explain)}
\text{ans=positionof(1,\ind)}
\text{list=item(1..\tot,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z)}
\text{anstype=checkbox iswordof \option?checkbox:radio}
:%%%%%%%%%%%%% Maintenant l'nonc en code html. %%%%%%%%%%%%%%%%%%%%
::Vous n'avez pas besoin de modifier ceci en gnral.
\statement{
\explain
\for{i=1 to \tot}{
<p class="oefreply"><label><strong>\embed{reply 1,\i}-</strong> \pick[\i;]</label></p>
}}
:%%%%%%%%%%%%% Rien modifier ci-aprs. %%%%%%%%%%%%%%%%%5
\answer{La rponse}{\ans;\list}{type=\anstype}{option=\option}
\feedback{1=1}{\feedback_general}
\feedback{\reply1 isitemof \list[\ans]}{\feedback_bon}
\feedback{\reply1 notitemof \list[\ans]}{\feedback_mauvais}
type=first
textarea="datatrue datafalse explain"
:Une question choix multiples avec permutation alatoire des choix.
Voici un modle de question choix multiples. L'ordre des choix est alatoire,
ainsi que les choix s'il y en a suffisamment qui sont dfinis.
Quand il y a plusieurs bons choix, il suffit d'en choisir un, peu importe lequel.
<p>
Le texte n'est pas alatoire. Un autre modle <b>QCM la suite</b>
permet d'avoir aussi un texte alatoire.
<p>Auteur du modle : Gang Xiao <qualite@wimsedu.info></p>
:%%%%%%%%%%%%%%%%% ATTENTION %%%%%%%%%%%%%%%%%%%%
Enlevez l'en-tte ci-dessus si vous dtruisez les balises pour le modle !
(Ce sont les lignes qui commencent par un ':'.)
Sinon l'exercice risque de ne pas pouvoir repasser sous Createxo.
:%%%%%%%% Paramtres d'exemples redfinir %%%%%%%%%%%%%%%%%
:\title{Cration de tableau}
:\author{Viviane, Pons}
:\email{viviane.pons@lri.fr}
:\credits{}
:Nombre de choix prsenter. Au plus 10.
Vous devez dfinir suffisamment de choix. Sinon l'exercice affichera seulement ce qui est disponible.
\integer{tot=4}
:Le nombre de bons choix dans chaque exercice. Ne doit pas depasser le total.
\integer{givetrue=1}
:Nombre de mauvais choix "obligatoires".
Par exemple si ce nombre est 2, les deux premiers mauvais choix dans la liste seront toujours prsents dans les exercices gnrs.
<p> Dans le doute, mettez 0.</p>
\integer{minfalse=0}
:Le texte qui explique ce qu'il faut faire.
help
\text{explain=Slectionner l'instruction correcte pour crer un tableau d'entier.}
:Le(s) bon(s) choix, un par ligne.
On peut en placer plusieurs (un par ligne) pour tirer au hasard.
Evitez les phrases trop longues ! Aucun point-virgule dans la phrase.
help
\matrix{datatrue=vector &lt;int&gt; tab = &#123;1,2,4,4,2,1&#125;;
vector &lt;int&gt; tab = vector &lt;int&gt; (3);
vector &lt;int&gt; a = &#123;3,3,4&#125;;}
:Les mauvais choix, un par ligne.
Vous pouvez en donner plus que ce qu'il faut tirer au hasard.
Evitez les phrases trop longues ! Aucun point-virgule dans la phrase.
help
\matrix{datafalse=vector tab = &#123;1,2,4,4,2,1&#125;;
int tab = vector &lt;int&gt; (3);
vector &lt;double&gt; tab = vector &lt;double&gt;(5);
vector&lt;int&gt; a = 5;
int a = &#123;3,3,4&#125;;}
:Mots d'option : <span class="tt wims_code_words">checkbox</span>, <span class="tt wims_code_words">split</span>.
Ajouter le mot <span class="tt wims_code_words">checkbox</span> s'il y a plusieurs bonnes rponses et si l'lve doit choisir toutes les bonnes rponses (au lieu d'une seule).
Dans ce cas, ajouter aussi le mot <span class="tt wims_code_words">split</span> si on autorise une note partielle quand seulement une partie des bonnes rponses sont choisies.
\text{option=}
:Feedback Gnral
Ce texte s'affichera aprs la rponse de l'apprenant, qu'elle soit juste ou fausse.
\text{feedback_general=}
:Feedback en cas de bonne rponse
Ce texte s'affichera aprs la rponse de l'apprenant, en cas de bonne reponse ou de reponse partielle.
\text{feedback_bon=}
:Feedback en cas de mauvaise rponse
Ce texte s'affichera aprs la rponse de l'apprenant, s'il a coch au moins une mauvaise rponse.
\text{feedback_mauvais=}
:Mise en alatoire par des accolades emboitables
help
\text{accolade=item(1,1 oui, 2 non)}
:%%%%%%%%%%%%%% Rien modifier avant l'nonc %%%%%%%%%%%%%%%%
\text{accolade=wims(word 1 of \accolade)}
\text{empty=}
\if{\feedback_general != \empty}{
\text{feedback_general=<p class="feedback">\feedback_general</p>}
}
\if{\feedback_bon != \empty}{
\text{feedback_bon=<p class="feedback good_answer">\feedback_bon</p>}
}
\if{\feedback_mauvais != \empty}{
\text{feedback_mauvais=<p class="feedback bad_answer">\feedback_mauvais</p>}
}
\text{datatrue=wims(nonempty rows \datatrue)}
\text{datafalse=wims(nonempty rows \datafalse)}
\integer{truecnt=rows(\datatrue)}
\integer{falsecnt=rows(\datafalse)}
\integer{givetrue=\givetrue<1?1}
\integer{givetrue=\givetrue>\truecnt?\truecnt}
\integer{tot=\tot > \falsecnt+\givetrue?\falsecnt+\givetrue}
\integer{givetrue=\givetrue>\tot-1?\tot-1}
\integer{minfalse=\minfalse>\tot-\givetrue?\tot-\givetrue}
\text{tsh=shuffle(\truecnt)}
\text{true=row(\tsh,\datatrue)}
\if{\minfalse>0}{
\text{false1=row(1..\minfalse,\datafalse);}
\text{false2=row(\minfalse+1..\falsecnt,\datafalse)}
}{
\integer{minfalse=0}
\text{false1=}
\text{false2=\datafalse}
}
\text{fsh=shuffle(\falsecnt)}
\text{false2=row(\fsh,\false2)}
\text{pick=row(1..\givetrue,\true);\false1 row(1..\tot-\givetrue-\minfalse,\false2)}
\text{ind=wims(makelist 1 for x=1 to \givetrue),wims(makelist 0 for x=1 to \tot-\givetrue)}
\text{sh=shuffle(\tot)}
\text{ind=item(\sh,\ind)}
\text{pick=row(\sh,\pick)}
\text{pick=\accolade=1 ? wims(embraced randitem \pick)}
\text{explain=\accolade=1 ? wims(embraced randitem \explain)}
\text{ans=positionof(1,\ind)}
\text{list=item(1..\tot,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z)}
\text{anstype=checkbox iswordof \option?checkbox:radio}
:%%%%%%%%%%%%% Maintenant l'nonc en code html. %%%%%%%%%%%%%%%%%%%%
::Vous n'avez pas besoin de modifier ceci en gnral.
\statement{
\explain
\for{i=1 to \tot}{
<p class="oefreply"><label><strong>\embed{reply 1,\i}-</strong> \pick[\i;]</label></p>
}}
:%%%%%%%%%%%%% Rien modifier ci-aprs. %%%%%%%%%%%%%%%%%5
\answer{La rponse}{\ans;\list}{type=\anstype}{option=\option}
\feedback{1=1}{\feedback_general}
\feedback{\reply1 isitemof \list[\ans]}{\feedback_bon}
\feedback{\reply1 notitemof \list[\ans]}{\feedback_mauvais}
CXXFLAGS=-g -Wall -std=c++0x
WIMSHOST=wimstest
#DOCKERHOST=134.158.75.87# wimsdocker
DOCKERHOSTADMIN=debian
DOCKERHOST=134.158.75.92
SSH=ssh -x
tests: test-compile-and-run.sh test-docker-compile-and-run test-docker-compile-and-run-client
test-%:
@echo running tests for $*
@echo | $* prog.cpp > prog.out.obtained 2> /dev/null && diff prog.out prog.out.obtained
@echo coucou | $* prog-stdin.cpp > prog-stdin.out.obtained 2> /dev/null && diff prog-stdin.out prog-stdin.out.obtained
@rm prog.out.obtained prog-stdin.out.obtained
dockerhost-preinstall:
scp dockerhost_setup.sh secure_exec_local secure_exec_server $(DOCKERHOSTADMIN)@$(DOCKERHOST):
$(SSH) $(DOCKERHOSTADMIN)@$(DOCKERHOST) sudo bash dockerhost-setup.sh
dockerhost-update:
scp secure_exec_local secure_exec_server $(DOCKERHOSTADMIN)@$(DOCKERHOST):
$(SSH) $(DOCKERHOSTADMIN)@$(DOCKERHOST) sudo cp secure_exec_server secure_exec_local /usr/local/bin
dockerhost-clean: # TODO Add a test that DOCKERHOST <-> WIMSHOST
ssh root@$(DOCKERHOST) userdel -r www
dockerhost-run:
$(SSH) wims@$(DOCKERHOST) other/bin/docker-compile-and-run-server
dockerhost-test:
@echo == Testing docker ===============
$(SSH) $(DOCKERHOSTADMIN)@$(DOCKERHOST) sudo docker run hello-world
@echo == Testing secure_exec_local ====
tar czf - -C tests/dir . | $(SSH) $(DOCKERHOSTADMIN)@$(DOCKERHOST) sudo -u www super secure_exec_local ./monscript
@echo == Testing server ===============
tar czf archive.tgz -C tests/dir .
curl --form "archive=@archive.tgz" --form "cmd=./monscript" "http://$(DOCKERHOST):8080/secure_exec"
wimshost-install:
scp secure_exec wims@$(WIMSHOST):other/bin
scp secure_exec_wrapper.sh wims@$(WIMSHOST):public_html/bin/secure_exec
# $(SSH) root@$(WIMSHOST) service httpd restart
wimshost-test: # Needs to be updated
scp prog.cpp wims@$(WIMSHOST):
$(SSH) wims@$(WIMSHOST) ./other/bin/docker-compile-and-run prog.cpp < /dev/null
install-remote:
xxx
# Secure execution of a command in a sandbox
This implements a web service allowing to execute a command in a
docker sandbox with reasonable security.
## Usage of the client
This assumes that the webservice is running and its url is set in
[](secure_exec).
The following command uses the webservice to create a new sandbox,
initialize it with a copy of the content of `dir` in the sandbox, run
`cmd` in it, and print the output:
secure_exec <dir> <cmd>
## Installation of the webservice
This assumes that you have access to some remote machine running some
variant of debian, under a user with sudo permission.
- Edit the [](Makefile) to point DOCKERHOST to the ip address of the
server and DOCKERHOSTADMIN to the user
- Run:
make dockerhost-preinstall
make dockerhost-run
- (optional) Run
make dockerhost-test
## Updating the webservice
Run:
make dockerhost-update
## Tests
The directory `tests` contains a collection of tests scripts:
- Test 1 assumes that docker is installed.
- Tests 2 and 3 assume in addition that `secure_exec_local` has been
installed in `/usr/local/bin` and `/etc/super.tab` has been
configured locally as in `super.tab`.
- Test 4 assumes that the web service is running on some (remote)
server, and that its url is set in `secure_exec`.
In addition, the following command runs some tests on the webservice:
make dockerhost-test
## TODO
- More documentation
- Security review
- Truncation of output
- Authentication between client and server
A minima: firewall setup to restrict incoming connections from the client
- Resource limitations
- The created temporary archive should be in a temporary directory and cleaned up
Or could we avoid the temporary file?
#!/bin/bash
BASE_DOCKER_IMAGE=crosbymichael/build-essential
# Taken from https://docs.docker.com/engine/installation/linux/docker-ce/debian/#install-using-the-repository
sudo apt-get update
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg2 \
software-properties-common \
super python3-flask
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
sudo apt-key fingerprint 0EBFCD88
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/debian \
$(lsb_release -cs) \
stable"
sudo apt-get update
sudo apt-get install docker-ce
#sudo groupadd docker # aready exists
#sudo service docker restart
sudo docker pull $BASE_DOCKER_IMAGE
sudo useradd www
sudo cp secure_exec_local secure_exec_server /usr/local/bin
sudo sh -c 'echo "secure_exec_local /usr/local/bin/secure_exec_local u=nobody g=docker www" >> /etc/super.tab'
# At boot time run the server as www
sudo sh -c '#!/bin/sh echo "su -c /usr/local/bin/secure_exec_server www" >> /etc/rc.local'
# TODO
#! /bin/sh
#vm="$1"
url=http://134.158.75.92:8080/secure_exec
dir="$1"
cmd="$2"
tar czf archive.tgz -C "$dir" .
curl --form "archive=@archive.tgz" --form "cmd=$cmd" "$url"
#! /bin/sh
cmd="$1"
vm=crosbymichael/build-essential
timeout=1000 # seconds
logfile=$(tempfile)
cleanup () { rm -f "$logfile"; docker rm -f $ID >/dev/null 2>&1; }
die () { cat "$logfile" >&2; echo "FATAL: $1" >&2; cleanup; exit 255; }
error_exit () { die "interrupted"; }
trap error_exit HUP INT TERM
ID=`docker run -d -w /home/secure_exec $vm sleep $timeout 2>$logfile` \
|| die "docker run failed!"
# pour prendre correctement l'entrée standard, on a besoin d'utiliser
# docker exec -i
docker exec -i $ID sh -c "tar xzf -" 2>>$logfile \
|| die "archive extraction failed"
docker exec $ID "$cmd" || die "Command $cmd failed"
cleanup
#!/usr/bin/python3
import tempfile
from subprocess import Popen, PIPE
import os
from flask import Flask, redirect, url_for, request
import pdb
secure_exec_local="/usr/local/bin/secure_exec_local"
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Web service for executing a command in a remote sandbox.\nPost on /secure_exec with a tar.gz archive of the directory in which the command is to be run as form input `archive` and command to run as form input `cmd`\n'
@app.route('/secure_exec',methods=['POST'])
def compile_and_run():
archive = request.files['archive']
cmd = request.form['cmd']
p = Popen(["super", "secure_exec_local", cmd],stdin=PIPE, stdout=PIPE,close_fds=True)
child_in, child_out = p.stdin, p.stdout
# (child_out, child_in) = popen2.popen2("super " + secure_exec_local + " "+cmd)
#pdb.set_trace
child_in.write(archive.stream.read())
child_in.flush()
child_in.close()
result = child_out.read()
return result
if __name__ == '__main__':
#app.run(debug=True, port=8080)
app.run(host="0.0.0.0", port=8080)
#!/bin/sh
./bin/wrap..exec ../other/bin/secure_exec $wims_exec_parm
# Replace judicael by the names of the users that will run secure_exec_local
secure_exec_local /usr/local/bin/secure_exec_local \
uid=nobody gid=docker judicael
Ceci est un fichier d'essai.
Avec plusieurs lignes.
#! /bin/sh
cal
pwd
env
wc fichier.txt
#! /bin/sh
tar czf - -C dir . | sudo ../secure_exec_local ./monscript
#! /bin/sh
tar czf - -C dir . | super secure_exec_local ./monscript
#! /bin/sh
tar czf archive.tgz -C dir .
../secure_exec_server &
sleep 3
curl --form "archive=@archive.tgz" --form "cmd=./monscript" "http://127.0.0.1:8080/secure_exec"
killall secure_exec_server
# This file is automatically generated by Modtool 4.05.
# Do not edit by hand.
title=Exercices de programmation C++
description=quelques exercices de lecture et interprtation de programmes en C++
language=fr
category=oef, exercise
domain=programming,
level=U1
keywords=C++
require=
scoring=yes
copyright=&copy; 2015 (<a href=\COPYING\>GNU GPL</a>)
author=Nicolas,Thiry
address=Nicolas.Thiery@u-psud.fr
version=1.5
wims_version=4.11a
vardef=oef/var.def
translator=
translator_address=
data=
maintainer=
maintainer_address=
translation_language=
SUBSTITUTION='s/CI1/1/g; s/CI2/3/g; s/I1/j/g; s/I2/k/g; s/I3/i/g; s/F1/g/g; s/D1/x/g; s/D2/y/g; s/D3/z/g; s/S1/s/g; s/S2/s1/g; s/S3/s2/g; '
PROGRAMS=$(wildcard data/*.cpp)
INPUT_PROGRAMS=$(wildcard data/*input.cpp)
PROGRAMS_MASSAGED=$(PROGRAMS:data/%.cpp=data/static/%.cpp)
PROGRAM_ANSWERS=$(PROGRAMS:data/%.cpp=data/static/%.cpp.answer)
#ANSWER=$(INPUT_PROGRAMS:%=%.answer)
TARGETS=$(shell head -1 src/cpp/read_program.cpp | awk -F'=' '{print $$2}')
all: data/static/index $(PROGRAMS_MASSAGED) $(PROGRAM_ANSWERS)
data/static/index: $(PROGRAMS) data/static src/cpp/read_program.cpp
@echo Targets: $(TARGETS)
@if [ -f $@ ]; then rm $@; fi; \
for target in $(TARGETS); do \
(echo "$$target: "`cd data; ls -m $${target}_*.cpp`) >> $@; \
done
# Variante to avoid input programs:
# (echo "$$target: "`cd data; ls -m \`ls $${target}_*.cpp | grep -v _input.cpp\``) >> $@; \
data/static:
mkdir $@
data/static/%.cpp.answer: data/static/% data/static
@echo execution de $<
@if echo $< | grep -q _input; then \
count=0; \
for i in `seq 0 99`; do if [ x`echo $$i | $<` = 'x42' ]; then echo $$i; count=$$((count+1)); fi; done > $@; \
if [ $$count != 1 ]; then \
echo "ATTENTION IL N'Y A PAS EXACTEMENT UNE BONNE RÉPONSE pour $<"; \
fi; \
else \
./$< > $@; \
fi
data/static/%.cpp: data/%.cpp
sed $(SUBSTITUTION) $< > $@
data/static/%: data/static/%.cpp
g++ -Wall -Wno-sign-compare -Wno-unused-value -pedantic -std=c++11 $< -o $@
.PRECIOUS: data/static/%
clean:
-rm data/static/*
# Pour restauration
archive: #all
cd ..; tar zcf /tmp/modtool-test~coding~readingCppPrograms.fr.tgz test~coding~readingCppPrograms.fr
#main.oef: header.oef programs/guess-output/*.cpp footer.oef Makefile
# cd programs/guess-output; make all.oef
# cat header.oef programs/guess-output/all.oef footer.oef > main.oef
reformat:
astyle \
--style=java --indent=spaces --indent=spaces=4 --indent-switches --indent-namespaces \
--indent-modifiers \
--indent-col1-comments \
--min-conditional-indent=0 \
--pad-oper \
--pad-header \
--align-pointer=name \
--align-reference=name \
--keep-one-line-statements \
--convert-tabs \
--close-templates \
--break-after-logical \
--max-code-length=78 \
'data/*.cpp'
# --exclude=data/static \
.DELETE_ON_ERROR:
# make is bogus
# This file registers changes to the module.
# Please write in reverse order: the last version first.
Version 1.5: ???
Plus d'exercices pour Info 121: ???
Version 1.4: 30 Novembre 2015
Un peu de randomisation (statique)
Plus d'exercices (io, fichiers)
Version 1.3: 28 Novembre 2015
Support expérimental pour compilation dynamique
Plus d'exercices (fichiers)
Version 1.2: Octobre 2015
Plus d'exercices
Version 1.1: Octobre 2014
Plus d'exercices (vecteurs, vecteurs 2D, ...)
Version 1.00: Octobre 2014
First publication.
Module WIMS: Compréhension de programmes C++
============================================
Présentation
------------
Ce module présente à l'étudiant des programmes qu'il doit lire et
comprendre, afin de deviner quelle en sera la sortie, ou bien l'entrée
appropriée pour obtenir 42. Les programmes sont tirés aléatoirement
d'une collection de programmes groupés par thèmes. Pour rajouter un
nouveau programme il suffit de l'ajouter dans le répertoire
idoine. Voir ci-dessous.
Pour l'instant, la collection est constituée d'exercices de C++,
donnés dans le cadre des cours d'introduction à l'informatique `Info
111 <Nicolas.Thiery.name>`_ et Info 121 de la licence MPI de
l'Université Paris Sud, mais l'infrastructure est conçue pour être
étendue à d'autres thèmes et généralisable à d'autres langages de
programmation.
Ce module est développé collaborativement sur:
`<https://gitlri.lri.fr/nthiery/wims-info/tree/master/test~coding~readingCppPrograms.fr>`_
Étendre le module avec de nouveaux programmes
---------------------------------------------
Le répertoire `<data/>`_ contient des programmes C++, qui peuvent être de deux types.
Pour les programmes du premier type, l'utilisateur doit deviner la sortie du programme.
Ces programmes sont nommés sous la forme ``<theme>_<nom>.cpp``.
Les programme du deuxième type doivent lire un entier entre
0 et 99 sur l'entrée standard, et l'utilisateur doit deviner lequel
donne 42; pour l'instant cet entier doit être unique.
Ces programmes sont nommés ``<theme>_<nom>_input.cpp``
Pour les deux types de programme, le thème peut être constitué d'un thème principal et de sous-thèmes, séparés par des ``_`` (p. ex. ``loop_for``, ``loop_while``).
Les noms de fichiers ne doivent contenir que des caractères alphanumériques et le caractère ``_``.
En vue d'obtenir un peu de variabilité les programmes sont transformés
avant affichage et compilation, de la manière suivante:
- Remplacement de CI1, CI2 par des petits entiers
- Remplacement de I1, I2, I3, I4 par i,j,k,n respectivement (ou une
permutation de ces derniers);
- Remplacement de D1, D2, D3 par x,y,z respectivement (ou une
permutation de ces derniers);
- Remplacement de F1 par f.
Ces remplacements sont fait de manière purement textuelle. Ainsi,
«AI1» sera remplacé par, par exemple, «Ai».
Dans la version actuelle, le remplacement est fait statiquement avant
le chargement du module dans WIMS (éditer la première ligne du
Makefile pour changer/compléter la liste des remplacements). À terme
ce remplacement sera fait dynamiquement par WIMS, avec une permutation
différente à chaque exécution de l'exercice.
.. TODO:: Améliorer l'entête du Makefile pour que ne soient remplacés que les mots complets.
L'infrastructure du module est implantée dans
`<./src/cpp/read_program.cpp>`_.
.. WARNING::
Dans l'état actuel de l'exercice, l'utilisateur ne peut pas
rentrer de réponse vide. Il faut donc que tous les programmes du
premier type affiche au moins un caractère. Éviter les caractères
unicode compliqués aussi :-)
Conventions de style
--------------------
Pour faciliter une lecture rapide, il est bon pour les élèves que tous
les programmes soient écrits dans un style cohérent (indentation,
espaces, ...). Pour donner cette cohérence, ce module utilise `astyle
<http://astyle.sourceforge.net/>`_ pour reformater systématiquement
tous les programmes. Voir:
make reformat
Les choix suivants, forcément un peu arbitraire, ont été fait. Voir la
documentation de astyle pour les détails:
--style=java --indent=spaces --indent=spaces=4 --indent-switches --indent-namespaces
À voir: --indent-modifiers
--indent-col1-comments: À voir en pratique si cela devient gênant
--min-conditional-indent=0
--pad-oper
--pad-header
--align-pointer=name Sous réserve que, dans "char *f, g", le * ne s'applique qu'à f
--align-reference=name
--keep-one-line-statements
--convert-tabs
--close-templates
--break-after-logical
--max-code-length=78
--recursive
Pour utiliser ce module dans un contexte utilisant d'autres
conventions, il serait tout à fait possible de reformater le code
selon d'autres conventions, soit au vol dans wims, ou au moment moment
de la fabrication de la version static.
Création automatique des exercices de type OEF
----------------------------------------------
L'entête du fichier `src/cpp/read_program.cpp` permet de définir les exercices de type OEF qui vont être construits automatiquement par WIMS lors de l'import du module (voir section suivante).
L'entête doit être de la forme ``target=<cible1> <cible2> <cible3> ...``.
WIMS crée un exercice OEF par cible sous la forme d'un fichier `src/<cible>.oef`.
Lors de chaque exécution de l'exercice OEF `<cible>.oef`, un programme est choisi aléatoirement parmi tous les programmes de `data/static` dont le nom commence par ``<cible>``.
Il est ainsi possible de définir un exercice OEF prenant en compte tous les programmes ayant un certain thème, ou un certain thème et sous-thème, ou simplement un seul exercice (dans ce dernier cas, la cible doit être le nom du programme complet, sans l'extension ``.cpp``).
Pour chaque cible, le fichier `src/cpp/read_program.cpp` doit contenir les définitions suivantes:
``#if defined TARGET_<cible>
#define TARGET <cible>
#define TARGET_FR <Titre de l'exercice>
#endif``
Importer ou mettre à jour le module sur WIMS
--------------------------------------------
Lancer `make archive` dans ce répertoire. Cela créé une archive:
/tmp/modtool-test~coding~readingCppPrograms.fr.tgz
Charger l'archive dans son compte modtools sur WIMS avec:
wims.u-psud.fr -> serveur de l'université -> Accueil WIMS -> modtools -> login -> Restauration
TODO
----
- data/function_if.cpp:
le contenu de la fonction semble trop compliqué par rapport à ce que
l'on veut tester
- data/procedure-simplest_1.cpp: a conserver?
- data/static/procedure_math_exam_1: ne compile pas
Documentation générique des modules WIMS
========================================
Pour installer des exercices OEF dans un module :
1. Créer un module de type OEF
2. Pour chaque exercice, créer dans le module un nouveau fichier
d'extension oef dans le répertoire src/ (exemple : src/euclide.oef).
Une zone de texte apparaît ; y écrire (ou coller) le texte source
de l'exercice. Enregistrer les changements.
3. Tester le module.
4. Modifier à son goût intro.phtml et endhook.phtml,
et tester à nouveau.
%%%%%% Pour utiliser directement le module sur un serveur WIMS local,
1- Mettre le template à la bonne place,
en changeant le nom.
2. Modifier intro.phtml
3. Modifier le fichier INDEX.
4. Installer les fichiers sources.
5. Exécuter le script $wims_home/other/bin/src2def. (Cette étape
doit être répétée à chaque fois que les fichiers sources sont modifiés).