--- /dev/null
+#!/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 "$@"
--- /dev/null
+#!/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 "$@"