Skip to content
Snippets Groups Projects
Commit 43e5c9fd authored by Vincent MAZENOD's avatar Vincent MAZENOD
Browse files

Merge branch 'working-docker' into 'master'

Working docker

See merge request !4
parents 841ad440 b4ca4b82
No related branches found
No related tags found
1 merge request!4Working docker
Pipeline #9339 passed
Showing
with 245 additions and 736 deletions
# FROM nikolaik/python-nodejs:python3.7-nodejs16-bullseye AS compile-image
FROM nikolaik/python-nodejs:python3.7-nodejs16-bullseye AS source-image
FROM debian:stable
ARG DEBIAN_FRONTEND=noninteractive
RUN { \
......@@ -9,11 +8,9 @@ RUN { \
} | debconf-set-selections \
&& \
apt-get update && apt-get install -y --no-install-recommends \
build-essential \
gcc \
apt-utils \
krb5-user \
krb5-config \
openssh-client \
locales \
rsync \
&& \
......@@ -22,33 +19,4 @@ RUN { \
update-locale LANG=fr_FR.UTF-8 \
. /etc/default/locale
COPY requirements.txt .
RUN pip install --user -r requirements.txt
COPY content/package.json ./content/package.json
RUN cd content && yarn install
# FROM nikolaik/python-nodejs:python3.7-nodejs16-bullseye AS build-image
# COPY --from=compile-image /root/.local /root/.local
# COPY --from=compile-image /usr/bin /usr/bin
# COPY --from=compile-image /usr/lib/x86_64-linux-gnu /usr/lib/x86_64-linux-gnu
# LABEL stage=builder
ENV SRV_DIR=//srv
ENV WORKING_DIR=//srv/pelican
ENV PORT=8000
ENV PATH=/root/.local/bin:$PATH
ADD . $SRV_DIR
WORKDIR $WORKING_DIR
RUN mkdir output content cache
# VOLUME ["$WORKING_DIR/"]
# make python server in foreground
RUN sed -i 's/\$port &/\$port/g' $SRV_DIR/develop_server.sh
RUN chmod +x $SRV_DIR/develop_server.sh
EXPOSE $PORT
ENTRYPOINT $SRV_DIR/develop_server.sh start $PORT
WORKDIR /srv/blog
\ No newline at end of file
FROM debian:stable
RUN apt-get update && apt-get install -y --no-install-recommends \
python3 \
python3-pip \
locales \
&& \
locale-gen fr_FR \
locale-gen fr_FR.UTF-8 \
update-locale LANG=fr_FR.UTF-8 \
. /etc/default/locale
COPY requirements.txt .
RUN pip install --user -r requirements.txt
WORKDIR /srv/blog
\ No newline at end of file
source .env
SSH_CMD="ssh -o StrictHostKeyChecking=no -K ${KRB_USER}@${SERVER}"
RSYNC_CMD=''
kinit ${KRB_USER}
${SSH_CMD} "mkdir -p ~/public_html/"
${SSH_CMD} "echo 'Options +FollowSymLinks' > ~/public_html/.htaccess"
${SSH_CMD} "echo 'RewriteEngine on' >> ~/public_html/.htaccess"
${SSH_CMD} "echo 'RewriteCond %{HTTP_HOST} ^perso.isima.fr$' >> ~/public_html/.htaccess"
${SSH_CMD} "echo 'RewriteRule (.*) https://perso.limos.fr%{REQUEST_URI} [R=301,L]' >> ~/public_html/.htaccess"
${SSH_CMD} "mkdir -p ~/public_html/_"
${SSH_CMD} "echo '<FilesMatch "\.phar">' > ~/public_html/_/.htaccess"
${SSH_CMD} "echo ' php_flag engine off' >> ~/public_html/_/.htaccess"
${SSH_CMD} "echo ' ForceType application/octet-stream' >> ~/public_html/_/.htaccess"
${SSH_CMD} "echo ' Header set Content-Disposition attachment' >> ~/public_html/_/.htaccess"
${SSH_CMD} "echo '</FilesMatch>' >> ~/public_html/_/.htaccess"
rsync -az --exclude "_" -e "ssh -o StrictHostKeyChecking=no -K" ./output/ ${KRB_USER}@${SERVER}:~/public_html/
\ No newline at end of file
cd /srv/blog/content/slides
yarn
\ No newline at end of file
git submodule init
git submodule update --recursive --remote
sed -i 's/\$port &/\$port/g' ./develop_server.sh
chmod +x develop_server.sh
export PATH=/root/.local/bin:$PATH
export PY='/usr/bin/python3'
./develop_server.sh start 8000
\ No newline at end of file
PORT=8001
REGISTRY_URL=docker.isima.fr
NAMESPACE=docker.isima.fr/vimazeno
APP_NAME=pelican_perso
\ No newline at end of file
APP_NAME=pelican_perso
KRB_USER=vimazeno
SERVER=perso.local.isima.fr
image: docker.isima.fr/vimazeno/pelican_perso
cache:
paths:
- output/ # le répertoire où se trouve le HTML statique généré
.pre:
image: node:latest
stage: .pre
script:
- cd /srv/blog/content/slides && yarn
build:
image: docker.isima.fr/vimazeno/pelican_perso_python:35046e8
stage: build
script:
- git submodule init
- git submodule update --recursive --remote
- PATH=/root/.local/bin:$PATH pelican
deploy:
image: docker.isima.fr/vimazeno/pelican_perso_kerberos:35046e8
stage: deploy
script:
# récupération du KEYTAB en hexa
- ls
- echo "$KEYTAB" > my.keytab.hex
# conversion du KEYTAB en hexa en binaire
- sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI' my.keytab.hex | xargs printf > my.keytab
......@@ -27,8 +39,4 @@ build:
- ssh -o StrictHostKeyChecking=no -K vimazeno@perso.local.isima.fr "echo ' Header set Content-Disposition attachment' >> ~/public_html/_/.htaccess"
- ssh -o StrictHostKeyChecking=no -K vimazeno@perso.local.isima.fr "echo '</FilesMatch>' >> ~/public_html/_/.htaccess"
# rsync du HTML statique généré
- rsync -az --exclude '_' -e "ssh -o StrictHostKeyChecking=no -K" output/ vimazeno@perso.local.isima.fr:~/public_html/
- ssh -o StrictHostKeyChecking=no -K vimazeno@perso.local.isima.fr "mkdir -p ~/public_html/node_modules"
- rsync -az -e "ssh -o StrictHostKeyChecking=no -K" content/node_modules/ vimazeno@perso.local.isima.fr:~/public_html/node_modules
# le déploiement se fera uniquement lorsque je clique sur le "play" de la CI via l'interface gitlab
when: manual
\ No newline at end of file
- rsync -az --exclude '_' -e "ssh -o StrictHostKeyChecking=no -K" output/ vimazeno@perso.local.isima.fr:~/public_html/
\ No newline at end of file
......@@ -16,25 +16,34 @@ DOCKER_COMP := docker-compose
.DEFAULT_GOAL := help
# Docker containers
PELICAN_CONT := $(DOCKER_COMP) exec pelican
KERBEROS_CONT := $(DOCKER_COMP) run kerberos
include .env
build: ## Build required docker compose images
@$(DOCKER_COMP) build
@docker image prune -f --filter label=stage=source-image
@docker image prune -f --filter label=stage=build-image
.PHONY: build
push: ## Push build docker compose images
@TAG=$(shell git rev-parse --short HEAD)
@docker login ${REGISTRY_URL}
@docker push ${NAMESPACE}/${APP_NAME}:latest
@docker image tag ${NAMESPACE}/${APP_NAME}:latest ${NAMESPACE}/${APP_NAME}:${TAG}
@docker push ${NAMESPACE}/${APP_NAME}:${TAG} ;
@docker push ${NAMESPACE}/${APP_NAME}_python:latest ;
@docker tag ${NAMESPACE}/${APP_NAME}_python:latest ${NAMESPACE}/${APP_NAME}_python:${TAG} ;
@docker push ${NAMESPACE}/${APP_NAME}_python:${TAG} ;
@docker push ${NAMESPACE}/${APP_NAME}_kerberos:latest ;
@docker tag ${NAMESPACE}/${APP_NAME}_kerberos:latest ${NAMESPACE}/${APP_NAME}_kerberos:${TAG} ;
@docker push ${NAMESPACE}/${APP_NAME}_kerberos:${TAG} ;
.PHONY: push
up: ## Make required containers up
@$(DOCKER_COMP) up --remove-orphans
@$(DOCKER_COMP) up --remove-orphans node
@echo -e "⏰ ${BOLD}${GREEN}Wait for node to install needed js (there's no problem we're just wait)...${RESET}"
@$(DOCKER_COMP) run dockerize -timeout 180s -wait-retry-interval 3s \
-wait file:///tmp/content/node_modules/.yarn-integrity ;
@echo -e "⏰ ${BOLD}${GREEN}Wait for pelican to generate content (there's no problem we're just wait)...${RESET}"
@echo -e "${GREEN}${BOLD}up and running${RESET}"
@echo -e " 🐳 blog in docker ${BLUE}${BOLD}http://localhost:${PORT}${RESET}"
@$(DOCKER_COMP) up --remove-orphans python
.PHONY: up
down: ## Make required containers down
......@@ -54,9 +63,9 @@ errors: ## Show live container errors.
@$(DOCKER_COMP) logs | grep error
.PHONY: errors
pelican: ## Open bash on php container
@$(PELICAN_CONT) bash
.PHONY: pelican
publish: ## Open bash on php container
@$(KERBEROS_CONT) bash .docker/scripts/kerberos/command.dev.sh
.PHONY: publish
clean: ## Remove node and php folders and files
@for volume in ${VOLUMES} ; do \
......@@ -64,6 +73,10 @@ clean: ## Remove node and php folders and files
done
.PHONY: clean
slides: ## Force slides refresh
@sudo cp -R content/slides output/
.PHONY: slides
help:
@grep -h -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
.PHONY: help
\ No newline at end of file
Title: ZZ2 F5 - Securité logicielle - sécurité des applications web
Date: 2021-09-20 10:55
Date: 2022-09-13 10:55
Category: <i class='fa fa-graduation-cap' aria-hidden='true'></i> &Eacute;tudiants
Tags: cours
......
......@@ -9,7 +9,7 @@
"author": "",
"license": "ISC",
"dependencies": {
"font-awesome": "^4.7.0",
"@fortawesome/fontawesome-free": "^6.1.1",
"reveal.js": "^3.5.0"
}
}
......@@ -9,18 +9,26 @@ Number: 2
## <i class="fas fa-desktop"></i> Ingénieur de Recherche Informatique au CNRS <a class="expand btn btn-primary float-right">version courte</a>
### "You can't defend. You can't prevent. The only thing you can do is detect and respond." *Bruce Schneier*
### <i class="fas fa-quote-left"></i>You can't defend. You can't prevent. The only thing you can do is detect and respond.<i class="fas fa-quote-right"></i> <span style="float:right;font-size: smaller; padding-top: 15px;">*Bruce Schneier*</span>
<hr />
* Je travaille au [LIMOS](htttps://limos.fr) UMR (CNRS/UCA/EMSE) hébergée par l'[ISIMA](htttps://isima.fr)
<center>
#### En poste au [LIMOS](htttps://limos.fr), UMR (CNRS/UCA/EMSE), hébergée par l'[ISIMA](htttps://isima.fr)
</center>
<hr />
* Je supervise <a name="cri" class="toggle"><i class="fas fa-users-cog"></i>l'équipe informatique commune CRI ISIMA / LIMOS</a>
* <i id="cri" class="fas fa-users-cog"></i> équipe commune CRI ISIMA / LIMOS
* composée de 2 ingénieurs d'études et 5 techniciens
* composée de 3 ingénieurs d'études et 5 techniciens
* animation et gestion de l'équipe
* suivi de tous les projets de l'équipe
* gestion du budget
* interlocuteur [UCA](https://uca.fr) / nouvel INP
* interlocuteur [UCA](https://uca.fr) / [INP](https://www.clermont-auvergne-inp.fr/)
* blog du [CRI ISIMA / LIMOS](https://cri.isima.fr)
<hr />
......@@ -93,6 +101,7 @@ Number: 2
* J'interviens dans différents contextes sur <a name="talks" class="toggle"><i class="fas fa-comment"></i> diverses thématiques</a>
* <i id="talks" class="fas fa-comment"></i> interventions
* 07/06/2022 pour les [journées Proxmox VE / Ceph 2022](https://indico.mathrice.fr/event/327/): [Proxmox VE & DevOps](https://webtv.uca.fr/video/c82cf242-bbb0-427a-b5d6-b44c700f9409?time=4h27m12s)
* 15/01/2021 pour [La Montagne](https://www.lamontagne.fr/): [Les cyberattaques, retour sur ce virus qui touche les organismes de santé en France en plein Covid-19](https://www.lamontagne.fr/paris-75000/actualites/les-cyberattaques-retour-sur-ce-virus-qui-touche-les-organismes-de-sante-en-france-en-plein-covid-19_13900627/)
* 27/11/2020 pour [Subatech](http://www-subatech.in2p3.fr/fr/): [sécurité et navigateur](/slides/privacy/browser.html)
* 01/12/2020 pour [Le GRIN](https://legrin.fr/): [ÉPIDÉMIE(S)#25 - Peut-on encore compter sur le progrès?](https://podcast.ausha.co/epidemie-s/epidemie-s-25-peut-on-encore-compter-sur-le-progres) (avec [Yves Caseau](https://www.linkedin.com/in/ycaseau/))
......@@ -111,4 +120,6 @@ Number: 2
<!-- * 16/12/2014 pour [Clermont'ech](https://www.clermontech.org): [la PSSI de la nation](https://www.youtube.com/watch?v=jdWDdY2IdEw) -->
<hr />
* Je suis président de l'association <i class="far fa-file-code"></i> [AuDACES, réseau régional de DevLOG](http://audaces.asso.st/)
\ No newline at end of file
* Je suis président de l'association <a name="audaces" class="toggle"><i class="far fa-file-code"></i></a> [AuDACES, réseau régional de DevLOG](http://audaces.asso.st/)
* <i id="audaces" class="far fa-file-code"></i> événement
* co-organisateur des [journées Proxmox VE / Ceph 2022](https://indico.mathrice.fr/event/327/)
\ No newline at end of file
# CRI
## service CRI ISIMA / LIMOS
## INP / ISIMA / LIMOS
![service CRI ISIMA / LIMOS](https://support.isima.fr/upload/logo/cri_.png)<!-- .element width="30%" -->
### Vincent Mazenod
[vincent.mazenod@isima.fr](maitlo:vincent.mazenod@isima.fr)
#### responsable de service
## CRI INP / ISIMA / LIMOS
## 🔧 service CRI ISIMA / LIMOS
* [missions](https://doc.isima.fr/cri/#ses-missions)
* [organisation](https://doc.isima.fr/cri/#support)
* [composition](https://doc.isima.fr/cri/#composition)
* [Missions](https://doc.isima.fr/support/cri#3-missions) / [organisation](https://doc.isima.fr/cri#1-organisation-du-support)
* [Composition](https://doc.isima.fr/support/cri#2-composition)
* 7 membres support (A109 /A115)
* documentation ([https://doc.isima.fr](https://doc.isima.fr))
* support
* [tickets incidents/demandes](https://support.isima.fr)([https://support.isima.fr](https://support.isima.fr))
* Bureau A109
* Téléphone 0473405262
* ### 📘 [https://doc.isima.fr](https://doc.isima.fr)
* 💁 Support
* 🎫 [tickets incidents/demandes](https://support.isima.fr)
* [https://support.isima.fr](https://support.isima.fr)
* 🏨 Bureau A109
* 📞 Téléphone 0473405262
## Inscription (1/2)
## 📝 Inscription (1/2)
* [https://inscription.uca.fr](https://inscription.uca.fr)
* se munir de son numéro CVEC
......@@ -32,38 +33,39 @@
* **n°étudiant** + **date de naissance** + **mail personnel**
## Inscription (2/2)
## 📝 Inscription (2/2)
* Règlement financier pour finaliser l'inscription
* 💵 Règlement financier pour finaliser l'inscription
* Orion Web (INP)
* **Questions Scola**:
* scolarite@isima.fr
* Bureau A010
* 💬 Questions Scola:
* 📨 [scolarite@isima.fr](mailto:scolarite@isima.fr)
* 🏨 Bureau A010
## Compte UCA
## 🔌 Compte UCA
* ENT ([https://ent.uca.fr](https://ent.uca.fr))
* 🏦 ENT ([https://ent.uca.fr](https://ent.uca.fr))
* mon compte > mot de passe
* notes
* emplois du temps
* cours en ligne
* Mail ([https://mail.uca.fr](https://mail.uca.fr))
* 📨 [Mail](https://doc.isima.fr/services/mail/uca) ([https://mail.uca.fr](https://mail.uca.fr))
* prenom.nom@etu.uca.fr
* prenom.nom@etu.isima.fr (alias)
## Compte UCA
## 🔖 Services UCA
* Drive
* [https://drive.uca.fr/](https://drive.uca.fr/)
* [1 To sur OneDrive](https://confluence.dsi.uca.fr/display/KBUCA/%5BOffice+365%5D+-+Profiter+du+stockage+en+ligne+avec+OneDrive)
* WiFi ([https://cat.eduroam.org](https://cat.eduroam.org))
* Teams ([https://teams.microsoft.com](https://teams.microsoft.com))
* 📶 [WiFi (Eduroam)](https://doc.isima.fr/locaux/wifi) ([https://cat.eduroam.org](https://cat.eduroam.org))
* 📹 [Teams](https://doc.isima.fr/services/visio/teams) ([https://teams.microsoft.com](https://teams.microsoft.com))
* 📁 Drive
* [drive UCA (Seafile)](https://doc.isima.fr/services/stockage/seafile) [https://drive.uca.fr/](https://drive.uca.fr/)
* [OneDrive (1To)](https://doc.isima.fr/services/stockage/owncloud)
* 🔍 [Catalogue de services UCA](https://dsi.uca.fr/catalogue-de-services)
## Mots de passe
## 🔐 Mots de passe
* ça ne se prête pas
* ça ne se laisse pas traîner à la vue de tous
......@@ -75,19 +77,20 @@
* mieux vaut les avoir avec soi
## C'est une question d'hygiène!
## 💉 question d'hygiène!
![preservatif](images/preservatif-darvador.jpg)<!-- .element width="30%" -->
[CNIL / Authentification par mot de passe : les mesures de sécurité élémentaires](https://www.cnil.fr/fr/authentification-par-mot-de-passe-les-mesures-de-securite-elementaires)
* [CNIL / Authentification par mot de passe : les mesures de sécurité élémentaires](https://www.cnil.fr/fr/authentification-par-mot-de-passe-les-mesures-de-securite-elementaires)
* [ANSSI / Recommandations relatives à l'authenbtification multifacteur et aux mots de passe](https://www.ssi.gouv.fr/guide/recommandations-relatives-a-lauthentification-multifacteur-et-aux-mots-de-passe/)
## Locaux
## 🏦 [Locaux](https://doc.isima.fr/locaux/salles)
![bâtiments](images/batiments.png "batiments")
## Salles informatiques
## 🖥 [Salles informatiques](https://doc.isima.fr/pedagogie/salles)
* Salles PC :
* Dual boot Windows / Linux
......@@ -100,99 +103,85 @@
* réalité virtuelle
## Salles informatiques
## 🖥 [Salles informatiques](https://doc.isima.fr/pedagogie/salles)
* Salles Tx :
* D013 et D018 (libre accès de 7h30 à 18h45 en semaine)
* D013 et 💻 D018 (libre accès de 7h30 à 18h45 en semaine)
* Laboratoire de langue : G116 (Bâtiment Pôle Commun)
* Salles de cours
## Serveurs pédagogiques
## 🖥 [Serveurs pédagogiques](https://doc.isima.fr/pedagogie/serveurs)
* TSE1 (MS Windows server 2016R2)
* Ada (GNU/Linux Debian)
* Turing (GNU/Linux Debian)
* Exam (GNU/Linux CentOS 6 isolé)
* Connexion possible
* ssh ([https://doc.isima.fr/ssh/acces_externe/](https://doc.isima.fr/ssh/acces_externe/))
* 🔌 Connexion possible
* ssh (kerberos)
* RDP
* guacamole([https://guacamole.isima.fr](https://guacamole.isima.fr))
* xRDP
## VMs Perso
## 🖥 [VM Perso](https://doc.isima.fr/pedagogie/vm)
* Debian 11 / KDE
* Connexion possible
* ssh ([https://doc.isima.fr/ssh/acces_externe/](https://doc.isima.fr/ssh/acces_externe/))
* 🔌 Connexion possible
* ssh (kerberos)
* RDP
* guacamole([https://guacamole.isima.fr](https://guacamole.isima.fr))
* xRDP
* Eteinte toutes les nuits à
* 😴 Eteinte toutes les nuits à 2h00 du matin
## Authentification
## 🕵🏼 [Authentification](https://doc.isima.fr/authentification)
* Compte UCA pour tout
* ouverture de session (Windows ou Linux)
* ssh
* serveurs péda, VMs perso, dirs
* authentification aux services
* guacamole, gitlab
* 🔌 Compte UCA pour **tous les services**
* guacamole, gitlab, support, ...
* ouverture de session
* impressions
* Pas de compte = pas de service
* S'inscrire avant le 9 septembre!
* 😥 Pas de compte = pas de service
* S'inscrire avant le 9 septembre!
## Données (homedir)
## 💾 [Données (~/shared)](https://doc.isima.fr/stockage/shared)
* != drive.uca.fr
* dirs.local.isima.fr
* ssh
* ssh (kerberos)
* nfs
* samba
* Montage PARTOUT
* Répertoire « shared » sous GNU/Linux
* Montage réseau sous MS Windows et MacOS
* Montage automatique PARTOUT
* Répertoire `~/shared` sous GNU/Linux et MacOS
* Montage réseau `P:\\` sous MS Windows
## WARNING!!
## 💀 WARNING!!
* Tout peut être réinstallé à tout moment
* 🤦 Tout peut être réinstallé à tout moment
* Les salles machine
* Les serveurs péda
* Votre VM Perso
* votre homedir monté partout est le seul répertoire sauvegardé
* 🙇🏼 `~/shared` et `P:\\` est le seul répertoire sauvegardé
* Tout le reste peut disparâitre
* A tout moment!!
## Services
## 🕸 Services
* Gitlab : https://gitlab.isima.fr
* Guacamole : https://guacamole.isima.fr
* VPN : https://doc.isima.fr/vpn/presentation/
* Une plateforme de Cloud Computing (accès restreint)
* Hedgedoc : https://hedgedoc.isima.fr
* VPN
* Une plateforme de Cloud Computing
* contacter le [service CRI ISIMA/LIMOS](https://doc.isima.fr/support/cri)
* Plateforme HPC (accès restreint)
* Une page web personnel
* contacter [Hélène Toussaint](mailto:helene.toussaint@isima.fr)
* Page web personnel
* https://perso.isima.fr/~login
* répertoire "public_html" du homedir
* [https://doc.isima.fr/homepage/perso](https://doc.isima.fr/homepage/perso/)
## Serveurs de calcul (HPC)
* https://hpc.isima.fr/
## Cloud
* sur demande auprès de l'équipe
* soumis à condition
## Logiciels
## 🎁 Logiciels
* Microsoft Office et Office 365
* https://doc.isima.fr/Imagine/office/
......@@ -200,19 +189,19 @@
* https://doc.isima.fr/Imagine/imagine/
## Ressources et cadres
## 👋 [Cadres légaux](https://doc.isima.fr/support/cadres)
* Les ressources informatiques ont pour objet la formation et la
recherche
* Respecter les usages prévus et le travail des autres (scolaire, propriété intellectuelle, ...)
* [Charte générale à l'usage des ressources nuémriques / UCA](https://www.uca.fr/medias/fichier/deliberation-ca-2017-10-27-21-charte-des-usages-numeriques-et-des-administrateurs-techniques-annexe_1509372123880-pdf)
* [Règlment ISIMA](https://ent.uca.fr/moodle/mod/page/view.php?id=263490)
* [Cadre national / ANSSI](https://www.ssi.gouv.fr/en/)
* Sanction disciplinaires et pénales
* Soyez "fair": si vous trouvez, signalez au CRI :)
* [règlement intérieur de l'ISIMA](https://ent.uca.fr/moodle/mod/page/view.php?id=263490)
* [Charte générale à l'usage des ressources numériques / UCA](https://www.uca.fr/medias/fichier/deliberation-ca-2017-10-27-21-charte-des-usages-numeriques-et-des-administrateurs-techniques-annexe_1509372123880-pdf)
* Cadre national [ANSSI](https://www.ssi.gouv.fr/en/), [PSSIE](https://www.ssi.gouv.fr/entreprise/reglementation/protection-des-systemes-dinformations/la-politique-de-securite-des-systemes-dinformation-de-letat-pssie/)
* Sanctions disciplinaires et pénales
* 🙏 Soyez "fair"
* si vous trouvez, 😎 signalez au [service CRI ISIMA/LIMOS](https://doc.isima.fr/support/cri)
## Des questions ????
## 💬 Des questions ????
* https://doc.isima.fr
* https://support.isima
\ No newline at end of file
* 📘 https://doc.isima.fr
* 🎫 https://support.isima
* 🤗 typo et suggestions
* https://gitlab.isima.fr/vimazeno/blog.limos.fr
\ No newline at end of file
......@@ -2,10 +2,10 @@
# yarn lockfile v1
font-awesome@^4.7.0:
version "4.7.0"
resolved "https://registry.yarnpkg.com/font-awesome/-/font-awesome-4.7.0.tgz#8fa8cf0411a1a31afd07b06d2902bb9fc815a133"
integrity sha1-j6jPBBGhoxr9B7BtKQK7n8gVoTM=
"@fortawesome/fontawesome-free@^6.1.1":
version "6.1.2"
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-6.1.2.tgz#d18880eddeadd42b1c64cb559f2f3d13d47a4a64"
integrity sha512-XwWADtfdSN73/udaFm+1mnGIj/ShDZNFMe/PRoqv3FhQ4GNI2PUN70yFTPsjq65Lw2C9i4TG5/hTbxXIXVCiqQ==
reveal.js@^3.5.0:
version "3.9.2"
......
......@@ -67,7 +67,7 @@ function start_up(){
pelican_pid=$!
echo $pelican_pid > $PELICAN_PID
mkdir -p $OUTPUTDIR && cd $OUTPUTDIR
$PY -m pelican.server $port &
$PY -m pelican.server $port
srv_pid=$!
echo $srv_pid > $SRV_PID
cd $BASEDIR
......
......@@ -2,15 +2,44 @@ version: '3.5'
services:
pelican:
image: ${NAMESPACE}/${APP_NAME}:latest
node:
image: node:latest
container_name: ${APP_NAME}_node
environment:
TZ: ${TIMEZONE:-Europe/Paris}
working_dir: /srv/blog
volumes:
- .:/srv/blog
command: bash /srv/blog/.docker/scripts/node/command.dev.sh
python:
image: ${NAMESPACE}/${APP_NAME}_python:latest
build:
context: .
dockerfile: .docker/build/pelican/Dockerfile
container_name: pelican
dockerfile: .docker/build/python/Dockerfile
container_name: ${APP_NAME}_python
environment:
TZ: ${TIMEZONE:-Europe/Paris}
# volumes:
# - .:/srv/pelican
working_dir: /srv/blog
volumes:
- .:/srv/blog
ports:
- "8000:8000"
\ No newline at end of file
- "${PORT-8000}:8000"
command: bash /srv/blog/.docker/scripts/python/command.dev.sh
kerberos:
image: ${NAMESPACE}/${APP_NAME}_kerberos:latest
build:
context: .
dockerfile: .docker/build/kerberos/Dockerfile
container_name: ${APP_NAME}_kerberos
environment:
TZ: ${TIMEZONE:-Europe/Paris}
volumes:
- .:/srv/blog
command: bash /srv/blog/.docker/scripts/kerberos/command.dev.sh
dockerize:
image: jwilder/dockerize
volumes:
- .:/tmp
\ No newline at end of file
......@@ -57,7 +57,7 @@ SOCIAL = (
(
'users-cog',
'<span style="font-size:13px">CRI ISIMA/LIMOS</span>',
'/content/slides/cri/cri.html'
'./slides/cri/cri.html'
),
(
'building',
......
=======================
I18N Sub-sites Plugin
=======================
This plugin extends the translations functionality by creating
internationalized sub-sites for the default site.
This plugin is designed for Pelican 3.4 and later.
What it does
============
1. When the content of the main site is being generated, the settings
are saved and the generation stops when content is ready to be
written. While reading source files and generating content objects,
the output queue is modified in certain ways:
- translations that will appear as native in a different (sub-)site
will be removed
- untranslated articles will be transformed to drafts if
``I18N_UNTRANSLATED_ARTICLES`` is ``'hide'`` (default), removed if
``'remove'`` or kept as they are if ``'keep'``.
- untranslated pages will be transformed into hidden pages if
``I18N_UNTRANSLATED_PAGES`` is ``'hide'`` (default), removed if
``'remove'`` or kept as they are if ``'keep'``.''
- additional content manipulation similar to articles and pages can
be specified for custom generators in the ``I18N_GENERATOR_INFO``
setting.
2. For each language specified in the ``I18N_SUBSITES`` dictionary the
settings overrides are applied to the settings from the main site
and a new sub-site is generated in the same way as with the main
site until content is ready to be written.
3. When all (sub-)sites are waiting for content writing, all removed
contents, translations and static files are interlinked across the
(sub-)sites.
4. Finally, all the output is written.
Setting it up
=============
For each extra used language code, a language-specific settings overrides
dictionary must be given (but can be empty) in the ``I18N_SUBSITES`` dictionary
.. code-block:: python
PLUGINS = ['i18n_subsites', ...]
# mapping: language_code -> settings_overrides_dict
I18N_SUBSITES = {
'cz': {
'SITENAME': 'Hezkej blog',
}
}
Default and special overrides
-----------------------------
The settings overrides may contain arbitrary settings, however, there
are some that are handled in a special way:
``SITEURL``
Any overrides to this setting should ensure that there is some level
of hierarchy between all (sub-)sites, because Pelican makes all URLs
relative to ``SITEURL`` and the plugin can only cross-link between
the sites using this hierarchy. For instance, with the main site
``http://example.com`` a sub-site ``http://example.com/de`` will
work, but ``http://de.example.com`` will not. If not overridden, the
language code (the language identifier used in the ``lang``
metadata) is appended to the main ``SITEURL`` for each sub-site.
``OUTPUT_PATH``, ``CACHE_PATH``
If not overridden, the language code is appended as with ``SITEURL``.
Separate cache paths are required as parser results depend on the locale.
``STATIC_PATHS``, ``THEME_STATIC_PATHS``
If not overridden, they are set to ``[]`` and all links to static
files are cross-linked to the main site.
``THEME``, ``THEME_STATIC_DIR``
If overridden, the logic with ``THEME_STATIC_PATHS`` does not apply.
``DEFAULT_LANG``
This should not be overridden as the plugin changes it to the
language code of each sub-site to change what is perceived as translations.
Localizing templates
--------------------
Most importantly, this plugin can use localized templates for each
sub-site. There are two approaches to having the templates localized:
- You can set a different ``THEME`` override for each language in
``I18N_SUBSITES``, e.g. by making a copy of a theme ``my_theme`` to
``my_theme_lang`` and then editing the templates in the new
localized theme. This approach means you don't have to deal with
gettext ``*.po`` files, but it is harder to maintain over time.
- You use only one theme and localize the templates using the
`jinja2.ext.i18n Jinja2 extension
<http://jinja.pocoo.org/docs/templates/#i18n>`_. For a kickstart
read this `guide <./localizing_using_jinja2.rst>`_.
Additional context variables
............................
It may be convenient to add language buttons to your theme in addition
to the translation links of articles and pages. These buttons could,
for example, point to the ``SITEURL`` of each (sub-)site. For this
reason the plugin adds these variables to the template context:
``main_lang``
The language of the main site — the original ``DEFAULT_LANG``
``main_siteurl``
The ``SITEURL`` of the main site — the original ``SITEURL``
``lang_siteurls``
An ordered dictionary, mapping all used languages to their
``SITEURL``. The ``main_lang`` is the first key with ``main_siteurl``
as the value. This dictionary is useful for implementing global
language buttons that show the language of the currently viewed
(sub-)site too.
``extra_siteurls``
An ordered dictionary, subset of ``lang_siteurls``, the current
``DEFAULT_LANG`` of the rendered (sub-)site is not included, so for
each (sub-)site ``set(extra_siteurls) == set(lang_siteurls) -
set([DEFAULT_LANG])``. This dictionary is useful for implementing
global language buttons that do not show the current language.
``relpath_to_site``
A function that returns a relative path from the first (sub-)site to
the second (sub-)site where the (sub-)sites are identified by the
language codes given as two arguments.
If you don't like the default ordering of the ordered dictionaries,
use a Jinja2 filter to alter the ordering.
All the siteurls above are always absolute even in the case of
``RELATIVE_URLS == True`` (it would be to complicated to replicate the
Pelican internals for local siteurls), so you may rather use something
like ``{{ SITEURL }}/{{ relpath_to_site(DEFAULT_LANG, main_lang }}``
to link to the main site.
This short `howto <./implementing_language_buttons.rst>`_ shows two
example implementations of language buttons.
Usage notes
===========
- It is **mandatory** to specify ``lang`` metadata for each article
and page as ``DEFAULT_LANG`` is later changed for each sub-site, so
content without ``lang`` metadata would be rendered in every
(sub-)site.
- As with the original translations functionality, ``slug`` metadata
is used to group translations. It is therefore often convenient to
compensate for this by overriding the content URL (which defaults to
slug) using the ``url`` and ``save_as`` metadata. You could also
give articles e.g. ``name`` metadata and use it in ``ARTICLE_URL =
'{name}.html'``.
Development
===========
- A demo and a test site is in the ``gh-pages`` branch and can be seen
at http://smartass101.github.io/pelican-plugins/
from .i18n_subsites import *
File deleted
"""i18n_subsites plugin creates i18n-ized subsites of the default site
This plugin is designed for Pelican 3.4 and later
"""
import os
import six
import logging
import posixpath
from copy import copy
from itertools import chain
from operator import attrgetter
from collections import OrderedDict
from contextlib import contextmanager
from six.moves.urllib.parse import urlparse
import gettext
import locale
from pelican import signals
from pelican.generators import ArticlesGenerator, PagesGenerator
from pelican.settings import configure_settings
from pelican.contents import Draft
# Global vars
_MAIN_SETTINGS = None # settings dict of the main Pelican instance
_MAIN_LANG = None # lang of the main Pelican instance
_MAIN_SITEURL = None # siteurl of the main Pelican instance
_MAIN_STATIC_FILES = None # list of Static instances the main Pelican instance
_SUBSITE_QUEUE = {} # map: lang -> settings overrides
_SITE_DB = OrderedDict() # OrderedDict: lang -> siteurl
_SITES_RELPATH_DB = {} # map: (lang, base_lang) -> relpath
# map: generator -> list of removed contents that need interlinking
_GENERATOR_DB = {}
_NATIVE_CONTENT_URL_DB = {} # map: source_path -> content in its native lang
_LOGGER = logging.getLogger(__name__)
@contextmanager
def temporary_locale(temp_locale=None):
'''Enable code to run in a context with a temporary locale
Resets the locale back when exiting context.
Can set a temporary locale if provided
'''
orig_locale = locale.setlocale(locale.LC_ALL)
if temp_locale is not None:
locale.setlocale(locale.LC_ALL, temp_locale)
yield
locale.setlocale(locale.LC_ALL, orig_locale)
def initialize_dbs(settings):
'''Initialize internal DBs using the Pelican settings dict
This clears the DBs for e.g. autoreload mode to work
'''
global _MAIN_SETTINGS, _MAIN_SITEURL, _MAIN_LANG, _SUBSITE_QUEUE
_MAIN_SETTINGS = settings
_MAIN_LANG = settings['DEFAULT_LANG']
_MAIN_SITEURL = settings['SITEURL']
_SUBSITE_QUEUE = settings.get('I18N_SUBSITES', {}).copy()
prepare_site_db_and_overrides()
# clear databases in case of autoreload mode
_SITES_RELPATH_DB.clear()
_NATIVE_CONTENT_URL_DB.clear()
_GENERATOR_DB.clear()
def prepare_site_db_and_overrides():
'''Prepare overrides and create _SITE_DB
_SITE_DB.keys() need to be ready for filter_translations
'''
_SITE_DB.clear()
_SITE_DB[_MAIN_LANG] = _MAIN_SITEURL
# make sure it works for both root-relative and absolute
main_siteurl = '/' if _MAIN_SITEURL == '' else _MAIN_SITEURL
for lang, overrides in _SUBSITE_QUEUE.items():
if 'SITEURL' not in overrides:
overrides['SITEURL'] = posixpath.join(main_siteurl, lang)
_SITE_DB[lang] = overrides['SITEURL']
# default subsite hierarchy
if 'OUTPUT_PATH' not in overrides:
overrides['OUTPUT_PATH'] = os.path.join(
_MAIN_SETTINGS['OUTPUT_PATH'], lang)
if 'CACHE_PATH' not in overrides:
overrides['CACHE_PATH'] = os.path.join(
_MAIN_SETTINGS['CACHE_PATH'], lang)
if 'STATIC_PATHS' not in overrides:
overrides['STATIC_PATHS'] = []
if ('THEME' not in overrides and 'THEME_STATIC_DIR' not in overrides and
'THEME_STATIC_PATHS' not in overrides):
relpath = relpath_to_site(lang, _MAIN_LANG)
overrides['THEME_STATIC_DIR'] = posixpath.join(
relpath, _MAIN_SETTINGS['THEME_STATIC_DIR'])
overrides['THEME_STATIC_PATHS'] = []
# to change what is perceived as translations
overrides['DEFAULT_LANG'] = lang
def subscribe_filter_to_signals(settings):
'''Subscribe content filter to requested signals'''
for sig in settings.get('I18N_FILTER_SIGNALS', []):
sig.connect(filter_contents_translations)
def initialize_plugin(pelican_obj):
'''Initialize plugin variables and Pelican settings'''
if _MAIN_SETTINGS is None:
initialize_dbs(pelican_obj.settings)
subscribe_filter_to_signals(pelican_obj.settings)
def get_site_path(url):
'''Get the path component of an url, excludes siteurl
also normalizes '' to '/' for relpath to work,
otherwise it could be interpreted as a relative filesystem path
'''
path = urlparse(url).path
if path == '':
path = '/'
return path
def relpath_to_site(lang, target_lang):
'''Get relative path from siteurl of lang to siteurl of base_lang
the output is cached in _SITES_RELPATH_DB
'''
path = _SITES_RELPATH_DB.get((lang, target_lang), None)
if path is None:
siteurl = _SITE_DB.get(lang, _MAIN_SITEURL)
target_siteurl = _SITE_DB.get(target_lang, _MAIN_SITEURL)
path = posixpath.relpath(get_site_path(target_siteurl),
get_site_path(siteurl))
_SITES_RELPATH_DB[(lang, target_lang)] = path
return path
def save_generator(generator):
'''Save the generator for later use
initialize the removed content list
'''
_GENERATOR_DB[generator] = []
def article2draft(article):
'''Transform an Article to Draft'''
draft = Draft(article._content, article.metadata, article.settings,
article.source_path, article._context)
draft.status = 'draft'
return draft
def page2hidden_page(page):
'''Transform a Page to a hidden Page'''
page.status = 'hidden'
return page
class GeneratorInspector(object):
'''Inspector of generator instances'''
generators_info = {
ArticlesGenerator: {
'translations_lists': ['translations', 'drafts_translations'],
'contents_lists': [('articles', 'drafts')],
'hiding_func': article2draft,
'policy': 'I18N_UNTRANSLATED_ARTICLES',
},
PagesGenerator: {
'translations_lists': ['translations', 'hidden_translations'],
'contents_lists': [('pages', 'hidden_pages')],
'hiding_func': page2hidden_page,
'policy': 'I18N_UNTRANSLATED_PAGES',
},
}
def __init__(self, generator):
'''Identify the best known class of the generator instance
The class '''
self.generator = generator
self.generators_info.update(generator.settings.get(
'I18N_GENERATORS_INFO', {}))
for cls in generator.__class__.__mro__:
if cls in self.generators_info:
self.info = self.generators_info[cls]
break
else:
self.info = {}
def translations_lists(self):
'''Iterator over lists of content translations'''
return (getattr(self.generator, name) for name in
self.info.get('translations_lists', []))
def contents_list_pairs(self):
'''Iterator over pairs of normal and hidden contents'''
return (tuple(getattr(self.generator, name) for name in names)
for names in self.info.get('contents_lists', []))
def hiding_function(self):
'''Function for transforming content to a hidden version'''
hiding_func = self.info.get('hiding_func', lambda x: x)
return hiding_func
def untranslated_policy(self, default):
'''Get the policy for untranslated content'''
return self.generator.settings.get(self.info.get('policy', None),
default)
def all_contents(self):
'''Iterator over all contents'''
translations_iterator = chain(*self.translations_lists())
return chain(translations_iterator,
*(pair[i] for pair in self.contents_list_pairs()
for i in (0, 1)))
def filter_contents_translations(generator):
'''Filter the content and translations lists of a generator
Filters out
1) translations which will be generated in a different site
2) content that is not in the language of the currently
generated site but in that of a different site, content in a
language which has no site is generated always. The filtering
method bay be modified by the respective untranslated policy
'''
inspector = GeneratorInspector(generator)
current_lang = generator.settings['DEFAULT_LANG']
langs_with_sites = _SITE_DB.keys()
removed_contents = _GENERATOR_DB[generator]
for translations in inspector.translations_lists():
for translation in translations[:]: # copy to be able to remove
if translation.lang in langs_with_sites:
translations.remove(translation)
removed_contents.append(translation)
hiding_func = inspector.hiding_function()
untrans_policy = inspector.untranslated_policy(default='hide')
for (contents, other_contents) in inspector.contents_list_pairs():
for content in other_contents: # save any hidden native content first
if content.lang == current_lang: # in native lang
# save the native URL attr formatted in the current locale
_NATIVE_CONTENT_URL_DB[content.source_path] = content.url
for content in contents[:]: # copy for removing in loop
if content.lang == current_lang: # in native lang
# save the native URL attr formatted in the current locale
_NATIVE_CONTENT_URL_DB[content.source_path] = content.url
elif content.lang in langs_with_sites and untrans_policy != 'keep':
contents.remove(content)
if untrans_policy == 'hide':
other_contents.append(hiding_func(content))
elif untrans_policy == 'remove':
removed_contents.append(content)
def install_templates_translations(generator):
'''Install gettext translations in the jinja2.Environment
Only if the 'jinja2.ext.i18n' jinja2 extension is enabled
the translations for the current DEFAULT_LANG are installed.
'''
if 'JINJA_ENVIRONMENT' in generator.settings: # pelican 3.7+
jinja_extensions = generator.settings['JINJA_ENVIRONMENT'].get(
'extensions', [])
else:
jinja_extensions = generator.settings['JINJA_EXTENSIONS']
if 'jinja2.ext.i18n' in jinja_extensions:
domain = generator.settings.get('I18N_GETTEXT_DOMAIN', 'messages')
localedir = generator.settings.get('I18N_GETTEXT_LOCALEDIR')
if localedir is None:
localedir = os.path.join(generator.theme, 'translations')
current_lang = generator.settings['DEFAULT_LANG']
if current_lang == generator.settings.get('I18N_TEMPLATES_LANG',
_MAIN_LANG):
translations = gettext.NullTranslations()
else:
langs = [current_lang]
try:
translations = gettext.translation(domain, localedir, langs)
except (IOError, OSError):
_LOGGER.error((
"Cannot find translations for language '{}' in '{}' with "
"domain '{}'. Installing NullTranslations.").format(
langs[0], localedir, domain))
translations = gettext.NullTranslations()
newstyle = generator.settings.get('I18N_GETTEXT_NEWSTYLE', True)
generator.env.install_gettext_translations(translations, newstyle)
def add_variables_to_context(generator):
'''Adds useful iterable variables to template context'''
context = generator.context # minimize attr lookup
context['relpath_to_site'] = relpath_to_site
context['main_siteurl'] = _MAIN_SITEURL
context['main_lang'] = _MAIN_LANG
context['lang_siteurls'] = _SITE_DB
current_lang = generator.settings['DEFAULT_LANG']
extra_siteurls = _SITE_DB.copy()
extra_siteurls.pop(current_lang)
context['extra_siteurls'] = extra_siteurls
def interlink_translations(content):
'''Link content to translations in their main language
so the URL (including localized month names) of the different subsites
will be honored
'''
lang = content.lang
# sort translations by lang
content.translations.sort(key=attrgetter('lang'))
for translation in content.translations:
relpath = relpath_to_site(lang, translation.lang)
url = _NATIVE_CONTENT_URL_DB[translation.source_path]
translation.override_url = posixpath.join(relpath, url)
def interlink_translated_content(generator):
'''Make translations link to the native locations
for generators that may contain translated content
'''
inspector = GeneratorInspector(generator)
for content in inspector.all_contents():
interlink_translations(content)
def interlink_removed_content(generator):
'''For all contents removed from generation queue update interlinks
link to the native location
'''
current_lang = generator.settings['DEFAULT_LANG']
for content in _GENERATOR_DB[generator]:
url = _NATIVE_CONTENT_URL_DB[content.source_path]
relpath = relpath_to_site(current_lang, content.lang)
content.override_url = posixpath.join(relpath, url)
def interlink_static_files(generator):
'''Add links to static files in the main site if necessary'''
if generator.settings['STATIC_PATHS'] != []:
return # customized STATIC_PATHS
filenames = generator.context['filenames'] # minimize attr lookup
relpath = relpath_to_site(generator.settings['DEFAULT_LANG'], _MAIN_LANG)
for staticfile in _MAIN_STATIC_FILES:
if staticfile.get_relative_source_path() not in filenames:
staticfile = copy(staticfile) # prevent override in main site
staticfile.override_url = posixpath.join(relpath, staticfile.url)
generator.add_source_path(staticfile)
def save_main_static_files(static_generator):
'''Save the static files generated for the main site'''
global _MAIN_STATIC_FILES
# test just for current lang as settings change in autoreload mode
if static_generator.settings['DEFAULT_LANG'] == _MAIN_LANG:
_MAIN_STATIC_FILES = static_generator.staticfiles
def update_generators():
'''Update the context of all generators
Ads useful variables and translations into the template context
and interlink translations
'''
for generator in _GENERATOR_DB.keys():
install_templates_translations(generator)
add_variables_to_context(generator)
interlink_static_files(generator)
interlink_removed_content(generator)
interlink_translated_content(generator)
def get_pelican_cls(settings):
'''Get the Pelican class requested in settings'''
cls = settings['PELICAN_CLASS']
if isinstance(cls, six.string_types):
module, cls_name = cls.rsplit('.', 1)
module = __import__(module)
cls = getattr(module, cls_name)
return cls
def create_next_subsite(pelican_obj):
'''Create the next subsite using the lang-specific config
If there are no more subsites in the generation queue, update all
the generators (interlink translations and removed content, add
variables and translations to template context). Otherwise get the
language and overrides for next the subsite in the queue and apply
overrides. Then generate the subsite using a PELICAN_CLASS
instance and its run method. Finally, restore the previous locale.
'''
global _MAIN_SETTINGS
if len(_SUBSITE_QUEUE) == 0:
_LOGGER.debug(
'i18n: Updating cross-site links and context of all generators.')
update_generators()
_MAIN_SETTINGS = None # to initialize next time
else:
with temporary_locale():
settings = _MAIN_SETTINGS.copy()
lang, overrides = _SUBSITE_QUEUE.popitem()
settings.update(overrides)
settings = configure_settings(settings) # to set LOCALE, etc.
cls = get_pelican_cls(settings)
new_pelican_obj = cls(settings)
_LOGGER.debug(("Generating i18n subsite for language '{}' "
"using class {}").format(lang, cls))
new_pelican_obj.run()
# map: signal name -> function name
_SIGNAL_HANDLERS_DB = {
'get_generators': initialize_plugin,
'article_generator_pretaxonomy': filter_contents_translations,
'page_generator_finalized': filter_contents_translations,
'get_writer': create_next_subsite,
'static_generator_finalized': save_main_static_files,
'generator_init': save_generator,
}
def register():
'''Register the plugin only if required signals are available'''
for sig_name in _SIGNAL_HANDLERS_DB.keys():
if not hasattr(signals, sig_name):
_LOGGER.error((
'The i18n_subsites plugin requires the {} '
'signal available for sure in Pelican 3.4.0 and later, '
'plugin will not be used.').format(sig_name))
return
for sig_name, handler in _SIGNAL_HANDLERS_DB.items():
sig = getattr(signals, sig_name)
sig.connect(handler)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment