From 13a9891e712fc1a7fa16219c7e6ab862f27d2ed9 Mon Sep 17 00:00:00 2001
From: Adrian Amaglio <aamaglio@dbmtechnologies.com>
Date: Wed, 13 Sep 2023 10:46:02 +0200
Subject: [PATCH] =?UTF-8?q?pouloulou=E2=80=A6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 installing/debootstrap_ordis_portables.sh     |  21 ++-
 installing/notes                              |   3 +
 provisioning/inventory.ini                    |  11 +-
 .../deploy_all/files/bin/deploy_service.sh    |  11 +-
 .../roles/deploy_all/files/bin/deployall.sh   |  17 +-
 .../deploy_all/files/bin/driglibash-base      |   4 +-
 .../roles/deploy_all/files/bin/dummy_cert.sh  |  38 ++++
 .../roles/deploy_all/files/bin/git_update.sh  |  41 +++--
 .../roles/deploy_all/files/bin/letsencrypt.sh |   6 +-
 .../cousinades2.jean-cloud.net/Dockerfile     |   6 -
 .../docker-compose.yml                        |  35 ----
 .../nginx_server.conf                         |  25 ---
 .../feteducourt.jean-cloud.net/deploy_http.sh |   4 +
 .../nginx_server.conf                         |  17 +-
 .../deploy_http.sh                            |   4 +
 .../nginx_server.conf                         |  19 +-
 .../metamorphosemagazine.fr/nginx_server.conf |   2 +-
 services/ns.jean-cloud.org/deploy.sh          |  13 ++
 services/ns1.jean-cloud.org/deploy.sh         | 141 ++++-----------
 .../ns1.jean-cloud.org/helper_functions.sh    | 162 ++++++++++++++++++
 services/radiodemo-back.oma-radio.fr/.env     |   1 -
 .../docker-compose.yml                        |   2 +-
 .../nginx_server.conf                         |   6 +-
 .../radiodemo.oma-radio.fr/wg-radiodemo.sh    |   5 -
 services/services.txt                         |  33 ++--
 25 files changed, 354 insertions(+), 273 deletions(-)
 create mode 100755 provisioning/roles/deploy_all/files/bin/dummy_cert.sh
 delete mode 100755 services/cousinades2.jean-cloud.net/Dockerfile
 delete mode 100755 services/cousinades2.jean-cloud.net/docker-compose.yml
 delete mode 100755 services/cousinades2.jean-cloud.net/nginx_server.conf
 create mode 100755 services/feteducourt.jean-cloud.net/deploy_http.sh
 create mode 100755 services/feteducourt2020.jean-cloud.net/deploy_http.sh
 create mode 100755 services/ns.jean-cloud.org/deploy.sh
 create mode 100644 services/ns1.jean-cloud.org/helper_functions.sh

diff --git a/installing/debootstrap_ordis_portables.sh b/installing/debootstrap_ordis_portables.sh
index aa29e15..56d52a5 100755
--- a/installing/debootstrap_ordis_portables.sh
+++ b/installing/debootstrap_ordis_portables.sh
@@ -195,8 +195,14 @@ chroot_run locale-gen
 
 
 if [ -n "$data_device" ] ; then
-	section "Mounting data dir"
-	cryptsetup create --type plain dmcrypt-jeancloud "$data_device"	
+	section "Mounting and encrypting data dir"
+	run cryptsetup create --type plain dmcrypt-jeancloud "$data_device"	
+	run mkfs.ext4 dmcrypt-jeancloud
+	uuid="$(blkid | grep dmcrypt-jeancloud | grep -o 'UUID="[^"]\+"')"
+	if [ -z "$uuid" ] ; then
+		die "Error, unexpected empty uuid"
+	fi
+	line_in_file "$uuid	/data	ext4	rw,nofail	0	1" "$mnt/etc/fstab"
 fi
 
 
@@ -210,15 +216,20 @@ line_in_file "proc /proc proc defaults" "$mnt/etc/fstab"
 run echo "$hostname" > "$mnt/etc/hostname"
 
 # Prenvent suspend on lid close
-line_in_file HandleLidSwitch=ignore /etc/systemd/logind.conf
+line_in_file HandleLidSwitch=ignore "$mnt/etc/systemd/logind.conf"
 
-# Fix path and remove noisy beep
+# Inform futur scripts that /data is not mounted
+touch "$mnt/data/mounted"
+
+# Fix path
 run cat > "$mnt/root/.bashrc" <<EOF
 PATH=$PATH:/usr/bin:/bin:/sbin:/usr/sbin:/sbin
+setterm -powerdown 0
 EOF
 # Be sure this fucking beep is gone
 echo 'set bell-style none' >> "$mnt/etc/inputrc"
-# TODO find a third method to kill this doomed beep
+# TODO find a second method to kill this doomed beep
+line_in_file '@reboot root shutdownscreen.sh' "$mnt/etc/crontab"
 
 
 # boot crypted
diff --git a/installing/notes b/installing/notes
index 43f39a3..216e221 100644
--- a/installing/notes
+++ b/installing/notes
@@ -2,3 +2,6 @@ blatte :
 DO NOT REBOOT IT. it sometimes fails…
 -i 'firmware-amd-graphics firmware-realtek'
 
+raku :
++ ajouter nonfree dans les sources
+-i firmware-atheros
diff --git a/provisioning/inventory.ini b/provisioning/inventory.ini
index 7de6cf1..63e1da1 100644
--- a/provisioning/inventory.ini
+++ b/provisioning/inventory.ini
@@ -1,9 +1,14 @@
+[shlago]
+max.jean-cloud.org
+tetede.jean-cloud.org
+raku.jean-cloud.org
+
 [servers]
-#vandamme.jean-cloud.org
 #nougaro.jean-cloud.org
-#tetede.jean-cloud.org
 #carcasse.jean-cloud.org
 #benevoles.karnaval.fr
 #montbonnot.jean-cloud.org
-max.jean-cloud.org
 #blatte.jean-cloud.org
+max.jean-cloud.org
+tetede.jean-cloud.org
+raku.jean-cloud.org
diff --git a/provisioning/roles/deploy_all/files/bin/deploy_service.sh b/provisioning/roles/deploy_all/files/bin/deploy_service.sh
index 69a29da..f22694d 100755
--- a/provisioning/roles/deploy_all/files/bin/deploy_service.sh
+++ b/provisioning/roles/deploy_all/files/bin/deploy_service.sh
@@ -131,15 +131,8 @@ if [ -f "/docker/$service/nginx_server.conf" ] ; then
     run template.sh "/docker/$service/.env" < "/docker/$service/nginx_server.conf" > "$new_nginx_conf_path/$service"
 fi
 
-# Do we need dummy cert?
-if [ ! -e "$certs_path/$service/fullchain.pem" ] ; then
-    section "Create cert dir"
-    run mkdir -p "$certs_path/$service"
-
-    section "Link dummy to cert"
-    run ln -s "$dummy_cert_path/fullchain.pem" "$certs_path/$service"
-    run ln -s "$dummy_cert_path/privkey.pem" "$certs_path/$service"
-fi
+section "Add dummy cert if needed"
+dummy_cert.sh "$service" add
 
 section "Testing nginx conf"
 run nginx -t -c /etc/nginx/new_nginx.conf
diff --git a/provisioning/roles/deploy_all/files/bin/deployall.sh b/provisioning/roles/deploy_all/files/bin/deployall.sh
index 305d8f0..c58ba5d 100755
--- a/provisioning/roles/deploy_all/files/bin/deployall.sh
+++ b/provisioning/roles/deploy_all/files/bin/deployall.sh
@@ -11,12 +11,9 @@ set -euo pipefail
 #                       Variables
 ###############################################################################
 
-export proxy_dir="/etc/nginx"
-export nginx_conf_path="$proxy_dir/sites-enabled"
-export new_nginx_conf_path="$proxy_dir/new-sites-enabled"
-
-export certs_path="/etc/letsencrypt/live"
-export dummy_cert_path="$certs_path/dummy"
+set -a
+. /etc/jeancloud.env
+set +a
 
 ###############################################################################
 #                       Helpers
@@ -50,14 +47,6 @@ run chown root:root /data
 run chmod 755 /docker
 run chmod 755 /data
 
-section "Check dummy cert exists "
-#TODO check if expired
-if [ ! -f "$dummy_cert_path/privkey.pem" ] ; then
-    echo "Dummy cert generation"
-    run mkdir -p "$dummy_cert_path"
-    run openssl req -x509 -newkey rsa:2048 -keyout /etc/letsencrypt/live/dummy/privkey.pem -out /etc/letsencrypt/live/dummy/fullchain.pem -days 365 -nodes -subj "/C=FR/ST=France/O=IT/CN=jean-cloud.net"
-fi
-
 section "Create new conf directory"
 run mkdir -p "$new_nginx_conf_path"
 
diff --git a/provisioning/roles/deploy_all/files/bin/driglibash-base b/provisioning/roles/deploy_all/files/bin/driglibash-base
index 5f7d430..d17115d 100755
--- a/provisioning/roles/deploy_all/files/bin/driglibash-base
+++ b/provisioning/roles/deploy_all/files/bin/driglibash-base
@@ -150,8 +150,8 @@ clean() {
 
 # tells where your executable is (absolute path). Follow simlinks if any argument provided
 where() {
-  if [ -z "$1" ] ; then
-    echo "$( cd -P "$( dirname "$1" )" && pwd )"
+  if [ "$#" -lt 1 ] || [ -z "$1" ] ; then
+    echo "$( cd -P "$( dirname "$0" )" && pwd )"
   else
     SOURCE="$0"
     while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
diff --git a/provisioning/roles/deploy_all/files/bin/dummy_cert.sh b/provisioning/roles/deploy_all/files/bin/dummy_cert.sh
new file mode 100755
index 0000000..1fa9caa
--- /dev/null
+++ b/provisioning/roles/deploy_all/files/bin/dummy_cert.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+
+. driglibash-base
+. /etc/jeancloud.env
+
+if [ "$#" -ne 2 ] || [ -z "$1" ] || [ -z "$2" ] ; then
+	die "Usage: $0 <service-name> <action>"
+fi
+
+service="$1"
+action="$2"
+
+# Create dummy cert if needed
+#TODO check if expired
+if [ ! -f "$dummy_cert_path/privkey.pem" ] ; then
+    echo "Dummy cert generation"
+    run mkdir -p "$dummy_cert_path"
+    run openssl req -x509 -newkey rsa:2048 -keyout /etc/letsencrypt/live/dummy/privkey.pem -out /etc/letsencrypt/live/dummy/fullchain.pem -days 365 -nodes -subj "/C=FR/ST=France/O=IT/CN=jean-cloud.net"
+fi
+
+if [ "$action" = add ] ; then
+	# Link letsencrypt dir to dummy cert dir if there is no cert
+	if [ ! -e "$certs_path/$service/fullchain.pem" ] ; then
+	    section "Create cert dir"
+	    run mkdir -p "$certs_path/$service"
+	
+	    section "Link dummy to cert"
+	    run ln -s "$dummy_cert_path/fullchain.pem" "$certs_path/$service"
+	    run ln -s "$dummy_cert_path/privkey.pem" "$certs_path/$service"
+	fi
+elif [ "$action" = remove ] ; then
+	# UNlink letsencrypt dir to dummy cert dir IF it is the dummy cert
+    if [ "$(readlink "$certs_path/$service_name/fullchain.pem")" = "$dummy_cert_path/fullchain.pem" ] ; then
+        rm -r "$certs_path/$service_name"
+    fi
+else
+	die "$0: Unknown action '$action'"
+fi
diff --git a/provisioning/roles/deploy_all/files/bin/git_update.sh b/provisioning/roles/deploy_all/files/bin/git_update.sh
index 7ccf44b..4655184 100755
--- a/provisioning/roles/deploy_all/files/bin/git_update.sh
+++ b/provisioning/roles/deploy_all/files/bin/git_update.sh
@@ -1,5 +1,6 @@
 #!/bin/bash
 
+
 declare -A usage
 declare -A varia
 
@@ -17,6 +18,10 @@ usage[i]="privkey used to ssh pull"
 varia[i]=privkey
 privkey=''
 
+usage[N]="Clone to a Non-empty target. Existing files will be overwriten"
+varia[N]=nonempty_target
+nonempty_target=false
+
 
 . driglibash-args
 
@@ -35,16 +40,32 @@ fi
 cd "$dst"
 
 if [ -d .git ] ; then
-	git fetch origin "$branch"
-	git checkout --force -B "$branch" "origin/$branch"
-    git reset --hard
-	git clean -qffdx
-	git submodule update --init --recursive --force --recommend-shallow
-	git submodule foreach git fetch
-	git submodule foreach git checkout --force -B "$branch" "origin/$branch"
-	git submodule foreach git reset --hard
-	git submodule foreach git clean -fdx
+	run git fetch origin "$branch"
+	run git checkout --force -B "$branch" "origin/$branch"
+    run git reset --hard
+	# Preserve existing files in some cases
+	if ! "$nonempty_target" ; then
+		git clean -qffdx
+	fi
+	run git submodule update --init --recursive --force --recommend-shallow
+	run git submodule foreach git fetch
+	run git submodule foreach git checkout --force HEAD
+	run git submodule foreach git reset --hard
+	run git submodule foreach git clean -fdx
 else
-    git clone -b "$branch" --single-branch --recurse-submodules --shallow-submodules --depth 1 --config core.sshCommand="$ssh_opt" "$repo" .
+	clone_dst='.'
+
+	# To override an existing dir, we need to clone elsewhere first
+	if "$nonempty_target" ; then
+		clone_dst="$(mktemp -d)"
+	fi
+
+    run git clone -b "$branch" --single-branch --recurse-submodules --shallow-submodules --depth 1 --config core.sshCommand="$ssh_opt" "$repo" "$clone_dst"
+
+	# To override an existing dir, we then move everything to that dir
+	if "$nonempty_target" ; then
+		run mv "$clone_dst/"{*,.*} .
+		run rmdir "$clone_dst"
+	fi
 fi
 
diff --git a/provisioning/roles/deploy_all/files/bin/letsencrypt.sh b/provisioning/roles/deploy_all/files/bin/letsencrypt.sh
index ccc0a6c..8af02f9 100755
--- a/provisioning/roles/deploy_all/files/bin/letsencrypt.sh
+++ b/provisioning/roles/deploy_all/files/bin/letsencrypt.sh
@@ -34,9 +34,7 @@ for file in "$nginx_sites_dir"* ; do
   domains="$(extract_domain_nginx_conf.sh "$file")"
   if [ -n "$domains" ] ; then
     # If using dummy cert, disabling it
-    if [ "$(readlink "/etc/letsencrypt/live/$service_name/fullchain.pem")" = "/etc/letsencrypt/live/dummy/fullchain.pem" ] ; then
-        rm -r "/etc/letsencrypt/live/$service_name"
-    fi
+	dummy_cert.sh "$service_name" remove
 
     echo "$domains"
     # adding -d before every domain
@@ -71,8 +69,10 @@ for file in "$nginx_sites_dir"* ; do
       echo "     ------------------------------------------"
       echo "$out"
       echo "     ------------------------------------------"
+	  dummy_cert.sh "$service_name" add
     else
         echo "Unknown error : $result.\n$out"
+	    dummy_cert.sh "$service_name" add
     fi
   fi
 done
diff --git a/services/cousinades2.jean-cloud.net/Dockerfile b/services/cousinades2.jean-cloud.net/Dockerfile
deleted file mode 100755
index de80780..0000000
--- a/services/cousinades2.jean-cloud.net/Dockerfile
+++ /dev/null
@@ -1,6 +0,0 @@
-FROM php:7.2-fpm-alpine
-#RUN apt-get update && apt-get install -y libpq-dev && docker-php-ext-install pdo pdo_pgsql
-RUN set -ex \
-  && apk --no-cache add \
-  postgresql-dev
-RUN docker-php-ext-install pdo_pgsql
diff --git a/services/cousinades2.jean-cloud.net/docker-compose.yml b/services/cousinades2.jean-cloud.net/docker-compose.yml
deleted file mode 100755
index b268cc7..0000000
--- a/services/cousinades2.jean-cloud.net/docker-compose.yml
+++ /dev/null
@@ -1,35 +0,0 @@
-version: '3'
-services:
-  app:
-    build: .
-    volumes:
-      - /data/cousinades2.jean-cloud.net/public:/usr/src/app
-    restart: unless-stopped
-    networks:
-      default:
-        ipv4_address: 172.29.8.101
-    deploy:
-      resources:
-        limits:
-          cpus: '0.50'
-          memory: 100M
-
-  db:
-    image: postgres:9.6-alpine
-    volumes:
-      - /data/cousinades2.jean-cloud.net/db:/var/lib/postgresql/data
-    networks:
-      default:
-        ipv4_address: 172.29.8.101
-    deploy:
-      resources:
-        limits:
-          cpus: '0.50'
-          memory: 100M
-
-networks:
-  default:
-    ipam:
-      config:
-        - subnet: 172.29.8.0/24
-
diff --git a/services/cousinades2.jean-cloud.net/nginx_server.conf b/services/cousinades2.jean-cloud.net/nginx_server.conf
deleted file mode 100755
index dd8441e..0000000
--- a/services/cousinades2.jean-cloud.net/nginx_server.conf
+++ /dev/null
@@ -1,25 +0,0 @@
-server {
-  listen 443 ssl http2;
-  listen [::]:443 ssl http2;
-  ssl_certificate /etc/letsencrypt/live/cousinades2.jean-cloud.net/fullchain.pem;
-  ssl_certificate_key /etc/letsencrypt/live/cousinades2.jean-cloud.net/privkey.pem;
-  server_name cousinades2.jean-cloud.net www.cousinades2.jean-cloud.net;
-
-  index index.php;
-  root /data/cousinades2.jean-cloud.net/public;
-
-  location / {
-    #auth_basic "Restricted";
-    #auth_basic_user_file /data/cousinades2.jean-cloud.net/private/passwords.txt;
-    try_files $uri $uri/ =404;
-  }
-
-  location ~ \.php$ {
-    fastcgi_split_path_info ^(.+\.php)(/.+)$;
-    fastcgi_pass 172.29.8.100:9000;
-    fastcgi_index index.php;
-    include fastcgi_params;
-    fastcgi_param SCRIPT_FILENAME /usr/src/app/$fastcgi_script_name;
-    fastcgi_param PATH_INFO $fastcgi_path_info;
-  }
-}
diff --git a/services/feteducourt.jean-cloud.net/deploy_http.sh b/services/feteducourt.jean-cloud.net/deploy_http.sh
new file mode 100755
index 0000000..4c221b6
--- /dev/null
+++ b/services/feteducourt.jean-cloud.net/deploy_http.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+set -euo pipefail
+
+git_update.sh -d "$HTTP_DIR" -b 2021 "https://git.jean-cloud.net/adrian/feteducourt-static.git"
diff --git a/services/feteducourt.jean-cloud.net/nginx_server.conf b/services/feteducourt.jean-cloud.net/nginx_server.conf
index 98959b8..1ca7e07 100755
--- a/services/feteducourt.jean-cloud.net/nginx_server.conf
+++ b/services/feteducourt.jean-cloud.net/nginx_server.conf
@@ -1,20 +1,11 @@
 server {
   listen 443 ssl http2;
   listen [::]:443 ssl http2;
-  ssl_certificate /etc/letsencrypt/live/feteducourt.jean-cloud.net/fullchain.pem;
-  ssl_certificate_key /etc/letsencrypt/live/feteducourt.jean-cloud.net/privkey.pem;
-  server_name feteducourt.jean-cloud.net www.feteducourt.jean-cloud.net;
-  #location /static {
-  #  alias /data/feteducourt.jean-cloud.net/app/static;
-  #  try_files $uri $uri/ =404;
-  #}
-  #location / {
-  #  proxy_pass http://app.feteducourtjean-cloudnet.docker;
-  #  proxy_set_header Host $host;
-  #}
+  ssl_certificate /etc/letsencrypt/live/$JC_SERVICE/fullchain.pem;
+  ssl_certificate_key /etc/letsencrypt/live/$JC_SERVICE/privkey.pem;
+  server_name $JC_SERVICE www.$JC_SERVICE;
   location / {
-    root /data/feteducourt.jean-cloud.net/static;
+    root $HTTP_DIR;
     try_files $uri $uri/ =404;
   }
 }
-
diff --git a/services/feteducourt2020.jean-cloud.net/deploy_http.sh b/services/feteducourt2020.jean-cloud.net/deploy_http.sh
new file mode 100755
index 0000000..c9ce0d7
--- /dev/null
+++ b/services/feteducourt2020.jean-cloud.net/deploy_http.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+set -euo pipefail
+
+git_update.sh -d "$HTTP_DIR" -b 2020 "https://git.jean-cloud.net/adrian/feteducourt-static.git"
diff --git a/services/feteducourt2020.jean-cloud.net/nginx_server.conf b/services/feteducourt2020.jean-cloud.net/nginx_server.conf
index 94c0eb3..1ca7e07 100755
--- a/services/feteducourt2020.jean-cloud.net/nginx_server.conf
+++ b/services/feteducourt2020.jean-cloud.net/nginx_server.conf
@@ -1,22 +1,11 @@
 server {
   listen 443 ssl http2;
   listen [::]:443 ssl http2;
-  ssl_certificate /etc/letsencrypt/live/feteducourt2020.jean-cloud.net/fullchain.pem;
-  ssl_certificate_key /etc/letsencrypt/live/feteducourt2020.jean-cloud.net/privkey.pem;
-  server_name feteducourt2020.jean-cloud.net www.feteducourt2020.jean-cloud.net;
-
-  #location /static {
-  #  alias /data/feteducourt2020.jean-cloud.net/app/static;
-  #  try_files $uri $uri/ =404;
-  #}
-  #location / {
-  #  proxy_pass http://app.feteducourt2020jean-cloudnet.docker;
-  #  proxy_set_header Host $host;
-  #}
-
+  ssl_certificate /etc/letsencrypt/live/$JC_SERVICE/fullchain.pem;
+  ssl_certificate_key /etc/letsencrypt/live/$JC_SERVICE/privkey.pem;
+  server_name $JC_SERVICE www.$JC_SERVICE;
   location / {
-    root /data/feteducourt2020.jean-cloud.net/static;
+    root $HTTP_DIR;
     try_files $uri $uri/ =404;
   }
 }
-
diff --git a/services/metamorphosemagazine.fr/nginx_server.conf b/services/metamorphosemagazine.fr/nginx_server.conf
index 36c5e1f..60c6ab0 100755
--- a/services/metamorphosemagazine.fr/nginx_server.conf
+++ b/services/metamorphosemagazine.fr/nginx_server.conf
@@ -3,7 +3,7 @@ server {
   listen [::]:443 ssl http2;
   ssl_certificate /etc/letsencrypt/live/metamorphosemagazine.fr/fullchain.pem;
   ssl_certificate_key /etc/letsencrypt/live/metamorphosemagazine.fr/privkey.pem;
-  server_name metamorphosemagazine.fr;
+  server_name $JC_SERVICE www.$JC_SERVICE;
   location / {
           add_header Content-language fr;
           root $HTTP_DIR/src;
diff --git a/services/ns.jean-cloud.org/deploy.sh b/services/ns.jean-cloud.org/deploy.sh
new file mode 100755
index 0000000..e03bb54
--- /dev/null
+++ b/services/ns.jean-cloud.org/deploy.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+set -euo pipefail
+
+cd ../ns1.jean-cloud.org
+. deploy.sh
+. .env
+
+# Do not run if primary exists
+[ -d "$DATA_DIR/keys" ] && echo 'ns1 found on this host. Aborting.' && exit 0
+
+export keydir=""
+run secondary
diff --git a/services/ns1.jean-cloud.org/deploy.sh b/services/ns1.jean-cloud.org/deploy.sh
index 3f5959b..88c16c7 100755
--- a/services/ns1.jean-cloud.org/deploy.sh
+++ b/services/ns1.jean-cloud.org/deploy.sh
@@ -1,125 +1,56 @@
 #!/bin/bash
 
 . driglibash-base
+. "$(where)/helper_functions.sh"
 
 set -euo pipefail
 
 # Working variables
-debian_bind_workdir="/var/cache/bind"
 debian_bind_confdir="/etc/bind"
-keydir="$DATA_DIR/keys"
-
-# Install dependencies
-apt install -y bind9 &>/dev/null
-
-# Create Directories
-mkdir -p "$keydir"
-chown bind:bind "$keydir" -R
-chown bind:bind "$debian_bind_confdir" -R
-
-# Empty bind dir if it is not our git repo
-if [ ! -d "$debian_bind_confdir/.git" ] ; then
-	echo "lets delete $debian_bind_confdir"
-	rm -rf "$debian_bind_confdir/"{*,.*}
-fi
-
-# Sync the git repo
-sudo -u bind git_update.sh -b main -i "$DATA_DIR/gitkey" -d "$debian_bind_confdir" 'ssh://git@git.jean-cloud.net:22529/adrian/dnszones.git'
-cd /etc/bind
-sudo -u bind git status
-
-### Generate zones from service directory ###
-
-servicefile="/docker/services.txt"
-
-# Function that simulate a DNS resolve by reading bind zone file
-# Returns all the record line:
-# @ IN A X.X.X.X
-fakeresolve () {
-	if [ "$#" -ne 1 ] ; then
-		die "Usage: fakeresolve <name>"
-	fi
-	name="$1"
-	
-	zonefile="$debian_bind_confdir/db.jean-cloud.org"
-	shortname="$(echo "$name" | grep -Po '^.*(?=\.[^\.]+\.[^\.]+$)' || true)"
-
-	grep -v -e  '^[[:space:]]*;' "$zonefile"  |grep -oP "^[[:space:]]*$shortname\K[[:space:]]*IN[[:space:]]*A{1,4}[[:space:]]*[\S;]+" | sed 's/^/@/'
-
-}
-
-# Function that add DNS record in the right file
-addbindline () {
-	if [ "$#" -ne 2 ] ; then
-		die "Usage: addbindline <name> <target_cname>"
-	fi
-
-	name="$1"
-	target="$2"
-
-	# extract the truc.com part
-	domain="$(echo "$name" | grep -o '[^\.]\+\.[^\.]\+$' || true)"	
-	[ -z "$domain" ] && return 0
-
-	# extract the subdomain part (www)
-	shortname="$(echo "$name" | grep -Po '^.*(?=\.[^\.]+\.[^\.]+$)' || true)"
-
-	# bind DB file
-	bindfile="$debian_bind_confdir/db.$domain"
-
-	if [ -z "$shortname" ] ; then
-		# CNAME are forbiden for empty shortnames, so we must resolve the target IPs
-		while read line ; do
-			line_in_file "$line" "$bindfile"
-		done < <(fakeresolve "$target")
-	else
-		line_in_file "$shortname IN CNAME $target." "$bindfile"
-	fi
-
-	#XXX Add CAA records
-}
-
-
 autoconf_separator=";;; Autogeneration. Do not write under this line! ;;;"
 
-echo 'Prepare bind: Remove autogenerated part from bind conf files'
-sed -i -n "/$autoconf_separator/q;p" "$debian_bind_confdir"/*
 
-echo 'Put the separator back'
-for file in $( ls "$debian_bind_confdir"/db.* | grep -v '.signed$\|.jbk$\|.jnl$') ; do
-	echo "$autoconf_separator" >> "$file"
-done
+# File that contain "service target" lines
+# With service a symbolic dns name and target an existing server hostname
+servicefile="/docker/services.txt"
 
-for file in "$debian_bind_confdir"/db.* ; do
-	domain="$(basename "$file" | sed 's/db.//')"
+# The bind file containing server declarations
+server_zone_file="template.db.jean-cloud.org"
 
-	# TODO fill header too?
+# Where you want your DNS keys stored
+keydir="$DATA_DIR/keys"
 
-	# If no NS record in the db file
-	if [ -z "$(grep '[^;].*IN.*NS' "$file")" ] ; then
-		echo -e "@ IN NS ns.jean-cloud.org\n" >> "$file"
+# IP of primary servers
+primary_ips=""
+
+# IP of secondary servers (for zone transfer)
+secondary_ips="37.65.119.74"
+
+# NS name
+default_dns_name="shlago.jean-cloud.org."
+
+
+run () {
+	if [ "$#" -ne 1 ] ; then
+		die "Usage: run <primary|secondary>"
 	fi
 
-	echo -n "
-zone '$domain' {
-    allow-update { none; };
-    type master;
-    file \"$file\";
-};" >> "$debian_bind_confdir/named.conf.local"
-done
+	prepare
+	primary_ips="$primary_ips;$(fakeresolve_ip_list raku)"
+	secondary_ips="$secondary_ips;$(fakeresolve_ip_list shlago)"
 
-echo 'Find every used domain and add them to bind db'
-while read line ; do
-	read -r service target <<<$(echo "$line")
-	addbindline "$service" "$target"
-	nginxfile="/docker/$service/nginx_server.conf"
-	if [ -f "$nginxfile" ] ; then
-		for name in $(extract_domain_nginx_conf.sh "$nginxfile" | template.sh "/docker/$service/.env") ; do
-			addbindline "$name" "$target"
-		done
+	if [ "$1" = "primary" ] ; then
+		create_primary_files
+	else
+		create_secondary_files
 	fi
-done <"$servicefile"
 
+	restart
+}
 
-echo 'Restart bind9'
-systemctl restart bind9
+main () {
+	run primary
+}
+
+# Do not execute main if script is sourced
+! (return 0 2>/dev/null) && main "$@" || true # return 0 whatever happends
diff --git a/services/ns1.jean-cloud.org/helper_functions.sh b/services/ns1.jean-cloud.org/helper_functions.sh
new file mode 100644
index 0000000..4dfa37c
--- /dev/null
+++ b/services/ns1.jean-cloud.org/helper_functions.sh
@@ -0,0 +1,162 @@
+set -euo pipefail
+
+fakeresolve_ip_list () {
+	if [ "$#" -ne 1 ] ; then
+		die "Usage: fakeresolve_ip_list <name>"
+	fi
+	grep -oP "^$1[[:space:]]+IN[[:space:]]+A{1,4}[[:space:]]+\K[^;\s]+" "$debian_bind_confdir/$server_zone_file" | tr '\n' ';'
+}
+
+prepare () {
+	# Install dependencies
+	apt install -y bind9 &>/dev/null
+	
+	# Create Directories
+	if [ -n "$keydir" ] ; then
+		mkdir -p "$keydir"
+		chown bind:bind "$keydir" -R
+		chown bind:bind "$debian_bind_confdir" -R
+	fi
+	
+	# Sync the git repo
+	sudo -u bind git_update.sh -N -b main -i "$DATA_DIR/gitkey" -d "$debian_bind_confdir" 'ssh://git@git.jean-cloud.net:22529/adrian/dnszones.git'
+	cd /etc/bind
+	
+	
+	echo 'Prepare bind: Remove autogenerated part from bind conf files'
+	sed -i -n "/$autoconf_separator/q;p" "$debian_bind_confdir"/*
+	
+	echo 'Put the separator back'
+	for file in $( ls "$debian_bind_confdir"/template.db.* | grep -v '.signed$\|.jbk$\|.jnl$') ; do
+		echo "$autoconf_separator" >> "$file"
+	done
+
+}
+
+restart () {
+	echo 'Restart bind9'
+	systemctl restart bind9
+}
+
+# Function that simulate a DNS resolve by reading bind zone file
+# Returns all the record line:
+# @ IN A X.X.X.X
+fakeresolve () {
+	if [ "$#" -ne 1 ] ; then
+		die "Usage: fakeresolve <name>"
+	fi
+	name="$1"
+	
+	zonefile="$debian_bind_confdir/$server_zone_file"
+
+	# Split full name if there are dots
+	shortname="$name"
+	if [ -n "$(echo "$name" | grep -o '\.')" ] ; then
+		shortname="$(echo "$name" | grep -Po '^.*(?=\.[^\.]+\.[^\.]+$)' || true)"
+	fi
+
+	grep -v -e  '^[[:space:]]*;' "$zonefile"  |grep -oP "^[[:space:]]*$shortname\K[[:space:]]*IN[[:space:]]*A{1,4}[[:space:]]*[\S;]+" | sed 's/^/@/'
+
+}
+
+# Function that add DNS record in the right file
+addbindline () {
+	if [ "$#" -ne 2 ] ; then
+		die "Usage: addbindline <name> <target_cname>"
+	fi
+
+	name="$1"
+	target="$2"
+
+	# extract the truc.com part
+	domain="$(echo "$name" | grep -o '[^\.]\+\.[^\.]\+$' || true)"	
+	[ -z "$domain" ] && return 0
+
+	# extract the subdomain part (www)
+	shortname="$(echo "$name" | grep -Po '^.*(?=\.[^\.]+\.[^\.]+$)' || true)"
+
+	# bind DB file
+	bindfile="$debian_bind_confdir/db.$domain"
+
+	# Only append if db file exists
+	[ ! -f "$bindfile" ] && return 0
+
+	if [ -z "$shortname" ] ; then
+		# CNAME are forbiden for empty shortnames, so we must resolve the target IPs
+		while read line ; do
+			line_in_file "$line" "$bindfile"
+		done < <(fakeresolve "$target")
+	else
+		line_in_file "$shortname IN CNAME $target." "$bindfile"
+	fi
+
+	#XXX Add CAA records
+}
+
+list_template_db_files () {
+	ls "$debian_bind_confdir"/template.db.*
+}
+
+
+create_primary_files () {
+	# Compact the default SOA
+	SOA="$(grep -o '^[^;]*' SOA | sed -z -e 's/[[:space:]]\{2,\}/ /g' -e 's/\n/\\n/')"
+	
+	
+	for file in $(list_template_db_files) ; do
+		domain="$(basename "$file" | sed 's/template.db.//')"
+		new_db_file="$(echo "$file" | sed 's/template.db./db./')"
+
+		# Set the default SOA if needed
+		sed "s/^;JC_AUTOSOA$/$SOA/" "$file" > "$new_db_file"
+	
+		# If no NS record in the db file
+		if [ -z "$(grep '[^;].*IN.*NS' "$new_db_file")" ] ; then
+			echo "@ IN NS $default_dns_name" >> "$new_db_file"
+		fi
+	
+		cat  >> "$debian_bind_confdir/named.conf.local" <<EOF
+zone "$domain" {
+	# https://kb.isc.org/docs/aa-00723
+	#allow-update { !{!{$secondary_ips};any;}; key update-key; };
+	allow-transfer { $secondary_ips };
+	also-notify { $secondary_ips };
+	notify yes;
+    type master;
+    file "$new_db_file";
+	dnssec-policy default;
+	inline-signing yes;
+	key-directory "$DATA_DIR/keys";
+
+};
+EOF
+	done
+	
+	echo 'Find every used domain and add them to bind db'
+	while read line ; do
+		read -r service target < <(echo "$line")
+		addbindline "$service" "$target"
+		nginxfile="/docker/$service/nginx_server.conf"
+		if [ -f "$nginxfile" ] ; then
+			for name in $(extract_domain_nginx_conf.sh "$nginxfile" | template.sh "/docker/$service/.env") ; do
+				addbindline "$name" "$target"
+			done
+		fi
+	done <"$servicefile"
+}
+
+create_secondary_files () {
+	primary_ips="$(echo "$primary_ips" | sed 's/^;//')"
+	for file in "$debian_bind_confdir"/template.db.* ; do
+		file="$(echo "$file" | sed 's/template.db.//')"
+		domain="$(basename "$file")"
+	
+		echo -n "
+zone \"$domain\" {
+	masters { $primary_ips };
+    type slave;
+    file \"$file\";
+};" >> "$debian_bind_confdir/named.conf.local"
+	done
+
+}
diff --git a/services/radiodemo-back.oma-radio.fr/.env b/services/radiodemo-back.oma-radio.fr/.env
index fa4a92b..4053245 100644
--- a/services/radiodemo-back.oma-radio.fr/.env
+++ b/services/radiodemo-back.oma-radio.fr/.env
@@ -13,7 +13,6 @@ RADIO_NAME_SIMPLE=radiodemo
 OMA_CONFIG_NomRadio=radiodemo
 OMA_CONFIG_LogLevel=8
 RADIO_NAME_PRETTY="Radio Démo"
-RADIO_HOST=radiodemo.oma-radio.fr
 COMPOSE_NAME=radiodemo-backoma-radiofr
 DOCKER_INSTANCES_PREFIX=radiodemo-backoma-radiofr-
 DOCKER_INSTANCES_SUFIX=-1
diff --git a/services/radiodemo-back.oma-radio.fr/docker-compose.yml b/services/radiodemo-back.oma-radio.fr/docker-compose.yml
index 1cb2b2b..0a1cb07 100644
--- a/services/radiodemo-back.oma-radio.fr/docker-compose.yml
+++ b/services/radiodemo-back.oma-radio.fr/docker-compose.yml
@@ -142,7 +142,7 @@ services:
       CONFIG_PATH: /config
     restart: unless-stopped
     volumes:
-      - /tmp/uwsgi/$RADIO_HOST:/tmp/uwsgi
+      - /tmp/uwsgi/$JC_SERVICE:/tmp/uwsgi
       - /var/run/docker.sock:/var/run/docker.sock
       - $SOUNDBASE_DIR:/soundbase
     networks:
diff --git a/services/radiodemo-back.oma-radio.fr/nginx_server.conf b/services/radiodemo-back.oma-radio.fr/nginx_server.conf
index e6edbe7..08f0e21 100644
--- a/services/radiodemo-back.oma-radio.fr/nginx_server.conf
+++ b/services/radiodemo-back.oma-radio.fr/nginx_server.conf
@@ -18,7 +18,7 @@
 server {
 	listen 80;
 	listen [::]:80;
-	server_name $RADIO_HOST;
+	server_name $JC_SERVICE;
 
 	root $SOUNDBASE_DIR/website;
 	index index.html;
@@ -49,7 +49,7 @@ server {
         include uwsgi_params;
         uwsgi_param PATH_INFO "/pigeindex$1";
         uwsgi_param SCRIPT_NAME /api;
-        uwsgi_pass unix:/tmp/uwsgi/$RADIO_HOST/uwsgi-api.sock;
+        uwsgi_pass unix:/tmp/uwsgi/$JC_SERVICE/uwsgi-api.sock;
         client_max_body_size 0;
         uwsgi_connect_timeout       6000;
         uwsgi_send_timeout          6000;
@@ -70,7 +70,7 @@ server {
             include uwsgi_params;
             uwsgi_param PATH_INFO "$1";
             uwsgi_param SCRIPT_NAME /api;
-            uwsgi_pass unix:/tmp/uwsgi/$RADIO_HOST/uwsgi-api.sock;
+            uwsgi_pass unix:/tmp/uwsgi/$JC_SERVICE/uwsgi-api.sock;
             client_max_body_size 0;
             proxy_connect_timeout       6000;
             proxy_send_timeout          60000;
diff --git a/services/radiodemo.oma-radio.fr/wg-radiodemo.sh b/services/radiodemo.oma-radio.fr/wg-radiodemo.sh
index e030808..fd69ddb 100755
--- a/services/radiodemo.oma-radio.fr/wg-radiodemo.sh
+++ b/services/radiodemo.oma-radio.fr/wg-radiodemo.sh
@@ -30,9 +30,4 @@ PostDown = iptables -t nat -D POSTROUTING -o $wgif -j MASQUERADE
 [Peer]
 PublicKey = 1YIpMhZGrZRnZPlrTjtCfjvXXGk8j0Ug2AfcHEtN/hE=
 AllowedIPs = 10.29.0.1/32,$NET.0/24
-
-# test separation PA
-[Peer]
-PublicKey = todo
-AllowedlIPs = 10.29.0.2
 "
diff --git a/services/services.txt b/services/services.txt
index 297c9a7..55b9098 100644
--- a/services/services.txt
+++ b/services/services.txt
@@ -1,34 +1,33 @@
 benevoles31.karnaval.fr max.jean-cloud.org
 chahut.jean-cloud.net max.jean-cloud.org
 collectif-arthadie.fr vandamme.jean-cloud.org
-compagnienouvelle.fr max.jean-cloud.org
+compagnienouvelle.fr nougaro.jean-cloud.org
 copaines.jean-cloud.net max.jean-cloud.org
-cousinades2.jean-cloud.net max.jean-cloud.org
 cousinades.jean-cloud.net max.jean-cloud.org
+deployer.jean-cloud.org shlago.jean-cloud.org
 etrevivant.net shlago.jean-cloud.org
 feministesucl34.jean-cloud.net tetede.jean-cloud.org
-feteducourt2020.jean-cloud.net tetede.jean-cloud.org
-feteducourt.jean-cloud.net tetede.jean-cloud.org
+feteducourt2020.jean-cloud.net shlago.jean-cloud.org
+feteducourt.jean-cloud.net shlago.jean-cloud.org
+git.jean-cloud.net vandamme.jean-cloud.org
 grapes.chahut.jean-cloud.net max.jean-cloud.org
 gypsylyonfestival.com max.jean-cloud.org
-metamorphosemagazine.fr shlago.jean-cloud.org
 inurbe.fr max.jean-cloud.org
 jean-cloud.net shlago.jean-cloud.org
+leida.fr vandamme.jean-cloud.org
 lexicographe.jean-cloud.net shlago.jean-cloud.org
+metamorphosemagazine.fr shlago.jean-cloud.org
 nc-backup.jean-cloud.net raku.jean-cloud.org
-pa1.studios.oma-radio.fr tetede.jean-cloud.org
-raplacgr.jean-cloud.net tetede.jean-cloud.org
-velov.jean-cloud.net shlago.jean-cloud.org
-radionimaitre.oma-radio.fr tetede.jean-cloud.org
-paj.oma-radio.fr nougaro.jean-cloud.org
-radiodemo.oma-radio.fr tetede.jean-cloud.org
-radiodemo-back.oma-radio.fr montbonnot.jean-cloud.org
-pa1.studios.oma-radio.fr tetede.joun-cloud.org
-leida.fr shlago.jean-cloud.org
-deployer.jean-cloud.org shlago.jean-cloud.org
 ns1.jean-cloud.org raku.jean-cloud.org
-git.jean-cloud.net vandamme.jean-cloud.org
+ns.jean-cloud.org shlago.jean-cloud.org
 nuage.jean-cloud.net vandamme.jean-cloud.org
+pa1.studios.oma-radio.fr tetede.jean-cloud.org
+paj.oma-radio.fr nougaro.jean-cloud.org
+radiodemo-back.oma-radio.fr montbonnot.jean-cloud.org
+radiodemo.oma-radio.fr tetede.jean-cloud.org
+radionimaitre.oma-radio.fr tetede.jean-cloud.org
+raplacgr.jean-cloud.net tetede.jean-cloud.org
 rpnow.jean-cloud.net vandamme.jean-cloud.org
-wiki-cgr.jean-cloud.net vandamme.jean-cloud.org
 _ssh vandamme.jean-cloud.org
+velov.jean-cloud.net shlago.jean-cloud.org
+wiki-cgr.jean-cloud.net vandamme.jean-cloud.org