Ajout : ateliers_host{,ed} : premier jet du cadre de travail.
authorJulien Moutinho <julm+burette@autogeree.net>
Tue, 12 Feb 2013 08:50:57 +0000 (09:50 +0100)
committerJulien Moutinho <julm+burette@autogeree.net>
Tue, 12 Feb 2013 08:54:18 +0000 (09:54 +0100)
ateliers_host [new file with mode: 0755]
ateliers_hosted [new file with mode: 0755]
env.sh [new file with mode: 0644]
inc.sh [new file with mode: 0644]
key/julm.ssh.pub [new file with mode: 0644]

diff --git a/ateliers_host b/ateliers_host
new file mode 100755 (executable)
index 0000000..2daec2f
--- /dev/null
@@ -0,0 +1,238 @@
+#!/bin/sh
+set -e -f ${DRY_RUN:+-n} -u ${TRACE:+-x}
+ # -e: erreur si une commande non testée échoue.
+ # -f: désactive les jokers dans les chemins.
+ # -u: erreur si une variable non-définie est utilisée.
+ # -x: affiche les commandes exécutées sur la sortie d'erreur standard.
+
+tool=${0%/*}
+. "$tool"/env.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' "$0")
+               ENVIRONMENT:
+               $(sed -ne 's/^readonly \([^ =]*\).*}\( *#.*\|\)$/\t$\1\2/p' "$tool"/env.sh "$0")
+               EOF
+ }
+
+readonly dev_disk="/dev/xvda"
+readonly dev_disk_boot="${dev_disk}1"
+readonly dev_disk_swap="${dev_disk}5"
+readonly dev_disk_root="${dev_disk}6"
+readonly dev_disk_var="${dev_disk}7"
+readonly dev_disk_home="${dev_disk}8"
+
+rule_xen_config_init () {
+       tee /etc/xen/$vm_fqdn.cfg <<-EOF
+               #  -*- mode: python; -*-
+               import os, re
+               name         = "$vm"
+               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 () {
+ # Montage du disque de la VM depuis l'hôte
+       test ! -e $vm_dev_disk
+       sudo xm block-attach 0 phy:/dev/domU/$vm_fqdn-disk $vm_dev_disk w
+ }
+rule_disk_unmount () {
+       # Démontage du disque de la VM depuis l'hôte
+       test -e $vm_dev_disk
+       ! mountpoint /mnt/$vm_fqdn
+       sudo xm block-detach 0 $vm_dev_disk
+ }
+rule_disk_part () {
+ # Partitionage du disque de la VM
+ # NOTE: on fait le choix de ne pas utiliser LVM sur la machine virtuelle car :
+ # - pour l'extension de mémoire:
+ #   1. on créera une nouvelle partition sur le LVM de l'hôte
+ #   2. on l'ajoutera comme un disque supplémentaire dans /etc/xen/$vm_fqdn.cfg
+ #   3. on le montera sur /home2 en pensant à changer DHOME=/home2 dans /etc/adduser.conf
+ # - pour la sauvegarde: LVM snapshoot est trop 
+ #   1. sauvegarde au niveau applicatif (pgdump, mysqldump)
+ #   2. sauvegarde des configurations (etckeeper, git)
+ #   3. sauvegarde incrémentale et chiffrée des autres fichiers (duplicity)
+ # NOTE: 
+       sudo sfdisk -d $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
+ }
+
+rule_boot_format () {
+       mount | grep -q "^$vm_dev_disk_boot "
+       sudo mkfs.ext2 -m 0 -T small -L "boot" $vm_dev_disk_boot
+ }
+rule_boot_mount () {
+       ! mountpoint /mnt/$vm_fqdn/boot
+       sudo mount -v $vm_dev_disk_boot /mnt/$vm_fqdn/boot
+ }
+rule_boot_unmount () {
+       mountpoint /mnt/$vm_fqdn/boot
+       sudo unmount -v /mnt/$vm_fqdn/boot
+ }
+
+rule_part_clean () {
+ # NOTE: long, optionnel
+ # Déjà fait à la main histoire de pouvoir créer la machine virtuelle plus 
+ # rapidement le jour venu.
+       part=$1
+       eval "sudo dd if=/dev/urandom of=\$vm_dev_disk_$part"
+ }
+rule_part_clean_stat () {
+ # USE: exécuter cette fonction dans un shell distinct de rule_part_clean()
+ # lui fait afficher sa progression.
+       part=$1
+       eval "pkill -USR1 -f \"^dd if=/dev/urandom of=\$vm_dev_disk_$part\""
+ }
+rule_part_format_root () {
+ # DECRIPTION: Formatage de /
+       part="root"
+       eval dev="\$vm_dev_disk_$part"
+       sudo cryptsetup luksFormat --hash=sha512 --key-size=512 --key-file=- \
+        --cipher=aes-xts-essiv:sha256 --align-payload=8 $dev
+       sudo cryptsetup luksOpen --key-file=- $dev ${vm}_${part}_deciphered
+       sudo mkfs.ext4 -m 5 -T ext4 -L ${vm}_$part -E stripe_width=32,resize=15G \
+        /dev/mapper/${vm}_${part}_deciphered
+ }
+rule_format_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.
+       part=$1
+       eval dev="\$vm_dev_disk_$part"
+       test -e /dev/mapper/${vm}_root_deciphered
+       sudo /lib/cryptsetup/scripts/decrypt_derived ${vm}_root_deciphered |
+       sudo cryptsetup luksFormat --key-file=- --hash=sha512 --key-size=512 --cipher=aes-xts-essiv:sha256 $dev
+ }
+rule_mount_part () {
+       part=$1
+       eval dev="\$vm_dev_disk_$part"
+       test -e /dev/mapper/${vm}_root_deciphered
+       sudo /lib/cryptsetup/scripts/decrypt_derived ${vm}_root_deciphered |
+       sudo cryptsetup luksOpen --key-file=- $dev ${vm}_${part}_deciphered
+ }
+rule_unmount_part () {
+       part=$1
+       eval dev="\$vm_dev_disk_$part"
+       sudo cryptsetup luksClose ${vm}_${part}_deciphered
+ }
+rule_part_format_swap () {
+       part="swap"
+       rule_format_part $part
+       rule_mount_part $part
+       sudo mkswap -f -L ${vm}_swap /dev/mapper/${vm}_${part}_deciphered
+       rule_unmount_part $part
+ }
+rule_part_format_var () {
+       part="var"
+       rule_format_part $part
+       rule_mount_part $part
+       sudo mkfs.ext4 -m 5 -T ext4 -L ${vm}_$part -E stripe_width=32,resize=5G /dev/mapper/${vm}_${part}_deciphered
+       rule_unmount_part $part
+ }
+rule_part_format_home () {
+       part="home"
+       rule_format_part $part
+       rule_mount_part $part
+       sudo mkfs.ext4 -m 5 -T ext4 -L ${vm}_$part -E stripe_width=32,resize=200G /dev/mapper/${vm}_${part}_deciphered
+       rule_unmount_part $part
+ }
+
+rule_install_debian () {
+       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 \
+                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 () {
+       mountpoint /mnt/$vm_fqdn
+       mountpoint /mnt/$vm_fqdn/boot
+       mount --bind /dev /mnt/$vm_fqdn/dev
+       sudo chroot /mnt/$vm_fqdn /bin/bash
+       umount /mnt/$vm_fqdn/dev
+ }
+
+rule=${1:-help}
+${1+shift}
+rule_$rule "$@"
diff --git a/ateliers_hosted b/ateliers_hosted
new file mode 100755 (executable)
index 0000000..306bf2f
--- /dev/null
@@ -0,0 +1,180 @@
+#!/bin/sh
+set -e -f ${DRY_RUN:+-n} -u ${TRACE:+-x}
+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' "$0")
+               ENVIRONMENT:
+               $(sed -ne 's/^readonly \([^ =]*\).*}\( *#.*\|\)$/\t$\1\2/p' "$tool"/env.sh "$0")
+               EOF
+ }
+
+rule_filesystem_mount () {
+       mountpoint /proc ||
+       mount -t proc proc /proc
+       mountpoint /sys ||
+       mount -t sysfs sys /sys
+       mountpoint /dev
+ }
+rule_filesystem_unmount () {
+       ! mountpoint /proc ||
+       umount /proc
+       ! mountpoint /sys ||
+       umount /sys
+ }
+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.local $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,keyscript=/lib/cryptsetup/scripts/decrypt_derived
+               ${vm}_swap_deciphered LABEL=${vm}_swap ${vm}_root_deciphered luks,keyscript=/lib/cryptsetup/scripts/decrypt_derived
+               ${vm}_home_deciphered LABEL=${vm}_home ${vm}_root_deciphered luks,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
+       sed -i /etc/default/grub -e '/^GRUB_CMDLINE_LINUX=/d;r/dev/fd/3' 3<<-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_dir mod=0750 own="$admin:$admin" "$home"/etc
+       mk_dir mod=0700 own="$admin:$admin" "$home"/etc/ssh
+       mk_reg mod=0400 own="$admin:$admin" "$home"/etc/ssh/authorized_keys <"$tool"/key/"$admin".ssh.pub
+ }
+rule_users_init () {
+       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=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}
+rule_$rule "$@"
diff --git a/env.sh b/env.sh
new file mode 100644 (file)
index 0000000..10705fc
--- /dev/null
+++ b/env.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+# DESCRIPTION: ce fichier regroupe les variables propres à la VM
+
+readonly PATH=$PATH:/usr/sbin:/sbin
+readonly vm="ateliers"
+readonly vm_arch="amd64"
+readonly vm_bridge="br-gresille"
+readonly vm_fqdn="$vm.heureux-cyclage.org"
+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 ».
diff --git a/inc.sh b/inc.sh
new file mode 100644 (file)
index 0000000..757fbcb
--- /dev/null
+++ b/inc.sh
@@ -0,0 +1,17 @@
+#!/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
+       mkdir -p "$@"
+       ! [ ${mod:+set} ] || sudo chmod $mod "$@"
+       ! [ ${own:+set} ] || sudo chown $own "$@"
+ }
+mk_reg () {
+       local mod=${1#mod=}; shift
+       local own=${1#own=}; shift
+       tee >/dev/null "$@"
+       ! [ ${mod:+set} ] || sudo chmod $mod "$@"
+       ! [ ${own:+set} ] || sudo chown $own "$@"
+ }
diff --git a/key/julm.ssh.pub b/key/julm.ssh.pub
new file mode 100644 (file)
index 0000000..07774a5
--- /dev/null
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQD5FtR++UPEg/5wFeyb2JSS09idTaDb4tMIRf1yxCsyIJEp5LQMif/fIptDeHoYc55lwy8vnWWN9PJpb6PS8YSaLLFV5tn8esR8Ml+evNCAD52Tdu1kPRXGLCSF5kSVnbAMoxqiNi8vRRKXwAzGgXmIUzDAE4QTsq3EwZM6cBnDx5O79wBIZ9va2TObL52qv+Vpi+QyINuslKKc+Osu92pdwceIGZUcwA6Y8aH6lavaTyDUQdSjMRMTAiXSPRjmHf1q+V7wENXT/TKXuuahN8NnJShX3Qf9hwNEIU46SOENsrRFQ5eYahAmqUIK4GbsERS2KRDxbvSOl7rKh2sauBxyKfkW/gxQ4LAyywxuumpI0pO7XmdINCGWdXS9gD216lcGuH/TC0KboiOVExh65eRIOeEFTec0VJQEqqnFul7u8YNPmbBpLnM+SQ3TAkdQmfasKgPIazFNCAnC8I9hKlGYpLk/Dgi/sVbwFeoOUQcaTBRnWKUCedX4v4kmPIHuHSNPV2C/0770gH2iJ1N1XEO3YDGiixuHHiLlCV8Ko950CoTh1PwDNCd3Qy/jR/QhE2waVPliFwl2+H6IkIxkUO8A9ktLCJUeaZJN3snoV+9hvpT1E2TrEccsTVx5BaGAJCUkvO2XYlEsNceIIitkrbhidjZvfZ4/czGUKoN1wSSpMw== GnuPG pub=F2E027182397AC0775714F2AD15AF7F467E8299B sub=7819E44BAEEDE91683811BB00E1AAADBE227DDAA Julien Moutinho <julm@autogeree.net>