mirror of
https://github.com/jpetazzo/container.training.git
synced 2026-09-06 03:07:15 +00:00
Merge May/June Ardan Live courses
This commit is contained in:
+18
-1
@@ -12,7 +12,7 @@
|
||||
</li>
|
||||
<li>
|
||||
<a href="k8s-adv-2.yml.html">
|
||||
Day 2: capacity management and Kubernetes operators
|
||||
Day 2: capacity management and Kubernetes operators
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
@@ -29,3 +29,20 @@
|
||||
<h2>
|
||||
Docker Bootcamp
|
||||
</h2>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="ctr-bootcamp.yml.html">
|
||||
Day 1, 2, and 3
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<h2>
|
||||
Kubernetes Bootcamp
|
||||
</h2>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="k8s-bootcamp.yml.html">
|
||||
Day 1, 2, and 3
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -280,3 +280,8 @@ CONTAINER ID IMAGE ... CREATED STATUS
|
||||
5c1dfd4d81f1 jpetazzo/clock ... 40 min. ago Exited (0) 40 min. ago
|
||||
b13c164401fb ubuntu ... 55 min. ago Exited (130) 53 min. ago
|
||||
```
|
||||
|
||||
???
|
||||
|
||||
:EN:- Foreground and background containers
|
||||
:FR:- Exécution interactive ou en arrière-plan
|
||||
|
||||
@@ -167,3 +167,8 @@ Automated process = good.
|
||||
|
||||
In the next chapter, we will learn how to automate the build
|
||||
process by writing a `Dockerfile`.
|
||||
|
||||
???
|
||||
|
||||
:EN:- Building our first images interactively
|
||||
:FR:- Fabriquer nos premières images à la main
|
||||
|
||||
@@ -363,3 +363,10 @@ In this example, `sh -c` will still be used, but
|
||||
The shell gets replaced by `figlet` when `figlet` starts execution.
|
||||
|
||||
This allows to run processes as PID 1 without using JSON.
|
||||
|
||||
???
|
||||
|
||||
:EN:- Towards automated, reproducible builds
|
||||
:EN:- Writing our first Dockerfile
|
||||
:FR:- Rendre le processus automatique et reproductible
|
||||
:FR:- Écrire son premier Dockerfile
|
||||
|
||||
@@ -272,3 +272,7 @@ $ docker run -it --entrypoint bash myfiglet
|
||||
root@6027e44e2955:/#
|
||||
```
|
||||
|
||||
???
|
||||
|
||||
:EN:- CMD and ENTRYPOINT
|
||||
:FR:- CMD et ENTRYPOINT
|
||||
|
||||
@@ -322,3 +322,11 @@ You can:
|
||||
Each copy will run in a different network, totally isolated from the other.
|
||||
|
||||
This is ideal to debug regressions, do side-by-side comparisons, etc.
|
||||
|
||||
???
|
||||
|
||||
:EN:- Using compose to describe an environment
|
||||
:EN:- Connecting services together with a *Compose file*
|
||||
|
||||
:FR:- Utiliser Compose pour décrire son environnement
|
||||
:FR:- Écrire un *Compose file* pour connecter les services entre eux
|
||||
@@ -226,3 +226,13 @@ We've learned how to:
|
||||
|
||||
In the next chapter, we will see how to connect
|
||||
containers together without exposing their ports.
|
||||
|
||||
???
|
||||
|
||||
:EN:Connecting containers
|
||||
:EN:- Container networking basics
|
||||
:EN:- Exposing a container
|
||||
|
||||
:FR:Connecter les conteneurs
|
||||
:FR:- Description du modèle réseau des conteneurs
|
||||
:FR:- Exposer un conteneur
|
||||
|
||||
@@ -98,3 +98,8 @@ Success!
|
||||
* Place it in a different directory, with the `WORKDIR` instruction.
|
||||
|
||||
* Even better, use the `gcc` official image.
|
||||
|
||||
???
|
||||
|
||||
:EN:- The build cache
|
||||
:FR:- Tirer parti du cache afin d'optimiser la vitesse de *build*
|
||||
|
||||
@@ -431,3 +431,8 @@ services:
|
||||
- It's OK (and even encouraged) to start simple and evolve as needed.
|
||||
|
||||
- Feel free to review this chapter later (after writing a few Dockerfiles) for inspiration!
|
||||
|
||||
???
|
||||
|
||||
:EN:- Dockerfile tips, tricks, and best practices
|
||||
:FR:- Bonnes pratiques pour la construction des images
|
||||
|
||||
@@ -290,3 +290,8 @@ bash: figlet: command not found
|
||||
* We have a clear definition of our environment, and can share it reliably with others.
|
||||
|
||||
* Let's see in the next chapters how to bake a custom image with `figlet`!
|
||||
|
||||
???
|
||||
|
||||
:EN:- Running our first container
|
||||
:FR:- Lancer nos premiers conteneurs
|
||||
|
||||
@@ -226,3 +226,8 @@ docker export <container_id> | tar tv
|
||||
```
|
||||
|
||||
This will give a detailed listing of the content of the container.
|
||||
|
||||
???
|
||||
|
||||
:EN:- Troubleshooting and getting inside a container
|
||||
:FR:- Inspecter un conteneur en détail, en *live* ou *post-mortem*
|
||||
|
||||
@@ -375,3 +375,13 @@ We've learned how to:
|
||||
* Understand Docker image namespacing.
|
||||
* Search and download images.
|
||||
|
||||
???
|
||||
|
||||
:EN:Building images
|
||||
:EN:- Containers, images, and layers
|
||||
:EN:- Image addresses and tags
|
||||
:EN:- Finding and transferring images
|
||||
|
||||
:FR:Construire des images
|
||||
:FR:- La différence entre un conteneur et une image
|
||||
:FR:- La notion de *layer* partagé entre images
|
||||
|
||||
@@ -80,3 +80,8 @@ $ docker ps --filter label=owner=alice
|
||||
(To determine internal cross-billing, or who to page in case of outage.)
|
||||
|
||||
* etc.
|
||||
|
||||
???
|
||||
|
||||
:EN:- Using labels to identify containers
|
||||
:FR:- Étiqueter ses conteneurs avec des méta-données
|
||||
|
||||
@@ -391,3 +391,10 @@ We've learned how to:
|
||||
|
||||
* Use a simple local development workflow.
|
||||
|
||||
???
|
||||
|
||||
:EN:Developing with containers
|
||||
:EN:- “Containerize” a development environment
|
||||
|
||||
:FR:Développer au jour le jour
|
||||
:FR:- « Containeriser » son environnement de développement
|
||||
@@ -313,3 +313,11 @@ virtually "free."
|
||||
* Sometimes, we want to inspect a specific intermediary build stage.
|
||||
|
||||
* Or, we want to describe multiple images using a single Dockerfile.
|
||||
|
||||
???
|
||||
|
||||
:EN:Optimizing our images and their build process
|
||||
:EN:- Leveraging multi-stage builds
|
||||
|
||||
:FR:Optimiser les images et leur construction
|
||||
:FR:- Utilisation d'un *multi-stage build*
|
||||
|
||||
@@ -130,3 +130,12 @@ $ docker inspect --format '{{ json .Created }}' <containerID>
|
||||
|
||||
* The optional `json` keyword asks for valid JSON output.
|
||||
<br/>(e.g. here it adds the surrounding double-quotes.)
|
||||
|
||||
???
|
||||
|
||||
:EN:Managing container lifecycle
|
||||
:EN:- Naming and inspecting containers
|
||||
|
||||
:FR:Suivre ses conteneurs à la loupe
|
||||
:FR:- Obtenir des informations détaillées sur un conteneur
|
||||
:FR:- Associer un identifiant unique à un conteneur
|
||||
|
||||
@@ -175,3 +175,10 @@ class: extra-details
|
||||
* This will cause some CLI and TUI programs to redraw the screen.
|
||||
|
||||
* But not all of them.
|
||||
|
||||
???
|
||||
|
||||
:EN:- Restarting old containers
|
||||
:EN:- Detaching and reattaching to container
|
||||
:FR:- Redémarrer des anciens conteneurs
|
||||
:FR:- Se détacher et rattacher à des conteneurs
|
||||
|
||||
@@ -125,3 +125,11 @@ Server:
|
||||
]
|
||||
|
||||
If this doesn't work, raise your hand so that an instructor can assist you!
|
||||
|
||||
???
|
||||
|
||||
:EN:Container concepts
|
||||
:FR:Premier contact avec les conteneurs
|
||||
|
||||
:EN:- What's a container engine?
|
||||
:FR:- Qu'est-ce qu'un *container engine* ?
|
||||
|
||||
@@ -11,10 +11,10 @@ class State(object):
|
||||
self.section_title = None
|
||||
self.section_start = 0
|
||||
self.section_slides = 0
|
||||
self.chapters = {}
|
||||
self.modules = {}
|
||||
self.sections = {}
|
||||
def show(self):
|
||||
if self.section_title.startswith("chapter-"):
|
||||
if self.section_title.startswith("module-"):
|
||||
return
|
||||
print("{0.section_title}\t{0.section_start}\t{0.section_slides}".format(self))
|
||||
self.sections[self.section_title] = self.section_slides
|
||||
@@ -38,10 +38,10 @@ for line in open(sys.argv[1]):
|
||||
if line == "--":
|
||||
state.current_slide += 1
|
||||
toc_links = re.findall("\(#toc-(.*)\)", line)
|
||||
if toc_links and state.section_title.startswith("chapter-"):
|
||||
if state.section_title not in state.chapters:
|
||||
state.chapters[state.section_title] = []
|
||||
state.chapters[state.section_title].append(toc_links[0])
|
||||
if toc_links and state.section_title.startswith("module-"):
|
||||
if state.section_title not in state.modules:
|
||||
state.modules[state.section_title] = []
|
||||
state.modules[state.section_title].append(toc_links[0])
|
||||
# This is really hackish
|
||||
if line.startswith("class:"):
|
||||
for klass in EXCLUDED:
|
||||
@@ -51,7 +51,7 @@ for line in open(sys.argv[1]):
|
||||
|
||||
state.show()
|
||||
|
||||
for chapter in sorted(state.chapters, key=lambda f: int(f.split("-")[1])):
|
||||
chapter_size = sum(state.sections[s] for s in state.chapters[chapter])
|
||||
print("{}\t{}\t{}".format("total size for", chapter, chapter_size))
|
||||
for module in sorted(state.modules, key=lambda f: int(f.split("-")[1])):
|
||||
module_size = sum(state.sections[s] for s in state.modules[module])
|
||||
print("{}\t{}\t{}".format("total size for", module, module_size))
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ slides: http://container.training/
|
||||
exclude:
|
||||
- self-paced
|
||||
|
||||
chapters:
|
||||
content:
|
||||
- shared/title.md
|
||||
- logistics.md
|
||||
- containers/intro.md
|
||||
|
||||
+3
-2
@@ -7,6 +7,7 @@ FLAGS=dict(
|
||||
fr=u"🇫🇷",
|
||||
uk=u"🇬🇧",
|
||||
us=u"🇺🇸",
|
||||
www=u"🌐",
|
||||
)
|
||||
|
||||
TEMPLATE="""<html>
|
||||
@@ -19,7 +20,7 @@ TEMPLATE="""<html>
|
||||
<div class="main">
|
||||
<table>
|
||||
<tr><td class="header" colspan="3">{{ title }}</td></tr>
|
||||
<tr><td class="details" colspan="3">Note: while some workshops are delivered in French, slides are always in English.</td></tr>
|
||||
<tr><td class="details" colspan="3">Note: while some workshops are delivered in other languages, slides are always in English.</td></tr>
|
||||
|
||||
<tr><td class="title" colspan="3">Free video of our latest workshop</td></tr>
|
||||
|
||||
@@ -35,7 +36,7 @@ TEMPLATE="""<html>
|
||||
<td class="details">If you're interested, we can deliver that workshop (or longer courses) to your team or organization.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="details">Contact <a href="mailto:jerome.petazzoni@gmail.com">Jérôme Petazzoni</a> to make that happen!</a></td>
|
||||
<td class="details">Contact <a href="mailto:jerome.petazzoni@gmail.com">Jérôme Petazzoni</a> to make that happen!</td>
|
||||
</tr>
|
||||
|
||||
{% if coming_soon %}
|
||||
|
||||
@@ -1,3 +1,36 @@
|
||||
- date: [2020-06-16, 2020-06-18]
|
||||
country: www
|
||||
city: streaming
|
||||
event: Ardan Live
|
||||
speaker: jpetazzo
|
||||
title: Intensive Kubernetes Bootcamp
|
||||
attend: https://www.eventbrite.com/e/livestream-intensive-kubernetes-bootcamp-tickets-103262336428
|
||||
|
||||
- date: [2020-05-19, 2020-05-21]
|
||||
country: www
|
||||
city: streaming
|
||||
event: Ardan Live
|
||||
speaker: jpetazzo
|
||||
title: Intensive Docker Bootcamp
|
||||
attend: https://www.eventbrite.com/e/livestream-intensive-docker-bootcamp-tickets-103258886108
|
||||
|
||||
- date: [2020-05-04, 2020-05-08]
|
||||
country: www
|
||||
city: streaming
|
||||
event: Ardan Live
|
||||
speaker: jpetazzo
|
||||
title: Intensive Kubernetes - Advanced Concepts
|
||||
attend: https://www.eventbrite.com/e/livestream-intensive-kubernetes-advanced-concepts-tickets-102358725704
|
||||
|
||||
- date: [2020-03-30, 2020-04-02]
|
||||
country: www
|
||||
city: streaming
|
||||
event: Ardan Live
|
||||
speaker: jpetazzo
|
||||
title: Intensive Docker and Kubernetes
|
||||
attend: https://www.eventbrite.com/e/ardan-labs-live-worldwide-march-30-april-2-2020-tickets-100331129108#
|
||||
slides: https://https://2020-03-ardan.container.training/
|
||||
|
||||
- date: 2020-03-06
|
||||
country: uk
|
||||
city: London
|
||||
|
||||
@@ -16,7 +16,7 @@ slides: https://2020-04-ardan.container.training/
|
||||
exclude:
|
||||
- self-paced
|
||||
|
||||
chapters:
|
||||
content:
|
||||
- shared/title.md
|
||||
- logistics.md
|
||||
- k8s/intro.md
|
||||
|
||||
@@ -16,7 +16,7 @@ slides: https://2020-04-ardan.container.training/
|
||||
exclude:
|
||||
- self-paced
|
||||
|
||||
chapters:
|
||||
content:
|
||||
- shared/title.md
|
||||
- logistics.md
|
||||
- k8s/intro.md
|
||||
|
||||
@@ -15,7 +15,7 @@ slides: https://2020-04-ardan.container.training/
|
||||
exclude:
|
||||
- self-paced
|
||||
|
||||
chapters:
|
||||
content:
|
||||
- shared/title.md
|
||||
- logistics.md
|
||||
- k8s/intro.md
|
||||
|
||||
@@ -16,7 +16,7 @@ slides: https://2020-04-ardan.container.training/
|
||||
exclude:
|
||||
- self-paced
|
||||
|
||||
chapters:
|
||||
content:
|
||||
- shared/title.md
|
||||
- logistics.md
|
||||
- k8s/intro.md
|
||||
|
||||
@@ -15,7 +15,7 @@ slides: http://container.training/
|
||||
exclude:
|
||||
- self-paced
|
||||
|
||||
chapters:
|
||||
content:
|
||||
- shared/title.md
|
||||
- logistics.md
|
||||
- k8s/intro.md
|
||||
|
||||
@@ -129,3 +129,8 @@ installed and set up `kubectl` to communicate with your cluster.
|
||||
```
|
||||
|
||||
]
|
||||
|
||||
???
|
||||
|
||||
:EN:- Securely accessing internal services
|
||||
:FR:- Accès sécurisé aux services internes
|
||||
|
||||
@@ -87,3 +87,8 @@
|
||||
- Tunnels are also fine
|
||||
|
||||
(e.g. [k3s](https://k3s.io/) uses a tunnel to allow each node to contact the API server)
|
||||
|
||||
???
|
||||
|
||||
:EN:- Ensuring API server availability
|
||||
:FR:- Assurer la disponibilité du serveur API
|
||||
|
||||
@@ -381,3 +381,8 @@ We demonstrated *update* and *watch* semantics.
|
||||
- if the pod has special constraints that can't be met
|
||||
|
||||
- if the scheduler is not running (!)
|
||||
|
||||
???
|
||||
|
||||
:EN:- Kubernetes architecture review
|
||||
:FR:- Passage en revue de l'architecture de Kubernetes
|
||||
|
||||
@@ -676,3 +676,13 @@ class: extra-details
|
||||
- Both are available as standalone programs, or as plugins for `kubectl`
|
||||
|
||||
(`kubectl` plugins can be installed and managed with `krew`)
|
||||
|
||||
???
|
||||
|
||||
:EN:- Authentication and authorization in Kubernetes
|
||||
:EN:- Role-Based Access Control (RBAC)
|
||||
:EN:- Restricting permissions with Service Accounts
|
||||
|
||||
:FR:- Identification et droits d'accès dans Kubernetes
|
||||
:FR:- Le modèle RBAC *(Role-Based Access Control)*
|
||||
:FR:- Restreindre les permissions grâce aux *Service Accounts*
|
||||
|
||||
@@ -187,3 +187,8 @@ class: extra-details
|
||||
- If we write these manifests ourselves, we can use all features and options
|
||||
|
||||
- We'll see later how to do that!
|
||||
|
||||
???
|
||||
|
||||
:EN:- Running batch and cron jobs
|
||||
:FR:- Tâches périodiques *(cron)* et traitement par lots *(batch)*
|
||||
|
||||
@@ -257,3 +257,8 @@ This is the TLS bootstrap mechanism, step by step.
|
||||
- [kubeadm token](https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm-token/) command
|
||||
|
||||
- [kubeadm join](https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm-join/) command (has details about [the join workflow](https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm-join/#join-workflow))
|
||||
|
||||
???
|
||||
|
||||
:EN:- Leveraging TLS bootstrap to join nodes
|
||||
:FR:- Ajout de nœuds grâce au *TLS bootstrap*
|
||||
|
||||
@@ -142,3 +142,8 @@ The list includes the following providers:
|
||||
- [configuration](https://kubernetes.io/docs/concepts/cluster-administration/cloud-providers/) (mainly for OpenStack)
|
||||
|
||||
- [deployment](https://kubernetes.io/docs/tasks/administer-cluster/running-cloud-controller/)
|
||||
|
||||
???
|
||||
|
||||
:EN:- The Cloud Controller Manager
|
||||
:FR:- Le *Cloud Controller Manager*
|
||||
|
||||
@@ -364,3 +364,8 @@ docker run --rm --net host -v $PWD:/vol \
|
||||
- [bivac](https://github.com/camptocamp/bivac)
|
||||
|
||||
Backup Interface for Volumes Attached to Containers
|
||||
|
||||
???
|
||||
|
||||
:EN:- Backing up clusters
|
||||
:FR:- Politiques de sauvegarde
|
||||
|
||||
@@ -165,3 +165,11 @@ class: extra-details
|
||||
- Security advantage (stronger isolation between pods)
|
||||
|
||||
Check [this blog post](http://jpetazzo.github.io/2019/02/13/running-kubernetes-without-nodes-with-kiyot/) for more details.
|
||||
|
||||
???
|
||||
|
||||
:EN:- Capacity planning
|
||||
:EN:- Cluster sizing and scaling
|
||||
|
||||
:FR:- Dimensionnement des clusters
|
||||
:FR:- Comportement en cas de famine
|
||||
|
||||
@@ -501,3 +501,11 @@ class: extra-details
|
||||
- Then upgrading kubeadm to 1.16.X, etc.
|
||||
|
||||
- **Make sure to read the release notes before upgrading!**
|
||||
|
||||
???
|
||||
|
||||
:EN:- Best practices for cluster upgrades
|
||||
:EN:- Example: upgrading a kubeadm cluster
|
||||
|
||||
:FR:- Bonnes pratiques pour la mise à jour des clusters
|
||||
:FR:- Exemple : mettre à jour un cluster kubeadm
|
||||
|
||||
@@ -574,3 +574,8 @@ done
|
||||
- This could be useful for embedded platforms with very limited resources
|
||||
|
||||
(or lab environments for learning purposes)
|
||||
|
||||
???
|
||||
|
||||
:EN:- Configuring CNI plugins
|
||||
:FR:- Configurer des plugins CNI
|
||||
|
||||
@@ -401,3 +401,8 @@ class: pic
|
||||
- IP addresses are associated with *pods*, not with individual containers
|
||||
|
||||
Both diagrams used with permission.
|
||||
|
||||
???
|
||||
|
||||
:EN:- Kubernetes concepts
|
||||
:FR:- Kubernetes en théorie
|
||||
|
||||
@@ -547,3 +547,13 @@ spec:
|
||||
- With RBAC, we can authorize a user to access configmaps, but not secrets
|
||||
|
||||
(since they are two different kinds of resources)
|
||||
|
||||
???
|
||||
|
||||
:EN:- Managing application configuration
|
||||
:EN:- The downward API
|
||||
:EN:- Config Maps and Secrets
|
||||
|
||||
:FR:- Gérer la configuration des applications
|
||||
:FR:- La *downward API*
|
||||
:FR:- Utiliser les *Config Maps* et *Secrets*
|
||||
|
||||
@@ -263,3 +263,8 @@ spec:
|
||||
#name: web-xyz1234567-pqr89
|
||||
EOF
|
||||
```
|
||||
|
||||
???
|
||||
|
||||
:EN:- Control plane authentication
|
||||
:FR:- Sécurisation du plan de contrôle
|
||||
|
||||
@@ -424,3 +424,8 @@ To be usable in real environments, we would need to add:
|
||||
- we get strong security *and* convenience
|
||||
|
||||
- Systems like Vault also have certificate issuance mechanisms
|
||||
|
||||
???
|
||||
|
||||
:EN:- Generating user certificates with the CSR API
|
||||
:FR:- Génération de certificats utilisateur avec la CSR API
|
||||
|
||||
@@ -688,3 +688,8 @@ class: extra-details
|
||||
(by setting their label accordingly)
|
||||
|
||||
- This gives us building blocks for canary and blue/green deployments
|
||||
|
||||
???
|
||||
|
||||
:EN:- Scaling with Daemon Sets
|
||||
:FR:- Utilisation de Daemon Sets
|
||||
|
||||
@@ -172,3 +172,8 @@ The dashboard will then ask you which authentication you want to use.
|
||||
- It introduces new failure modes
|
||||
|
||||
(for instance, if you try to apply YAML from a link that's no longer valid)
|
||||
|
||||
???
|
||||
|
||||
:EN:- The Kubernetes dashboard
|
||||
:FR:- Le *dashboard* Kubernetes
|
||||
|
||||
@@ -26,3 +26,8 @@
|
||||
- When we want to change some resource, we update the *spec*
|
||||
|
||||
- Kubernetes will then *converge* that resource
|
||||
|
||||
???
|
||||
|
||||
:EN:- Declarative vs imperative models
|
||||
:FR:- Modèles déclaratifs et impératifs
|
||||
|
||||
@@ -823,3 +823,8 @@ class: extra-details
|
||||
(it could be as a bare process, or in a container/pod using the host network)
|
||||
|
||||
- ... And it expects to be listening on port 6443 with TLS
|
||||
|
||||
???
|
||||
|
||||
:EN:- Building our own cluster from scratch
|
||||
:FR:- Construire son cluster à la main
|
||||
|
||||
@@ -344,3 +344,14 @@ class: extra-details
|
||||
- [Dynamic Admission Controllers](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/)
|
||||
|
||||
- [Aggregation Layer](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/apiserver-aggregation/)
|
||||
|
||||
???
|
||||
|
||||
:EN:- Extending the Kubernetes API
|
||||
:EN:- Custom Resource Definitions (CRDs)
|
||||
:EN:- The aggregation layer
|
||||
:EN:- Admission control and webhooks
|
||||
|
||||
:FR:- Comment étendre l'API Kubernetes
|
||||
:FR:- Les CRDs *(Custom Resource Definitions)*
|
||||
:FR:- Extension via *aggregation layer*, *admission control*, *webhooks*
|
||||
|
||||
@@ -237,3 +237,8 @@
|
||||
- Gitkube can also deploy Helm charts
|
||||
|
||||
(instead of raw YAML files)
|
||||
|
||||
???
|
||||
|
||||
:EN:- GitOps
|
||||
:FR:- GitOps
|
||||
|
||||
@@ -333,3 +333,8 @@ class: extra-details
|
||||
(and have gcr.io/pause take care of the reaping)
|
||||
|
||||
- Discussion of this in [Video - 10 Ways to Shoot Yourself in the Foot with Kubernetes, #9 Will Surprise You](https://www.youtube.com/watch?v=QKI-JRs2RIE)
|
||||
|
||||
???
|
||||
|
||||
:EN:- Adding healthchecks to an app
|
||||
:FR:- Ajouter des *healthchecks* à une application
|
||||
|
||||
@@ -282,3 +282,8 @@ If the Redis process becomes unresponsive, it will be killed.
|
||||
- check the timestamp of that file from an exec probe
|
||||
|
||||
- Writing logs (and checking them from the probe) also works
|
||||
|
||||
???
|
||||
|
||||
:EN:- Using healthchecks to improve availability
|
||||
:FR:- Utiliser des *healthchecks* pour amémliorer la disponibilité
|
||||
|
||||
@@ -237,3 +237,8 @@ We see the components mentioned above: `Chart.yaml`, `templates/`, `values.yaml`
|
||||
- This can be use for database migrations, backups, notifications, smoke tests ...
|
||||
|
||||
- Hooks named `test` are executed only when running `helm test RELEASE-NAME`
|
||||
|
||||
???
|
||||
|
||||
:EN:- Helm charts format
|
||||
:FR:- Le format des *Helm charts*
|
||||
|
||||
@@ -218,3 +218,8 @@ have details about recommended annotations and labels.
|
||||
```
|
||||
|
||||
]
|
||||
|
||||
???
|
||||
|
||||
:EN:- Creating basic Helm charts
|
||||
:FR:- Création de *Helm charts* basiques
|
||||
|
||||
@@ -577,3 +577,8 @@ We can look at the definition, but it's fairly complex ...
|
||||
- We can change the number of workers with `replicaCount`
|
||||
|
||||
- And much more!
|
||||
|
||||
???
|
||||
|
||||
:EN:- Creating better Helm charts
|
||||
:FR:- Création de *Helm charts* avancés
|
||||
|
||||
@@ -417,3 +417,13 @@ All unspecified values will take the default values defined in the chart.
|
||||
```
|
||||
|
||||
]
|
||||
|
||||
???
|
||||
|
||||
:EN:- Helm concepts
|
||||
:EN:- Installing software with Helm
|
||||
|
||||
:FR:- Fonctionnement général de Helm
|
||||
:FR:- Installer des composants via Helm
|
||||
|
||||
:FR:- Comment
|
||||
@@ -232,3 +232,8 @@ The chart is in a structured format, but it's entirely captured in this JSON.
|
||||
(including the full source of the chart, and the values used)
|
||||
|
||||
- This allows arbitrary rollbacks, as well as tweaking values even without having access to the source of the chart (or the chart repo) used for deployment
|
||||
|
||||
???
|
||||
|
||||
:EN:- Deep dive into Helm internals
|
||||
:FR:- Fonctionnement interne de Helm
|
||||
|
||||
@@ -306,3 +306,8 @@ This can also be set with `--cpu-percent=`.
|
||||
-->
|
||||
|
||||
]
|
||||
|
||||
???
|
||||
|
||||
:EN:- Auto-scaling resources
|
||||
:FR:- *Auto-scaling* (dimensionnement automatique) des ressources
|
||||
|
||||
@@ -718,3 +718,8 @@ We also need:
|
||||
(create them, promote them, delete them ...)
|
||||
|
||||
For inspiration, check [flagger by Weave](https://github.com/weaveworks/flagger).
|
||||
|
||||
???
|
||||
|
||||
:EN:- The Ingress resource
|
||||
:FR:- La ressource *ingress*
|
||||
|
||||
@@ -155,3 +155,8 @@ For critical services, we might want to precisely control the update process.
|
||||
- Even better if it's combined with DNS integration
|
||||
|
||||
(to facilitate name → ClusterIP resolution)
|
||||
|
||||
???
|
||||
|
||||
:EN:- Interconnecting clusters
|
||||
:FR:- Interconnexion de clusters
|
||||
|
||||
@@ -516,3 +516,8 @@ We'll see later how to address that shortcoming.
|
||||
- Until 30 seconds later, when the grace period expires
|
||||
|
||||
- The pod is then killed, and `kubectl logs` exits
|
||||
|
||||
???
|
||||
|
||||
:EN:- Running pods and deployments
|
||||
:FR:- Créer un pod et un déploiement
|
||||
|
||||
@@ -438,3 +438,13 @@ class: extra-details
|
||||
- They can also handle TLS certificates, URL rewriting ...
|
||||
|
||||
- They require an *Ingress Controller* to function
|
||||
|
||||
???
|
||||
|
||||
:EN:- Service discovery and load balancing
|
||||
:EN:- Accessing pods through services
|
||||
:EN:- Service types: ClusterIP, NodePort, LoadBalancer
|
||||
|
||||
:FR:- Exposer un service
|
||||
:FR:- Différents types de services : ClusterIP, NodePort, LoadBalancer
|
||||
:FR:- Utiliser CoreDNS pour la *service discovery*
|
||||
|
||||
@@ -578,3 +578,8 @@ $ curl -k https://10.96.0.1
|
||||
- Code running in pods can connect to services using their name
|
||||
|
||||
(e.g. https://kubernetes/...)
|
||||
|
||||
???
|
||||
|
||||
:EN:- Getting started with kubectl
|
||||
:FR:- Se familiariser avec kubectl
|
||||
|
||||
@@ -145,3 +145,8 @@ class: extra-details
|
||||
- Some solutions can fill multiple roles
|
||||
|
||||
(e.g. kube-router can be set up to provide the pod network and/or network policies and/or replace kube-proxy)
|
||||
|
||||
???
|
||||
|
||||
:EN:- The Kubernetes network model
|
||||
:FR:- Le modèle réseau de Kubernetes
|
||||
|
||||
@@ -242,3 +242,8 @@ https://@@GITREPO@@/blob/8279a3bce9398f7c1a53bdd95187c53eda4e6435/dockercoins/wo
|
||||
|
||||
A drawing area should show up, and after a few seconds, a blue
|
||||
graph will appear.
|
||||
|
||||
???
|
||||
|
||||
:EN:- Running a sample app
|
||||
:FR:- Lancer une application de démo
|
||||
|
||||
@@ -199,3 +199,8 @@
|
||||
]
|
||||
|
||||
Note: it might take a minute or two for the worker to start.
|
||||
|
||||
???
|
||||
|
||||
:EN:- Packaging and running apps with Kustomize
|
||||
:FR:- *Packaging* d'applications avec Kustomize
|
||||
|
||||
@@ -195,3 +195,8 @@ class: extra-details
|
||||
- Maximum length isn't defined
|
||||
|
||||
(dozens of kilobytes is fine, hundreds maybe not so much)
|
||||
|
||||
???
|
||||
|
||||
:EN:- Labels and annotations
|
||||
:FR:- *Labels* et annotations
|
||||
|
||||
@@ -246,3 +246,8 @@
|
||||
(when we can't or won't dedicate a whole disk to a volume)
|
||||
|
||||
- It's possible to mix both (using distinct Storage Classes)
|
||||
|
||||
???
|
||||
|
||||
:EN:- Local persistent volumes
|
||||
:FR:- Volumes locaux persistents
|
||||
|
||||
@@ -193,3 +193,8 @@ class: extra-details
|
||||
]
|
||||
|
||||
We can now utilize the cluster exactly as if we're logged into a node, except that it's remote.
|
||||
|
||||
???
|
||||
|
||||
:EN:- Working with remote Kubernetes clusters
|
||||
:FR:- Travailler avec des *clusters* distants
|
||||
|
||||
@@ -145,3 +145,8 @@ But this is outside of the scope of this chapter.
|
||||
The YAML file that we used creates all the resources in the
|
||||
`default` namespace, for simplicity. In a real scenario, you will
|
||||
create the resources in the `kube-system` namespace or in a dedicated namespace.
|
||||
|
||||
???
|
||||
|
||||
:EN:- Centralizing logs
|
||||
:FR:- Centraliser les logs
|
||||
|
||||
@@ -149,3 +149,8 @@ Exactly what we need!
|
||||
-->
|
||||
|
||||
]
|
||||
|
||||
???
|
||||
|
||||
:EN:- Viewing pod logs from the CLI
|
||||
:FR:- Consulter les logs des pods depuis la CLI
|
||||
|
||||
@@ -80,3 +80,8 @@ If it shows our nodes and their CPU and memory load, we're good!
|
||||
- kube-resource-report can generate HTML reports
|
||||
|
||||
(https://github.com/hjacobs/kube-resource-report)
|
||||
|
||||
???
|
||||
|
||||
:EN:- The *core metrics pipeline*
|
||||
:FR:- Le *core metrics pipeline*
|
||||
|
||||
@@ -532,3 +532,8 @@ Sometimes it works, sometimes it doesn't. Why?
|
||||
- We want to automate all these steps
|
||||
|
||||
- We want something that works on all networks
|
||||
|
||||
???
|
||||
|
||||
:EN:- Connecting nodes ands pods
|
||||
:FR:- Interconnecter les nœuds et les pods
|
||||
|
||||
@@ -365,3 +365,7 @@ Note: we could have used `--namespace=default` for the same result.
|
||||
|
||||
- Pro-tip: install it on your machine during the next break!
|
||||
|
||||
???
|
||||
|
||||
:EN:- Organizing resources with Namespaces
|
||||
:FR:- Organiser les ressources avec des *namespaces*
|
||||
|
||||
@@ -446,3 +446,8 @@ troubleshoot easily, without having to poke holes in our firewall.
|
||||
- a [very good talk about network policies](https://www.youtube.com/watch?list=PLj6h78yzYM2P-3-xqvmWaZbbI1sW-ulZb&v=3gGpMmYeEO8) at KubeCon North America 2017
|
||||
|
||||
- a repository of [ready-to-use recipes](https://github.com/ahmetb/kubernetes-network-policy-recipes) for network policies
|
||||
|
||||
???
|
||||
|
||||
:EN:- Network isolation with Network Policies
|
||||
:FR:- Protection réseau avec les *network policies*
|
||||
|
||||
@@ -377,3 +377,8 @@ class: extra-details
|
||||
- It should now say "Signature Verified"
|
||||
|
||||
]
|
||||
|
||||
???
|
||||
|
||||
:EN:- Authenticating with OIDC
|
||||
:FR:- S'identifier avec OIDC
|
||||
|
||||
@@ -356,3 +356,8 @@ class: extra-details
|
||||
(this is used e.g. by the metrics server)
|
||||
|
||||
- [This documentation page](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/#choosing-a-method-for-adding-custom-resources) compares the features of CRDs and API aggregation
|
||||
|
||||
???
|
||||
|
||||
:EN:- Guidelines to design our own operators
|
||||
:FR:- Comment concevoir nos propres opérateurs
|
||||
|
||||
@@ -615,3 +615,11 @@ After the Kibana UI loads, we need to click around a bit
|
||||
*Operators can be very powerful.
|
||||
<br/>
|
||||
But we need to know exactly the scenarios that they can handle.*
|
||||
|
||||
???
|
||||
|
||||
:EN:- Kubernetes operators
|
||||
:EN:- Deploying ElasticSearch with ECK
|
||||
|
||||
:FR:- Les opérateurs
|
||||
:FR:- Déployer ElasticSearch avec ECK
|
||||
|
||||
@@ -162,3 +162,8 @@ Yes, this may take a little while to update. *(Narrator: it was DNS.)*
|
||||
--
|
||||
|
||||
*Alright, we're back to where we started, when we were running on a single node!*
|
||||
|
||||
???
|
||||
|
||||
:EN:- Running our demo app on Kubernetes
|
||||
:FR:- Faire tourner l'application de démo sur Kubernetes
|
||||
|
||||
@@ -180,3 +180,8 @@ class: extra-details
|
||||
]
|
||||
|
||||
As always, the [documentation](https://kubernetes.io/docs/concepts/workloads/controllers/garbage-collection/) has useful extra information and pointers.
|
||||
|
||||
???
|
||||
|
||||
:EN:- Owners and dependents
|
||||
:FR:- Liens de parenté entre les ressources
|
||||
|
||||
@@ -531,3 +531,8 @@ class: extra-details
|
||||
```
|
||||
|
||||
]
|
||||
|
||||
???
|
||||
|
||||
:EN:- Pod Security Policies
|
||||
:FR:- Les *Pod Security Policies*
|
||||
|
||||
@@ -678,3 +678,10 @@ were inspired by [Portworx examples on Katacoda](https://katacoda.com/portworx/s
|
||||
- [HA PostgreSQL on Kubernetes with Portworx](https://www.katacoda.com/portworx/scenarios/px-k8s-postgres-all-in-one)
|
||||
|
||||
(with adaptations to use a Stateful Set and simplify PostgreSQL's setup)
|
||||
|
||||
???
|
||||
|
||||
:EN:- Highly available persistent volumes
|
||||
:EN:- Use-case: deploying Postgres with high availability
|
||||
|
||||
:FR:- Cas d'usage : déployer un serveur SQL haute disponibilité
|
||||
|
||||
@@ -562,3 +562,8 @@ class: extra-details
|
||||
Don't panic if you don't know these tools!
|
||||
|
||||
...But make sure at least one person in your team is on it 💯
|
||||
|
||||
???
|
||||
|
||||
:EN:- Collecting metrics with Prometheus
|
||||
:FR:- Collecter des métriques avec Prometheus
|
||||
|
||||
@@ -536,3 +536,15 @@ services.nodeports 0 0
|
||||
- [static demo](https://hjacobs.github.io/kube-resource-report/sample-report/output/index.html)
|
||||
|
|
||||
[live demo](https://kube-resource-report.demo.j-serv.de/applications.html)
|
||||
|
||||
???
|
||||
|
||||
:EN:- Allocate and limit container resources
|
||||
:EN:- Define default resource limits
|
||||
:EN:- Enforce resource quotas
|
||||
:EN:- Resource management in practice
|
||||
|
||||
:FR:- Allouer et limiter les ressources des conteneurs
|
||||
:FR:- Définition de ressources par défaut
|
||||
:FR:- Quotas de ressources
|
||||
:FR:- Conseils pratiques
|
||||
@@ -437,3 +437,12 @@ class: extra-details
|
||||
]
|
||||
|
||||
]
|
||||
|
||||
???
|
||||
|
||||
:EN:- Rolling updates
|
||||
:EN:- Rolling back a bad deployment
|
||||
|
||||
:FR:- Mettre à jour un déploiement
|
||||
:FR:- Concept de *rolling update* et *rollback*
|
||||
:FR:- Paramétrer la vitesse de déploiement
|
||||
|
||||
@@ -200,3 +200,8 @@ Now we can access the IP addresses of our services through `$HASHER` and `$RNG`.
|
||||
- `rng` is not (it should take about 700 milliseconds if there are 10 workers)
|
||||
|
||||
- Something is wrong with `rng`, but ... what?
|
||||
|
||||
???
|
||||
|
||||
:EN:- Scaling up our demo app
|
||||
:FR:- *Scale up* de l'application de démo
|
||||
|
||||
@@ -92,3 +92,8 @@
|
||||
- For a longer list, check the Kubernetes documentation:
|
||||
<br/>
|
||||
it has a great guide to [pick the right solution](https://kubernetes.io/docs/setup/#production-environment) to set up Kubernetes.
|
||||
|
||||
???
|
||||
|
||||
:EN:- Overview of the kubeadm installer
|
||||
:FR:- Survol de kubeadm
|
||||
|
||||
@@ -250,6 +250,11 @@ with a cloud provider
|
||||
|
||||
- OVH
|
||||
|
||||
- Scaleway (private beta)
|
||||
- Scaleway
|
||||
|
||||
- ...
|
||||
|
||||
???
|
||||
|
||||
:EN:- Installing a managed cluster
|
||||
:FR:- Installer un cluster infogéré
|
||||
|
||||
@@ -108,3 +108,8 @@
|
||||
<br/>(do they need training?)
|
||||
|
||||
- etc.
|
||||
|
||||
???
|
||||
|
||||
:EN:- Various ways to set up Kubernetes
|
||||
:FR:- Différentes méthodes pour installer Kubernetes
|
||||
|
||||
@@ -115,4 +115,9 @@
|
||||
There might be a long pause before the first layer is pulled,
|
||||
because the API behind `docker pull` doesn't allow to stream build logs, and there is no feedback during the build.
|
||||
|
||||
It is possible to view the build logs by setting up an account on [ctr.run](https://ctr.run/).
|
||||
It is possible to view the build logs by setting up an account on [ctr.run](https://ctr.run/).
|
||||
|
||||
???
|
||||
|
||||
:EN:- Shipping images to Kubernetes
|
||||
:FR:- Déployer des images sur notre cluster
|
||||
|
||||
@@ -600,3 +600,10 @@ This will trigger the following actions.
|
||||
5. The PersistentVolumeClaimBinder associates the PVs and the PVCs together.
|
||||
|
||||
6. PVCs are now bound, the Pods can start.
|
||||
|
||||
???
|
||||
|
||||
:EN:- Deploying stateful applications
|
||||
:EN:- Use-case: running Consul with a Stateful Set
|
||||
:FR:- Déployer des applications persistante
|
||||
:FR:- Example: lancer Consul avec un Sateful Set
|
||||
|
||||
@@ -239,3 +239,8 @@ The `-node1` suffix was added automatically by kubelet.
|
||||
If we delete the pod (with `kubectl delete`), it will be recreated immediately.
|
||||
|
||||
To delete the pod, we need to delete (or move) the manifest file.
|
||||
|
||||
???
|
||||
|
||||
:EN:- Static pods
|
||||
:FR:- Les *static pods*
|
||||
|
||||
@@ -88,3 +88,8 @@ class: extra-details
|
||||
```
|
||||
|
||||
- Check [the documentation](https://kubernetes.io/docs/setup/release/version-skew-policy/#kubectl) for the whole story about compatibility
|
||||
|
||||
???
|
||||
|
||||
:EN:- Kubernetes versioning and compatibility
|
||||
:FR:- Les versions de Kubernetes et leur compatibilité
|
||||
|
||||
@@ -467,3 +467,11 @@ spec:
|
||||
- A volume survives across container restarts
|
||||
|
||||
- A volume is destroyed (or, for remote storage, detached) when the pod is destroyed
|
||||
|
||||
???
|
||||
|
||||
:EN:- Sharing data between containers with volumes
|
||||
:EN:- When and how to use Init Containers
|
||||
|
||||
:FR:- Partager des données grâce aux volumes
|
||||
:FR:- Quand et comment utilise un *Init Container*
|
||||
|
||||
@@ -164,3 +164,8 @@ class: extra-details
|
||||
- this is typical for things that may be deployed multiple times
|
||||
|
||||
- example: applications (production, staging, feature branches ...)
|
||||
|
||||
???
|
||||
|
||||
:EN:- Deploying with YAML manifests
|
||||
:FR:- Déployer avec des *manifests* YAML
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
## Intros
|
||||
|
||||
- Hello! We are:
|
||||
|
||||
- .emoji[👷🏻♀️] AJ ([@s0ulshake], [EphemeraSearch])
|
||||
|
||||
- .emoji[🐳] Jérôme ([@jpetazzo], Enix SAS)
|
||||
|
||||
- The training will run for 4 hours, with a 10 minutes break every hour
|
||||
|
||||
(the middle break will be a bit longer)
|
||||
|
||||
- Feel free to ask questions at any time
|
||||
|
||||
- *Especially when you see full screen container pictures!*
|
||||
|
||||
- Live feedback, questions, help: @@CHAT@@
|
||||
|
||||
[EphemeraSearch]: https://ephemerasearch.com/
|
||||
[@s0ulshake]: https://twitter.com/s0ulshake
|
||||
[@jpetazzo]: https://twitter.com/jpetazzo
|
||||
@@ -0,0 +1,35 @@
|
||||
## Intros
|
||||
|
||||
- This slide should be customized by the tutorial instructor(s).
|
||||
|
||||
- Hello! We are:
|
||||
|
||||
- .emoji[👩🏻🏫] Ann O'Nymous ([@...](https://twitter.com/...), Megacorp Inc)
|
||||
|
||||
- .emoji[👨🏾🎓] Stu Dent ([@...](https://twitter.com/...), University of Wakanda)
|
||||
|
||||
<!-- .dummy[
|
||||
|
||||
- .emoji[👷🏻♀️] AJ ([@s0ulshake](https://twitter.com/s0ulshake), Travis CI)
|
||||
|
||||
- .emoji[🚁] Alexandre ([@alexbuisine](https://twitter.com/alexbuisine), Enix SAS)
|
||||
|
||||
- .emoji[🐳] Jérôme ([@jpetazzo](https://twitter.com/jpetazzo), Enix SAS)
|
||||
|
||||
- .emoji[⛵] Jérémy ([@jeremygarrouste](twitter.com/jeremygarrouste), Inpiwee)
|
||||
|
||||
- .emoji[🎧] Romain ([@rdegez](https://twitter.com/rdegez), Enix SAS)
|
||||
|
||||
] -->
|
||||
|
||||
- The workshop will run from ...
|
||||
|
||||
- There will be a lunch break at ...
|
||||
|
||||
(And coffee breaks!)
|
||||
|
||||
- Feel free to interrupt for questions at any time
|
||||
|
||||
- *Especially when you see full screen container pictures!*
|
||||
|
||||
- Live feedback, questions, help: @@CHAT@@
|
||||
@@ -1,35 +0,0 @@
|
||||
## Intros
|
||||
|
||||
- This slide should be customized by the tutorial instructor(s).
|
||||
|
||||
- Hello! We are:
|
||||
|
||||
- .emoji[👩🏻🏫] Ann O'Nymous ([@...](https://twitter.com/...), Megacorp Inc)
|
||||
|
||||
- .emoji[👨🏾🎓] Stu Dent ([@...](https://twitter.com/...), University of Wakanda)
|
||||
|
||||
<!-- .dummy[
|
||||
|
||||
- .emoji[👷🏻♀️] AJ ([@s0ulshake](https://twitter.com/s0ulshake), Travis CI)
|
||||
|
||||
- .emoji[🚁] Alexandre ([@alexbuisine](https://twitter.com/alexbuisine), Enix SAS)
|
||||
|
||||
- .emoji[🐳] Jérôme ([@jpetazzo](https://twitter.com/jpetazzo), Enix SAS)
|
||||
|
||||
- .emoji[⛵] Jérémy ([@jeremygarrouste](twitter.com/jeremygarrouste), Inpiwee)
|
||||
|
||||
- .emoji[🎧] Romain ([@rdegez](https://twitter.com/rdegez), Enix SAS)
|
||||
|
||||
] -->
|
||||
|
||||
- The workshop will run from ...
|
||||
|
||||
- There will be a lunch break at ...
|
||||
|
||||
(And coffee breaks!)
|
||||
|
||||
- Feel free to interrupt for questions at any time
|
||||
|
||||
- *Especially when you see full screen container pictures!*
|
||||
|
||||
- Live feedback, questions, help: @@CHAT@@
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
logistics-template.md
|
||||
+38
-29
@@ -42,7 +42,7 @@ def insertslide(markdown, title):
|
||||
|
||||
before = markdown[:slide_position]
|
||||
|
||||
toclink = "toc-chapter-{}".format(title2path[title][0])
|
||||
toclink = "toc-module-{}".format(title2path[title][0])
|
||||
_titles_ = [""] + all_titles + [""]
|
||||
currentindex = _titles_.index(title)
|
||||
previouslink = anchor(_titles_[currentindex-1])
|
||||
@@ -54,7 +54,7 @@ def insertslide(markdown, title):
|
||||
|
||||
class: pic
|
||||
|
||||
.interstitial[]
|
||||
.interstitial[]
|
||||
|
||||
---
|
||||
|
||||
@@ -98,7 +98,7 @@ def generatefromyaml(manifest, filename):
|
||||
if "html" not in manifest:
|
||||
manifest["html"] = filename + ".html"
|
||||
|
||||
markdown, titles = processchapter(manifest["chapters"], filename)
|
||||
markdown, titles = processcontent(manifest["content"], filename)
|
||||
logging.debug("Found {} titles.".format(len(titles)))
|
||||
toc = gentoc(titles)
|
||||
markdown = markdown.replace("@@TOC@@", toc)
|
||||
@@ -134,9 +134,8 @@ def generatefromyaml(manifest, filename):
|
||||
|
||||
|
||||
# Maps a section title (the string just after "^# ") to its position
|
||||
# in the table of content (as a (chapter,part,subpart,...) tuple).
|
||||
# in the table of content (as a (module,part,subpart,...) tuple).
|
||||
title2path = {}
|
||||
path2title = {}
|
||||
all_titles = []
|
||||
|
||||
# "tree" is a list of titles, potentially nested.
|
||||
@@ -144,50 +143,60 @@ def gentoc(tree, path=()):
|
||||
if not tree:
|
||||
return ""
|
||||
if isinstance(tree, str):
|
||||
logging.debug("Path {} Title {}".format(path, tree))
|
||||
title = tree
|
||||
title2path[title] = path
|
||||
path2title[path] = title
|
||||
all_titles.append(title)
|
||||
logging.debug("Path {} Title {}".format(path, title))
|
||||
return "- [{}](#{})".format(title, anchor(title))
|
||||
if isinstance(tree, list):
|
||||
# If there is only one sub-element, give it index zero.
|
||||
# Otherwise, elements will have indices 1-to-N.
|
||||
offset = 0 if len(tree) == 1 else 1
|
||||
logging.debug(
|
||||
"Path {} Tree [...({} sub-elements)]"
|
||||
.format(path, len(tree)))
|
||||
if len(path) == 0:
|
||||
return "\n---\n".join(gentoc(subtree, path+(i+1,)) for (i,subtree) in enumerate(tree))
|
||||
return "\n---\n".join(gentoc(subtree, path+(i+offset,)) for (i,subtree) in enumerate(tree))
|
||||
elif len(path) == 1:
|
||||
chapterslide = "name: toc-chapter-{n}\n\n## Chapter {n}\n\n".format(n=path[0])
|
||||
# If there is only one module, don't show "Module 1" but just "TOC"
|
||||
if path[0] == 0:
|
||||
label = "Table of contents"
|
||||
else:
|
||||
label = "Module {}".format(path[0])
|
||||
moduleslide = "name: toc-module-{n}\n\n## {label}\n\n".format(n=path[0], label=label)
|
||||
for (i,subtree) in enumerate(tree):
|
||||
chapterslide += gentoc(subtree, path+(i+1,)) + "\n\n"
|
||||
chapterslide += ".debug[(auto-generated TOC)]"
|
||||
return chapterslide
|
||||
moduleslide += gentoc(subtree, path+(i+offset,)) + "\n\n"
|
||||
moduleslide += ".debug[(auto-generated TOC)]"
|
||||
return moduleslide
|
||||
else:
|
||||
return "\n\n".join(gentoc(subtree, path+(i+1,)) for (i,subtree) in enumerate(tree))
|
||||
return "\n\n".join(gentoc(subtree, path+(i+offset,)) for (i,subtree) in enumerate(tree))
|
||||
|
||||
|
||||
# Arguments:
|
||||
# - `chapter` is a string; if it has multiple lines, it will be used as
|
||||
# - `content` is a string; if it has multiple lines, it will be used as
|
||||
# a markdown fragment; otherwise it will be considered as a file name
|
||||
# to be recursively loaded and parsed
|
||||
# - `filename` is the name of the file that we're currently processing
|
||||
# (to generate inline comments to facilitate edition)
|
||||
# Returns: (epxandedmarkdown,[list of titles])
|
||||
# The list of titles can be nested.
|
||||
def processchapter(chapter, filename):
|
||||
if isinstance(chapter, str):
|
||||
if "\n" in chapter:
|
||||
titles = re.findall("^# (.*)", chapter, re.MULTILINE)
|
||||
def processcontent(content, filename):
|
||||
if isinstance(content, str):
|
||||
if "\n" in content:
|
||||
titles = re.findall("^# (.*)", content, re.MULTILINE)
|
||||
slidefooter = ".debug[{}]".format(makelink(filename))
|
||||
chapter = chapter.replace("\n---\n", "\n{}\n---\n".format(slidefooter))
|
||||
chapter += "\n" + slidefooter
|
||||
return (chapter, titles)
|
||||
if os.path.isfile(chapter):
|
||||
return processchapter(open(chapter).read(), chapter)
|
||||
if isinstance(chapter, list):
|
||||
chapters = [processchapter(c, filename) for c in chapter]
|
||||
markdown = "\n---\n".join(c[0] for c in chapters)
|
||||
titles = [t for (m,t) in chapters if t]
|
||||
content = content.replace("\n---\n", "\n{}\n---\n".format(slidefooter))
|
||||
content += "\n" + slidefooter
|
||||
return (content, titles)
|
||||
if os.path.isfile(content):
|
||||
return processcontent(open(content).read(), content)
|
||||
if isinstance(content, list):
|
||||
subparts = [processcontent(c, filename) for c in content]
|
||||
markdown = "\n---\n".join(c[0] for c in subparts)
|
||||
titles = [t for (m,t) in subparts if t]
|
||||
return (markdown, titles)
|
||||
logging.warning("Invalid chapter: {}".format(chapter))
|
||||
return "```\nInvalid chapter: {}\n```\n".format(chapter), []
|
||||
logging.warning("Invalid content: {}".format(content))
|
||||
return "```\nInvalid content: {}\n```\n".format(content), []
|
||||
|
||||
# Try to figure out the URL of the repo on GitHub.
|
||||
# This is used to generate "edit me on GitHub"-style links.
|
||||
|
||||
Reference in New Issue
Block a user