J'arrive enfin à créer une image machine de l'installeur Debian automatiquement, sans qu'aucune clé ou mot de passe ne transite par le réseau ni dans le Nuage, et sans utiliser les ec2-api-tools, qui ne sont pas libre. Merci à Eucalyptus pour avoir implémenté l'attribut InstanceInitiatedShutdownBehavior dans euca2ools 2.1.2.

En résumé, je démarre une micro-instance avec un volume supplémentaire, et je lui passe un script via cloud-init, qui va télécharger l'Installeur Debian sur ce volume et éteindre la micro instance. Ensuite, j'enregistre ce volume comme image machine.

Ces images machines de l'Installeur sont faites pour être pré-configurées via les métadonnées d'instance pour installer Debian sur un autre volume. Je bute encore sur cette pré-configuration. Plus de détails dans un prochain article. En attendant, voici les commandes que j'utilise.

Depuis l'ordinateur local, lancer une instance sur le Nuage. J'utilise une image Ubuntu en attendant que #696595 soit réglé et que cloud-init soit installé par défaut sur les images Debian.

HELPER_AMI=ami-7609bb77 # Ubuntu 12.04 LTS Precise amd64 EBS in (Asie Nord-Est)

On démarre l'instance avec un volume supplémentaire de 1 GiB qui persistera après l'extinction de l'instance (/dev/sdb=:1:false). On lui passe le script debigen-install-installer-cloud (voir plus bas).

HELPER_INSTANCE=$( euca-run-instances \
        --instance-initiated-shutdown-behavior terminate \
        --instance-type t1.micro \
        --block-device-mapping /dev/sdb=:1:false \
        --user-data-file debigen-install-installer-cloud \
        $HELPER_AMI |
        tee /dev/stderr | grep INSTANCE | awk '{print $2}')

On attend que le démarrage soit fini.

while [ ! $(euca-describe-instances $HELPER_INSTANCE | grep INSTANCE | cut -f 6 | tee /dev/stderr) = "running" ]
    do sleep 30
done

On récupère le numéro du volume persistant.

TARGET_VOLUME=$( euca-describe-volumes |
        grep $HELPER_INSTANCE | grep '/dev/sdb' |
        tee /dev/stderr | awk '{print $2}')

On attend que le script termine l'instance.

while [ ! $(euca-describe-instances $HELPER_INSTANCE | grep INSTANCE | cut -f 6 | tee /dev/stderr) = "terminated" ]
    do sleep 30
done

Et enfin, on enregistre une image à partir d'un instantané du volume.

PV_KERNEL=aki-44992845 # Démarre PV-Grub sur hd0 (Asie Nord-Est)

TARGET_SNAPSHOT=$( euca-create-snapshot $TARGET_VOLUME |
        tee /dev/stderr | awk '{print $2}')

while euca-describe-snapshots $TARGET_SNAPSHOT | grep -q pending ; do sleep 30 ; done

euca-register \
    --name test_di \
    --description test_of_debian_installer \
    --snapshot $TARGET_SNAPSHOT \
    --kernel $PV_KERNEL \
    --architecture x86_64

Voici le script appelé debigen-install-installer-cloud, lancé plus haut.

#!/bin/sh -ex

mke2fs -L debian-installer /dev/xvdb -F
mount LABEL=debian-installer /mnt/

cd /mnt

ARCH=amd64
DIST=squeeze
DI_VERSION=20110106+squeeze4+b2
MIRROR=jp
BASEURL=http://ftp.$MIRROR.debian.org/debian/dists/$DIST/main/installer-$ARCH/$DI_VERSION/images/netboot/xen

wget $BASEURL/initrd.gz $BASEURL/vmlinuz

mkdir -p boot/grub

cat > boot/grub/menu.lst <<__END__
default 0
timeout 3

title  Debian Installer ($DI_VERSION $ARCH)
root   (hd0)
kernel /vmlinuz root=LABEL=debian-installer ro console=hvc0 auto=true priority=critical url=http://169.254.169.254/latest/user-data DEBIAN_FRONTEND=text
initrd /initrd.gz
__END__

sleep 30

halt