juin 15 2010

Sondage de la communauté Debian

Tag: Actualités, Debian GNU/LinuxSylvain @ 08:03

Suite à la préparation de la « mini debconf » qui s’est déroulée les 10 et 11 juin 2010 à Berlin, il a été décidé de proposer aux utilisateurs Debian, un petit sondage comportant différentes questions sur l’usage que vous faites de cet OS, de ses dérivés, sur votre avis concernant les cycles de publication, etc. Ça ne prend que deux minutes à remplir, je vous invite donc à remplir ce questionnaire et à le diffuser à la communauté. :)

Lien :


nov 06 2009

Créer une image ISO Debian avec les firmwares non libres

Tag: Bash, Debian GNU/Linux, Développement, Langages, SystèmeSylvain @ 20:53

Les images ISO officielles de Debian, conformément aux DFSG, ne contiennent pas de firmwares non libres ce qui peut poser problème lorsque l’on a, par exemple, des serveurs équipés de carte réseaux Broadcom NetXtreme II utilisant le module « bnx2 » qui nécessite un firmware évidemment non libre. Dans ce genre de cas, l’installateur Debian demande de fournir ce dernier via une clé USB, c’est bien mais je souhaitais sauter cette étape, c’est pourquoi j’ai développé un petit script s’occupant d’intégrer directement dans l’image ISO les firmwares non libres disponibles dans la section « non-free ». Voici le script pour les intéressés :

#!/bin/bash

#//////////////////////////////////////#
# Affiche l'aide du script             #
#                                      #
# @stdout Aide d'utilisation du script #
#//////////////////////////////////////#
usage(){
 echo "Usage : $0 <architecture> (i386, amd64)"
}

#/////////////////////////////////////////////////////////////#
# Teste si l'utilisateur est loggué en root ou non            #
#                                                             #
# @return Renvoie 0 si l'utilisateur est root sinon renvoie 1 #
#/////////////////////////////////////////////////////////////#
is_root(){
 if [[ $(id -u) -eq 0 ]]; then
 return 0 ;
 else
 return 1 ;
 fi
}

#///////////////////////////////////////////////////////////#
# Vérifie la présence des programmes utilisés par le script #
#                                                           #
# @return Renvoie 0 si tous les programmes sont présents    #
#///////////////////////////////////////////////////////////#
check_installed_software(){
    if [[ -z $(which ar) || -z $(which genisoimage) || -z $(which wget) || -z $(which tar) || -z $(which zcat) || -z $(which cpio) ]]; then
        return 1 ;
    else
        return 0 ;
    fi
}

