Modification : vm_host{,ed} : paravirtualised machine (PV).
authorJulien Moutinho <julm+burette@autogeree.net>
Sat, 16 Feb 2013 16:31:30 +0000 (17:31 +0100)
committerJulien Moutinho <julm+burette@autogeree.net>
Mon, 18 Feb 2013 20:44:03 +0000 (21:44 +0100)
15 files changed:
README [new file with mode: 0644]
ateliers_host [deleted file]
ateliers_hosted [deleted file]
env.sh [deleted file]
functions.sh [new file with mode: 0644]
inc.sh [deleted file]
key/julm.gpg.pub [new file with mode: 0644]
key/ssh.known_hosts [new file with mode: 0644]
machine-ateliers.txt [new file with mode: 0644]
vm.sh [new file with mode: 0644]
vm_host [new file with mode: 0755]
vm_hosted [new file with mode: 0755]
vm_remote [new file with mode: 0755]
vm_ssh [new file with mode: 0755]
workflow.txt [deleted file]

diff --git a/README b/README
new file mode 100644 (file)
index 0000000..b4b463b
--- /dev/null
+++ b/README
@@ -0,0 +1,40 @@
+DESCRIPTION:
+  ce fichier donne une idée des commandes à effectuer
+  pour effectuer diverses tâches.
+ATTENTION:
+  il peut y avoir des oublis ;
+  ne pas hésiter donc à bien relire les règles
+  _avant_ de les exécuter.
+NOTE:
+  à priori les règles sont pensées pour être exécutées
+  plusieurs fois selon les erreurs que l'on rencontre
+  ou les modifications que l'on y apporte.
+
+TASK: obtenir une installation chrootable
+       @host % export TRACE=1
+       @host % ./vm_host disk_mount
+       @host % ./vm_host disk_format
+       @host % ./vm_host part_lvm_format
+       @host % ./vm_host part_root_format
+       @host % ./vm_host part_boot_format
+       @host % ./vm_host part_swap_format
+       @host % ./vm_host part_var_format
+       @host % ./vm_host part_home_format
+       @host % ./vm_host debian_install
+       @host % ./vm_host disk_umount
+TASK: obtenir une installation démarable
+       @host % ./vm_host chroot
+       @host % export TRACE=1 LANG=C LC_CTYPE=C
+       @host % /root/tool/vm/vm_hosted init
+       @host % exit
+TASK: initialiser la VM
+       @host   % vm_host vm_init
+       @host   % vm_host vm_start
+       @hosted % vm_hosted user_init
+TASK: démarrer la VM
+       @host   % vm_host vm_start
+TASK: ajouter un administrateur
+       @hosted % vm_hosted user_admin_add $user # NOTE: remplacer $user
+TASK: démarrer la VM
+       @host   % vm_host vm_start
+       @remote % vm_remote disk_send_key
diff --git a/ateliers_host b/ateliers_host
deleted file mode 100755 (executable)
index 46ef940..0000000
+++ /dev/null
@@ -1,382 +0,0 @@
-#!/bin/sh
-set -e -f ${DRY_RUN:+-n} -u
-
-tool=${0%/*}
-. "$tool"/env.sh
-. "$tool"/inc.sh
-
-rule_help () {
-       cat >&2 <<-EOF
-               DESCRIPTION: ce script regroupe des fonctions utilitaires
-                            pour gérer la VM des ateliers _depuis_ son hôte ;
-                            il sert à la fois d'outil et de documentation.
-                            Voir \`$tool/ateliers_hosted' pour les utilitaires côté VM hébergée.
-               SYNTAX: $0 \$RULE \${RULE}_SYNTAX
-               RULES:
-               $(sed -ne 's/^rule_\([^_][^ ]*\) () {\( *#.*\|\)/\t\1\2/p' "$tool"/env.sh "$0")
-               ENVIRONMENT:
-                 TRACE # affiche les commandes avant leur exécution
-               $(sed -ne 's/^readonly \([^ ][^ =]*\).*}\( *#.*\|\)$/\t$\1\2/p' "$tool"/env.sh "$0")
-               EOF
- }
-
-readonly vm_dev_disk=/dev/mapper/domU-$(printf %s "$vm_fqdn-disk" | sed -e 's/-/--/g')
-readonly vm_dev_disk_boot="${vm_dev_disk}1"
-
-rule_xen_config_init () {
-       sudo tee /etc/xen/$vm_fqdn.cfg <<-EOF
-               #  -*- mode: python; -*-
-               import os, re
-               name         = "$vm_fqdn"
-               arch         = os.uname()[4]
-               memory       = 2048
-               vcpus        = 1
-               vif          = ['mac=$vm_mac,bridge=$vm_bridge']
-               disk         = ['phy:/dev/domU/$vm_fqdn-disk,hda,w']
-               kernel       = "/usr/lib/xen-4.0/boot/hvmloader"
-               builder      = 'hvm'
-               device_model = 'qemu-dm'
-               acpi         = 1
-               apic         = 1
-               # boot on floppy (a), hard disk (c) or CD-ROM (d)
-               #boot         = 'd'
-               
-               #vnc        = 1
-               #sdl        = 0
-               #vncconsole = 0
-               #vnclisten  = "0.0.0.0"
-               #vncpasswd  = ""
-               #usbdevice  = 'tablet'
-               
-               keymap      = 'fr'
-               serial      = 'pty'
-               on_poweroff = 'destroy'
-               on_reboot   = 'restart'
-               on_crash    = 'restart'
-               EOF
- }
-rule_xen_on () {
-       sudo xm create $vm_fqdn.cfg
- }
-rule_xen_off () {
-       sudo xm shutdown $vm_fqdn.cfg
- }
-
-rule_disk_mount () { # DESCRIPTION: montage du disque de la VM depuis l'hôte
-       sudo kpartx -a -v /dev/domU/$vm_fqdn-disk
-       #sudo xm block-attach 0 phy:/dev/domU/$vm_fqdn-disk $vm_dev_disk w
- }
-rule_disk_umount () { # DESCRIPTION: démontage du disque de la VM depuis l'hôte
-       rule_part_boot_umount
-       case $vm_use_lvm in
-        (yes)
-               rule_part_lvm_umount
-               ;;
-        (no)
-               rule_part_root_umount
-               rule_part_var_umount
-               rule_part_home_umount
-               ;;
-        (*) exit 1;;
-        esac
-       sudo kpartx -d -v /dev/domU/$vm_fqdn-disk
-       #sudo xm block-detach 0 $vm_dev_disk
-       # XXX: DANGEREUX ; si jamais il bloque parce que le disque était encore utilisé :
-       #      utiliser xm block-detach 0 $vm_dev_disk --force ;
-       #      ôter les éventuels mappages LVM concernés avec dmsetup table et dmsetup remove --force ;
-       #      ôter les mappages concernés dans /etc/lvm/cache/.cache,
-       #      et pour bien trouver tous les mappages :
-       #        % sudo find /dev -type l -exec sh -c 'printf "%s -> " "$@"; readlink "$@"' - {} \; | grep $vm_dev_disk
-       #      enfin, ôter l'éventuel verrou dans /var/lock/lvm/
- }
-
-case $vm_use_lvm in
- (no)
-       readonly vm_dev_disk_swap="${vm_dev_disk}5"
-       readonly vm_dev_disk_root="${vm_dev_disk}6"
-       readonly vm_dev_disk_var="${vm_dev_disk}7"
-       readonly vm_dev_disk_home="${vm_dev_disk}8"
-       ;;
- (yes)
-       readonly vm_lvm_pv="${vm_dev_disk}2"
-       readonly vm_dev_disk_swap=/dev/$vm_lvm_vg/${vm_lvm_lv}_swap
-       readonly vm_dev_disk_root=/dev/$vm_lvm_vg/${vm_lvm_lv}_root
-       readonly vm_dev_disk_var=/dev/$vm_lvm_vg/${vm_lvm_lv}_var
-       readonly vm_dev_disk_home=/dev/$vm_lvm_vg/${vm_lvm_lv}_home
-       ;;
- (*)
-       exit 1;;
- esac
-
-rule_disk_format () { # DESCRIPTION: partitionnage du disque de la VM
-       case $vm_use_lvm in
-       (no)
-               sudo sfdisk $vm_dev_disk <<-EOF
-                       # partition table of $vm_dev_disk
-                       unit: sectors
-                       
-                       ${vm_dev_disk}1 : start=       63, size=   497952, Id=83, bootable
-                       ${vm_dev_disk}2 : start=   498015, size=418927005, Id= 5
-                       ${vm_dev_disk}3 : start=        0, size=        0, Id= 0
-                       ${vm_dev_disk}4 : start=        0, size=        0, Id= 0
-                       ${vm_dev_disk}5 : start=   498078, size=  1959867, Id=82
-                       ${vm_dev_disk}6 : start=  2458008, size= 29302497, Id=83
-                       ${vm_dev_disk}7 : start= 31760568, size=  9767457, Id=83
-                       ${vm_dev_disk}8 : start= 41528088, size=377896932, Id=83
-               EOF
-               ;;
-       (yes)
-               sudo sfdisk $vm_dev_disk <<-EOF
-                       # partition table of $vm_dev_disk
-                       unit: sectors
-                       
-                       ${vm_dev_disk}1 : start=       63, size=   497952, Id=83, bootable
-                       ${vm_dev_disk}2 : start=   498015, size=418927005, Id=8E
-                       EOF
-               ;;
-       (*) exit 1;;
-        esac
-       #sudo partprobe $vm_dev_disk
-       sudo kpartx -u -v /dev/domU/$vm_fqdn-disk
- }
-
-rule_part_lvm_format () {
-       rule_part_lvm_umount
-       ! sudo vgs | grep -q "^  $vm_lvm_vg " ||
-       sudo vgremove $vm_lvm_vg
-       sudo pvcreate --dataalignment 512k $vm_lvm_pv
-       sudo vgcreate --dataalignment 512k $vm_lvm_vg $vm_lvm_pv
-       sudo lvcreate --contiguous y -n ${vm_lvm_lv}_swap -L  1G     $vm_lvm_vg
-       sudo lvcreate --contiguous y -n ${vm_lvm_lv}_root -L 15G     $vm_lvm_vg
-       sudo lvcreate --contiguous y -n ${vm_lvm_lv}_var  -L  5G     $vm_lvm_vg
-       sudo lvcreate --contiguous y -n ${vm_lvm_lv}_home -l 99%FREE $vm_lvm_vg
-       rule_part_lvm_umount
- }
-rule_part_lvm_mount () {
-       sudo vgchange -a y $vm_lvm_vg
-       sudo lvchange -a y $vm_lvm_lv
- }
-rule_part_lvm_umount () {
-       rule_part_root_umount
-       rule_part_var_umount
-       rule_part_home_umount
-       if sudo vgs | grep -q "^  $vm_lvm_vg "
-        then
-               sudo lvchange -a n $vm_lvm_vg
-               sudo vgchange -a n $vm_lvm_vg
-        fi
- }
-
-rule_part_randomize () { # SYNTAX: $part # NOTE: à anticiper
-       local part=$1
-       eval "sudo dd if=/dev/urandom of=\$vm_dev_disk_$part"
- }
-rule_part_randomize_stat () { # SYNTAX: $part # DESCRIPTION: fait afficher la progression de rule_part_clean
-       local part=$1
-       eval "pkill -USR1 -f \"^dd if=/dev/urandom of=\$vm_dev_disk_$part\""
- }
-rule__part_encrypted_format () { # SYNTAX: $part # DESCRIPTION: formatage d'une partition distincte de /
- # NOTE: la clef de chiffrement est dérivée de celle de /,
- #       / doit être déchiffrée pour que cela fonctionne.
-       local part=$1
-       eval "local dev=\$vm_dev_disk_$part"
-       test ! -e /dev/mapper/${vm}_root_deciphered ||
-       sudo /bin/sh -c "/lib/cryptsetup/scripts/decrypt_derived ${vm}_root_deciphered |
-       cryptsetup luksFormat --hash=sha512 --key-size=512 \
-        --cipher=aes-xts-essiv:sha256 --key-file=- --align-payload=8 $dev"
- }
-rule__part_encrypted_mount () { # SYNTAX: $part
-       local part=$1
-       eval "local dev=\$vm_dev_disk_$part"
-       test -e /dev/mapper/${vm}_${part}_deciphered ||
-       sudo /bin/sh -c "/lib/cryptsetup/scripts/decrypt_derived ${vm}_root_deciphered |
-       cryptsetup luksOpen --key-file=- $dev ${vm}_${part}_deciphered"
- }
-rule__part_encrypted_umount () { # SYNTAX: $part
-       local part=$1
-       eval "local dev=\$vm_dev_disk_$part"
-       test ! -e     /dev/mapper/${vm}_${part}_deciphered ||
-       sudo cryptsetup luksClose ${vm}_${part}_deciphered
- }
-
-rule_part_root_format () {
-       if ! mount | grep -q "^$vm_dev_disk_root "
-        then
-               sudo cryptsetup luksFormat --hash=sha512 --key-size=512 \
-                --cipher=aes-xts-essiv:sha256 --key-file=- --align-payload=8 $vm_dev_disk_root
-               sudo cryptsetup luksOpen --key-file=- $vm_dev_disk_root ${vm}_root_deciphered
-               sudo mke2fs -t ext4 -c -c -m 5 -T ext4 -b $vm_e2fs_block_size \
-                -E resize=30G${vm_e2fs_extended_options} \
-                -L ${vm}_root \
-                /dev/mapper/${vm}_root_deciphered
-               ! mountpoint -q /mnt/$vm_fqdn
-               sudo mount -v /dev/mapper/${vm}_root_deciphered /mnt/$vm_fqdn
-               mk_dir mod=0770 own=root:root /mnt/$vm_fqdn/boot
-               mk_dir mod=0770 own=root:root /mnt/$vm_fqdn/dev
-               mk_dir mod=0770 own=root:root /mnt/$vm_fqdn/home
-               mk_dir mod=0770 own=root:root /mnt/$vm_fqdn/proc
-               mk_dir mod=0770 own=root:root /mnt/$vm_fqdn/sys
-               mk_dir mod=0770 own=root:root /mnt/$vm_fqdn/var
-               mk_dir mod=0770 own=root:root /mnt/$vm_fqdn/root
-               mk_dir mod=0770 own=root:root /mnt/$vm_fqdn/root/tool
-               mk_dir mod=0770 own=root:root /mnt/$vm_fqdn/root/tool/ateliers
-               sudo umount -v /mnt/$vm_fqdn
-               sudo cryptsetup luksClose ${vm}_root_deciphered
-        fi
- }
-rule_part_root_mount () {
-       test -e /dev/mapper/${vm}_root_deciphered ||
-       sudo cryptsetup luksOpen $vm_dev_disk_root ${vm}_root_deciphered
-       mountpoint -q /mnt/$vm_fqdn ||
-       sudo mount -v -t ext4 /dev/mapper/${vm}_root_deciphered /mnt/$vm_fqdn
- }
-rule_part_root_umount () {
-       ! mountpoint -q /mnt/$vm_fqdn ||
-       sudo umount -v  /mnt/$vm_fqdn
-       ! test -e     /dev/mapper/${vm}_root_deciphered ||
-       sudo cryptsetup luksClose ${vm}_root_deciphered
- }
-rule_part_root_backup_luks () {
-       sudo cryptsetup luksHeaderBackup $vm_dev_disk_root --header-backup-file ./root.luks
- }
-rule_part_swap_format () {
-       rule__part_encrypted_format swap
-       rule__part_encrypted_mount  swap
-       sudo mkswap -f -L ${vm}_swap /dev/mapper/${vm}_swap_deciphered
-       rule__part_encrypted_umount swap
- }
-rule_part_boot_format () {
-       mount | grep -q "^$vm_dev_disk_boot " ||
-       sudo mke2fs -t ext2 -c -c -m 5 -T small \
-        -E resize=1G${vm_e2fs_extended_options} \
-        -L ${vm}_boot $vm_dev_disk_boot
- }
-rule_part_boot_mount () {
-       mountpoint -q /mnt/$vm_fqdn
-       test -d /mnt/$vm_fqdn/boot
-       mountpoint -q                           /mnt/$vm_fqdn/boot ||
-       sudo mount -v -t ext2 $vm_dev_disk_boot /mnt/$vm_fqdn/boot
- }
-rule_part_boot_umount () {
-       ! mountpoint -q /mnt/$vm_fqdn/boot ||
-       sudo umount -v  /mnt/$vm_fqdn/boot
- }
-rule_part_var_format () {
-       rule__part_encrypted_format var
-       rule__part_encrypted_mount  var
-       sudo mke2fs -t ext4 -c -c -m 5 -T ext4 -b $vm_e2fs_block_size \
-        -E resize=10G${vm_e2fs_extended_options} \
-        -L ${vm}_var \
-        /dev/mapper/${vm}_var_deciphered
-       rule__part_encrypted_umount var
- }
-rule_part_var_mount () {
-       rule__part_encrypted_mount var
-       mountpoint -q /mnt/$vm_fqdn/var ||
-       sudo mount -v -t ext4 /dev/mapper/${vm}_var_deciphered /mnt/$vm_fqdn/var
- }
-rule_part_var_umount () {
-       ! mountpoint -q /mnt/$vm_fqdn/var ||
-       sudo umount -v  /mnt/$vm_fqdn/var
-       rule__part_encrypted_umount var
- }
-rule_part_home_format () {
-       rule__part_encrypted_format home
-       rule__part_encrypted_mount  home
-       sudo mke2fs -t ext4 -c -c -m 0 -T ext4 -b $vm_e2fs_block_size \
-        -E resize=400G${vm_e2fs_extended_options} \
-        -L ${vm}_home \
-        /dev/mapper/${vm}_home_deciphered
-        # NOTE: -O quota pas supporté par e2fsprogs/squeeze
-       rule__part_encrypted_umount home
- }
-rule_part_home_mount () {
-       rule__part_encrypted_mount home
-       mountpoint -q /mnt/$vm_fqdn/home ||
-       sudo mount -v -t ext4 /dev/mapper/${vm}_home_deciphered /mnt/$vm_fqdn/home
- }
-rule_part_home_umount () {
-       ! mountpoint -q /mnt/$vm_fqdn/home ||
-       sudo umount -v  /mnt/$vm_fqdn/home
-       rule__part_encrypted_umount home
- }
-
-rule_debian_install () {
-       rule_part_root_mount
-       rule_part_boot_mount
-       rule_part_var_mount
-       sudo DEBOOTSTRAP_DIR=/usr/share/debootstrap/ debootstrap \
-        --arch=$vm_arch --verbose --keyring=/usr/share/keyrings/debian-archive-keyring.gpg \
-        --exclude=vim-tiny \
-        --include=$(printf '%s,' \
-                acl \
-                bsdmainutils \
-                busybox \
-                ca-certificates \
-                console-setup \
-                cryptsetup \
-                dash \
-                dnsutils \
-                dropbear \
-                etckeeper \
-                hashalot \
-                htop \
-                ifupdown \
-                initramfs-tools \
-                kbd \
-                less \
-                mosh \
-                ncurses-term \
-                openssh-client \
-                openssh-server \
-                openssl \
-                pciutils \
-                procps \
-                quota \
-                quotatool \
-                rsync \
-                screen \
-                sudo \
-                sysprofile \
-                vim-nox \
-                wget \
-                zsh \
-        ) \
-        $vm_lsb_name /mnt/$vm_fqdn/ \
-        http://ftp.fr.debian.org/debian/
- }
-rule_chroot () {
-       rule_part_root_mount
-       rule_part_boot_mount
-       rule_part_var_mount
-       #rule_part_home_mount
-       mountpoint -q /mnt/$vm_fqdn/proc ||
-       sudo mount -t proc proc /mnt/$vm_fqdn/proc
-       mountpoint -q /mnt/$vm_fqdn/sys ||
-       sudo mount -t sysfs sys /mnt/$vm_fqdn/sys
-       mountpoint -q /mnt/$vm_fqdn/dev ||
-       sudo mount --bind /dev /mnt/$vm_fqdn/dev
-       mountpoint -q /mnt/$vm_fqdn/root/tool/ateliers ||
-       sudo mount --bind "$tool" /mnt/$vm_fqdn/root/tool/ateliers
-       sudo chroot /mnt/$vm_fqdn /bin/dash || true
-       rule__chroot_clean
- }
-rule__chroot_clean () {
-       ! sudo mountpoint -q /mnt/$vm_fqdn/root/tool/ateliers ||
-       sudo umount -v /mnt/$vm_fqdn/root/tool/ateliers
-       ! mountpoint -q /mnt/$vm_fqdn/dev ||
-       sudo umount -v /mnt/$vm_fqdn/dev
-       ! mountpoint -q /mnt/$vm_fqdn/sys ||
-       sudo umount -v /mnt/$vm_fqdn/sys
-       ! mountpoint -q /mnt/$vm_fqdn/proc ||
-       sudo umount -v /mnt/$vm_fqdn/proc
-       rule_part_home_umount
-       rule_part_var_umount
-       rule_part_boot_umount
-       rule_part_root_umount
- }
-
-rule=${1:-help}
-${1+shift}
-set "${TRACE:+-x}"
-rule_$rule "$@"
diff --git a/ateliers_hosted b/ateliers_hosted
deleted file mode 100755 (executable)
index 3359fb6..0000000
+++ /dev/null
@@ -1,556 +0,0 @@
-#!/bin/sh
-set -e -f ${DRY_RUN:+-n} -u
-tool=${0%/*}
-. "$tool"/env.sh
-. "$tool"/inc.sh
-
-rule_help () {
-       cat >&2 <<-EOF
-               DESCRIPTION: ce script regroupe des fonctions utilitaires
-                            pour gérer la VM des ateliers _depuis_ la VM hébergée ;
-                            il sert à la fois d'outil et de documentation.
-                            Voir \`$tool/ateliers_host' pour les utilitaires côté machine hôte.
-               SYNTAX: $0 \$RULE \${RULE}_SYNTAX
-               RULES:
-               $(sed -ne 's/^rule_\([^_][^ ]*\) () {\( *#.*\|\)/\t\1\2/p' "$tool"/env.sh "$0")
-               ENVIRONMENT:
-                 TRACE # affiche les commandes avant leur exécution
-               $(sed -ne 's/^readonly \([^ ][^ =]*\).*}\( *#.*\|\)$/\t$\1\2/p' "$tool"/env.sh "$0")
-               EOF
- }
-
-rule_filesystem_init () {
-       mk_reg mod= own= --append /etc/sysctl.conf <<-EOF
-               vm.swappiness = 10 # NOTE: n'utilise le swap qu'en cas d'absolue nécessité
-               vm.vfs_cache_pressure=50
-               EOF
- }
-rule_shell_source () {
-       . /etc/profile
- }
-rule_network_init () {
-       mk_reg mod= own= /etc/hostname <<-EOF
-               $vm
-               EOF
-       grep -q " $vm\$" /etc/hosts ||
-       mk_reg mod= own= --append /etc/hosts <<-EOF
-               127.0.0.1 $vm_fqdn $vm
-               EOF
-       mk_reg mod= own= /etc/network/interfaces <<-EOF
-               auto lo
-               iface lo inet loopback
-               
-               auto eth0=grenode
-               iface grenode inet static
-                       address   $vm_ipv4
-                       gateway   $vm_ipv4 # NOTE: proxy_arp sur la passerelle permet d'utiliser la même adresse
-                       network   $vm_ipv4
-                       broadcast $vm_ipv4
-                       netmask   255.255.255.255
-                       mtu 1300 # TODO: voir si c'est nécessaire à Lyon
-                       up   ip address add    $vm_ipv4/32 dev \$IFACE
-                       down ip address delete $vm_ipv4/32 dev \$IFACE
-               EOF
- }
-rule_apt_init () {
-       mk_reg mod= own= /etc/apt/sources.list <<-EOF
-               deb http://ftp.fr.debian.org/debian $vm_lsb_name main contrib non-free
-               EOF
-       mk_reg mod= own= /etc/apt/sources.list.d/openerp.list <<-EOF
-               deb http://nightly.openerp.com/trunk/nightly/deb/ ./
-               EOF
-       mk_reg mod= own= /etc/apt/sources.list.d/$vm_lsb_name-backports.list <<-EOF
-               deb http://backports.debian.org/debian-backports $vm_lsb_name-backports main contrib non-free
-               EOF
-       mk_reg mod= own= /etc/apt/preferences <<-EOF
-               Package: *
-               Pin: release a=$vm_lsb_name
-               Pin-Priority: 170
-               
-               Package: *
-               Pin: release a=$vm_lsb_name-backports
-               Pin-Priority: 200
-               EOF
- }
-rule_boot_init () {
-       mk_reg mod= own= /etc/fstab <<-EOF
-               # <file system> <mount point> <type> <options> <dump> <pass>
-               LABEL=boot /boot ext2 defaults,no-auto 0 0
-               proc /proc proc defaults 0 0
-               sysfs /sys sysfs defaults 0 0
-               tmpfs /tmp tmpfs rw,nosuid,nodev,auto,size=200m,nr_inodes=1000k,mode=1777,noatime,nodiratime 0 0
-               /dev/mapper/${vm}_root_deciphered /     ext4 defaults,errors=remount-ro,acl,noatime 0 1
-               /dev/mapper/${vm}_var_deciphered  /var  ext4 defaults,errors=remount-ro,acl,noatime 0 1
-               /dev/mapper/${vm}_home_deciphered /home ext4 defaults,errors=remount-ro,acl,noatime,usrquota,grpquota 0 0
-               /dev/mapper/${vm}_swap_deciphered swap swap sw 0 0
-               EOF
-       mk_reg mod= own= /etc/crypttab <<-EOF
-               # <target name> <source device> <key file> <options>
-               ${vm}_root_deciphered LABEL=${vm}_root ${vm}_root            luks
-               ${vm}_var_deciphered  LABEL=${vm}_var  ${vm}_root_deciphered luks,lvm=$vm_lvm_vg,keyscript=/lib/cryptsetup/scripts/decrypt_derived
-               ${vm}_swap_deciphered LABEL=${vm}_swap ${vm}_root_deciphered luks,lvm=$vm_lvm_vg,keyscript=/lib/cryptsetup/scripts/decrypt_derived
-               ${vm}_home_deciphered LABEL=${vm}_home ${vm}_root_deciphered luks,lvm=$vm_lvm_vg,keyscript=/lib/cryptsetup/scripts/decrypt_derived
-               EOF
-       mk_reg mod= own= /etc/initramfs-tools/modules <<-EOF
-               #loop
-               sha1_generic
-               sha256_generic
-               sha512_generic
-               aes-x86_64
-               xts
-               EOF
-       mk_reg mod= own= --append /etc/default/grub <<-EOF
-               GRUB_CMDLINE_LINUX="vt.default_utf8=1 rootfstype=ext4 loglevel=5 console=hvc0 resume=/dev/mapper/${vm}_swap_deciphered"
-               EOF
- }
-rule_user_admin_add () { # SYNTAX: <name>
-       admin=$1
-       ! id "$admin" || adduser "$admin"
-       eval home="~$admin"
-       adduser "$admin" sudo
-       mk_reg mod=0400 own="$admin:$admin" "$home"/etc/ssh/authorized_keys <"$tool"/key/"$admin".ssh.pub
- }
-rule_user_mail_format () {
-       mk_dir mod=0770 own=root:adm /etc/skel/etc/procmail
-       mk_dir mod=0770 own=root:adm /etc/skel/var/mail
-       mk_dir mod=0770 own=root:adm /etc/skel/var/cache/procmail
-       mk_reg mod=0660 own=root:adm /etc/skel/etc/procmail/delivery.rc <<-EOF
-               # vim: ft=procmail
-               
-               # NOTE: paramètres passés par postfix
-               SENDER=\$1
-               RECIPIENT=\$2
-               USER=\$3
-               EXTENSION=\$4
-               DOMAIN=\$5
-               ORIGINAL_RECIPIENT=\$6
-               
-               PATH="\$HOME/bin:/usr/local/bin:/usr/bin:/bin"
-               MAILDIR="\$HOME/var/mail/"
-               DEFAULT="\$MAILDIR"
-               #LOGFILE=`cd="\$HOME/var/log/procmail/" d=\$(date +"%Y-%m-%d"); ln -fns "\$d.log" "\$cd/current.log"; printf %s "\$cd/\$d.log"`
-               LOGFILE="/dev/null"
-               LOGABSTRACT=all
-               LOGABSTRACT
-               VERBOSE
-               SHELL=/bin/sh
-               SHELLMETAS=&|<>~;?*%{}
-               
-               # DESCRIPTION: supprime les doublons en fonction du champ Message-Id
-               #:0 Wh:            "\$HOME/var/cache/procmail/msgid\$LOCKEXT"
-               #| formail -D 8192 "\$HOME/var/cache/procmail/msgid"
-               
-               # DESCRIPTION: fait suivre à l'adresse configurée dans /etc/passwd ; on peut aussi utiliser ~/.forward
-               EMAIL=`sed /etc/passwd -ne "/^\$USER:/s/[^:]*:[^:]*:[^:]*:[^:]*:[^,]*,[^,]*,[^,]*,[^,]*,\([^:]*\):.*/\1/p"`
-                # NOTE: récupère l’adresse courriel dans le champ GECOS
-               FROM_=`formail -c -x "From " | sed -e 's/^\s*\([^ \t]*\).*/\1/g'`
-                # NOTE: récupère l’expéditeur inscrit sur l’enveloppe
-               :0
-               | \$SENDMAIL -i -bm -f "\$FROM_" "\${EMAIL/@/\${EXTENSION:++\${EXTENSION}}@}"
-               
-               # DESCRIPTION: IMAP
-               #:0
-               #| /usr/lib/dovecot/deliver -f "\$SENDER" -a "\$RECIPIENT"
-               
-               # DESCRIPTION: UUCP
-               #:0
-               #| /usr/bin/uux \
-               # -I "\$HOME/etc/uucp/uucp.cfg" \
-               # --nouucico \
-               # --notification=error \
-               # --requestor "\$USER" \
-               # - "\$USER!rmail" "(\$USER)"
-               EOF
-       mk_reg mod=0664 own=root:root /etc/postfix/main.cf <<-EOF
-               # /etc/postfix/main.cf
-               # SEE: http://postfix.traduc.org/index.php/TLS_README.html
-               
-               parent_domain_matches_subdomains =
-                       #debug_peer_list
-                       #fast_flush_domains
-                       #mynetworks
-                       #permit_mx_backup_networks
-                       #qmqpd_authorized_clients
-                       #smtpd_access_maps
-               mydomain                         = $vm_domainname
-               myorigin                         = \$mydomain
-               myhostname                       = $vm_hostname.\$mydomain
-               mail_name                        = \$myhostname
-               mydestination                    =
-                       $vm_hostname
-                       \$myhostname
-                       \$myorigin
-               mynetworks                       =
-                       127.0.0.0/8
-                       #[::1]/128
-               inet_protocols = ipv4
-                       # "all" to activate IPv6
-               inet_interfaces                  = all
-               permit_mx_backup_networks        =
-               
-               alias_database         =
-                       hash:/etc/aliases
-                       # NOTE: fichier de hash contenant une table d’alias mail.
-                       #       Celle-ci est éditable dans /etc/aliases, puis (indispensable)
-                       #       regénérée en hash grâce à la commande newaliases qui produit /etc/aliases.db
-               alias_maps             =
-                       hash:/etc/aliases
-               recipient_delimiter    = +
-                       # NOTE: séparateur entre le nom d’utilisateur
-                       #       et les extensions d’adresse (par défaut le signe +).
-               #virtual_alias_domains  =
-               virtual_alias_maps     =
-                       hash:/etc/postfix/\$mydomain/virtual
-                       # NOTE: do not specify virtual alias domain names in  the  main.cf
-                       #       mydestination or relay_domains configuration parameters.
-                       #
-                       # With  a  virtual  alias  domain,  the  Postfix SMTP server
-                       # accepts  mail  for  known-user@virtual-alias.domain,   and
-                       # rejects   mail  for  unknown-user@virtual-alias.domain  as
-                       # undeliverable.
-               #relayhost              =
-               relay_clientcerts      =
-                       hash:/etc/postfix/\$mydomain/smtpd/tls/relay_clientcerts
-               relay_domains          =
-                       \$mydestination
-                               # NOTE: ajouter les domaines pour lesquels on est backup MX ici,
-                               #       pas dans mydestination ou virtual_alias...
-               
-               maximal_queue_lifetime = 5d
-               
-               header_checks        =
-                       regexp:/etc/postfix/\$mydomain/header_checks
-               mime_header_checks   =
-               nested_header_checks =
-               milter_header_checks =
-               body_checks          =
-               
-               #content_filter               = amavisfeed:[127.0.0.1]:10024
-               #receive_override_options     = no_address_mappings
-                       # no_unknown_recipient_checks
-                       #         Do not try to reject unknown recipients (SMTP server only).
-                       #         This is typically specified AFTER an external content filter.
-                       # no_address_mappings
-                       #         Disable canonical address mapping, virtual alias map expansion,
-                       #         address masquerading, and automatic BCC (blind carbon-copy) recipients.
-                       #         This is typically specified BEFORE an external content filter (eg. amavis).
-                       # no_header_body_checks
-                       #         Disable header/body_checks. This is typically specified AFTER an external content filter.
-                       # no_milters
-                       #         Disable Milter (mail filter) applications. This is typically specified AFTER an external content filter.
-               #local_header_rewrite_clients =
-               transport_maps                =
-                       hash:/etc/postfix/\$mydomain/transport_maps
-               mailbox_command               =
-                       /usr/bin/procmail -t -a "\$SENDER" -a "\$RECIPIENT" -a "\$USER" -a "\$EXTENSION" -a "\$DOMAIN" -a "\$ORIGINAL_RECIPIENT" "\$HOME/etc/procmail/delivery.rc"
-               mailbox_size_limit            = 0
-               biff                          = no
-                       # Activer la notification en cas de réception de nouveaux e-mails dans la console (yes / no).
-               append_dot_mydomain           = no
-                       # appending .domain is the MUA's job.
-               
-               #tls_random_source             =
-               #       dev:/dev/urandom
-                       # Non-blocking
-               #tls_random_reseed_period      = 3600s
-               #tls_random_exchange_name      =
-               #       \${data_directory}/prng_exch
-                       # NOTE: à ne pas mettre dans la cage chroot
-               #tls_random_bytes              = 32
-               #tls_random_prng_update_period = 3600s
-               #tls_high_cipherlist           = AES256-SHA
-                       # NOTE: postconf(5) déconseille de changer ceci
-               
-               #smtp_cname_overrides_servername = no
-               smtp_connect_timeout            = 60s
-               #smtp_tls_CAfile                 = /etc/postfix/\$mydomain/smtp/tls/ca/crt.pem
-               #smtp_tls_CApath                 = /etc/postfix/\$mydomain/smtp/tls/ca/
-               #smtp_tls_cert_file              = /etc/postfix/\$mydomain/smtp/tls/crt.pem
-               #smtp_tls_key_file               = /etc/postfix/\$mydomain/smtp/tls/key.pem
-               #smtp_tls_per_site               = hash:/etc/postfix/\$mydomain/smtp/tls/per_site
-                       # NOTE: déprécié en faveur de smtp_tls_policy_maps
-               smtp_tls_policy_maps            = hash:/etc/postfix/\$mydomain/smtp/tls/policy
-               smtp_tls_fingerprint_digest     = sha1
-               smtp_tls_scert_verifydepth      = 5
-               #smtp_tls_secure_cert_match      = nexthop, dot-nexthop
-               #smtp_tls_verify_cert_match      = hostname
-               #smtp_tls_note_starttls_offer    = yes
-               smtp_tls_loglevel               = 1
-               smtp_tls_protocols              = !SSLv2, !SSLv3
-                       # Only allow TLSv*
-               smtp_tls_session_cache_database = btree:/var/lib/postfix/smtp_tls_session_cache
-               #smtp_tls_session_cache_timeout  = 3600s
-               smtp_tls_security_level         = may
-               smtp_header_checks              = regexp:/etc/postfix/\$mydomain/smtp/header_checks
-               smtp_body_checks                =
-               smtp_mime_header_checks         =
-               smtp_nested_header_checks       =
-               
-               smtpd_starttls_timeout                  = 300s
-               smtpd_banner                            =
-                \$myhostname ESMTP \$mail_name (Debian/GNU)
-               
-               # Restrictions
-               smtpd_helo_required             = yes
-               strict_rfc821_envelopes         = yes
-               smtpd_authorized_xclient_hosts  = 127.0.0.1
-                       # NOTE: utile pour tester les restrictions
-               
-               smtpd_helo_restrictions         =
-                       reject_invalid_helo_hostname
-                       reject_non_fqdn_helo_hostname
-                       #reject_unknown_helo_hostname
-                               # NOTE: pourrait pourtant être utile pour lutter contre le spam
-                       permit
-               
-               smtpd_sender_restrictions       =
-                       permit_mynetworks
-                       permit_tls_clientcerts
-                       permit_sasl_authenticated
-                       check_sender_access hash:/etc/postfix/\$mydomain/smtpd/sender_access
-                       check_sender_access hash:/etc/postfix/sender_blacklist
-                       reject_unauth_pipelining
-                       reject_non_fqdn_sender
-                       #reject_unknown_sender_domain
-                               # NOTE: temporaire
-                       permit
-               
-               smtpd_client_new_tls_session_rate_limit = 0
-               smtpd_client_event_limit_exceptions     = \$mynetworks
-               smtpd_client_recipient_rate_limit       = 0
-               smtpd_client_connection_count_limit     = 50
-               smtpd_client_connection_rate_limit      = 0
-               smtpd_client_message_rate_limit         = 0
-               smtpd_client_port_logging               = no
-               
-               smtpd_client_restrictions               =
-                       check_client_access hash:/etc/postfix/client_blacklist
-               
-               policy_time_limit                       = 3600
-               default_extra_recipient_limit           = 5000
-               duplicate_filter_limit                  = 5000
-               smtpd_recipient_limit                   = 5000
-               smtpd_recipient_overshoot_limit         = 5000
-               smtpd_recipient_restrictions            =
-                       reject_non_fqdn_recipient
-                       #reject_invalid_hostname
-                               # NOTE: postfix < 2.3. voir reject_invalid_helo_hostname
-                               #       dans smtpd_helo_restrictions
-                       reject_unknown_recipient_domain
-                       #reject_non_fqdn_sender
-                               # NOTE: dans smtpd_sender_restrictions
-                       reject_unauth_pipelining
-                               # NOTE: dans smtpd_client_restrictions ou smtpd_data_restrictions
-                       permit_mynetworks
-                       permit_tls_clientcerts
-                       permit_sasl_authenticated
-                       reject_unauth_destination
-                               # NOTE: ne pas passer par SPFCheck / Postgrey si le mail n'est pas pour nous
-                               #       ou quelqu'un pour lequel on tient lieu de backup_mx
-                       check_policy_service inet:127.0.0.1:10023
-                               # NOTE: Postgrey (greylisting)
-                       check_policy_service unix:private/spfcheck
-                       permit_auth_destination
-                               # NOTE: une fois Postgrey passé, on accepte ce qui nous est destiné
-                               #       (voir permit_auth_destination) ; sans doute redondant
-                       reject
-                       #check_relay_domains <- removed from postfix
-                       #reject_unknown_sender_domain
-                               # aurait probablement été mieux dans smtpd_sender_restrictions
-                       #reject_rbl_client bl.spamcop.net
-                       #reject_rbl_client list.dsbl.org
-                       #reject_rbl_client zen.spamhaus.org
-                       #reject_rbl_client dnsbl.sorbs.net
-               
-               smtpd_data_restrictions                 =
-                       reject_unauth_pipelining
-                               # NOTE: obliger le serveur en face à attendre qu'on lui aie dit OK
-                       permit
-               
-               #smtpd_end_of_data_restrictions          =
-               
-               #smtpd_restriction_classes               =
-               
-               smtpd_error_sleep_time                  = 5
-                       # NOTE: forcer quelqu'un qui nous embête à attendre cinq secondes.
-               
-               # SASL
-               smtpd_sasl_auth_enable                  = yes
-               smtpd_sasl_type                         = dovecot
-               smtpd_sasl_path                         = private/auth
-               smtpd_sasl_security_options             = noanonymous
-               smtpd_sasl_domain                       = \$mydomain
-               
-               # SMTPD TLS
-               smtpd_discard_ehlo_keywords             = starttls
-                       # NOTE: les clients mails tentant d'utiliser le chiffrement opportuniste
-                       #       se mangent une erreur en tentant un starttls
-               smtpd_tls_fingerprint_digest            = sha1
-                       # sha512 ?
-               smtpd_tls_mandatory_protocols           = TLSv1
-               smtpd_tls_mandatory_ciphers             = high
-               smtpd_tls_ciphers                       = high
-                       # restrictif. s/high/medium/ ?
-               smtpd_tls_CAfile                        = /etc/postfix/\$mydomain/smtpd/tls/ca/crt+crl.slf.pem
-               smtpd_tls_CApath                        = /etc/postfix/\$mydomain/smtpd/tls/ca/
-               smtpd_tls_cert_file                     = /etc/postfix/\$mydomain/smtpd/tls/crt+crl.slf.pem
-               smtpd_tls_key_file                      = /etc/postfix/\$mydomain/smtpd/tls/key.pem
-               ##
-               #smtpd_tls_received_header               = no
-               smtpd_tls_session_cache_database        =
-                       btree:/var/lib/postfix/smtpd_tls_session_cache
-               #smtpd_tls_session_cache_timeout         = 3600s
-               smtpd_tls_security_level                = may
-                       # Postfix 2.3 and later
-                       # encrypt
-                       #  Mandatory TLS encryption: announce STARTTLS support to SMTP clients, and require that clients use TLS
-                       #  encryption. According to [1720]RFC 2487 this MUST NOT be applied in case of a publicly-referenced
-                       #  SMTP server. Instead, this option should be used only on dedicated servers.
-               smtpd_tls_loglevel                      = 1
-               smtpd_tls_ccert_verifydepth             = 5
-               smtpd_tls_auth_only                     = yes
-                       # Pas d'AUTH SASL sans TLS
-               smtpd_tls_ask_ccert                     = no
-               smtpd_tls_req_ccert                     = no
-               #smtpd_tls_always_issue_session_ids      = yes
-               smtpd_peername_lookup                   = yes
-                       # Nécessaire pour postgrey, etc
-               smtpd_milters                           =
-               non_smtpd_milters                       =
-               line_length_limit                       = 2048
-               queue_minfree                           = 0
-               message_size_limit                      = 20480000
-               #smtpd_enforce_tls    # NOTE: obsolète
-               #smtpd_use_tls        # NOTE: obsolète
-               #smtpd_tls_cipherlist # NOTE: obsolète
-               
-               readme_directory   = no
-               #delay_warning_time = 4h
-                       # NOTE: uncomment the previous line to generate "delayed mail" warnings
-               #debug_peer_level   = 4
-               #debug_peer_list    = .\$myhostname
-               EOF
-       mk_reg mod=0664 own=root:root /etc/dovecot/dovecot.conf <<-EOF
-               auth_ssl_username_from_cert = yes
-               listen = *
-               log_timestamp = "%Y-%m-%d %H:%M:%S "
-               mail_debug = yes
-               mail_location = maildir:~/var/mail
-               mail_privileged_group = mail
-               passdb {
-                 args = /home/%u/etc/dovecot/passwd
-                 driver = passwd-file
-               }
-               protocols = imap
-               service auth {
-                 unix_listener /var/spool/postfix/private/auth {
-                   group = postfix
-                   mode = 0660
-                   user = postfix
-                 }
-                 user = root
-               }
-               ssl_ca = </etc/dovecot/imap/tls/crt+crl.slf.pem
-               ssl_cert = </etc/dovecot/imap/tls/crt+crl.slf.pem
-               ssl_cipher_list = AES256-SHA
-               ssl_key = </etc/dovecot/imap/tls/key.pem
-               ssl_verify_client_cert = yes
-               userdb {
-                 driver = passwd
-               }
-               verbose_ssl = yes
-               protocol lda {
-                 auth_socket_path = /var/run/dovecot/auth-master
-                 hostname = $vm_domainname
-                 info_log_path = /var/log/dovecot/lda/info.log
-                 log_path = /var/log/dovecot/lda/error.log
-                 mail_plugins = sieve
-                 postmaster_address = contact+dovecot+lda@$vm_domainname
-               }
-               EOF
-       mk_reg mod=0664 own=root:root /etc/postgrey/whitelist_recipients.local <<-EOF
-               
-               EOF
- }
-rule_mail_install () {
-       sudo apt-get install postfix postgrey dovecot
- }
-rule_user_format () {
-       mk_dir mod=0750 own="root:adm" /etc/skel/etc
-       mk_dir mod=0770 own="root:adm" /etc/skel/etc/apache2
-       mk_dir mod=0770 own="root:adm" /etc/skel/etc/ssh
-       mk_dir mod=0700 own="root:adm" /etc/skel/var
-       mk_dir mod=0700 own="root:adm" /etc/skel/var/log
-       mk_dir mod=0700 own="root:adm" /etc/skel/var/cache
-       mk_dir mod=0700 own="root:adm" /etc/skel/var/cache/ssh
-       mk_dir mod=0700 own="root:adm" /etc/skel/tmp
-       mk_dir mod=0700 own="root:adm" /etc/skel/tmp
-       mk_reg mod=0664 own=root:root /etc/ssh/sshd_config <<-EOF
-               ListenAddress $vm_ipv4
-               #ListenAddress ::
-               Port 22
-               Protocol 2
-               Compression yes
-               HostKey /etc/ssh/ssh_host_rsa_key
-               UsePrivilegeSeparation yes
-               KeyRegenerationInterval 3600
-               ServerKeyBits 768
-               SyslogFacility AUTH
-               LogLevel INFO
-               LoginGraceTime 120
-               PermitRootLogin no
-               StrictModes yes
-               RSAAuthentication yes
-               PubkeyAuthentication yes
-               AuthorizedKeysFile %h/etc/ssh/authorized_keys
-               IgnoreRhosts yes
-               RhostsRSAAuthentication no
-               HostbasedAuthentication no
-               IgnoreUserKnownHosts no
-               PermitEmptyPasswords no
-               ChallengeResponseAuthentication no
-               PasswordAuthentication no
-               KerberosAuthentication no
-               GSSAPIAuthentication no
-               X11Forwarding no
-               X11DisplayOffset 10
-               PrintMotd no
-               DebianBanner no
-               PrintLastLog yes
-               TCPKeepAlive yes
-               ClientAliveInterval 0
-               AcceptEnv LANG LC_*
-               Subsystem sftp /usr/lib/openssh/sftp-server
-               UsePAM yes
-               EOF
-       mk_reg mod=0440 own=root:root /etc/sudoers.d/passwd-init <<-EOF
-               %sudo ALL=(ALL) NOPASSWD: /bin/sh -e -f -u -c \
-                 case \$(/usr/bin/passwd --status "\$SUDO_USER") in \
-                   ("\$SUDO_USER L "*) /usr/bin/passwd \$SUDO_USER;; esac
-               EOF
-       mk_reg mod=0440 own=root:root /etc/sudoers.d/etckeeper-unclean <<-EOF
-               %sudo ALL=(ALL) NOPASSWD: /usr/sbin/etckeeper unclean
-               EOF
-       mk_reg mod=0440 own=root:root /etc/sudoers.d/env_keep <<-EOF
-               Defaults env_keep = " \
-                 EDITOR \
-                 GIT_AUTHOR_NAME \
-                 GIT_AUTHOR_EMAIL \
-                 GIT_COMMITTER_NAME \
-                 GIT_COMMITTER_EMAIL \
-                "
-               EOF
-       mk_reg mod=0555 own=root:root /usr/local/sbin/passwd-init <<-EOF
-               #!/bin/sh
-               sudo /bin/sh -e -f -u -c \
-                 'case \$(/usr/bin/passwd --status "\$SUDO_USER") in ("\$SUDO_USER L "*) /usr/bin/passwd \$SUDO_USER;; esac'
-               EOF
- }
-rule_kernel_init () {
-       sudo apt-get install --reinstall linux-image-$vm_arch
- }
-
-rule=${1:-help}
-${1+shift}
-set "${TRACE:+-x}"
-rule_$rule "$@"
diff --git a/env.sh b/env.sh
deleted file mode 100644 (file)
index ac13553..0000000
--- a/env.sh
+++ /dev/null
@@ -1,94 +0,0 @@
-#!/bin/sh
-# DESCRIPTION: ce fichier regroupe les variables propres à la VM
-
-readonly PATH=$PATH:/usr/sbin:/sbin
-readonly vm_domainname="heureux-cyclage.org"
-readonly vm_hostname="ateliers"
-readonly vm_fqdn="$vm_hostname.$vm_domainname"
-readonly vm=$vm_hostname
-
-readonly vm_use_lvm="yes"
- # - sans LVM :
- #   - on a accès au LVM de l'hôte, mais c'est pas très propre.
- #   - pour l'extension de mémoire, on peut soit :
- #       1.1.   étendre avec lvresize /dev/domU/$vm_fqdn-disk
- #       1.2.   étendre avec sfdisk $vm_dev_disk_home
- #       1.3.   étendre avec resize2fs /dev/mapper/${vm}_home_deciphered
- #     soit :
- #       2.1. créer une nouvelle partition sur le LVM de l'hôte
- #       2.2. l'ajouter comme un disque supplémentaire dans /etc/xen/$vm_fqdn.cfg
- #       2.3. le monter sur /home2 en pensant à changer DHOME=/home2 dans /etc/adduser.conf
- #   - pour la sauvegarde: on peut soit :
- #     1. sauvegarder au niveau applicatif (pgdump, mysqldump, etckeeper, git)
- #     2. sauvegarder incrémentalement avec (duplicity, backup-ninja, BackupPC),
- #        depuis l'hôte pour avoir un snapshot LVM.
- # - avec LVM :
- #   - question ouverte de la performance du LVM dans du LVM.
- #   - pour l'extension de mémoire, on peut soit :
- #       1.1.   étendre avec lvresize /dev/domU/$vm_fqdn-disk
- #       1.1.   étendre avec pvextend $vm_lvm_pv
- #       1.1.   étendre avec lvresize  /dev/mapper/${vm}_home_deciphered
- #       1.3.   étendre avec resize2fs /dev/mapper/${vm}_home_deciphered
- #   - pour la sauvegarde: on peut soit :
- #     1. sauvegarder au niveau applicatif (pgdump, mysqldump, etckeeper, git)
- #     2. sauvegarder incrémentalement avec (duplicity, backup-ninja, BackupPC),
- #        depuis la VM pour avoir un snapshot LVM.
-
-# Cartographie de la mémoire morte :
-#   SATA2 * 2 (/dev/sd{a,b})
-#     /dev/sda -> /dev/sda{1,2,3}
-#     /dev/sdb -> /dev/sdb{1,2,3}
-#   RAID1 logiciel
-#     /dev/sd{a,b}1 -> /dev/md0
-#     /dev/sd{a,b}2 -> /dev/md1
-#     /dev/sd{a,b}3 -> /dev/md2
-#   LVM
-#     /dev/md0 -> dom0
-#     /dev/md2 -> domU -> /dev/mapper/$vm_fqdn-disk
-#   LVM
-#     /dev/mapper/$vm_fqdn-disk -> /dev/xvda{1,2}
-#     /dev/xvda2 -> /dev/mapper/${vm_lvm_vg}-${vm_lvm_lv}_{swap,root,var,home}
-
-case $vm_use_lvm in
- (no)
-       ;;
- (yes)
-       readonly vm_lvm_vg=$vm_fqdn
-       readonly vm_lvm_lv=$vm
-       ;;
- (*)
-       exit 1;;
- esac
-
-readonly vm_raid_effective_disks=1 # NOTE: RAID1 (mirroring)
-       # NOTE: julm@rouf:~$ sudo pvs /dev/md2 -o+pe_start
-       #       PV         VG   Fmt  Attr PSize   PFree   1st PE
-       #       /dev/md2   domU lvm2 a-   925,64g 470,64g 192,00k <- pas adapté au TRIM SSD, mais on utilise du SATA2
-readonly vm_e2fs_block_size=4096
-       # NOTE: valeur standard pour un disque avec des secteurs de 512 octets :
-       # julm@rouf:~$ grep . /sys/block/sd{a,b}/queue/*_block_size
-       # /sys/block/sda/queue/logical_block_size:512
-       # /sys/block/sda/queue/physical_block_size:512
-       # /sys/block/sdb/queue/logical_block_size:512
-       # /sys/block/sdb/queue/physical_block_size:512
-readonly vm_e2fs_stripe_size=
-       # NOTE: égal au chunk size de mdadm --detail ;
-       # mais ne concerne pas RAID1 où il n'y a pas de changement de disque à effectuer,
-       # et donc pas de chunk size.
-readonly  vm_e2fs_stride=${vm_e2fs_stripe_size:+$((vm_e2fs_stripe_size / vm_e2fs_block_size))}
-readonly  vm_e2fs_stripe_width=${vm_e2fs_stride:+$((vm_e2fs_stride * vm_raid_effective_disks))}
-          vm_e2fs_extended_options=${vm_e2fs_stride:+,stride=$vm_e2fs_stride}${vm_e2fs_stripe_width:+,stripe_width=$vm_e2fs_stripe_width}
-
-readonly vm_arch="amd64"
-readonly vm_bridge="br-gresille"
-readonly vm_ipv4="91.216.110.42" # NOTE: IPv4 publique assignée par Grésille
-readonly vm_lsb_name="wheezy"
-readonly vm_mac="00:16:3E:E5:98:42" # NOTE: addresse MAC assignée par Grésille
- # NOTE: on part sur wheezy dès le début
- # dans l'idée de ne pas s'embêter avec
- # une migration squeeze -> wheezy dans deux mois ;
- # et parce qu'on juge wheezy « suffisamment stable ».
-
-rule_env () { # DESCRIPTION: affiche les $vm_*
-       set | grep '^vm_'
- }
diff --git a/functions.sh b/functions.sh
new file mode 100644 (file)
index 0000000..1f2c97a
--- /dev/null
@@ -0,0 +1,58 @@
+#!/bin/sh
+# DESCRIPTION: ce fichier regroupe des utilitaires très génériques
+
+mk_dir () {
+       local mod=${1#mod=}; shift
+       local own=${1#own=}; shift
+       sudo mkdir -p "$@"
+       ! [ ${mod:+set} ] || sudo chmod $mod "$@"
+       ! [ ${own:+set} ] || sudo chown $own "$@"
+ }
+mk_reg () {
+       local mod=${1#mod=}; shift
+       local own=${1#own=}; shift
+       local append
+       if [ "x${1#--append}" = "x" ]
+        then append='-a'; shift
+        else append=''
+        fi
+       sudo tee >&2 $append "$@"
+       ! [ ${mod:+set} ] || sudo chmod $mod "$@"
+       ! [ ${own:+set} ] || sudo chown $own "$@"
+ }
+mk_lnk () {
+       sudo ln -fns "$@"
+ }
+ssh_key_add () {
+       local user=${1#user=}; shift
+       local in=$1
+       local out=$2
+       local tmp=$(mktemp -t "$vm.ssh.XXXXXXXXX.tmp")
+               # NOTE: ssh-keygen ne sait lire que depuis un fichier..
+       while IFS= read -r key
+        do
+        # DESCRIPTION: ajoute dans le compte de root les clefs SSH de l'admin non déjà ajoutées.
+               has=
+               cat >"$tmp" <<-EOF
+                       $key
+                       EOF
+               key_fpr=$(ssh-keygen -l -f "$tmp" | cut -d ' ' -f 1,2)
+               while IFS= read -r auth_key
+                do
+                       cat >"$tmp" <<-EOF
+                               $auth_key
+                               EOF
+                       auth_key_fpr=$(ssh-keygen -l -f "$tmp" | cut -d ' ' -f 1,2)
+                       if [ "$key_fpr" = "$auth_key_fpr" ]
+                        then has=1; break
+                        fi
+                done <<-EOF
+                       $(sudo cat /root/etc/ssh/authorized_keys)
+                       EOF
+               [ ${has:+set} ] ||
+               mk_reg mod=640 own="$user:$user" --append "$out" <<-EOF
+                       $key
+                       EOF
+        done <"$in"
+       rm -f "$tmp"
+ }
diff --git a/inc.sh b/inc.sh
deleted file mode 100644 (file)
index 28df016..0000000
--- a/inc.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/sh
-# DESCRIPTION: ce fichier regroupe des utilitaires très génériques
-
-mk_dir () {
-       local mod=${1#mod=}; shift
-       local own=${1#own=}; shift
-       sudo mkdir -p "$@"
-       ! [ ${mod:+set} ] || sudo chmod $mod "$@"
-       ! [ ${own:+set} ] || sudo chown $own "$@"
- }
-mk_reg () {
-       local mod=${1#mod=}; shift
-       local own=${1#own=}; shift
-       sudo tee >/dev/null "$@"
-       ! [ ${mod:+set} ] || sudo chmod $mod "$@"
-       ! [ ${own:+set} ] || sudo chown $own "$@"
- }
diff --git a/key/julm.gpg.pub b/key/julm.gpg.pub
new file mode 100644 (file)
index 0000000..3de477b
--- /dev/null
@@ -0,0 +1,245 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.12 (GNU/Linux)
+
+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
+OzRIGbQeSnVsaWVuIE1vdXRpbmhvIDxqdWxtQGxpcDYuZnI+iQKRBBMBCgB7AhsD
+Ah4BAheAAwsKCQYVCgkICwIFFgMCAQAwFIAAAAAAFQAScGthLWFkZHJlc3NAZ251
+cGcub3JnanVsbUBhdXRvZ2VyZWUubmV0IxhodHRwOi8vYXV0b2dlcmVlLm5ldC9+
+anVsbS9wdWIuZ3BnBQJOV2IlBQkF6CxRAAoJENFa9/Rn6CmbXRAP/RXMI1LzU8tR
+G5UVm7FYKx0BBEgLg50JBRJ0HbqyYqp5wy5aqIyQyYkq2Dc0Oxqmxppfje7UXr9m
+cP7euhiIdBlxmvJYFakCi4ox+wIE1pygE/SeN5Ob21Gw4r/7ilqjuzgLYwYpqxlJ
+o6Q67qAGitIWbUMfY6wMg8ejV9QgZkBxJ8X79E+zIPHecVHSPgTgE/qfScCD2Sq8
+CYClfFiesT5iGLGvk4fhY/lC9aVuk+KHVwywMa8qraisR5iH8zQRKyUzmKJZnldE
+whaQaU6yKPUCtzr4T9NKNoOt5jY8zoqbeODWWs5e6Al87/dcl2Tavlz/iGwoOfwg
+s8PZz2eYaK3rryT0GU/6Bv1BfpVG3T6miRvSYEsFY/OMMm1WwW5PiQ7Vx/yMzaXe
+3087it3X+LEtfLl+4DTdEaFl39xl0fC3incVgUQ24EEM1mQm+Ng2srZRlz0nb2/2
+8Kl8wvEGdWXj3CvvUD7DBrDk+StQlCrygvdr07flpIA8hQAj/vp6LcNW8BYXBm2i
+8zwkfCE/O3FTfEE/fIaea6/SMIR7JaDkfIBMGVU7cnTq03Ij093F4yrN2nFbI0iu
+Wyksk1uUNgy83Het6WPWrWSa1z0NxGdSiR3CsbWZX2w/yz2rDQ6RXh+hGHH0Jjgc
+ImfjWvL33N+OZcU2x0c4w/5SIl/xXfvjtCBKdWxpZW4gTW91dGluaG8gPGp1bG1A
+cG9vbHAub3JnPokCkQQTAQoAewIbAwIeAQIXgAMLCgkGFQoJCAsCBRYDAgEAMBSA
+AAAAABUAEnBrYS1hZGRyZXNzQGdudXBnLm9yZ2p1bG1AYXV0b2dlcmVlLm5ldCMY
+aHR0cDovL2F1dG9nZXJlZS5uZXQvfmp1bG0vcHViLmdwZwUCTldiJgUJBegsUQAK
+CRDRWvf0Z+gpm41aEACAJ2a7Dfk8FOabL50ntxBkd7F6Rk5kuYU2JwtUWlvZ0e9w
+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
+MPW60kuSKRmx07BXUXV44LRO1th2fY+krMg9IzqAlLlZXqa/fsv+VgVWxKWVBKLE
+zIxlpBgW8rQuSnVsaWVuIE1vdXRpbmhvIDxqdWxtQHNhdmluZXMuYWxwZXMuZnIu
+ZXUub3JnPokCmwQTAQoAhQIbAwIeAQIXgDoUgAAAAAAVABxwa2EtYWRkcmVzc0Bn
+bnVwZy5vcmdqdWxtQHNhdmluZXMuYWxwZXMuZnIuZXUub3JnAwsKCQYVCgkICwIF
+FgMCAQAjGGh0dHA6Ly9hdXRvZ2VyZWUubmV0L35qdWxtL3B1Yi5ncGcFAk5XYiUF
+CQXoLFEACgkQ0Vr39GfoKZubAxAAtg6UK6qULT2mUxbPfdSzzC7MZtf4JqR80FOm
+6/5IX+syZNltBw0K7+L7lr/h31LEtNyj5XkXyZZzZvuit/YBNBrLLtO7Seknl/fq
+UGswrH/+cmvO7+GXtc2HwRY+RU9HJu9r/m2mjjeucUIzr3ngEpDDSLgEjJji8/6A
+jYJ6/eEkvsn9l8Sy9OHVuDcI1p9eUBe55M1cM6uAWPL9XMHNzVclL9jajHMQwcLg
+7CxdcIU5NGVi0/yET2w4c877sRCezkzuJw3HFRdXvxPjvVcQJZrvtLGpy1KDaxdY
+4AbseGO8nwSj0Yg8mKhk9cD5bRg5PAW+0cDiZ2eH9BLzc2YLVB2lXwnt2WePVzud
+9zPwxnGsaV56lI3cDfMYuJZOR3wrc9WKfJb4hFNgxu/6bnWJIfP+wSxWBaPGmOKh
+hmd7ZZvDxBm51SYtRQwsbyq5wXN99E8n59AkLwng1BtF8kMh4qxAldpobveQzreC
+izGqlkzyAU2Ou9Mlb1aS5N6neSwcgTznMQEVQyfcc8BQrneVAsVnLZwhyxXVCV7b
+VaSVbARWXfoHWnPtWkc6XQpOCVIYx5lHMMkFDjmvK5YHx9PqGBMm6Y6gis9JHbY2
+g+UrLVpBn1maW7HesqfjjHUub1jVsTX03JjyRFuiyOhX+iqftaIHwyYTTmtA0MmJ
+MQMK7+S0L0p1bGllbiBNb3V0aW5obyA8anVsbUBpbnRlcm5ldC5hbHBlcy5mci5l
+dS5vcmc+iQJIBDABCgAyBQJQTNMCKx0gaW50ZXJuZXQuYWxwZXMuZnIuZXUub3Jn
+IC0+IGF1dG9nZXJlZS5uZXQACgkQ0Vr39GfoKZt9zA//blGui+A6+4bx3WixRMi/
+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
++JOXylIEam3Nybo/mSRCHxYjz499KHM=
+=RsTM
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/key/ssh.known_hosts b/key/ssh.known_hosts
new file mode 100644 (file)
index 0000000..4376a5e
--- /dev/null
@@ -0,0 +1,4 @@
+rouf.grenode.net,91.216.110.98 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCWolyL7ErNN/uHTAoQFIylOOC9sixbd4i0CNxAcGN0Ht7Z7HpquzwAmRj4JHNgRRTkUFnW0GBOB/E3Py5ckU1CZ8SBZyqt3zrBwO0xybZ6ZWNlzebdgiMU3Ke2p9WfZsAd0HKG9oJjeNJFDVATI/ez0IT8pKFR0AT5wO1u5HHDX3szPl19F5Blk8S3XYc//ZypVTokpH7EDgq+tj8FPERAuwIYl3qAJesR0omwn5Gro87pUhTgqK+9mkXcWacUYsLA6m0uR+1DhdTIHwcsHFoVI+DjwOGmfeI5ZallbgRdmoeTUi1lf1RVu5myoBl6eRob9dLWCtp+7zjp0fmPEDaJ root@rouf
+init.ateliers.heureux-cyclage.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAmQZqrcEum8Ixy6kKU6AhENis9EmHOg8z0IPjCrF9glZjet66PLTPCulYcPdiBFhPJjxBFiKKp+bY/qiiVphSO7LXYutgzcbH9dKn681w4vsiAxTYIkgQao0AhrmsIMgoY+PZs3spoKt/E8GQq7SLXb9v7VuRcvQbkKIxp+HIc5uvaf8pZnhT2ODJLW1MiYlyIlJp+ZjvrBKd8/2TZaLOAW6P3XUqNQKCocngnDwDJQnq6EbVhrBjfU4CuFPXk9QY5dJjvSdyb5oCXDabHcQNymZwIYFsfdSjswpoDQH/bzqN0LhlvKYTauUoZNvMQ6FhHb5eiSBOv4vfJM8bJ/EftcT+Lz27u3KD7RePZudNJen75rB99UPWfcc1HkWS6I7pX4wzKtd9cUyx7qqpN7wn9G1RLYDbZ2Zo7AFJeHGdkIZ+SBEdFXuPc7W7p33A7VoRG1U/2Cq8DAiD6FpBYYYscFiacW2oGr913sYKWbSF1QxzmHHIefyio6+GthNHXebXkj3mS7DZGhEDtMq5WO5yhd3kGKsA5z67K0tdf5yte9ACOIVPJ7Ttg/adDHYVKM9Hr8PLX1OpCEuZu4CtX3F+BBH0dn3mLkBFpnHlXdN5mGNw/FDHFSO63t61xSJjM7PJG2/KOREr/5naYhEypG4FwLrbvjFq7dCwcywh+A0a4t6w98=
+ateliers.heureux-cyclage.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCs2PjhfXSTUryiFfbzB3Qc5lF2bvMR56tzDTmrKGtBFXifzQuAltftPAgKTFeuFohOl1jXD3KzeZS6EAk8iZ7hUzBCbPGx5nrIizw9Kak8Jvy477uHzRNuCSbdgxzpwRr8nOKkohwARxFgkRQxM08rKBZyuSYU8N+Z9OSEwMQqv+uU+/NUHWZC0JVfWwfBunwc9mQBmxzt5Y+zhKk3qzEu2Iqu4ilr8FolAwGkWp60ruffrQrnJYFpIwFGsE+k/WAd4RgGyASclCPA5upVLKiSnwx5vnyXggYX0mXNrch3Uak99rrOVH/0YpGUy1dJY91UT+BESWyvMFDbK8fQWTR39kCnESS02F8/FnVTB9tP1XRPBWWUMtavOQIL0BxsgmvbM8rJEHImiRfLCwH/6oXP5JkPQnKQZlu++WPjWxuMraPNwvFsrqBdfPuYY97L4cXiI4loea5/eEBhEyz5RVBSHXoy3BUceSsXloGH1/2iC50k5IpZJIRthYi+OJ9ZjDBLk0YioVsf4TjADythqLu2zOT+ota63trJ/AMEV2tGX1mPGiFJgJ69cHN5CIsSDJH6VcbswPWxGa3n9r/b1Wnzadp4wiNFODoe5a20qbvLg3jrOJldxowKhNHExZpgPXuEKA/gSBKnyvhnZBerFwAGBKqaQOmfDMlknQtzg1fGyQ==
+|1|p+07/BQvEHNha3nWzaQimjM242U=|Ouc4VzPcrmZoCecGIJb27ztT/Og= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCs2PjhfXSTUryiFfbzB3Qc5lF2bvMR56tzDTmrKGtBFXifzQuAltftPAgKTFeuFohOl1jXD3KzeZS6EAk8iZ7hUzBCbPGx5nrIizw9Kak8Jvy477uHzRNuCSbdgxzpwRr8nOKkohwARxFgkRQxM08rKBZyuSYU8N+Z9OSEwMQqv+uU+/NUHWZC0JVfWwfBunwc9mQBmxzt5Y+zhKk3qzEu2Iqu4ilr8FolAwGkWp60ruffrQrnJYFpIwFGsE+k/WAd4RgGyASclCPA5upVLKiSnwx5vnyXggYX0mXNrch3Uak99rrOVH/0YpGUy1dJY91UT+BESWyvMFDbK8fQWTR39kCnESS02F8/FnVTB9tP1XRPBWWUMtavOQIL0BxsgmvbM8rJEHImiRfLCwH/6oXP5JkPQnKQZlu++WPjWxuMraPNwvFsrqBdfPuYY97L4cXiI4loea5/eEBhEyz5RVBSHXoy3BUceSsXloGH1/2iC50k5IpZJIRthYi+OJ9ZjDBLk0YioVsf4TjADythqLu2zOT+ota63trJ/AMEV2tGX1mPGiFJgJ69cHN5CIsSDJH6VcbswPWxGa3n9r/b1Wnzadp4wiNFODoe5a20qbvLg3jrOJldxowKhNHExZpgPXuEKA/gSBKnyvhnZBerFwAGBKqaQOmfDMlknQtzg1fGyQ==
diff --git a/machine-ateliers.txt b/machine-ateliers.txt
new file mode 100644 (file)
index 0000000..c41c688
--- /dev/null
@@ -0,0 +1,5 @@
+- script de grenode pour définir son mot-de-passe
+- voir gunicorn
+- script de grenode/gresille pour les oublis de commit dans etc ...
+- voir xoe: http://sisalp.fr/index.php/post/Installation-OpenERP-procedure-totalement-automatisee-d-installation-de-xoe-et-d-OpenERP
+- 
\ No newline at end of file
diff --git a/vm.sh b/vm.sh
new file mode 100644 (file)
index 0000000..eb4b556
--- /dev/null
+++ b/vm.sh
@@ -0,0 +1,95 @@
+#!/bin/sh
+# DESCRIPTION: ce fichier regroupe les variables propres à la VM
+
+readonly PATH=$PATH:/usr/sbin:/sbin
+readonly vm_domainname="heureux-cyclage.org"
+readonly vm_hostname="ateliers"
+readonly vm_fqdn="$vm_hostname.$vm_domainname"
+readonly vm=$vm_hostname
+readonly vm_host="rouf.grenode.net"
+
+readonly vm_use_lvm="yes"
+ # - sans LVM :
+ #   - on a accès au LVM de l'hôte, mais c'est pas très propre.
+ #   - pour l'extension de mémoire, on peut soit :
+ #       1.1.   étendre avec lvresize /dev/domU/$vm_fqdn-disk
+ #       1.2.   étendre avec sfdisk $vm_dev_disk_home
+ #       1.3.   étendre avec resize2fs /dev/mapper/${vm_lvm_lv}_home_deciphered
+ #     soit :
+ #       2.1. créer une nouvelle partition sur le LVM de l'hôte
+ #       2.2. l'ajouter comme un disque supplémentaire dans /etc/xen/$vm_fqdn.cfg
+ #       2.3. le monter sur /home2 en pensant à changer DHOME=/home2 dans /etc/adduser.conf
+ #   - pour la sauvegarde: on peut soit :
+ #     1. sauvegarder au niveau applicatif (pgdump, mysqldump, etckeeper, git)
+ #     2. sauvegarder incrémentalement avec (duplicity, backup-ninja, BackupPC),
+ #        depuis l'hôte pour avoir un snapshot LVM.
+ # - avec LVM :
+ #   - question ouverte de la performance du LVM dans du LVM.
+ #   - pour l'extension de mémoire, on peut soit :
+ #       1.1.   étendre avec lvresize /dev/domU/$vm_fqdn-disk
+ #       1.1.   étendre avec pvextend $vm_lvm_pv
+ #       1.1.   étendre avec lvresize  /dev/${vm_lvm_vg}/${vm_lvm_lv}_home
+ #       1.3.   étendre avec resize2fs /dev/mapper/${vm_lvm_lv}_home_deciphered
+ #   - pour la sauvegarde: on peut soit :
+ #     1. sauvegarder au niveau applicatif (pgdump, mysqldump, etckeeper, git)
+ #     2. sauvegarder incrémentalement avec (duplicity, backup-ninja, BackupPC),
+ #        depuis la VM pour avoir un snapshot LVM.
+
+# Cartographie de la mémoire morte :
+#   SATA2 * 2 (/dev/sd{a,b})
+#     /dev/sda -> /dev/sda{1,2,3}
+#     /dev/sdb -> /dev/sdb{1,2,3}
+#   RAID1 logiciel
+#     /dev/sd{a,b}1 -> /dev/md0
+#     /dev/sd{a,b}2 -> /dev/md1
+#     /dev/sd{a,b}3 -> /dev/md2
+#   LVM
+#     /dev/md0 -> dom0
+#     /dev/md2 -> domU -> /dev/mapper/$vm_fqdn-disk
+#   LVM
+#     /dev/mapper/$vm_fqdn-disk -> /dev/xvda{1,2}
+#     /dev/xvda2 -> /dev/mapper/${vm_lvm_vg}-${vm_lvm_lv}_{swap,root,var,home}
+
+case $vm_use_lvm in
+ (no)
+       ;;
+ (yes)
+       readonly vm_lvm_vg=$vm_fqdn
+       readonly vm_lvm_lv=$vm
+       ;;
+ (*)
+       exit 1;;
+ esac
+
+readonly vm_raid_effective_disks=1 # NOTE: RAID1 (mirroring)
+       # NOTE: julm@rouf:~$ sudo pvs /dev/md2 -o+pe_start
+       #       PV         VG   Fmt  Attr PSize   PFree   1st PE
+       #       /dev/md2   domU lvm2 a-   925,64g 470,64g 192,00k <- pas adapté au TRIM SSD, mais on utilise du SATA2
+readonly vm_e2fs_block_size=4096
+       # NOTE: valeur standard pour un disque avec des secteurs de 512 octets :
+       # julm@rouf:~$ grep . /sys/block/sd{a,b}/queue/*_block_size
+       # /sys/block/sda/queue/logical_block_size:512
+       # /sys/block/sda/queue/physical_block_size:512
+       # /sys/block/sdb/queue/logical_block_size:512
+       # /sys/block/sdb/queue/physical_block_size:512
+readonly vm_e2fs_stripe_size=
+       # NOTE: égal au chunk size de mdadm --detail ;
+       # mais ne concerne pas RAID1 où il n'y a pas de changement de disque à effectuer,
+       # et donc pas de chunk size.
+readonly  vm_e2fs_stride=${vm_e2fs_stripe_size:+$((vm_e2fs_stripe_size / vm_e2fs_block_size))}
+readonly  vm_e2fs_stripe_width=${vm_e2fs_stride:+$((vm_e2fs_stride * vm_raid_effective_disks))}
+          vm_e2fs_extended_options=${vm_e2fs_stride:+,stride=$vm_e2fs_stride}${vm_e2fs_stripe_width:+,stripe_width=$vm_e2fs_stripe_width}
+
+readonly vm_arch="amd64"
+readonly vm_bridge="br-gresille"
+readonly vm_ipv4="91.216.110.42" # NOTE: IPv4 publique assignée par Grésille
+readonly vm_lsb_name="wheezy"
+readonly vm_mac="00:16:3E:E5:98:42" # NOTE: addresse MAC assignée par Grésille
+ # NOTE: on part sur wheezy dès le début
+ # dans l'idée de ne pas s'embêter avec
+ # une migration squeeze -> wheezy dans deux mois ;
+ # et parce qu'on juge wheezy « suffisamment stable ».
+
+rule_env () { # DESCRIPTION: affiche les $vm_*
+       set | grep '^vm_'
+ }
diff --git a/vm_host b/vm_host
new file mode 100755 (executable)
index 0000000..f754547
--- /dev/null
+++ b/vm_host
@@ -0,0 +1,438 @@
+#!/bin/sh
+set -e -f ${DRY_RUN:+-n} -u
+tool=${0%/*}
+. "$tool"/functions.sh
+. "$tool"/vm.sh
+test "$(hostname --fqdn)" = "$vm_host"
+
+rule_help () {
+       cat >&2 <<-EOF
+               DESCRIPTION: ce script regroupe des fonctions utilitaires
+                            pour gérer la VM _depuis_ son hôte ;
+                            il sert à la fois d'outil et de documentation.
+                            Voir \`$tool/vm_hosted' pour les utilitaires côté VM hébergée.
+               SYNTAX: $0 \$RULE \${RULE}_SYNTAX
+               RULES:
+               $(sed -ne 's/^rule_\([^_][^ ]*\) () {\( *#.*\|\)/\t\1\2/p' "$tool"/vm.sh "$0")
+               ENVIRONMENT:
+                 TRACE # affiche les commandes avant leur exécution
+               $(sed -ne 's/^readonly \([^ ][^ =]*\).*}\( *#.*\|\)$/\t$\1\2/p' "$tool"/vm.sh "$0")
+               EOF
+ }
+
+readonly vm_dev_disk=/dev/mapper/domU-$(printf %s "$vm_fqdn-disk" | sed -e 's/-/--/g')
+readonly vm_dev_disk_boot="${vm_dev_disk}1"
+
+rule_git_reset () {
+       (
+       cd "$tool"
+       #git checkout -f -B master origin
+       # NOTE: pas de -B sous squeeze
+       git checkout HEAD'^' &&
+       git branch -f master origin &&
+       git checkout master
+       git clean -f -d -x
+       )
+ }
+
+rule_vm_init () {
+       mk_reg mod=644 own=root:root /etc/xen/$vm_fqdn.cfg <<-EOF
+               #  -*- mode: python; -*-
+               # DOC: http://wiki.xen.org/wiki/Xen_Linux_PV_on_HVM_drivers
+               import os, re
+               name         = "$vm_fqdn"
+               arch         = os.uname()[4]
+               memory       = 2048
+               vcpus        = 1
+               pae          = 1
+               acpi         = 1
+               apic         = 1
+               vif          = ['mac=$vm_mac,bridge=$vm_bridge']
+               disk         = ['phy:/dev/domU/$vm_fqdn-disk,hda,w']
+               device_model = 'qemu-dm'
+               # HVM :
+               #kernel       = "/usr/lib/xen-4.0/boot/hvmloader"
+               #builder      = 'hvm'
+               #xen_platform_pci = 1 # NOTE: the guest VM can use optimized PV on HVM drivers
+               # PV :
+               #kernel       = "pv-grub.gz" # NOTE: pas encore dans Debian car il ne fonctionne qu'avec grub-legacy
+               #extra        = "(hd0,0)/grub/grub.cfg"
+               bootloader    = '/usr/bin/pygrub'
+               
+               # boot on floppy (a), hard disk (c) or CD-ROM (d)
+               #boot         = 'd'
+               
+               #vnc        = 1
+               #sdl        = 0
+               #vncconsole = 0
+               #vnclisten  = "0.0.0.0"
+               #vncpasswd  = ""
+               #usbdevice  = 'tablet'
+               
+               keymap      = 'fr'
+               serial      = 'pty'
+               on_poweroff = 'destroy'
+               on_reboot   = 'restart'
+               on_crash    = 'restart'
+               EOF
+ }
+rule_vm_start () {
+       test ! -e /dev/domU/$vm_fqdn-disk1
+       sudo xm create $vm_fqdn.cfg
+       rule_vm_attach
+ }
+rule_vm_attach () {
+       cat <<-EOF
+               NOTE: Ctrl-] pour se détacher de la console
+               EOF
+       sudo xm console $vm_fqdn
+ }
+rule_vm_stop () {
+       sudo xm shutdown $vm_fqdn
+ }
+rule_vm_stop_force () {
+       sudo xm destroy $vm_fqdn
+ }
+
+rule_disk_mount () { # DESCRIPTION: montage du disque de la VM depuis l'hôte
+       sudo kpartx -a -v /dev/domU/$vm_fqdn-disk
+       #sudo xm block-attach 0 phy:/dev/domU/$vm_fqdn-disk $vm_dev_disk w
+ }
+rule_disk_umount () { # DESCRIPTION: démontage du disque de la VM depuis l'hôte
+       rule_part_boot_umount
+       case $vm_use_lvm in
+        (yes)
+               rule_part_lvm_umount
+               ;;
+        (no)
+               rule_part_root_umount
+               rule_part_var_umount
+               rule_part_home_umount
+               ;;
+        (*) exit 1;;
+        esac
+       sudo kpartx -d -v /dev/domU/$vm_fqdn-disk
+       #sudo xm block-detach 0 $vm_dev_disk
+       # XXX: DANGEREUX ; si jamais il bloque parce que le disque était encore utilisé :
+       #      utiliser xm block-detach 0 $vm_dev_disk --force ;
+       #      ôter les éventuels mappages LVM concernés avec dmsetup table et dmsetup remove --force ;
+       #      ôter les mappages concernés dans /etc/lvm/cache/.cache,
+       #      et pour bien trouver tous les mappages :
+       #        % sudo find /dev -type l -exec sh -c 'printf "%s -> " "$@"; readlink "$@"' - {} \; | grep $vm_dev_disk
+       #      enfin, ôter l'éventuel verrou dans /var/lock/lvm/
+ }
+
+case $vm_use_lvm in
+ (no)
+       readonly vm_dev_disk_swap="${vm_dev_disk}5"
+       readonly vm_dev_disk_root="${vm_dev_disk}6"
+       readonly vm_dev_disk_var="${vm_dev_disk}7"
+       readonly vm_dev_disk_home="${vm_dev_disk}8"
+       ;;
+ (yes)
+       readonly vm_lvm_pv="${vm_dev_disk}2"
+       readonly vm_dev_disk_swap=/dev/$vm_lvm_vg/${vm_lvm_lv}_swap
+       readonly vm_dev_disk_root=/dev/$vm_lvm_vg/${vm_lvm_lv}_root
+       readonly vm_dev_disk_var=/dev/$vm_lvm_vg/${vm_lvm_lv}_var
+       readonly vm_dev_disk_home=/dev/$vm_lvm_vg/${vm_lvm_lv}_home
+       ;;
+ (*) exit 1;;
+ esac
+
+rule_disk_format () { # DESCRIPTION: partitionnage du disque de la VM
+       case $vm_use_lvm in
+       (no)
+               sudo sfdisk $vm_dev_disk <<-EOF
+                       # partition table of $vm_dev_disk
+                       unit: sectors
+                       
+                       ${vm_dev_disk}1 : start=       63, size=   497952, Id=83, bootable
+                       ${vm_dev_disk}2 : start=   498015, size=418927005, Id= 5
+                       ${vm_dev_disk}3 : start=        0, size=        0, Id= 0
+                       ${vm_dev_disk}4 : start=        0, size=        0, Id= 0
+                       ${vm_dev_disk}5 : start=   498078, size=  1959867, Id=82
+                       ${vm_dev_disk}6 : start=  2458008, size= 29302497, Id=83
+                       ${vm_dev_disk}7 : start= 31760568, size=  9767457, Id=83
+                       ${vm_dev_disk}8 : start= 41528088, size=377896932, Id=83
+               EOF
+               ;;
+       (yes)
+               sudo sfdisk $vm_dev_disk <<-EOF
+                       # partition table of $vm_dev_disk
+                       unit: sectors
+                       
+                       ${vm_dev_disk}1 : start=       63, size=   497952, Id=83, bootable
+                       ${vm_dev_disk}2 : start=   498015, size=418927005, Id=8E
+                       EOF
+               ;;
+       (*) exit 1;;
+        esac
+       #sudo partprobe $vm_dev_disk
+       sudo kpartx -u -v /dev/domU/$vm_fqdn-disk
+ }
+
+rule_part_lvm_format () {
+       rule_part_lvm_umount
+       ! sudo vgs | grep -q "^  $vm_lvm_vg " ||
+       sudo vgremove $vm_lvm_vg
+       sudo pvcreate --dataalignment 512k $vm_lvm_pv
+       sudo vgcreate --dataalignment 512k $vm_lvm_vg $vm_lvm_pv
+       sudo lvcreate --contiguous y -n ${vm_lvm_lv}_swap -L  1G     $vm_lvm_vg
+       sudo lvcreate --contiguous y -n ${vm_lvm_lv}_root -L 15G     $vm_lvm_vg
+       sudo lvcreate --contiguous y -n ${vm_lvm_lv}_var  -L  5G     $vm_lvm_vg
+       sudo lvcreate --contiguous y -n ${vm_lvm_lv}_home -l 99%FREE $vm_lvm_vg
+       rule_part_lvm_umount
+ }
+rule_part_lvm_mount () {
+       case $vm_use_lvm in
+        (yes)
+               sudo vgchange -a y $vm_lvm_vg
+               ;;
+        (*) exit 1;;
+        esac
+ }
+rule_part_lvm_umount () {
+       case $vm_use_lvm in
+        (yes)
+               rule_part_root_umount
+               rule_part_var_umount
+               rule_part_home_umount
+               ! sudo vgs | grep -q "^  $vm_lvm_vg " ||
+               sudo vgchange -a n $vm_lvm_vg
+               ;;
+        (*) exit 1;;
+        esac
+ }
+
+rule_part_randomize () { # SYNTAX: $part # NOTE: à anticiper
+       local part=$1
+       eval "sudo dd if=/dev/urandom of=\$vm_dev_disk_$part"
+ }
+rule_part_randomize_stat () { # SYNTAX: $part # DESCRIPTION: fait afficher la progression de rule_part_clean
+       local part=$1
+       eval "pkill -USR1 -f \"^dd if=/dev/urandom of=\$vm_dev_disk_$part\""
+ }
+rule__part_encrypted_format () { # SYNTAX: $part # DESCRIPTION: formatage d'une partition distincte de /
+ # NOTE: la clef de chiffrement est dérivée de celle de /,
+ #       / doit être déchiffrée pour que cela fonctionne.
+       local part=$1
+       eval "local dev=\$vm_dev_disk_$part"
+       test ! -e /dev/mapper/${vm_lvm_lv}_root_deciphered ||
+       sudo /bin/sh -c "/lib/cryptsetup/scripts/decrypt_derived ${vm_lvm_lv}_root_deciphered |
+       cryptsetup luksFormat --hash=sha512 --key-size=512 \
+        --cipher=aes-xts-essiv:sha256 --key-file=- --align-payload=8 $dev"
+ }
+rule__part_encrypted_mount () { # SYNTAX: $part
+       local part=$1
+       eval "local dev=\$vm_dev_disk_$part"
+       test -e /dev/mapper/${vm_lvm_lv}_${part}_deciphered ||
+       sudo /bin/sh -c "/lib/cryptsetup/scripts/decrypt_derived ${vm_lvm_lv}_root_deciphered |
+       cryptsetup luksOpen --key-file=- $dev ${vm_lvm_lv}_${part}_deciphered"
+ }
+rule__part_encrypted_umount () { # SYNTAX: $part
+       local part=$1
+       eval "local dev=\$vm_dev_disk_$part"
+       test ! -e     /dev/mapper/${vm_lvm_lv}_${part}_deciphered ||
+       sudo cryptsetup luksClose ${vm_lvm_lv}_${part}_deciphered
+ }
+
+rule_part_root_format () {
+       if ! mount | grep -q "^$vm_dev_disk_root "
+        then
+               sudo cryptsetup luksFormat --hash=sha512 --key-size=512 \
+                --cipher=aes-xts-essiv:sha256 --key-file=- --align-payload=8 $vm_dev_disk_root
+               sudo cryptsetup luksOpen --key-file=- $vm_dev_disk_root ${vm_lvm_lv}_root_deciphered
+               sudo mke2fs -t ext4 -c -c -m 5 -T ext4 -b $vm_e2fs_block_size \
+                -E resize=30G${vm_e2fs_extended_options} \
+                -L ${vm_lvm_lv}_root \
+                /dev/mapper/${vm_lvm_lv}_root_deciphered
+               ! mountpoint -q /mnt/$vm_fqdn
+               sudo mount -v /dev/mapper/${vm_lvm_lv}_root_deciphered /mnt/$vm_fqdn
+               mk_dir mod=0770 own=root:root /mnt/$vm_fqdn/boot
+               mk_dir mod=0770 own=root:root /mnt/$vm_fqdn/dev
+               mk_dir mod=0770 own=root:root /mnt/$vm_fqdn/home
+               mk_dir mod=0770 own=root:root /mnt/$vm_fqdn/proc
+               mk_dir mod=0770 own=root:root /mnt/$vm_fqdn/sys
+               mk_dir mod=0770 own=root:root /mnt/$vm_fqdn/var
+               mk_dir mod=0770 own=root:root /mnt/$vm_fqdn/root
+               mk_dir mod=0770 own=root:root /mnt/$vm_fqdn/root/tool
+               mk_dir mod=0770 own=root:root /mnt/$vm_fqdn/root/tool/ateliers
+               sudo umount -v /mnt/$vm_fqdn
+               sudo cryptsetup luksClose ${vm_lvm_lv}_root_deciphered
+        fi
+ }
+rule_part_root_mount () {
+       test -e /dev/mapper/${vm_lvm_lv}_root_deciphered ||
+       sudo cryptsetup luksOpen $vm_dev_disk_root ${vm_lvm_lv}_root_deciphered
+       mountpoint -q /mnt/$vm_fqdn ||
+       sudo mount -v -t ext4 /dev/mapper/${vm_lvm_lv}_root_deciphered /mnt/$vm_fqdn
+ }
+rule_part_root_umount () {
+       ! mountpoint -q /mnt/$vm_fqdn ||
+       sudo umount -v  /mnt/$vm_fqdn
+       ! test -e     /dev/mapper/${vm_lvm_lv}_root_deciphered ||
+       sudo cryptsetup luksClose ${vm_lvm_lv}_root_deciphered
+ }
+rule_part_root_backup_luks () {
+       sudo cryptsetup luksHeaderBackup $vm_dev_disk_root --header-backup-file ./root.luks
+ }
+rule_part_swap_format () {
+       rule__part_encrypted_format swap
+       rule__part_encrypted_mount  swap
+       sudo mkswap -f -L ${vm_lvm_lv}_swap \
+        /dev/mapper/${vm_lvm_lv}_swap_deciphered
+       rule__part_encrypted_umount swap
+ }
+rule_part_boot_format () {
+       mount | grep -q "^$vm_dev_disk_boot " ||
+       sudo mke2fs -t ext2 -c -c -m 5 -T small \
+        -E resize=1G${vm_e2fs_extended_options} \
+        -L ${vm_lvm_lv}_boot $vm_dev_disk_boot
+ }
+rule_part_boot_mount () {
+       mountpoint -q /mnt/$vm_fqdn
+       test -d /mnt/$vm_fqdn/boot
+       mountpoint -q                           /mnt/$vm_fqdn/boot ||
+       sudo mount -v -t ext2 $vm_dev_disk_boot /mnt/$vm_fqdn/boot
+ }
+rule_part_boot_umount () {
+       ! mountpoint -q /mnt/$vm_fqdn/boot ||
+       sudo umount -v  /mnt/$vm_fqdn/boot
+ }
+rule_part_var_format () {
+       rule__part_encrypted_format var
+       rule__part_encrypted_mount  var
+       sudo mke2fs -t ext4 -c -c -m 5 -T ext4 -b $vm_e2fs_block_size \
+        -E resize=10G${vm_e2fs_extended_options} \
+        -L ${vm_lvm_lv}_var \
+        /dev/mapper/${vm_lvm_lv}_var_deciphered
+       rule__part_encrypted_umount var
+ }
+rule_part_var_mount () {
+       rule__part_encrypted_mount var
+       mountpoint -q /mnt/$vm_fqdn/var ||
+       sudo mount -v -t ext4 /dev/mapper/${vm_lvm_lv}_var_deciphered /mnt/$vm_fqdn/var
+ }
+rule_part_var_umount () {
+       ! mountpoint -q /mnt/$vm_fqdn/var ||
+       sudo umount -v  /mnt/$vm_fqdn/var
+       rule__part_encrypted_umount var
+ }
+rule_part_home_format () {
+       rule__part_encrypted_format home
+       rule__part_encrypted_mount  home
+       sudo mke2fs -t ext4 -c -c -m 0 -T ext4 -b $vm_e2fs_block_size \
+        -E resize=400G${vm_e2fs_extended_options} \
+        -L ${vm_lvm_lv}_home \
+        /dev/mapper/${vm_lvm_lv}_home_deciphered
+        # NOTE: -O quota pas supporté par e2fsprogs/squeeze
+       rule__part_encrypted_umount home
+ }
+rule_part_home_mount () {
+       rule__part_encrypted_mount home
+       mountpoint -q /mnt/$vm_fqdn/home ||
+       sudo mount -v -t ext4 /dev/mapper/${vm_lvm_lv}_home_deciphered /mnt/$vm_fqdn/home
+ }
+rule_part_home_umount () {
+       ! mountpoint -q /mnt/$vm_fqdn/home ||
+       sudo umount -v  /mnt/$vm_fqdn/home
+       rule__part_encrypted_umount home
+ }
+
+rule_debian_install () {
+       rule_disk_mount
+       rule_part_lvm_mount
+       rule_part_root_mount
+       rule_part_boot_mount
+       rule_part_var_mount
+       sudo DEBOOTSTRAP_DIR=/usr/share/debootstrap/ LANG=C LC_CTYPE=C debootstrap \
+        --arch=$vm_arch --verbose --keyring=/usr/share/keyrings/debian-archive-keyring.gpg \
+        --exclude=vim-tiny \
+        --include=$(printf '%s,' \
+                acl \
+                bsdmainutils \
+                busybox \
+                ca-certificates \
+                console-setup \
+                cryptsetup \
+                dash \
+                dnsutils \
+                dropbear \
+                etckeeper \
+                gnupg \
+                hashalot \
+                htop \
+                ifupdown \
+                initramfs-tools \
+                kbd \
+                less \
+                locales \
+                lvm2 \
+                mosh \
+                molly-guard \
+                ncurses-term \
+                openssh-client \
+                openssh-server \
+                openssl \
+                pciutils \
+                procps \
+                quota \
+                quotatool \
+                rsync \
+                screen \
+                sudo \
+                sysprofile \
+                vim-nox \
+                wget \
+                zsh \
+        ) \
+        $vm_lsb_name /mnt/$vm_fqdn/ \
+        http://ftp.fr.debian.org/debian/
+       rule_part_var_umount
+       rule_part_boot_umount
+       rule_part_root_umount
+ }
+
+rule_chroot () {
+       rule_disk_mount
+       rule_part_lvm_mount
+       rule_part_root_mount
+       rule_part_boot_mount
+       rule_part_var_mount
+       #rule_part_home_mount
+       mountpoint -q /mnt/$vm_fqdn/proc ||
+       sudo mount -t proc proc /mnt/$vm_fqdn/proc
+       mountpoint -q /mnt/$vm_fqdn/sys ||
+       sudo mount -t sysfs sys /mnt/$vm_fqdn/sys
+       mountpoint -q /mnt/$vm_fqdn/dev ||
+       sudo mount --bind /dev /mnt/$vm_fqdn/dev
+       if test -d /mnt/$vm_fqdn/root/tool/vm/.git
+        then
+               mountpoint -q /mnt/$vm_fqdn/root/tool/vm ||
+               sudo mount --bind "$tool" /mnt/$vm_fqdn/root/tool/vm
+        else
+               rsync -a "$tool"/ /mnt/$vm_fqdn/root/tool/vm
+        fi
+       sudo chroot /mnt/$vm_fqdn /bin/bash || true
+       rule__chroot_clean
+ }
+rule__chroot_clean () {
+       ! sudo mountpoint -q /mnt/$vm_fqdn/root/tool/vm ||
+       sudo umount -v /mnt/$vm_fqdn/root/tool/$vm
+       ! mountpoint -q /mnt/$vm_fqdn/dev ||
+       sudo umount -v /mnt/$vm_fqdn/dev
+       ! mountpoint -q /mnt/$vm_fqdn/sys ||
+       sudo umount -v /mnt/$vm_fqdn/sys
+       ! mountpoint -q /mnt/$vm_fqdn/proc ||
+       sudo umount -v /mnt/$vm_fqdn/proc
+       rule_part_home_umount
+       rule_part_var_umount
+       rule_part_boot_umount
+       rule_part_root_umount
+       rule_disk_umount
+ }
+
+rule=${1:-help}
+${1+shift}
+set "${TRACE:+-x}"
+rule_$rule "$@"
diff --git a/vm_hosted b/vm_hosted
new file mode 100755 (executable)
index 0000000..56e1ee0
--- /dev/null
+++ b/vm_hosted
@@ -0,0 +1,804 @@
+#!/bin/sh
+set -e -f ${DRY_RUN:+-n} -u
+tool=${0%/*}
+. "$tool"/functions.sh
+. "$tool"/vm.sh
+test "$(hostname --fqdn)" = "$vm_fqdn"
+
+rule_help () {
+       cat >&2 <<-EOF
+               DESCRIPTION: ce script regroupe des fonctions utilitaires
+                            pour gérer la VM _depuis_ la VM hébergée ;
+                            il sert à la fois d'outil et de documentation.
+                            Voir \`$tool/vm_host' pour les utilitaires côté machine hôte.
+               SYNTAX: $0 \$RULE \${RULE}_SYNTAX
+               RULES:
+               $(sed -ne 's/^rule_\([^_][^ ]*\) () {\( *#.*\|\)/\t\1\2/p' "$tool"/vm.sh "$0")
+               ENVIRONMENT:
+                 TRACE # affiche les commandes avant leur exécution
+               $(sed -ne 's/^readonly \([^ ][^ =]*\).*}\( *#.*\|\)$/\t$\1\2/p' "$tool"/vm.sh "$0")
+               EOF
+ }
+
+rule_git_reset () {
+       (
+       cd "$tool"
+       git checkout -f -B master origin
+       git clean -f -d -x
+       )
+ }
+
+rule_chrooted () {
+       export LANG=C
+       export LC_CTYPE=C
+       . /etc/profile
+ }
+
+rule__etckeeper_init () {
+       mk_reg mod=644 own=root:root /etc/etckeeper/etckeeper.conf <<-EOF
+               VCS=git
+               GIT_COMMIT_OPTIONS=""
+               AVOID_DAILY_AUTOCOMMITS=1
+               #AVOID_SPECIAL_FILE_WARNING=1
+               #AVOID_COMMIT_BEFORE_INSTALL=1
+               HIGHLEVEL_PACKAGE_MANAGER=apt
+               LOWLEVEL_PACKAGE_MANAGER=dpkg
+               EOF
+ }
+rule__locale_init () {
+       mk_reg mod=644 own=root:root /etc/locale.gen <<-EOF
+               fr_FR.UTF-8 UTF-8
+               EOF
+       sudo update-locale
+ }
+rule__network_init () {
+       mk_reg mod= own= /etc/hostname <<-EOF
+               $vm
+               EOF
+       grep -q " $vm\$" /etc/hosts ||
+       mk_reg mod= own= --append /etc/hosts <<-EOF
+               127.0.0.1 $vm_fqdn $vm
+               EOF
+       mk_reg mod= own= /etc/network/interfaces <<-EOF
+               auto lo
+               iface lo inet loopback
+               
+               auto eth0=grenode
+               iface grenode inet static
+                   address   $vm_ipv4
+                   gateway   $vm_ipv4 # NOTE: proxy_arp sur la passerelle permet d'utiliser la même adresse
+                   network   $vm_ipv4
+                   broadcast $vm_ipv4
+                   netmask   255.255.255.255
+                   mtu 1300 # TODO: voir si c'est nécessaire à Lyon
+                   post-up   ip address add    $vm_ipv4/32 dev \$IFACE
+                   pre-down  ip address delete $vm_ipv4/32 dev \$IFACE
+               EOF
+ }
+rule__apt_init () {
+       mk_reg mod= own= /etc/apt/sources.list <<-EOF
+               deb http://ftp.fr.debian.org/debian $vm_lsb_name main contrib non-free
+               EOF
+       mk_reg mod= own= /etc/apt/sources.list.d/$vm_lsb_name-backports.list <<-EOF
+               deb http://backports.debian.org/debian-backports $vm_lsb_name-backports main contrib non-free
+               EOF
+       mk_reg mod= own= /etc/apt/preferences <<-EOF
+               Package: *
+               Pin: release a=$vm_lsb_name
+               Pin-Priority: 170
+               
+               Package: *
+               Pin: release a=$vm_lsb_name-backports
+               Pin-Priority: 200
+               EOF
+       mk_reg mod= own= /etc/apt/sources.list.d/openerp.list <<-EOF
+               deb http://nightly.openerp.com/trunk/nightly/deb/ ./
+               EOF
+ }
+rule__filesystem_init () {
+       mk_reg mod=644 own=root:root /etc/fstab <<-EOF
+               # <file system> <mount point> <type> <options> <dump> <pass>
+               LABEL=${vm_lvm_lv}_boot /boot ext2 defaults 0 0
+               proc /proc proc defaults 0 0
+               sysfs /sys sysfs defaults 0 0
+               tmpfs /tmp tmpfs rw,nosuid,nodev,auto,size=200m,nr_inodes=1000k,mode=1777,noatime,nodiratime 0 0
+               /dev/mapper/${vm_lvm_lv}_root_deciphered /     ext4 defaults,errors=remount-ro,acl,noatime 0 1
+               /dev/mapper/${vm_lvm_lv}_var_deciphered  /var  ext4 defaults,errors=remount-ro,acl,noatime 0 1
+               /dev/mapper/${vm_lvm_lv}_home_deciphered /home ext4 defaults,errors=remount-ro,acl,noatime,usrquota,grpquota 0 0
+               /dev/mapper/${vm_lvm_lv}_swap_deciphered swap swap sw 0 0
+               EOF
+       mk_reg mod=644 own=root:root /etc/crypttab <<-EOF
+               # <target name> <source device> <key file> <options>
+               ${vm_lvm_lv}_root_deciphered /dev/$vm_lvm_vg/${vm_lvm_lv}_root none                         luks,lvm=$vm_lvm_vg
+               ${vm_lvm_lv}_var_deciphered  /dev/$vm_lvm_vg/${vm_lvm_lv}_var  ${vm_lvm_lv}_root_deciphered luks,lvm=$vm_lvm_vg,keyscript=/lib/cryptsetup/scripts/decrypt_derived
+               ${vm_lvm_lv}_home_deciphered /dev/$vm_lvm_vg/${vm_lvm_lv}_home ${vm_lvm_lv}_root_deciphered luks,lvm=$vm_lvm_vg,keyscript=/lib/cryptsetup/scripts/decrypt_derived
+               ${vm_lvm_lv}_swap_deciphered /dev/$vm_lvm_vg/${vm_lvm_lv}_swap ${vm_lvm_lv}_root_deciphered luks,lvm=$vm_lvm_vg,keyscript=/lib/cryptsetup/scripts/decrypt_derived
+               EOF
+       mk_reg mod=644 own=root:root /etc/sysctl.d/local-swap.conf <<-EOF
+               vm.swappiness = 10 # NOTE: n'utilise le swap qu'en cas d'absolue nécessité
+               vm.vfs_cache_pressure=50
+               EOF
+ }
+rule__login_init () {
+       grep -q hvc0 /etc/securetty ||
+       mk_reg mod= own= --append /etc/securetty <<-EOF
+               hvc0
+               EOF
+       grep -q xvc0 /etc/securetty ||
+       mk_reg mod= own= --append /etc/securetty <<-EOF
+               xvc0
+               EOF
+       mk_reg mod=644 own=root:root /etc/inittab <<-EOF
+               # /etc/inittab: init(8) configuration.
+               
+               # The default runlevel.
+               id:2:initdefault:
+               
+               # Boot-time system configuration/initialization script.
+               # This is run first except when booting in emergency (-b) mode.
+               si::sysinit:/etc/init.d/rcS
+               
+               # What to do in single-user mode.
+               ~~:S:wait:/sbin/sulogin
+               
+               # /etc/init.d executes the S and K scripts upon change
+               # of runlevel.
+               #
+               # Runlevel 0 is halt.
+               # Runlevel 1 is single-user.
+               # Runlevels 2-5 are multi-user.
+               # Runlevel 6 is reboot.
+               
+               l0:0:wait:/etc/init.d/rc 0
+               l1:1:wait:/etc/init.d/rc 1
+               l2:2:wait:/etc/init.d/rc 2
+               l3:3:wait:/etc/init.d/rc 3
+               l4:4:wait:/etc/init.d/rc 4
+               l5:5:wait:/etc/init.d/rc 5
+               l6:6:wait:/etc/init.d/rc 6
+               # Normally not reached, but fallthrough in case of emergency.
+               z6:6:respawn:/sbin/sulogin
+               
+               # What to do when CTRL-ALT-DEL is pressed.
+               ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now
+               
+               # What to do when the power fails/returns.
+               pf::powerwait:/etc/init.d/powerfail start
+               pn::powerfailnow:/etc/init.d/powerfail now
+               po::powerokwait:/etc/init.d/powerfail stop
+               
+               # Xen hypervisor console
+               hvc:2345:respawn:/sbin/getty 38400 hvc0
+               #xvc:2345:respawn:/sbin/getty 38400 xvc0
+               EOF
+       mk_reg mod=644 own=root:root /etc/login.defs <<-EOF
+               MAIL_DIR         /var/mail
+               FAILLOG_ENAB     yes
+               LOG_UNKFAIL_ENAB no
+               LOG_OK_LOGINS    no
+               SYSLOG_SU_ENAB   yes
+               SYSLOG_SG_ENAB   yes
+               FTMP_FILE        /var/log/btmp
+               SU_NAME          su
+               HUSHLOGIN_FILE   .hushlogin
+               ENV_SUPATH       PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
+               ENV_PATH         PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
+               # NOTE: met les sbin/ dans ENV_PATH ;
+               #  - ça n'apporte aucune protection de ne pas les mettre ;
+               #  - ça frustre de ne pas les trouver.
+               TTYGROUP         tty
+               TTYPERM          0600
+               ERASECHAR        0177
+               KILLCHAR         025
+               # NOTE: rwxrwx--- ;
+               #  - donne une même confiance au groupe propriétaire qu'au propriétaire ;
+               #  - facilite l'utilisation des ACL, qui sont dépendantes des droits du groupe propriétaire.
+               UMASK            007
+               PASS_MAX_DAYS    99999
+               PASS_MIN_DAYS    0
+               PASS_WARN_AGE    7
+               UID_MIN           1000
+               UID_MAX          60000
+               GID_MIN           1000
+               GID_MAX          60000
+               LOGIN_RETRIES    3
+               LOGIN_TIMEOUT    60
+               CHFN_RESTRICT    rwh
+               DEFAULT_HOME     yes
+               USERGROUPS_ENAB  yes
+               ENCRYPT_METHOD   SHA512
+               EOF
+       grep -q '^session optional pam_umask.so\>' /etc/pam.d/common-session ||
+       mk_reg mod= own= --append /etc/pam.d/common-session <<-EOF
+               session optional pam_umask.so
+               EOF
+ }
+rule__user_root_init () {
+       mk_dir mod=750 own=root:root /root/etc
+       mk_dir mod=750 own=root:root /root/etc/ssh
+       mk_dir mod=750 own=root:root /root/etc/gpg
+       mk_lnk etc/gpg /root/.gnupg
+       mk_lnk etc/ssh /root/.ssh
+       getent group sudo |
+       while IFS=: read -r group x x users
+        do while IFS=, read -r user
+                do eval local home\; home="~$user"
+                       cat "$home"/etc/ssh/authorized_keys
+                done <<-EOF
+                       $users
+                       EOF
+        done |
+       mk_reg mod=640 own=root:root /root/etc/ssh/authorized_keys
+       sudo find "$tool"/key -type f -name '*.gpg.pub' -exec gpg --import {} \;
+ }
+rule__initramfs_init () {
+       mk_reg mod=644 own=root:root /etc/initramfs-tools/initramfs.conf <<-EOF
+               MODULES=most
+               BUSYBOX=y
+               KEYMAP=y
+               COMPRESS=gzip
+               DEVICE=eth0
+               EOF
+       mk_reg mod=644 own=root:root /etc/modprobe.d/xen-pv.conf <<-EOF
+               alias eth0 xennet
+               alias scsi_hostadapter xenblk
+               EOF
+       mk_reg mod=644 own=root:root /etc/modules <<-EOF
+               sha1_generic
+               sha256_generic
+               sha512_generic
+               aes-x86_64
+               xts
+               # NOTE: pour Xen en mode HVM :
+               #modprobe xen-platform-pci
+               EOF
+       mk_reg mod=644 own=root:root /etc/initramfs-tools/modules <<-EOF
+               EOF
+       sudo sed -e '/^configure_networking /s/ &$//' \
+        -i /usr/share/initramfs-tools/scripts/init-premount/dropbear
+        # NOTE: corrige une vermine : dropbear doit attendre que le réseau soit configuré..
+       sudo rm -f \
+        /etc/initramfs-tools/etc/dropbear/dropbear_dss_host_key \
+        /etc/initramfs-tools/etc/dropbear/dropbear_dss_host_key.pub \
+        /etc/initramfs-tools/etc/dropbear/dropbear_rsa_host_key \
+        /etc/initramfs-tools/etc/dropbear/dropbear_rsa_host_key.pub
+       #mk_reg mod=640 own=root:root </dev/null \
+       # /etc/initramfs-tools/etc/dropbear/dropbear_dss_host_key \
+       # /etc/initramfs-tools/etc/dropbear/dropbear_dss_host_key.pub
+       ssh-keygen -F "init.$vm_fqdn" -f "$tool"/key/ssh.known_hosts |
+       ( while IFS= read -r line
+        do case $line in (*" RSA") return 0; break;; esac
+        done; return 1 ) ||
+       sudo dropbearkey -t rsa -s 4096 -f \
+        /etc/initramfs-tools/etc/dropbear/dropbear_rsa_host_key
+       ssh-keygen -F "init.$vm_fqdn" -f "$tool"/key/ssh.known_hosts |
+       ( while IFS= read -r line
+        do case $line in (*" DSA") return 0; break;; esac
+        done; return 1 ) ||
+       sudo dropbearkey -t dss -s 1024 -f \
+        /etc/initramfs-tools/etc/dropbear/dropbear_dss_host_key
+       mk_dir mod=640 own=root:root \
+        /etc/initramfs-tools/root \
+        /etc/initramfs-tools/root/.ssh
+       getent group sudo |
+       while IFS=: read -r group x x users
+        do while IFS=, read -r user
+                do eval local home\; home="~$user"
+                       cat "$home"/etc/ssh/authorized_keys
+                done <<-EOF
+                       $users
+                       EOF
+        done |
+       mk_reg mod=644 own=root:root /etc/initramfs-tools/root/.ssh/authorized_keys
+       sudo rm -f \
+        /etc/initramfs-tools/root/.ssh/id_rsa.dropbear \
+        /etc/initramfs-tools/root/.ssh/id_rsa.pub \
+        /etc/initramfs-tools/root/.ssh/id_rsa
+        # NOTE: clefs générées par Debian
+       sudo update-initramfs -u
+ }
+rule__boot_init () {
+       sudo apt-get install --reinstall grub-pc # XXX: attention à n'installer GRUB sur AUCUN disque proposé !
+       mk_dir mod=644 own=root:root /boot/grub
+       sudo apt-get install --reinstall linux-image-$vm_arch
+       mk_reg mod=644 own=root:root /etc/default/grub <<-EOF
+               GRUB_DEFAULT=0
+               GRUB_TIMEOUT=5
+               GRUB_DISTRIBUTOR=\`lsb_release -i -s 2> /dev/null || echo Debian\`
+               GRUB_CMDLINE_LINUX_DEFAULT="quiet"
+               GRUB_CMDLINE_LINUX="vt.default_utf8=1 rootfstype=ext4 loglevel=5 console=hvc0 ip=$vm_ipv4::$vm_ipv4:255.255.255.254:$vm:eth0:off resume=/dev/mapper/${vm}_swap_deciphered"
+               GRUB_DISABLE_RECOVERY="true"
+               #GRUB_PRELOAD_MODULES="lvm"
+               EOF
+       mk_reg mod=644 own=root:root /boot/grub/device.map <<-EOF
+               (hd0)   /dev/xvda
+               (hd0)   /dev/mapper/domU-$(printf %s $vm_fqdn-disk | sed -e 's/-/--/g')
+               EOF
+       sudo update-grub2 # NOTE: prend en compte /boot/grub/device.map
+       rule__initramfs_init
+ }
+rule__bin_init () {
+       mk_lnk "$tool"/vm_hosted /usr/local/sbin/
+ }
+rule_init () {
+       rule__etckeeper_init
+       rule__locale_init
+       rule__network_init
+       rule__apt_init
+       rule__filesystem_init
+       rule__login_init
+       rule__user_root_init
+       rule__boot_init
+       rule__bin_init
+ }
+
+rule_disk_key_change () {
+       sudo cryptsetup luksChangeKey /dev/$vm_lvm_vg/${vm_lvm_lv}_root
+ }
+
+rule_user_init () {
+       mk_dir mod=750 own="root:adm" /etc/skel/etc
+       mk_dir mod=770 own="root:adm" /etc/skel/etc/apache2
+       mk_dir mod=770 own="root:adm" /etc/skel/etc/ssh
+       mk_dir mod=700 own="root:adm" /etc/skel/var
+       mk_dir mod=700 own="root:adm" /etc/skel/var/log
+       mk_dir mod=700 own="root:adm" /etc/skel/var/cache
+       mk_dir mod=700 own="root:adm" /etc/skel/var/cache/ssh
+       mk_dir mod=700 own="root:adm" /etc/skel/tmp
+       mk_dir mod=700 own="root:adm" /etc/skel/tmp
+       mk_lnk etc/ssh                /etc/skel/.ssh
+       mk_lnk etc/gpg                /etc/skel/.gnupg
+       ssh-keygen -F "$vm_fqdn" -f "$tool"/key/ssh.known_hosts |
+       ( while IFS= read -r line
+        do case $line in (*" RSA") return 0; break;; esac
+        done; return 1 ) ||
+       sudo ssh-keygen -t rsa -b 4096 -N '' -f /etc/ssh/ssh_host_rsa_key
+       sudo rm -f \
+        /etc/ssh/ssh_host_dsa_key \
+        /etc/ssh/ssh_host_dsa_key.pub \
+        /etc/ssh/ssh_host_ecdsa_key \
+        /etc/ssh/ssh_host_ecdsa_key.pub
+        # NOTE: clefs générées par Debian
+       mk_reg mod=664 own=root:root  /etc/ssh/sshd_config <<-EOF
+               Port 22
+               ListenAddress $vm_ipv4
+               #ListenAddress ::
+               Protocol 2
+               Compression yes
+               HostKey /etc/ssh/ssh_host_rsa_key
+               UsePrivilegeSeparation yes
+               KeyRegenerationInterval 3600
+               ServerKeyBits 768
+               SyslogFacility AUTH
+               LogLevel INFO
+               LoginGraceTime 120
+               PermitRootLogin yes
+               StrictModes yes
+               RSAAuthentication yes
+               PubkeyAuthentication yes
+               AuthorizedKeysFile %h/etc/ssh/authorized_keys
+               IgnoreRhosts yes
+               RhostsRSAAuthentication no
+               HostbasedAuthentication no
+               IgnoreUserKnownHosts no
+               PermitEmptyPasswords no
+               ChallengeResponseAuthentication no
+               PasswordAuthentication no
+               KerberosAuthentication no
+               GSSAPIAuthentication no
+               X11Forwarding no
+               X11DisplayOffset 10
+               PrintMotd no
+               DebianBanner no
+               PrintLastLog yes
+               TCPKeepAlive yes
+               ClientAliveInterval 0
+               AcceptEnv LANG LC_*
+               Subsystem sftp /usr/lib/openssh/sftp-server
+               UsePAM yes
+               EOF
+       sudo service ssh restart
+       mk_reg mod=440 own=root:root /etc/sudoers.d/passwd-init <<-EOF
+               %sudo ALL=(ALL) NOPASSWD: /bin/sh -e -f -u -c \\
+                 case \$(/usr/bin/passwd --status "\$SUDO_USER") in \\
+                   ("\$SUDO_USER L "*) /usr/bin/passwd \$SUDO_USER;; esac
+               EOF
+       mk_reg mod=440 own=root:root /etc/sudoers.d/etckeeper-unclean <<-EOF
+               %sudo ALL=(ALL) NOPASSWD: /usr/sbin/etckeeper unclean
+               EOF
+       mk_reg mod=440 own=root:root /etc/sudoers.d/env_keep <<-EOF
+               Defaults env_keep = " \\
+                 EDITOR \\
+                 GIT_AUTHOR_NAME \\
+                 GIT_AUTHOR_EMAIL \\
+                 GIT_COMMITTER_NAME \\
+                 GIT_COMMITTER_EMAIL \\
+                "
+               EOF
+       mk_reg mod=555 own=root:root /usr/local/sbin/passwd-init <<-EOF
+               #!/bin/sh
+               sudo /bin/sh -e -f -u -c \
+                 'case \$(/usr/bin/passwd --status "\$SUDO_USER") in ("\$SUDO_USER L "*) /usr/bin/passwd \$SUDO_USER;; esac'
+               EOF
+ }
+rule_user_admin_add () { # SYNTAX: $user
+       local user=$1
+       id "$user" >/dev/null ||
+       sudo adduser --disabled-password "$user"
+               # NOTE: le mot-de-passe doit être initialisé par l'utilisateur à l'aide de passwd-init .
+       eval local home\; home="~$user"
+       sudo adduser "$user" sudo
+       ssh_key_add user=$user "$tool"/key/"$user".ssh.pub "$home"/etc/ssh/authorized_keys
+       rule__initramfs_init
+       rule__user_root_init
+       sudo gpg --import "$tool"/key/"$user".gpg.pub
+ }
+rule_user_mail_format () {
+       mk_dir mod=770 own=root:adm /etc/skel/etc/procmail
+       mk_dir mod=770 own=root:adm /etc/skel/var/mail
+       mk_dir mod=770 own=root:adm /etc/skel/var/cache/procmail
+       mk_reg mod=660 own=root:adm /etc/skel/etc/procmail/delivery.rc <<-EOF
+               # vim: ft=procmail
+               
+               # NOTE: paramètres passés par postfix
+               SENDER=\$1
+               RECIPIENT=\$2
+               USER=\$3
+               EXTENSION=\$4
+               DOMAIN=\$5
+               ORIGINAL_RECIPIENT=\$6
+               
+               PATH="\$HOME/bin:/usr/local/bin:/usr/bin:/bin"
+               MAILDIR="\$HOME/var/mail/"
+               DEFAULT="\$MAILDIR"
+               #LOGFILE=`cd="\$HOME/var/log/procmail/" d=\$(date +"%Y-%m-%d"); ln -fns "\$d.log" "\$cd/current.log"; printf %s "\$cd/\$d.log"`
+               LOGFILE="/dev/null"
+               LOGABSTRACT=all
+               LOGABSTRACT
+               VERBOSE
+               SHELL=/bin/sh
+               SHELLMETAS=&|<>~;?*%{}
+               
+               # DESCRIPTION: supprime les doublons en fonction du champ Message-Id
+               #:0 Wh:            "\$HOME/var/cache/procmail/msgid\$LOCKEXT"
+               #| formail -D 8192 "\$HOME/var/cache/procmail/msgid"
+               
+               # DESCRIPTION: fait suivre à l'adresse configurée dans /etc/passwd ; on peut aussi utiliser ~/.forward
+               EMAIL=`sed /etc/passwd -ne "/^\$USER:/s/[^:]*:[^:]*:[^:]*:[^:]*:[^,]*,[^,]*,[^,]*,[^,]*,\([^:]*\):.*/\1/p"`
+                # NOTE: récupère l’adresse courriel dans le champ GECOS
+               FROM_=`formail -c -x "From " | sed -e 's/^\s*\([^ \t]*\).*/\1/g'`
+                # NOTE: récupère l’expéditeur inscrit sur l’enveloppe
+               :0
+               | \$SENDMAIL -i -bm -f "\$FROM_" "\${EMAIL/@/\${EXTENSION:++\${EXTENSION}}@}"
+               
+               # DESCRIPTION: IMAP
+               #:0
+               #| /usr/lib/dovecot/deliver -f "\$SENDER" -a "\$RECIPIENT"
+               
+               # DESCRIPTION: UUCP
+               #:0
+               #| /usr/bin/uux \
+               # -I "\$HOME/etc/uucp/uucp.cfg" \
+               # --nouucico \
+               # --notification=error \
+               # --requestor "\$USER" \
+               # - "\$USER!rmail" "(\$USER)"
+               EOF
+       mk_reg mod=664 own=root:root /etc/postfix/main.cf <<-EOF
+               # /etc/postfix/main.cf
+               # SEE: http://postfix.traduc.org/index.php/TLS_README.html
+               
+               parent_domain_matches_subdomains =
+                       #debug_peer_list
+                       #fast_flush_domains
+                       #mynetworks
+                       #permit_mx_backup_networks
+                       #qmqpd_authorized_clients
+                       #smtpd_access_maps
+               mydomain                         = $vm_domainname
+               myorigin                         = \$mydomain
+               myhostname                       = $vm_hostname.\$mydomain
+               mail_name                        = \$myhostname
+               mydestination                    =
+                       $vm_hostname
+                       \$myhostname
+                       \$myorigin
+               mynetworks                       =
+                       127.0.0.0/8
+                       #[::1]/128
+               inet_protocols = ipv4
+                       # "all" to activate IPv6
+               inet_interfaces                  = all
+               permit_mx_backup_networks        =
+               
+               alias_database         =
+                       hash:/etc/aliases
+                       # NOTE: fichier de hash contenant une table d’alias mail.
+                       #       Celle-ci est éditable dans /etc/aliases, puis (indispensable)
+                       #       regénérée en hash grâce à la commande newaliases qui produit /etc/aliases.db
+               alias_maps             =
+                       hash:/etc/aliases
+               recipient_delimiter    = +
+                       # NOTE: séparateur entre le nom d’utilisateur
+                       #       et les extensions d’adresse (par défaut le signe +).
+               #virtual_alias_domains  =
+               virtual_alias_maps     =
+                       hash:/etc/postfix/\$mydomain/virtual
+                       # NOTE: do not specify virtual alias domain names in  the  main.cf
+                       #       mydestination or relay_domains configuration parameters.
+                       #
+                       # With  a  virtual  alias  domain,  the  Postfix SMTP server
+                       # accepts  mail  for  known-user@virtual-alias.domain,   and
+                       # rejects   mail  for  unknown-user@virtual-alias.domain  as
+                       # undeliverable.
+               #relayhost              =
+               relay_clientcerts      =
+                       hash:/etc/postfix/\$mydomain/smtpd/tls/relay_clientcerts
+               relay_domains          =
+                       \$mydestination
+                               # NOTE: ajouter les domaines pour lesquels on est backup MX ici,
+                               #       pas dans mydestination ou virtual_alias...
+               
+               maximal_queue_lifetime = 5d
+               
+               header_checks        =
+                       regexp:/etc/postfix/\$mydomain/header_checks
+               mime_header_checks   =
+               nested_header_checks =
+               milter_header_checks =
+               body_checks          =
+               
+               #content_filter               = amavisfeed:[127.0.0.1]:10024
+               #receive_override_options     = no_address_mappings
+                       # no_unknown_recipient_checks
+                       #         Do not try to reject unknown recipients (SMTP server only).
+                       #         This is typically specified AFTER an external content filter.
+                       # no_address_mappings
+                       #         Disable canonical address mapping, virtual alias map expansion,
+                       #         address masquerading, and automatic BCC (blind carbon-copy) recipients.
+                       #         This is typically specified BEFORE an external content filter (eg. amavis).
+                       # no_header_body_checks
+                       #         Disable header/body_checks. This is typically specified AFTER an external content filter.
+                       # no_milters
+                       #         Disable Milter (mail filter) applications. This is typically specified AFTER an external content filter.
+               #local_header_rewrite_clients =
+               transport_maps                =
+                       hash:/etc/postfix/\$mydomain/transport_maps
+               mailbox_command               =
+                       /usr/bin/procmail -t -a "\$SENDER" -a "\$RECIPIENT" -a "\$USER" -a "\$EXTENSION" -a "\$DOMAIN" -a "\$ORIGINAL_RECIPIENT" "\$HOME/etc/procmail/delivery.rc"
+               mailbox_size_limit            = 0
+               biff                          = no
+                       # Activer la notification en cas de réception de nouveaux e-mails dans la console (yes / no).
+               append_dot_mydomain           = no
+                       # appending .domain is the MUA's job.
+               
+               #tls_random_source             =
+               #       dev:/dev/urandom
+                       # Non-blocking
+               #tls_random_reseed_period      = 3600s
+               #tls_random_exchange_name      =
+               #       \${data_directory}/prng_exch
+                       # NOTE: à ne pas mettre dans la cage chroot
+               #tls_random_bytes              = 32
+               #tls_random_prng_update_period = 3600s
+               #tls_high_cipherlist           = AES256-SHA
+                       # NOTE: postconf(5) déconseille de changer ceci
+               
+               #smtp_cname_overrides_servername = no
+               smtp_connect_timeout            = 60s
+               #smtp_tls_CAfile                 = /etc/postfix/\$mydomain/smtp/tls/ca/crt.pem
+               #smtp_tls_CApath                 = /etc/postfix/\$mydomain/smtp/tls/ca/
+               #smtp_tls_cert_file              = /etc/postfix/\$mydomain/smtp/tls/crt.pem
+               #smtp_tls_key_file               = /etc/postfix/\$mydomain/smtp/tls/key.pem
+               #smtp_tls_per_site               = hash:/etc/postfix/\$mydomain/smtp/tls/per_site
+                       # NOTE: déprécié en faveur de smtp_tls_policy_maps
+               smtp_tls_policy_maps            = hash:/etc/postfix/\$mydomain/smtp/tls/policy
+               smtp_tls_fingerprint_digest     = sha1
+               smtp_tls_scert_verifydepth      = 5
+               #smtp_tls_secure_cert_match      = nexthop, dot-nexthop
+               #smtp_tls_verify_cert_match      = hostname
+               #smtp_tls_note_starttls_offer    = yes
+               smtp_tls_loglevel               = 1
+               smtp_tls_protocols              = !SSLv2, !SSLv3
+                       # Only allow TLSv*
+               smtp_tls_session_cache_database = btree:/var/lib/postfix/smtp_tls_session_cache
+               #smtp_tls_session_cache_timeout  = 3600s
+               smtp_tls_security_level         = may
+               smtp_header_checks              = regexp:/etc/postfix/\$mydomain/smtp/header_checks
+               smtp_body_checks                =
+               smtp_mime_header_checks         =
+               smtp_nested_header_checks       =
+               
+               smtpd_starttls_timeout                  = 300s
+               smtpd_banner                            =
+                \$myhostname ESMTP \$mail_name (Debian/GNU)
+               
+               # Restrictions
+               smtpd_helo_required             = yes
+               strict_rfc821_envelopes         = yes
+               smtpd_authorized_xclient_hosts  = 127.0.0.1
+                       # NOTE: utile pour tester les restrictions
+               
+               smtpd_helo_restrictions         =
+                       reject_invalid_helo_hostname
+                       reject_non_fqdn_helo_hostname
+                       #reject_unknown_helo_hostname
+                               # NOTE: pourrait pourtant être utile pour lutter contre le spam
+                       permit
+               
+               smtpd_sender_restrictions       =
+                       permit_mynetworks
+                       permit_tls_clientcerts
+                       permit_sasl_authenticated
+                       check_sender_access hash:/etc/postfix/\$mydomain/smtpd/sender_access
+                       check_sender_access hash:/etc/postfix/sender_blacklist
+                       reject_unauth_pipelining
+                       reject_non_fqdn_sender
+                       #reject_unknown_sender_domain
+                               # NOTE: temporaire
+                       permit
+               
+               smtpd_client_new_tls_session_rate_limit = 0
+               smtpd_client_event_limit_exceptions     = \$mynetworks
+               smtpd_client_recipient_rate_limit       = 0
+               smtpd_client_connection_count_limit     = 50
+               smtpd_client_connection_rate_limit      = 0
+               smtpd_client_message_rate_limit         = 0
+               smtpd_client_port_logging               = no
+               
+               smtpd_client_restrictions               =
+                       check_client_access hash:/etc/postfix/client_blacklist
+               
+               policy_time_limit                       = 3600
+               default_extra_recipient_limit           = 5000
+               duplicate_filter_limit                  = 5000
+               smtpd_recipient_limit                   = 5000
+               smtpd_recipient_overshoot_limit         = 5000
+               smtpd_recipient_restrictions            =
+                       reject_non_fqdn_recipient
+                       #reject_invalid_hostname
+                               # NOTE: postfix < 2.3. voir reject_invalid_helo_hostname
+                               #       dans smtpd_helo_restrictions
+                       reject_unknown_recipient_domain
+                       #reject_non_fqdn_sender
+                               # NOTE: dans smtpd_sender_restrictions
+                       reject_unauth_pipelining
+                               # NOTE: dans smtpd_client_restrictions ou smtpd_data_restrictions
+                       permit_mynetworks
+                       permit_tls_clientcerts
+                       permit_sasl_authenticated
+                       reject_unauth_destination
+                               # NOTE: ne pas passer par SPFCheck / Postgrey si le mail n'est pas pour nous
+                               #       ou quelqu'un pour lequel on tient lieu de backup_mx
+                       check_policy_service inet:127.0.0.1:10023
+                               # NOTE: Postgrey (greylisting)
+                       check_policy_service unix:private/spfcheck
+                       permit_auth_destination
+                               # NOTE: une fois Postgrey passé, on accepte ce qui nous est destiné
+                               #       (voir permit_auth_destination) ; sans doute redondant
+                       reject
+                       #check_relay_domains <- removed from postfix
+                       #reject_unknown_sender_domain
+                               # aurait probablement été mieux dans smtpd_sender_restrictions
+                       #reject_rbl_client bl.spamcop.net
+                       #reject_rbl_client list.dsbl.org
+                       #reject_rbl_client zen.spamhaus.org
+                       #reject_rbl_client dnsbl.sorbs.net
+               
+               smtpd_data_restrictions                 =
+                       reject_unauth_pipelining
+                               # NOTE: obliger le serveur en face à attendre qu'on lui aie dit OK
+                       permit
+               
+               #smtpd_end_of_data_restrictions          =
+               
+               #smtpd_restriction_classes               =
+               
+               smtpd_error_sleep_time                  = 5
+                       # NOTE: forcer quelqu'un qui nous embête à attendre cinq secondes.
+               
+               # SASL
+               smtpd_sasl_auth_enable                  = yes
+               smtpd_sasl_type                         = dovecot
+               smtpd_sasl_path                         = private/auth
+               smtpd_sasl_security_options             = noanonymous
+               smtpd_sasl_domain                       = \$mydomain
+               
+               # SMTPD TLS
+               smtpd_discard_ehlo_keywords             = starttls
+                       # NOTE: les clients mails tentant d'utiliser le chiffrement opportuniste
+                       #       se mangent une erreur en tentant un starttls
+               smtpd_tls_fingerprint_digest            = sha1
+                       # sha512 ?
+               smtpd_tls_mandatory_protocols           = TLSv1
+               smtpd_tls_mandatory_ciphers             = high
+               smtpd_tls_ciphers                       = high
+                       # restrictif. s/high/medium/ ?
+               smtpd_tls_CAfile                        = /etc/postfix/\$mydomain/smtpd/tls/ca/crt+crl.slf.pem
+               smtpd_tls_CApath                        = /etc/postfix/\$mydomain/smtpd/tls/ca/
+               smtpd_tls_cert_file                     = /etc/postfix/\$mydomain/smtpd/tls/crt+crl.slf.pem
+               smtpd_tls_key_file                      = /etc/postfix/\$mydomain/smtpd/tls/key.pem
+               ##
+               #smtpd_tls_received_header               = no
+               smtpd_tls_session_cache_database        =
+                       btree:/var/lib/postfix/smtpd_tls_session_cache
+               #smtpd_tls_session_cache_timeout         = 3600s
+               smtpd_tls_security_level                = may
+                       # Postfix 2.3 and later
+                       # encrypt
+                       #  Mandatory TLS encryption: announce STARTTLS support to SMTP clients, and require that clients use TLS
+                       #  encryption. According to [1720]RFC 2487 this MUST NOT be applied in case of a publicly-referenced
+                       #  SMTP server. Instead, this option should be used only on dedicated servers.
+               smtpd_tls_loglevel                      = 1
+               smtpd_tls_ccert_verifydepth             = 5
+               smtpd_tls_auth_only                     = yes
+                       # Pas d'AUTH SASL sans TLS
+               smtpd_tls_ask_ccert                     = no
+               smtpd_tls_req_ccert                     = no
+               #smtpd_tls_always_issue_session_ids      = yes
+               smtpd_peername_lookup                   = yes
+                       # Nécessaire pour postgrey, etc
+               smtpd_milters                           =
+               non_smtpd_milters                       =
+               line_length_limit                       = 2048
+               queue_minfree                           = 0
+               message_size_limit                      = 20480000
+               #smtpd_enforce_tls    # NOTE: obsolète
+               #smtpd_use_tls        # NOTE: obsolète
+               #smtpd_tls_cipherlist # NOTE: obsolète
+               
+               readme_directory   = no
+               #delay_warning_time = 4h
+                       # NOTE: uncomment the previous line to generate "delayed mail" warnings
+               #debug_peer_level   = 4
+               #debug_peer_list    = .\$myhostname
+               EOF
+       mk_reg mod=664 own=root:root /etc/dovecot/dovecot.conf <<-EOF
+               auth_ssl_username_from_cert = yes
+               listen = *
+               log_timestamp = "%Y-%m-%d %H:%M:%S "
+               mail_debug = yes
+               mail_location = maildir:~/var/mail
+               mail_privileged_group = mail
+               passdb {
+                 args = /home/%u/etc/dovecot/passwd
+                 driver = passwd-file
+               }
+               protocols = imap
+               service auth {
+                 unix_listener /var/spool/postfix/private/auth {
+                   group = postfix
+                   mode = 0660
+                   user = postfix
+                 }
+                 user = root
+               }
+               ssl_ca = </etc/dovecot/imap/tls/crt+crl.slf.pem
+               ssl_cert = </etc/dovecot/imap/tls/crt+crl.slf.pem
+               ssl_cipher_list = AES256-SHA
+               ssl_key = </etc/dovecot/imap/tls/key.pem
+               ssl_verify_client_cert = yes
+               userdb {
+                 driver = passwd
+               }
+               verbose_ssl = yes
+               protocol lda {
+                 auth_socket_path = /var/run/dovecot/auth-master
+                 hostname = $vm_domainname
+                 info_log_path = /var/log/dovecot/lda/info.log
+                 log_path = /var/log/dovecot/lda/error.log
+                 mail_plugins = sieve
+                 postmaster_address = contact+dovecot+lda@$vm_domainname
+               }
+               EOF
+       mk_reg mod=664 own=root:root /etc/postgrey/whitelist_recipients.local <<-EOF
+               EOF
+ }
+rule_mail_install () {
+       sudo apt-get install postfix postgrey dovecot
+ }
+
+rule=${1:-help}
+${1+shift}
+set "${TRACE:+-x}"
+rule_$rule "$@"
diff --git a/vm_remote b/vm_remote
new file mode 100755 (executable)
index 0000000..8518503
--- /dev/null
+++ b/vm_remote
@@ -0,0 +1,81 @@
+#!/bin/sh
+set -e -f ${DRY_RUN:+-n} -u
+tool=${0%/*}
+. "$tool"/functions.sh
+. "$tool"/vm.sh
+test ! "$(hostname --fqdn)" = "$vm_fqdn"
+test ! "$(hostname --fqdn)" = "$vm_host"
+
+rule_help () {
+       cat >&2 <<-EOF
+               DESCRIPTION: ce script regroupe des fonctions utilitaires
+                            pour gérer la VM _depuis_ une machine distante ;
+                            il sert à la fois d'outil et de documentation.
+                            Voir \`$tool/vm_host'   pour les utilitaires côté machine hôte.
+                            Voir \`$tool/vm_hosted' pour les utilitaires côté VM hébergée.
+               SYNTAX: $0 \$RULE \${RULE}_SYNTAX
+               RULES:
+               $(sed -ne 's/^rule_\([^_][^ ]*\) () {\( *#.*\|\)/\t\1\2/p' "$tool"/vm.sh "$0")
+               ENVIRONMENT:
+                 TRACE # affiche les commandes avant leur exécution
+               $(sed -ne 's/^readonly \([^ ][^ =]*\).*}\( *#.*\|\)$/\t$\1\2/p' "$tool"/vm.sh "$0")
+               EOF
+ }
+
+rule_git_config () {
+       (
+       cd "$tool"
+       git config remote.host.url >/dev/null ||
+       git remote add host $vm_host:tool/vm
+       git config --replace remote.host HEAD:refs/heads/origin
+       git config remote.$vm.url >/dev/null ||
+       git remote add vm root@$vm_fqdn:tool/vm
+       git config --replace remote.$vm HEAD:refs/heads/origin
+       )
+ }
+rule_git_push () { # SYNTAX: $remote $options
+       local remote=${1#remote=}; shift
+       git add . &&
+       git commit -a -C HEAD "$@" &&
+       local pwd=$(cd "$tool" && cd -)
+       GIT_SSH=./vm_ssh git push -v -f "$remote"
+ }
+
+rule_ssh () {
+       "$tool"/vm_ssh $vm_fqdn "$@"
+ }
+rule__ssh_known_hosts_update () {
+       "$tool"/vm_ssh $vm_fqdn "$@" \
+        -o StrictHostKeyChecking=no \
+        -o CheckHostIP=no \
+        -o HashKnownHosts=no \
+        whoami
+ }
+rule_disk_key_send () {
+       gpg --decrypt key/secret/$vm_fqdn.disk.gpg |
+       ssh "$@" root@$vm_fqdn \
+        -o CheckHostIP=no \
+        -o HostKeyAlias=init.$vm_fqdn \
+        -o StrictHostKeyChecking=yes \
+        -o UserKnownHostsFile="$tool"/key/ssh.known_hosts \
+        tee /lib/cryptsetup/passfifo \>/dev/null
+ }
+rule_disk_key_backup () {
+       for part in root swap var home
+        do
+               rule_ssh sudo cryptsetup luksHeaderBackup /dev/$vm_lvm_vg/${vm_lvm_lv}_${part} |
+               gpg --encrypt --recipient $USER@ -o key/secret/${vm_lvm_lv}_${part}.luks.gpg
+        done
+ }
+rule_disk_key_restore () {
+       for part in root swap var home
+        do
+               gpg --decrypt ${vm_lvm_lv}_${part}.luks |
+               rule_ssh sudo cryptsetup luksHeaderRestore /dev/$vm_lvm_vg/${vm_lvm_lv}_${part}
+        done
+ }
+
+rule=${1:-help}
+${1+shift}
+set "${TRACE:+-x}"
+rule_$rule "$@"
diff --git a/vm_ssh b/vm_ssh
new file mode 100755 (executable)
index 0000000..d1c0c51
--- /dev/null
+++ b/vm_ssh
@@ -0,0 +1,7 @@
+#!/bin/sh
+set -e -f ${DRY_RUN:+-n} -u
+tool=${0%/*}
+ssh \
+ -o StrictHostKeyChecking=yes \
+ -o UserKnownHostsFile="$tool"/key/ssh.known_hosts \
+ "$@"
diff --git a/workflow.txt b/workflow.txt
deleted file mode 100644 (file)
index e9cd3a3..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-% export TRACE=1
-% ./ateliers_host disk_mount
-% ./ateliers_host disk_format
-% ./ateliers_host part_lvm_format
-% ./ateliers_host part_root_format
-% ./ateliers_host part_boot_format
-% ./ateliers_host part_swap_format
-% ./ateliers_host part_var_format
-% ./ateliers_host part_home_format