Proofreading.
This commit is contained in:
parent
3c20ed2657
commit
d56607a714
2
Makefile
2
Makefile
|
@ -14,7 +14,7 @@ output/index.md: $(SRCS)
|
||||||
|
|
||||||
.PHONY: publish
|
.PHONY: publish
|
||||||
publish: static
|
publish: static
|
||||||
rsync -vah --delete output/ mdk@mdk.fr:/var/www/mdk.fr/$DEST/
|
rsync -vah --delete output/ mdk@mdk.fr:/var/www/mdk.fr/$(DEST)/
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
|
|
164
slides.md
164
slides.md
|
@ -9,15 +9,19 @@
|
||||||
<tt>CPython core dev</tt>
|
<tt>CPython core dev</tt>
|
||||||
|
|
||||||
|
|
||||||
# C'est historique.
|
# Demo time !
|
||||||
|
|
||||||
Tu ne peux pas dire qu'HackInScience n'est pas né en 2014, parce que c'est historique.
|
Parce que vous êtes là pour ça.
|
||||||
|
|
||||||
|
::: notes
|
||||||
|
|
||||||
|
Qui à dit « C'est moche ! » ? Je ne suis pas dev front !
|
||||||
|
|
||||||
## Enseigner le Python
|
## Enseigner le Python
|
||||||
|
|
||||||
J'ai l'habitude.
|
J'ai l'habitude.
|
||||||
|
|
||||||
Mais à des groupes de ~6 pendant ~3 jours.
|
Mais à des groupes de ~6 pendant ~3 jours.
|
||||||
|
|
||||||
## C'est green
|
## C'est green
|
||||||
|
|
||||||
|
@ -25,7 +29,11 @@ Mais à des groupes de ~6 pendant ~3 jours.
|
||||||
|
|
||||||
## Enseigner le Python
|
## Enseigner le Python
|
||||||
|
|
||||||
Un jour on m'a proposé un groupe de 50 pendant 7 jours.
|
Un jour on nous a proposé un groupe de 50 pendant 7 jours.
|
||||||
|
|
||||||
|
::: notes
|
||||||
|
|
||||||
|
En fait il sont arrivés à 80.
|
||||||
|
|
||||||
## C'est pas green
|
## C'est pas green
|
||||||
|
|
||||||
|
@ -48,23 +56,8 @@ C'est un petit Django, avec un peu de celery.
|
||||||
|
|
||||||
Pour répartir les corrections sur des machines qui ne font que ça.
|
Pour répartir les corrections sur des machines qui ne font que ça.
|
||||||
|
|
||||||
## Démo en prod !
|
|
||||||
|
|
||||||
https://hackinscience.org
|
## 181 lignes de Python
|
||||||
|
|
||||||
::: notes
|
|
||||||
|
|
||||||
Faire un tour côté teams, et un tour côté admin aussi !
|
|
||||||
|
|
||||||
## C'est moche !
|
|
||||||
|
|
||||||
J'ai dit que j'étais dev, pas dev front, toute aide est la bienvenue.
|
|
||||||
|
|
||||||
::: notes c'est du bootstrap.
|
|
||||||
|
|
||||||
## Je veux voir le code !
|
|
||||||
|
|
||||||
La première version fonctionnelle : 181 lignes de Python.
|
|
||||||
|
|
||||||
Ça devrait loger dans quelques slides ;)
|
Ça devrait loger dans quelques slides ;)
|
||||||
|
|
||||||
|
@ -78,32 +71,10 @@ Aujourd'hui c'est 2700 lignes de code…
|
||||||
```python
|
```python
|
||||||
class Exercise(models.Model):
|
class Exercise(models.Model):
|
||||||
title = models.CharField(max_length=255)
|
title = models.CharField(max_length=255)
|
||||||
check = models.TextField()
|
|
||||||
wording = models.TextField()
|
wording = models.TextField()
|
||||||
|
check = models.TextField()
|
||||||
```
|
```
|
||||||
|
|
||||||
::: notes
|
|
||||||
|
|
||||||
Si vous connaissez déjà Django, concentrez-vous sur le contenu.
|
|
||||||
|
|
||||||
|
|
||||||
## Django models
|
|
||||||
|
|
||||||
Un modèle Django c'est pas just pour l'ORM, ça aide à générer :
|
|
||||||
|
|
||||||
- des migrations de DB ;
|
|
||||||
- l'interface d'admin ;
|
|
||||||
- les formulaires ;
|
|
||||||
- les vues ;
|
|
||||||
- l'API ;
|
|
||||||
- l'autocomplétion dans l'IDE .
|
|
||||||
- les requêtes SQL (l'ORM).
|
|
||||||
|
|
||||||
::: notes
|
|
||||||
|
|
||||||
Un modèle permet au code de connaître de la structure de la base de donnée. Il n'est plus aveugle. C'est bien.
|
|
||||||
|
|
||||||
|
|
||||||
## Django view
|
## Django view
|
||||||
|
|
||||||
```python
|
```python
|
||||||
|
@ -111,6 +82,9 @@ class ExerciseListView(LoginRequiredMixin, ListView):
|
||||||
model = Exercise
|
model = Exercise
|
||||||
template_name = "hkis/exercises.html"
|
template_name = "hkis/exercises.html"
|
||||||
|
|
||||||
|
class ExerciseView(LoginRequiredMixin, DetailView):
|
||||||
|
model = Exercise
|
||||||
|
template_name = "hkis/exercise.html"
|
||||||
```
|
```
|
||||||
|
|
||||||
::: notes
|
::: notes
|
||||||
|
@ -121,18 +95,10 @@ Ici il est garanti que les méthodes surchargées par `LoginRequiredMixin`
|
||||||
sont exécutées avant celles de `ListView`.
|
sont exécutées avant celles de `ListView`.
|
||||||
|
|
||||||
|
|
||||||
## Django view
|
|
||||||
|
|
||||||
```python
|
|
||||||
class ExerciseView(LoginRequiredMixin, DetailView):
|
|
||||||
model = Exercise
|
|
||||||
template_name = "hkis/exercise.html"
|
|
||||||
```
|
|
||||||
|
|
||||||
## Une petite API
|
## Une petite API
|
||||||
|
|
||||||
```python
|
```python
|
||||||
class ExerciseSerializer(serializers.HyperlinkedModelSerializer):
|
class ExerciseSerializer(HyperlinkedModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Exercise
|
model = Exercise
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
@ -182,11 +148,11 @@ Aucun tracker, aucune pub, aucun asset externe.
|
||||||
|
|
||||||
10k c'est peu ou beaucoup, je ne sais pas.
|
10k c'est peu ou beaucoup, je ne sais pas.
|
||||||
|
|
||||||
## Ça tient la charge ?
|
## Ça tient la charge ?
|
||||||
|
|
||||||
Les exercices sont corrigés en environ 200ms,
|
Les exercices sont corrigés en environ 200ms.
|
||||||
|
|
||||||
Deux serveurs se répartissent le travail (et ils s'ennuient).
|
Deux serveurs se répartissent le travail.
|
||||||
|
|
||||||
Les boucles infinies sont interrompues après 20s.
|
Les boucles infinies sont interrompues après 20s.
|
||||||
|
|
||||||
|
@ -194,82 +160,60 @@ Les boucles infinies sont interrompues après 20s.
|
||||||
|
|
||||||
Il est très facile d'ajouter un serveur de correction au besoin.
|
Il est très facile d'ajouter un serveur de correction au besoin.
|
||||||
|
|
||||||
|
|
||||||
|
## C'est rentable ?
|
||||||
|
|
||||||
|
Ren…quoi ? Pardon ?
|
||||||
|
|
||||||
|
J'ai pas de « business model », et non mon projet ne va pas « mourir demain » pour autant #sry.
|
||||||
|
|
||||||
|
::: notes
|
||||||
|
|
||||||
|
Afficher la page des sponsors, remercier les sponsors et Gandi.
|
||||||
|
|
||||||
|
En fait c'est rentable, juste pas de beaucoup mais OSEF !
|
||||||
|
|
||||||
|
|
||||||
# Côté sécu
|
# Côté sécu
|
||||||
|
|
||||||
Le code de chaque exercice est exécuté côté serveur, c'est un challenge niveau sécurité.
|
Les rendus sont exécutés côté serveur.
|
||||||
|
|
||||||
|
C'est un challenge niveau sécurité.
|
||||||
|
|
||||||
::: notes
|
::: notes
|
||||||
|
|
||||||
Python est réputé pour ne pas être sandboxable, du moins pas depuis l'intérieur de l'interpréteur.
|
Python est réputé pour ne pas être sandboxable, du moins pas depuis l'intérieur de l'interpréteur.
|
||||||
|
|
||||||
|
|
||||||
## Namespaces Linux + seccomp + rlimit
|
|
||||||
|
|
||||||
Les exercices sont exécutés dans des environements très restreints.
|
|
||||||
|
|
||||||
## seccomp
|
## seccomp
|
||||||
|
|
||||||
`seccomp` (*secure computing*) c'est un outil du kernel Linux pour
|
\+ Linux namespaces
|
||||||
limiter les appels systèmes que peuvent faire les programmes.
|
|
||||||
|
|
||||||
## rlimit
|
\+ rlimit
|
||||||
|
|
||||||
`rlimit` (*resource limit*) c'est un moyen de limiter les resources utilisées par un programme.
|
|
||||||
|
|
||||||
On limite par exemple à 20s de CPU, 2000 threads, 100 fichiers ouverts, 1GB de RAM, ….
|
|
||||||
|
|
||||||
## namespaces
|
|
||||||
|
|
||||||
C'est aussi une fonctionalité du kernel Linux, elle permet de faire
|
|
||||||
croire à un processus qu'il a une ressource « juste pour lui ».
|
|
||||||
|
|
||||||
## C'est compliqué
|
|
||||||
|
|
||||||
Configurer setccomp, rlimit, les namespaces, la vie et le reste
|
|
||||||
correctement, c'est pas simple.
|
|
||||||
|
|
||||||
Nous on utilise [firejail](https://github.com/netblue30/firejail).
|
|
||||||
|
|
||||||
## C'est simple
|
|
||||||
|
|
||||||
Un petit appercu de comment on lance firejail :
|
|
||||||
|
|
||||||
|
|
||||||
```python
|
|
||||||
FIREJAIL_OPTIONS = [
|
|
||||||
"--net=none",
|
|
||||||
"--shell=none",
|
|
||||||
"--x11=none",
|
|
||||||
"--private-dev",
|
|
||||||
"--private-tmp",
|
|
||||||
"--caps.drop=all",
|
|
||||||
"--nonewprivs",
|
|
||||||
"--nosound",
|
|
||||||
"--no3d",
|
|
||||||
"--noroot",
|
|
||||||
"--seccomp",
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
::: notes
|
::: notes
|
||||||
|
|
||||||
C'est rassurant écrit comme ça, mais on sait que rien n'est parfait…
|
Pourquoi pas Docker ? Pas besoin d'un filesystem complet, juste d'un processus.
|
||||||
|
|
||||||
# La rédaction d'exercices
|
# Vu d'un enseignant
|
||||||
|
|
||||||
## Via l'interface d'admin
|
::: notes
|
||||||
|
|
||||||
## Via un repo git
|
Vous êtes libres de quitter la salle.
|
||||||
|
|
||||||
|
## L'interface d'admin
|
||||||
|
|
||||||
|
## Un repo git
|
||||||
|
|
||||||
|
Juste pour les exos.
|
||||||
|
|
||||||
# L'hébergement d'instances locales
|
# L'hébergement d'instances locales
|
||||||
|
|
||||||
# L'API
|
# Mot de la fin
|
||||||
|
|
||||||
# L'AFPy
|
Si vous aimez Python, n'oubliez pas la PyConFr !
|
||||||
|
|
||||||
La PyConFr
|
Du 16 au 19 février 2023 !
|
||||||
|
|
||||||
# Gandi
|
|
||||||
|
|
||||||
# Questions
|
# Questions
|
||||||
|
|
||||||
|
@ -278,3 +222,5 @@ La PyConFr
|
||||||
- HTTP : https://mdk.fr
|
- HTTP : https://mdk.fr
|
||||||
- SMTP : julien@python.org
|
- SMTP : julien@python.org
|
||||||
- Whatsapp : HAHAHA jamais.
|
- Whatsapp : HAHAHA jamais.
|
||||||
|
- Insta : Et puis quoi encore ?
|
||||||
|
- TikTok : SSTTTTOOOOOOOOP !
|
||||||
|
|
Reference in New Issue