#////////////////////////////////////////////////////////////////////////#
# Télécharge l'image ISO en version netinstall de l'architecture désirée #
#                                                                        #
# @param in $1 Architecture de l'ISO à télécharger                       #
# @stdout Nom du fichier de l'image ISO téléchargée                      #
#////////////////////////////////////////////////////////////////////////#
download_iso_netinstall(){
 local ISO=$(wget -q -O- http://cdimage.debian.org/debian-cd/current/$1/iso-cd/|sed -nr 's/.*(debian.+?netinst.iso).*/\1/p')
 [[ -z $ISO ]] && {
 exit 1
 }
 wget "http://cdimage.debian.org/debian-cd/current/$1/iso-cd/$ISO" -O $ISO
 echo $ISO
}

#////////////////////////////////////////////////////////////////////#
# Extrait les fichiers d'une image ISO dans un répertoire temporaire #
#                                                                    #
# @param in $1 chemin de l'image ISO                                 #
# @stdout Chemin où se trouvent les fichiers extraits                #
#////////////////////////////////////////////////////////////////////#
function extract_files_from_iso(){
 local MOUNT_DIR=$(mktemp -d)
 local ISO_DIR=$(mktemp -du)
 mount -o loop $1 $MOUNT_DIR
 cp -a $MOUNT_DIR $ISO_DIR
 umount $MOUNT_DIR
 rmdir $MOUNT_DIR
 echo $ISO_DIR
}

#/////////////////////////////////////////////////////////////////////////////////////////////#
# Affiche le nom des paquets contenant les derniers firmwares non libres présents dans Debian #
#                                                                                             #
# @stdout Liste des paquets contenant les derniers firmwares non libres                       #
#/////////////////////////////////////////////////////////////////////////////////////////////#
list_firmware(){
 local FIRMWARE_DEB=$(wget -q -O- 'http://ftp.debian.org/debian/pool/non-free/f/firmware-nonfree/?C=N;O=D;V=1;F=0' | sed -nr "s/^<li><a href=\"(.+?\.deb)\".*/\1/p")
 local FIRMWARE_NAME=$(echo "$FIRMWARE_DEB" | cut -f1 -d_ | uniq)
 local NAME
 for NAME in ${FIRMWARE_NAME[@]}; do
 echo "$FIRMWARE_DEB" | grep -m1 "$NAME"_
 done
}

#///////////////////////////////////////////////////////#
# Télécharge et extrait les paquets passés en paramètre #
#                                                       #
# @stdout Répertoire contenant les fichiers extraits    #
#///////////////////////////////////////////////////////#
download_and_extract_firmware(){
 local FIRMWARE_DIR=$(mktemp -d)
 cd $FIRMWARE_DIR

 while [[ $# -gt 0 ]]; do
 wget -q -O $1 "http://ftp.debian.org/debian/pool/non-free/f/firmware-nonfree/$1"
 ar x $1 data.tar.gz
 tar xvf data.tar.gz './lib/firmware' &> /dev/null
 rm $1 data.tar.gz
 shift
 done

 cd $OLDPWD
 echo $FIRMWARE_DIR
}

#///////////////////////////////////////////////////#
# Intègre les firmwares dans les initrd trouvés     #
#                                                   #
# @param $1 Répertoire où se trouvent le(s) initrd  #
# @param $2 Répertoire où se trouvent les firmwares #
#///////////////////////////////////////////////////#
merge_firmware_initrd(){
 local INITRD
 for INITRD in $(find $1 -name initrd.gz); do
 local TMP_DIR=$(mktemp -d)
 cd $TMP_DIR
 zcat $INITRD | cpio -i &> /dev/null
 cp -a $2/lib/firmware .
 find . -print0 | cpio -0 -H newc -o 2> /dev/null | gzip -c > $INITRD
 cd $OLDPWD
 rm -rf $TMP_DIR
 done
}

#////////////////////////////////////////////////////////////////////////////#
# Mise à jour des sommes MD5                                                 #
#                                                                            #
# @param $1 Répertoire où se trouve le fichier de sommes MD5 à mettre à jour #
#////////////////////////////////////////////////////////////////////////////#
update_md5sum(){
 cd $1
 find . -type f ! -name md5sum.txt -exec md5sum {} \; > md5sum.txt
 cd $OLDPWD
}

#/////////////////////////////////////////////////////////////////////////#
# Génère une image ISO à partir d'un répertoire                           #
#                                                                         #
# @param $1 Répertoire contenant les fichiers à intégrer dans l'image ISO #
# @param $2 Chemin vers le fichier à générer                              #
#/////////////////////////////////////////////////////////////////////////#
build_iso_image(){
 genisoimage -no-emul-boot -r -J -boot-load-size 4 -boot-info-table -b isolinux/isolinux.bin -c isolinux/boot.cat -o $2 $1 &> /dev/null
}

#///////////////////////#
# Vérifications de base #
#///////////////////////#
check_installed_software
[[ $? -eq 1 ]] && {
    echo "Certains programmes nécessaires au fonctionnement du script n'ont pas été trouvés." >&2
    exit 1
}

[[ $# < 1 ]] && usage && exit 1
ARCH=$1

! is_root && {
 echo 'Ce script a besoin des droits root !' >&2
 exit 1
}

#///////////////////////////////#
# Téléchargement de l'image ISO #
#///////////////////////////////#
echo "Téléchargement de l'image ISO"
ISO=$(download_iso_netinstall $ARCH)
[[ $? -eq 1 ]] && {
 echo "Erreur : l'image ISO netinstall de l'architecture « $ARCH » n'a pas été trouvée." >&2
 exit 1
}

#/////////////////////#
# On crée l'image ISO #
#/////////////////////#
echo "Extraction des fichiers de l'image ISO"
ISO_DIR=$(extract_files_from_iso $ISO)
echo "Téléchargement des firmwares"
FIRMWARE_DIR=$(download_and_extract_firmware $(list_firmware))
echo "Intégration des firmwares"
merge_firmware_initrd $ISO_DIR $FIRMWARE_DIR
echo "Création de l'image ISO finale"
update_md5sum $ISO_DIR
NEW_ISO=${ISO/./.homemade.}
build_iso_image $ISO_DIR $NEW_ISO
echo "Image ISO originale : $ISO"
echo " Nouvelle image ISO : $NEW_ISO"

#////////////////////////////////////////#
# On nettoie les répertoires temporaires #
#////////////////////////////////////////#
rm -rf $FIRMWARE_DIR $ISO_DIR

Liens :


oct 21 2009

Variables variables en Bash

Tag: Bash, Debian GNU/Linux, Développement, Langages, SystèmeSylvain @ 21:29

Il peut parfois être pratique d’avoir des noms de variables qui soient variables. C’est-à-dire un nom de variable qui est affecté et utilisé dynamiquement. En bash, il suffit de d’utiliser la construction « ${!variable} » pour déréférencer la variable ayant son nom contenu dans $variable. Voici un exemple d’utilisation concret :

#!/bin/bash

BACKUP_DAY=10
BACKUP_WEEK=4

LIST=( DAY WEEK )
for i in ${LIST[@]}; do
    i="BACKUP_$i"
    echo "$i : ${!i}"
done

Affichera :

BACKUP_DAY : 10
BACKUP_WEEK : 4

À lire :


oct 21 2009

Équivalents de dirname & basename en Bash

Tag: Bash, Debian GNU/Linux, Développement, Langages, SystèmeSylvain @ 18:16

Les programmes dirname et basename sont très pratiques lors de l’écriture de scripts bash mais impliquent une exécution externe ce que les puristes aiment bien éviter. Voici, pour les intéressés, leurs équivalents en bash accompagnés d’une batterie de tests pour valider leur fonctionnement par rapport aux programmes de base :

#!/bin/bash

function basename(){
    echo ${1##*/}
}

function dirname(){
    local file=$1
    case $file in
        /*) ;;
        ./*) ;;
        *) file=./$file ;;
    esac
    file=${file%/*}
    echo ${file:-/}
}

PROGS=( dirname basename )
LIST_FILES=( /test.txt /tmp/test.txt /tmp/plop/test.txt ./test.txt ./tmp/test.txt ./tmp/plop/test.txt test.txt )

for prog in ${PROGS[@]}; do
    echo "--> $prog <--"
    for file in ${LIST_FILES[@]}; do
        SYSTEM=$(bash -c "$prog $file")
        MINE=$($prog $file)
        [[ $SYSTEM != $MINE ]] && echo -e "$file\nSystème : $SYSTEM\nLe mien : $MINE"
    done
done

Une petite comparaison rapide entre les deux solutions montre des performances supérieures de 75% en faveur de la solution bash. En pratique, la différence sera bien évidemment insignifiante sauf si vous vous amusez à itérer un grand nombre de fois sur ces fonctions. ;-)

Note : les options –help, –version ainsi que le paramètre permettant d’indiquer un suffixe pour basename ne sont pas pris en compte.

À lire :


Page suivante »