Outils pour utilisateurs

Outils du site


tuto_a20-olinuxino-micro_generation_d_un_rootfs_ubuntu_14.04_minimal_a_l_aide_de_live-build

====== Génération d'un "rootfs" Ubuntu 14.04 minimal a l'aide de live-build pour la carte A20-OLinuXino ====== ---- ===== Introduction ===== Suite a l'article précédent ([[tuto_a20-olinuxino-micro_generation_d_image_a_base_du_noyau_3.4.90_et_de_ubuntu_core|Génération d'image à base du noyau 3.4.90+ et Ubuntu Core pour la carte A20-OLinuXino]]), je vous propose de construire un rootfs Ubuntu 14.04 pour la carte A20-OLinuXino. Bien entendu, cette procedure reste applicable, dans les grands principes, pour les autres cartes basés sur un ARMv7, telle que la Raspberry Pi. Pour la petite histoire, j'en suis venu à devoir me contruire ce rootfs, car bien que la procedure ai fonctionné et que ma carte se soit bien connecté au reseau, il m'etait impossible de me connecter dessus ; Le rootfs Ubuntu Core n'embarque pas de serveur SSH, et je ne possede pas de convertisseur USB-RS232 TTL en 3.3V. Je me suis donc penché sur la generation d'un tel "rootfs". On ne parle plus vraiment de rootfs. dans la mesure ou les outils les generant (rootstock, notamment) sont devenus obseletes ; mais plutot de systemes "Live". Il apparait que dans les fait, pour les systemes debian et derivés, il s'agit toujours d'une surcouche a debootstrap... Comme toujours, vous pouvez retrouver l'integralité du projet sur le GitHub : https://github.com/spelle/Ubuntu-14.04-LTS-ARMHF-Minimal-SSH. Bonne lecture ! ---- ===== Prérequis ===== Sur une distribution *buntu 14.04 LTS Trusty Tahr, il convient d'installer les packages suivants : <code bash> $ sudo apt-get install live-build qemu-system-arm </code> //debootstrap// etant une dependance sera aussi deployé. Il convient aussi d'ajouter les depots //[[http://www.linaro.org|linaro]]// ainsi que le package qemu-user-static : <code bash> $ sudo add-apt-repository ppa:linaro-maintainers/tools $ sudo apt-get update $ sudo apt-get install qemu-user-static </code> Afin de travailler de maniere organisée, il est possible de se mettre à l'aise dans un espace de travail. Tout le monde travaillant selon sa methode, cette etape est facultative : <code bash> $ cd Workspaces $ mkdir workspace-Olimex $ cd worspace-Olimex $ mkdir Ubuntu-14.04-LTS-ARMHF-Minimal-SSH $ cd Ubuntu-14.04-LTS-ARMHF-Minimal-SSH </code> le retour de la commande "pwd" devrait donner ceci : <code bash> $ pwd /home/<user>/Workspaces/workspace-Olimex/Ubuntu-14.04-LTS-ARMHF-Minimal-SSH </code> Il peut etre utile pour la suite de se placer en tant que super-utilisateur. <code bash> $ sudo su </code> ---- ===== Image minimale ===== Donc pour commencer, et à la vue de ce qui se fait par ailleurs, puisque la génération se fait en deux etapes, le "//lb_config//" suivi du "//lb_build//", nous allons créer un fichier "configure" avec le code suivant : <file bash configure> #!/bin/sh set -e echo "I: create configuration" export LB_BOOTSTRAP_INCLUDE="apt-transport-https gnupg" lb config \ --apt-indices none \ --apt-secure false \ --architectures armhf \ --archive-areas 'main universe' \ --binary-filesystem ext3 \ --binary-images tar \ --bootappend-live "hostname=a20-olinuxino username=olimex" \ --bootstrap-qemu-arch armhf \ --bootstrap-qemu-static /usr/bin/qemu-arm-static \ --cache false \ --chroot-filesystem none \ --compression gzip \ --bootstrap-flavour minimal \ --distribution trusty \ --gzip-options '-9 --rsyncable' \ --iso-publisher 'Me Myself and I' \ --iso-volume 'ARMHF Ubuntu 14.04' \ --linux-flavours none \ --linux-packages none \ --mode ubuntu \ --security false \ --system normal echo "I: done" </file> On crée ensuite le fichier Makefile comme suit : <file bash Makefile> #!/bin/sh LOGFILE=lb-build.log all: set -e; sudo lb build 2>&1 | tee $(LOGFILE) clean: sudo lb clean --purge ; sudo rm -rf {config,local,$(LOGFILE)} </file> Il est d'ors-et-deja possible de proceder a la génération du systeme live decrit dans le configure. Le systeme resutant sera un systeme minimal (//--bootstrap-flavour minimal//) pour une architecture ARMHF (//--architectures armhf//), le tout etant une ubuntu Trusty (//--mode ubuntu// & //--distribution trusty//) . ---- ===== Customizations ===== Tout ceci est bien joli. Mais a y bien regarder, nous ne sommes pas plus avancés. Il n'y a toujours pas de serveur SSH sur ce rootfs ! Nous allons y Remedier. Commencons par créer un repertoire "//customization//" : <code bash> $ mkdir customization $ cd customization </code> Au sein de ce repertoire, trois autres repertoires se trouvent present : "hooks", "includes", et "package-lists" Il conviendra de modifier le configure afin qu'il prenne en compte les customizations en ajoutant les lignes suivantes : <code bash> echo "I: copy customization" cp -rf customization/* config/ </code> ==== Hook it up ! ==== En anglais, un "hook" c'est un "crochet". Rappellez vous du capitaine Hook dans Peter Pan... Et oui... Ce repertoire peut donc contenir de scripts qui seront exécutés pour eventuellement modifier notre rootfs. Ils ont pour extension //.chroot// car ils sont executés apres qu'un chroot n'ait été fait. Les chemin de fichier qu'il viennent modifier sont donc les chemin "//cibles//". Le premier hook vise a créer un utilisateur et renseigner le mot de passe. L'utilisateur sera "//olimex//" avec pour mot de passe "//olimex//". <file bash hooks/01-setup_user_olimex.chroot> #!/bin/sh echo "I: create olimex user" adduser --gecos olimex --disabled-login olimex echo "I: set olimex user password" echo "olimex:olimex" | chpasswd </file> Le second //hook// consiste a ajouter notre utilisateur "//olimex//" aux differents groupes auquel on souhaite le voir etre ajouté. <file bash hooks/02-add_olimex_to_groups.chroot> #!/bin/sh -x DEFGROUPS="admin,adm,dialout,cdrom,plugdev,audio,dip,video" /bin/egrep -i "^admin" /etc/group if [ $? -eq 0 ]; then echo "User admin exists in /etc/group" else echo "User admin does not exists in /etc/group must create" groupadd admin fi /bin/egrep -i "^dialout" /etc/group if [ $? -eq 0 ]; then echo "User dialout exists in /etc/group" else echo "User dialout does not exists in /etc/group must create" groupadd dialout fi /bin/egrep -i "^cdrom" /etc/group if [ $? -eq 0 ]; then echo "User cdrom exists in /etc/group" else echo "User cdrom does not exists in /etc/group must create" groupadd cdrom fi /bin/egrep -i "^plugdev" /etc/group if [ $? -eq 0 ]; then echo "User plugdev exists in /etc/group" else echo "User plugdev does not exists in /etc/group must create" groupadd plugdev fi /bin/egrep -i "^audio" /etc/group if [ $? -eq 0 ]; then echo "User audio exists in /etc/group" else echo "User audio does not exists in /etc/group must create" groupadd audio fi /bin/egrep -i "^dip" /etc/group if [ $? -eq 0 ]; then echo "User dip exists in /etc/group" else echo "User dip does not exists in /etc/group must create" groupadd dip fi /bin/egrep -i "^video" /etc/group if [ $? -eq 0 ]; then echo "User video exists in /etc/group" else echo "User video does not exists in /etc/group must create" groupadd video fi /bin/egrep -i "^adm" /etc/group if [ $? -eq 0 ]; then echo "User adm exists in /etc/group" else echo "User adm does not exists in /etc/group must create" groupadd adm fi echo "I: add olimex to ($DEFGROUPS) groups" usermod -a -G ${DEFGROUPS} olimex </file> Le troisieme //hook// consiste a attribuer des droits super-utilisateur a notre utilisateur "//olimex//". <file bash hooks/03-check_sudoers_for_admin.chroot> #!/bin/sh # check to make sure sudoers file has ref for admin ADMINEXISTS="$(awk '$1 == "%admin" { print $1 }' /etc/sudoers)" if [ -z "$ADMINEXISTS" ]; then # append admin entry to sudoers echo "# Members of the admin group may gain root privileges" >> /etc/sudoers echo "%admin ALL = (ALL) NOPASSWD: ALL" >> /etc/sudoers fi # make sure that NOPASSWD is set for %admin # expecially in the case that we didn't add it to /etc/sudoers # just blow the %admin line away and force it to be NOPASSWD sed -i -e ' /\%admin/ c \ %admin ALL = (ALL) NOPASSWD: ALL ' /etc/sudoers </file> Le quatrieme //hook// renseigne le fichier ///etc/fstab// de la maniere qu'on le souhaite. <file bash hooks/04-fstab.chroot> echo "# /etc/fstab: static file system information." > /etc/fstab echo "#" >> /etc/fstab echo "# <file system> <mount point> <type> <options> <dump> <pass>" >> /etc/fstab echo "/dev/root / ext4 noatime,errors=remount-ro 0 1" >> /etc/fstab echo "tmpfs /run/shm tmpfs defaults 0 0" >> /etc/fstab echo "tmpfs /tmp tmpfs defaults 0 0" >> /etc/fstab echo "tmpfs /var/tmp tmpfs defaults 0 0" >> /etc/fstab% </file> Le cinquieme //hook// procede de meme avec le fichier ///etc/network/interfaces// <file bash hooks/05-network-interfaces.chroot> echo "" >> /etc/network/interfaces echo "auto lo" >> /etc/network/interfaces echo "iface lo inet loopback" >> /etc/network/interfaces echo "auto eth0" >> /etc/network/interfaces echo "iface eth0 inet dhcp" >> /etc/network/interfaces </file> Voila pour les Hooks ! ==== Includes ==== Dans le repertoire includes, on y place les differents fichiers que l'on souhaite voir etre copiés tel quels sur le systeme hote. En passant, plutot que de faire des hooks pour le ///etc/fstab// et le ///etc/network/interfaces//, on aurait pu le faire via les //includes//. Voici donc les fichiers presents dans le "//includes.chroot//". <file bash includes.chroot/etc/default/locale> LANG=C.UTF-8 </file> <file bash includes.chroot/etc/hostname> a20-olinuxino </file> <file bash includes.chroot/etc/hosts> 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters 127.0.1.1 a20-olinuxino </file> <file bash includes.chroot/etc/rc.local> #!/bin/sh -e # # rc.local # # This script is executed at the end of each multiuser runlevel. # Make sure that the script will "exit 0" on success or any other # value on error. # # In order to enable or disable this script just change the execution # bits. # # By default this script does nothing. # Generate the SSH keys if non-existent test -f /etc/ssh/ssh_host_dsa_key || dpkg-reconfigure openssh-server exit 0 </file> ==== package-lists ==== Le troisieme et dernier repertoire de notre "customization" ne contient qu'un fichier : <file bash package-lists/a20-olinuxino-packages.list.chroot> # Packages needed for A20-OLinuXino isc-dhcp-server openssh-server sudo </file> ---- ===== Génération du rootfs ===== La Génération se fait simplement : <code bash> $ ./configure I: create configuration [2014-07-14 15:43:45] lb_config --apt-indices none --apt-secure false --architectures armhf --archive-areas main universe --binary-filesystem ext3 --binary-images tar --bootappend-live hostname=a20-olinuxino username=olimex --bootstrap-qemu-arch armhf --bootstrap-qemu-static /usr/bin/qemu-arm-static --cache false --chroot-filesystem none --compression gzip --bootstrap-flavour minimal --distribution trusty --gzip-options -9 --rsyncable --iso-publisher Me Myself and I --iso-volume ARMHF Ubuntu 14.04 --linux-flavours none --linux-packages none --mode ubuntu --security false --system normal P: Considering defaults defined in /etc/live/build.conf P: Creating config tree for a ubuntu/armhf system I: copy customization I: done $ make [...] </code> A la fin de la génération, nous avons le resultat suivant : <code bash> % la total 96776 drwxrwxr-x 10 nuptse nuptse 4096 juil. 14 16:06 ./ drwxrwxr-x 7 nuptse nuptse 4096 juil. 14 13:54 ../ drwxrwxr-x 2 nuptse nuptse 4096 juil. 14 15:43 auto/ drwxr-xr-x 20 root root 4096 juil. 14 16:05 binary/ -rw-r--r-- 1 root root 550593 juil. 14 16:05 binary.contents -rw-r--r-- 1 root root 5519 juil. 14 16:05 binary.packages -rw-r--r-- 1 root root 98387955 juil. 14 16:05 binary-tar.tar.gz drwxrwxr-x 2 nuptse nuptse 4096 juil. 14 16:06 .build/ drwxr-xr-x 4 root root 4096 juil. 14 15:53 cache/ drwxr-xr-x 20 root root 4096 juil. 14 16:05 chroot/ -rw-r--r-- 1 root root 0 juil. 14 16:02 chroot.headers -rw-r--r-- 1 root root 5519 juil. 14 16:02 chroot.packages.install -rw-r--r-- 1 root root 5519 juil. 14 16:03 chroot.packages.live drwxrwxr-x 19 nuptse nuptse 4096 juil. 14 15:43 config/ -rwxrwxr-x 1 nuptse nuptse 1175 juil. 14 15:03 configure* drwxrwxr-x 5 nuptse nuptse 4096 juil. 14 11:48 customization/ -rw-rw-r-- 1 nuptse nuptse 76790 juil. 14 16:06 lb-build.log drwxrwxr-x 4 nuptse nuptse 4096 juil. 14 15:43 local/ -rwxrwxr-x 1 nuptse nuptse 153 juil. 14 11:45 Makefile* </code> ---- ===== Deploiement ===== Le déploiement de notre rootfs ne pose a priori pas de problèmes. Il suffit de reprendre le tutoriel précédent ([[tuto_a20-olinuxino-micro_generation_d_image_a_base_du_noyau_3.4.90_et_de_ubuntu_core|Génération d'image à base du noyau 3.4.90+ et Ubuntu Core pour la carte A20-OLinuXino]]) à partir du paragraphe "//[[http://fablab-robert-houdin.org/wiki/doku.php?id=tuto_a20-olinuxino-micro_generation_d_image_a_base_du_noyau_3.4.90_et_de_ubuntu_core#deploiement_du_rootfs|Deploiement du rootfs]]//". Le contenu du rootfs est présent dans le répertoire //binary//. <code bash> $ sudo umount /dev/mmcblk0p* $ sudo mkfs.etx3 /dev/mmcblk0p2 $ sudo mount /dev/mmcblk0p2 /mnt/mmcblk $ sudo tar xzvf --strip=1 --wildcards binary-tar.tar.gz binary/* -C /mnt/mmcblk $ cd .. $ cd ubuntu_core_3.4.90+ $ sudo rm -rf /mnt/mmcblk/lib/modules/* zsh: sure you want to delete all the files in /mnt/mmcblk/lib/modules [yn]? y $ sudo rm -rf /mnt/mmcblk/lib/firmware/ $ sudo cp -rfv linux-sunxi/out/lib/modules/3.4.90+/ /mnt/mmcblk/lib/modules/ $ sudo cp -rfv linux-sunxi/out/lib/firmware/ /mnt/mmcblk/lib/ $ sync $ sudo umount /dev/mmcblk </code> ---- ===== Mise en route ===== Après avoir déployé notre rootfs sur la carte µSD, il convient de l’insérer dans le logement prévu pour sur la A20-OLinuXino. Il convient aussi de s'assurer que l'interface ethernet est bien connectée au réseau, et qu'un serveur DHCP sera en mesure d'attribuer une addresse IP a la carte. Une fois ceci fait, il est possible d'ouvrir une session SSH à destination de la carte et procéder a son exploitation. ---- ===== Remarques, Propositions d'améliorations, Questions ===== Vous pouvez poster vos remarques, propositions d’amélioration, et questions sur le forum, dans la discussion prévue a cet effet : [[http://fablab-robert-houdin.org/fablab/phpBB-3.0.11-fr/phpBB3/viewtopic.php?f=5&t=45]] ---- ===== Notes ===== Les packages listés sont les packages minimaux. J'ai depuis lors ajouter les packages suivants : zsh, git, aptitude, vim, wget, curl, ntpdate, dialog. J'ai aussi procédé à la configuration de mon editeur de texte favori : vim, tel que decrit ici : [[https://github.com/spelle/dotVIM|https://github.com/spelle/dotVIM]] ---- ===== Bibliographie ===== * https://wiki.ubuntu.com/ARM/RootStock * https://github.com/ngharo/ubuntu-nexus7-minimal-livebuild * http://crunchbang-fr.org/forum/viewtopic.php?id=1366 * http://linuxfactory.or.kr/dokuwiki/doku.php?id=how_to_create_ubuntu_image_with_linaro_image_tools#chrootfailed_to_run_command_usr_bin_envexec_format_error * http://www.linaro.org/

tuto_a20-olinuxino-micro_generation_d_un_rootfs_ubuntu_14.04_minimal_a_l_aide_de_live-build.txt · Dernière modification: 2014/07/19 18:46 par spelle