How tout casser chez tout le monde épisode 1
Afin de m'assurer que lorsque je joue avec mes ports, je casse bien tout, càd sur toutes les version supportées : 7.3, 8.0, 8.1 et celles à venir. Pour pouvoir bien vérifier que je mets le dawa aussi bien sur i386 que amd64, je me suis enfin décidé à poser une tinderbox.
La tinderbox officielle de freebsd ne me convient pas. Je la trouve démeusurément complexe pour ne pas dire tordu rapport à mes besoins, Elle a besoin d'une base de données (bon à la rigueur un petit postgresql ne me dérangerai pas plus que ça) mais pour la webui il faut aussi PHP et là faut pas déconner, je n'ai pas envie de me faire chier avec du PHP sur mes machines (comment ça je suis obtu ?).
Je suis donc parti pour me pondre la mienne. Je ferai ici l'état de l'avancée de ma tinderbox maison.
Episode 1 : principe et création des environnements.
Ma tinderbox sera moins automatisée que la tinderbox officielle, il faudra se faire à la main ses jails souches etc.
concepts :
- une jail sur un ZFS dédié par version et par architecture
- un snapshot de l'état neuf de la jail pour toujours repartir de quelque chose de propre
- du nullfs pour l'arbo des ports
- du nullfs pour les packages
- un joli script maison pour lier le tout. (Pour le moment ce script est en ZSH, peut être un jour il deviendra un shell POSIX propre)
Que va faire le script :
- démarrage de la jail
- un etat des lieux de la jail avant construction (mais après installation des dépendances)
- installation des dépendances depuis des packages si ils existent, sinon compilation depuis les ports (et construction du package comme ça au prochain tour le package sera là)
- construction du ports avec possibilité de changer les options
- installation/desinstallation/construction de packages, bref la tambouille habituelle pour s'assurer que le ports est tout joli comme il faut.
- état des lieux après désinstallation du ports histoire de s'assurer que celui ci ne laisser rien traîner comme un gros cochon.
maintenant que les concepts sont présentés passons à l'étape préparation des jails.
ici les jails sont dans /home/jails/tinderboxes celui ci étant un FS ZFS : system/jails/tinderboxes pour être précis. pour créer ces jails nous allons avoir besoin de : lftp et de zsh.
Oui comme je suis une loutre, je ne vais pas me lancer dans une compilation des sources pour créer mes jails, je vais directement partir des sets officiels.
for arch (i386 amd64) {
for version (7.3-RELEASE 8.0-RELEASE 8.1-RC2) {
zfs create system/jails/tinderboxes/${version%-*}-$arch
cd /home/jails/tinderboxes/${version%-*}-$arch
export DESTDIR=/home/jails/tinderboxes/${version%-*}-$arch
/usr/local/bin/lftp -c "open ftp://ftp.free.org/pub/FreeBSD/releases/$arch/$version/; mirror base"
/usr/local/bin/lftp -c "open ftp://ftp.free.org/pub/FreeBSD/releases/$arch/$version/; mirror src"
cd base
yes | ./install.sh
cd ../src
./install.sh all
}
}
J'ai donc maintenant à ma disposition 6 FS contenant chacun des images minimales freebsd il faut maintenant finir la config et les mettre à jours avec freebsd-update
pour chacune des jails il faudra forcer des variables d'environnement pour qu'elles sachent quel est leur version. Pour cela il faut modifier le login.conf de chacune d'entre elles et remplacer :
:setenv=MAIL=/var/mail/$,BLOCKSIZE=K,FTP_PASSIVE_MODE=YES:\
par
:setenv=MAIL=/var/mail/$,BLOCKSIZE=K,FTP_PASSIVE_MODE=YES,UNAME_r=7.3-RELEASE,OSVERSION=703000,UNAME_v=FreeBSD 7.3-RELEASE:\
Il faut adapter le 7.3-RELEASE pour chacune des jails.
Pour déterminer la bonne valeure pour OSVERSION, un petit awk à la racine de la jail va pouvoir nous aider :
awk '/\#define __FreeBSD_version/ { print $3 }' usr/include/sys/param.h
Pour les jails i386 il faut rajouter dans la ligne du login.conf
UNAME_m=i386,UNAME_p=i386
Pour que tout ceci soit pris en compte, ne pas oublier :
cap_mkdb login.conf
Toujours pour les jails i386, il ne faut pas oublier de mettre dans etc/make.conf
MACHINE=i386
MACHINE_ARCH=i386
Avant de démarrer les jails on ajoute 2 lignes sur le etc/rc.conf de chacunes d'entres elles afin qu'elles ne démarrent ni sendmail ni cron dont nous n'avons pas besoin. Pour le moment on garde la syslog pour que la jail reste fonctionnelle.
sendmail_enable="NO"
cron_enable="NO"
sur la machine hôte on peut ajouter les lignes nécessaires au démarrage des jails dans le rc.conf :
jail_73i386_rootdir=/home/jails/tinderboxes/7.3-i386
jail_73i386_hostname="tinder73i386"
jail_73i386_ip="192.168.1.51"
jail_73i386_interface="nfe0"
jail_73i386_devfs_enable="YES"
jail_73i386_devfs_ruleset="devfsrules_jail"
jail_73i386_flags="-n tinder73i386"
faire de même pour chacune des jails.
une fois les jails démarrées, il faut effectuer les mises à jours, toujours aider de zsh :
for arch (i386 amd64) {
for version (73 80 81) {
jexec -U root tinder${version}${arch} /usr/sbin/freebsd-update fetch install
}
}
Le -U root est important pour que login.conf soit pris en compte.
Un fois les mises à jours faites il est possible d'actualiser les fichiers login.conf afin de refléter les nouvelle version 7.3-RELEASE-p1 par exemple, mais ce n'est pas obligatoire.
maintenant il faut arrêter toutes les jails et faire un snapshot zfs qui nous servira de référence et permettera de repartir de bases propres :
zfs snapshot system/jails/tinderboxes/7.3-amd64@propre
recommencer l'opération pour toutes les jails.
Ceci est la fin du premier épisode (je sais ça a un air de déjà vue avec un post précédent, mais la suite sera différente :))
One-liner again
Je voulais pouvoir récupérer la liste complète des ports outdated de FreeBSD, pour ça nous disposons de portscout mais ce dernier ne présente que la liste par mainteneur, or je voulais la liste complète... mais portscout propose un flux rss qui, si il est appelé sans le paramètre ?m=, liste tous les ports outdated (attention le fichier est gros).
J'ai donc pris quelques armes :
- ZSH
- textproc/xmlstarlet pour faire des requête dans le xml
- textproc/html2text pour un peu de cosmétique dans la sortie
- fetch
le résultat :
feed=(${(f)"$(fetch -q -o - http://portscout.org/rss/rss.cgi)"}) && for item ({1..$(xml sel -t -v "count(//item)" =( print -lr $feed))}) { xml sel -t -v //item[$item]/title =( print -lr $feed) | html2text } > portscout.txt
avec cette ligne je récupère un fichier portscout.txt donc le contenu est :
categorie/port: ancienne_version -> nouvelle_version
tout simplement
UPDATE :
Voici une version plus zshienne (plus besoin de xmlstarlet ni de html2text) en revanche elle est moins souple mais plus rapide :
feed=(${(f)"$(fetch -q -o - http://portscout.org/rss/rss.cgi)"}) && for item ({0..$#feed}) { [[ -z ${feed[$item]:#\<item\>*} ]] && { print ${${${${feed[$item + 1]}/>/>}/\<\/title\>/}/\<title\>} } } > portscout.txt
Permission de sortie : 30 minutes
Le Besoin
- Un firewall qui interdit tout sauf le port 443 local de la machine.
- Un système permettant d'ouvrir pour 30 minutes seulement l'accès a un port du firewall donné
Les ingrédients
- FreeBSD 8.0
- PF
- AT
- /bin/sh
- sudo
Recette
PF
scrub in all
set skip on lo0
pass out all
block in all
table <allowips> persist
pass in quick inet proto tcp port https keep state
pass in quick inet proto tcp from <allowips> to port 8080 keep state
Voila tout simple tout beau, en gros on bloque tout sauf le https. On autorise toutes les ips qui sont contenu dans la table allowips
Problème : comme rajouter des adresses IPs dans la table allowips et surtout comment les supprimer au bout de 30 minutes
CGI shell
Nous créons donc un script cgi qui après une authentification "ultra basique" ajoutera l'adresse IP du demandeur dans la table allowips et schedulera la supression de celle ci
#!/bin/sh
if [ "$REQUEST_METHOD" = "POST" ];then
query="dd count=$CONTENT_LENGTH bs=1 2> /dev/null"
else
echo "Bad request"
return
fi
# Ceci n'est pas super clean, il y a mieux à faire mais flemme :)
eval $query
if [ -z $passwd ]; then
echo "Bad request"
return
fi
decodedpasswd=$(echo $passwd | awk '"'BEGIN{for(i=0;i<10;i++)hex[i]=i;hex["A"]=hex["a"]=10;hex["B"]=hex["b"]=11;hex["C"]=hex["c"]=12;hex["D"]=hex["d"]=13;hex["E"]=hex["e"]=14;hex["F"]=hex["f"]=15;}{gsub(/\+/," ");i=$0;while(match(i,/%../)){;if(RSTART>1);printf"%s",substr(i,1,RSTART-1);printf"%c",hex[substr(i,RSTART+1,1)]*16+hex[substr(i,RSTART+2,1)];i=substr(i,RSTART+RLENGTH);}print i;}'"')
if [ -f /usr/local/etc/authpasswd ]; then
read encryptpasswd < /usr/local/etc/authpasswd
else
echo "No password file"
return
fi
cryptpasswd=$(echo $decodedpasswd | /sbin/sha256)
if [ "$cryptpasswd" = "$encryptpasswd" ]; then
/usr/local/bin/sudo /sbin/pfctl -t allowips -T add $REMOTE_ADDR
echo "/usr/local/bin/sudo /sbin/pfctl -t allowips -T delete $REMOTE_ADDR" | /usr/bin/at now + 30 minute
echo "Acces granted for 30 minutes"
else
echo "Acces refused"
fi
C'est pas terrible mais suffisant : le mot de passe de référence est stocké dans /usr/local/etc/authpasswd et est en sha256
Il faut maintenant autoriser l'utilisateur www à pouvoir utiliser at :
$ echo "www" > /var/at/at.allow
Ensuite rajouter les entrées sudo qui vont bien dans /usr/local/etc/sudoers
%www ALL=NOPASSWD: /sbin/pfctl -t allowips *
Il vous reste à faire un fichier html qui appelle le script CGI via la méthode POST en lui fournissant le mot de passe donné dans une variable "passwd". Mettre le tout à dispo via un serveur web supportant le CGI.
Après on me demande pourquoi j'aime les Unix...
EDIT : alors on me dit dans l'oreillette que pfctl -t allowips -T expire 1800 lancé toutes les minutes dans une crontab ferait le même boulot mais je préfère ma solution à coup de at puisque at est géré par cron sous FreeBSD et que ce n'est exécuté qu'au besoin et non toutes les minutes
Emprisonner une debian dans un FreeBSD
Parfois on a besoin de tester des choses sous linux, parfois on a besoin d'utiliser des applications linux-only, où pour tout un tas d'autre raison on a besoin de faire tourner un linux.
Pour ça c'est vrai que l'on peut virtualiser dans un virtualbox ou un qemu, c'est bien mais c'est quand même coûteux en terme de ressources pour le host.
Sous FreeBSD nous disposons du linuxulator c'est la couche d'emulation permettant de faire tourner des applications Linux sous FreeBSD.
Ni une ni deux je me dis qu'il est possible de faire de petites choses sympathiques avec ça : une jail linux-only.
Il faut d'abord préparer le terrain :
# mkdir /home/jails/debian
# mkdir /home/jails/debian/dev
# mkdir /home/jails/debian/proc
# mkdir /home/jails/debian/sys
# kldload linux
# kldload linprocfs
# kldload linsysfs
# kldload lindev
# mount -t devfs none /home/jails/debian/dev
# mount -t linprocfs none /home/jails/debian/proc
# mount -t linsysfs none /home/jails/debian/sys
Nous allons donc utiliser /home/jails/debian comme racine de la debian que nous allons installer.
Nous chargeons tous les pilotes nécessaires (notez que lindev est apparu en FreeBSD 9 et a été MFCed en 8-STABLE il n'est absolument pas obligatoire)
On pourrait faire l'installation avec debootstrap, mais comme je suis un feignant j'ai préféré utiliser un template openvz tout fait :
# fetch http://download.openvz.org/template/precreated/debian-5.0-x86.tar.gz
Puis le depacker dans ma jail :
# tar xvfp debian-5.0-x86.tar.gz -C debian --exclude dev* --exclude proc* --exclude sys*
Pour démarrer correctement la jail il faut qu'au minimum un service tourne dans la jail (je n'ai pas réussit à faire une jail linux-only persistente). Par défaut le script de démarrage des jails essaye de lancer /etc/rc que nous allons créer et de lancer /etc/rc.shutdown pour s'arrêter.
# echo "/etc/init.d/cron start" > /home/jails/debian/etc/rc
# chmod 755 /home/jails/debian/etc/rc
# echo "/etc/init.d/cron stop" > /home/jails/debian/etc/rc.shutdown
# chmod 755 /home/jails/debian/etc/rc.shutdown
dans /etc/rc.conf on règle le lancement de la jail
jail_debian_rootdir=/home/jails/debian
jail_debian_hostname="debian"
jail_debian_ip="192.168.1.3"
jail_debian_interface="nfe0"
jail_debian_devfs_enable="YES"
jail_debian_devfs_ruleset="devfsrules_jail"
jail_debian_flags="-n debian"
on démarre la jail :
# /etc/rc.d/jail start debian
et magie :
#jls
JID IP Address Hostname Path
15 192.168.1.3 debian /home/jails/debian
#jexec debian uname -a
Linux debian 2.6.16 FreeBSD 8.0-STABLE #3: Sun Jan 10 20:39:38 CET 2010 i686 GNU/Linux
#jexec debian cat /etc/debian_version
5.0.4
Vous voila avec une belle debian emprisonnée dans un freebsd.
Attention, tout ne fonctionne pas parfaitement : sysklogd ne marche pas à cause des accès /dev par exemple, mais c'est 99% fonctionnel quand même.
Une jail 32bits sur un host 64bits
J'ai un eeepc 1000H qui fonctionne à merveille sous FreeBSD tout y est reconnu, juste un petite compilation maison pour le wifi, bref c'est pas le sujet de ce post.
Le truc c'est qu'un eeepc bah c'est lent pour la compilation, le binaire fournis par freebsd ne sont pas vraiment compilés avec les options que je souhaite, mais il s'avère que j'ai un beau Q6660 qui lui est plutôt très bien pour la compilation.
D'un autre côté je mijote toujours ma version FreeBSD de pkgin, du coup je me dis pourquoi pas compiler sur mon Q6600 les packages binaires depuis les ports et les installer via pkgin sur le 1000H, bah oui en voila une idée qu'elle est bonne.
De ce pas je me configure une jail 32bits (de la doc pour ça il y en a partout je vous laisse chercher :)) je me connecte dessus :
$ jexec eeepc /bin/sh
Je commence à compiler des ports, mais rapidement ça brotch de partout. Normal il me compile la moitié des choses en pensant avoir affaire à un amd64 :
$ uname -a
FreeBSD eeepc 8.0-STABLE FreeBSD 8.0-STABLE #3: Sun Jan 10 20:39:38 CET 2010 root@galway.lan:/usr/obj/usr/src/sys/GALWAY amd64
C'est pas du tout, mais alors pas du tout la cible que je cherche, moi je veux build de l'i386, en suivant la branche RELEASE du kernel (pour les drivers venant des ports).
Réglons les problèmes un par un.
Tout d'abord faisons fonctionner freebsd-update afin de pouvoir avoir le dernier niveau de patch de la branche RELEASE
$ freebsd-update fetch
Looking up update.FreeBSD.org mirrors... 3 mirrors found.
Fetching metadata signature for 8.0-STABLE from update5.FreeBSD.org... failed.
Fetching metadata signature for 8.0-STABLE from update4.FreeBSD.org... failed.
Fetching metadata signature for 8.0-STABLE from update2.FreeBSD.org... failed.
No mirrors remaining, giving up.
C'est pas gagné pourtant j'ai bien installé un jail 8.0-RELEASE. Il me faut donc le lui faire savoir. Pour cela, il suffit de modifier le /etc/login.conf de la jail et remplacer :
:setenv=MAIL=/var/mail/$,BLOCKSIZE=K,FTP_PASSIVE_MODE=YES:\
par
:setenv=MAIL=/var/mail/$,BLOCKSIZE=K,FTP_PASSIVE_MODE=YES,UNAME_m=i386,UNAME_p=i386,UNAME_r=8.0-RELEASE-p2,OSVERSION=800107,UNAME_v=FreeBSD 8.0-RELEASE-p2:\
Une recontruction de la db est nécessaire :
$ cap_mkdb /etc/login.conf
On peut maintenant quitter l'environnement et se reconnecter à la jail, par contre pour forcer la prise en compte de login.conf il faut forcer l'utilisateur dans la ligne jexec du coup :
$ jexec -U root eeepc /bin/sh
$ uname -a
FreeBSD eeepc 8.0-RELEASE-p2 FreeBSD 8.0-RELEASE-p2 i386
Parfait, maintenant relancez freebsd-update vous verrez qu'il fonctionne correctement.
Second problème les ports, là il en faut un peu plus.
En effet les ports vont chercher l'architecture via le sysctl :
- hw.machine
- hw.machine_arch
Là notre astuce ne fonctionne plus, de plus il est impossible de les changer depuis une jail. Du coup en cherchant un peu dans /usr/ports/Mk/*.mk on se rend vite compte que l'on peut contourner le problème via /etc/make.conf. Pour ça, il suffit de rajourer les variables suivantes :
MACHINE=i386
MACHINE_ARCH=i386
Désormais je peux tout compiler tranquilement depuis ma jail et utiliser les packages sous mon eeepc. Afin de gagner en simplicité j'utilise ma version maison de pkgin (oui un jour elle sera intégrée upstream), en générant un INDEX.bz2 de la liste de mes packages et en mettant ça à dispo sur un serveur web par exemple
PS: pour générer l'INDEX.bz2, j'ai fait un petit prog en C: pkg_index, il n'est pas aussi complet que l'INDEX.bz2 normal mais beaucoup plus simple à utiliser et suffisant pour pkgin.
$ ./pkg_index /usr/ports/packages
PS2: pour créer mes packages j'utilise portmaster c'est moins lourd qu'une tinderbox
$ portmaster -ag
Convertir l'arbre CVS des ports en git (round 2)
Il y a quelques mois je cherchais tranquillement à convertir l'arbre cvs des ports FreeBSD en arbre git.
Ça avait bien marché, mais il y avait deux inconvénients majeurs :
- C'était trop long a faire
- Les mises à jours était horrible à faire.
Et puis hier, gaston me montre ça nonchalamment, puis ça, bon j'y crois pas trop mais je me lance
Récupération du CVSROOT
Créer le fichier de config suivant pour csup
*default host=cvsup.free.org
*default base=/var/db
*default prefix=/usr/portsdev/cvsroot
*default release=cvs
*default delete use-rel-suffix
*default compress
ports-all
Puis récupérer le cvsroot :
$ csup cvsroot-supfile
Installation des pré-requis
Installation des packages
$ make -C /usr/ports/devel/mercurial install clean
$ make -C /usr/ports/lang/ruby18 install clean
$ make -C /usr/ports/textproc/ruby-iconv install clean
$ make -C /usr/ports/devel/ruby-rbtree install clean
Installation de rcsparse
$ hg clone http://ww2.fs.ei.tum.de/~corecode/hg/rcsparse
$ cd rcsparse
$ ruby extconf.rb
$ make
$ make site-install
Récupération des sources de fromcvs
$ hg clone http://ww2.fs.ei.tum.de/~corecode/hg/fromcvs
Conversion du CVSROOT en git
Préparation du répertoire de destination
$ mkdir /usr/portsdev/freebsd-ports.git
$ cd /usr/portsdev/freebsd-ports.git
$ git init --bare
Conversion
$ cd /usr/portsdev/fromcvs
$ ruby togit.rb /usr/portsdev/cvsroot ports /usr/portsdev/freebsd-ports.git
2h30 (oui seulement 2h30 !!! ) après c'était fait
Le répertoire de destination fait 720Mo.
Repack du rep
$ cd /usr/portsdev/freebsd-ports.git && git repack -a -f -d
Ce coup ci ça ne dure que 5 petites minutes et le répertoire ne fait plus que 410Mo
Mise à jour de l'arbre git
Comme fromcvs fonctionne de manière incrémentale, il faudra juste relancer le csup de temps en temps et relancer la commande togit.rb pour faire très rapidement les mises à jours
Bilan du round 2
fromcvs n'est pas parfait (il n'importe pas encore les tags) en revanche il a été capable de me conserver plus de branches que ce que parsecvs avait fait, en plus il est beaucoup, beaucoup, beaucoup plus rapide :
Pour les ports la conversion passe de 17h30 à 2h30 le repack passant lui de 28h50 à 5min, la taille du repos avant repack de 4go à 710Mo.
Par contre attention togit.rb est un très gros consommateur de RAM : il a bouffé mes 4Go de RAM plus 3Go de SWAP pour convertir les ports !!!
La mise à jour fonctionne parfaitement. Autant dire que je garde cette méthode. J'ai bien essayé de modifier fromcvs afin qu'il puisse importer les tags, mais je n'y suis pas arrivé, le ruby ne m'aime définitivement pas.
VirtualBox sur un hôte FreeBSD
Au boulot pour les mails, nous utilisons Br0tchus Notes, un espèce de daube infâme qui te pique ta ram pire qu'un firefox dans ces mauvais jours, bref.
Mon problème c'est que mon Desktop c'est du FreeBSD et que les gens de chez IBM, il ne fournissent de clients que pour Linux (si on ne considère que les environnements libre) - le java ça ne devait pas permettre de faire des applis qui tourne chez tout le monde ??? (oui il y a des vrais morceaux d'eclipse donc de java dans les derniers clients Notes)... bref -
VirtualBox ayant été porté récemment sous FreeBSD avec le support des extensions Vt-X je me suis donc lancé dans la virtualisation d'une debian minimaliste qui n'aura pour seul but que de lancer le client Notes et de le confiner en RAM afin qu'il ne me pique pas tout ce que j'ai de disponible sur ce Desktop.
Pour cela je l'ai donc installé depuis les ports (il faudra faire attention pour lancé les VMs à bien avoir mounté /proc - oui le ports n'est pas encore super propre, mais on fera avec). Comme c'est déjà super long à compiler je l'ai compilé en enlevant le support QT4, en effet la GUI n'apporte pas grand chose à cette application et en plus elle ne permet pas d'accéder à des fonctionnalités intéressantes de VBox.
Pour finir afin d'être plus souple j'ai utilisé les volumes zfs comme disques pour l'invité.
Installation de virtualbox
$ make -C /usr/ports/emulators/virtualbox config
Choisissez les options qui vous plaisent
$ make -C /usr/ports/emulators/virtualbox install clean
Si tout ce passe bien vous disposez maintenant de virtualbox sur votre machine.
Préparation du disque d'accueil de l'invité
Règle devfs
Pour que les volumes pour l'invité puisse être modifié par l'application virtualbox, ils doivent appartenir au groupe vbox, devfs nous permet de le faire à la volée, pour cela, dans le fichier /dev/devfs.rules :
[localrules=1]
add path 'zvol/vbox/*' mode 0660 group vbox
Ne pas oublier de modifier /etc/rc.conf pour qu'il le prenne en compte :
devfs_system_ruleset="localrules"
Un petit redémarrage de devfs pour finir :
$ /etc/rc.d/devfs restart
Création du volume
5G suffirons largement pour notre installation et encore je suis très large
$ zfs create -V 5G vbox/debian
Nous disposons maintenant d'un disque qu'il ne reste plus qu'à ajouter au pool de disques VirtualBox :
$ VBoxManage internalcommands createrawvmdk -filename melebian.vmdk -rawdisk /dev/zvol/vbox/debian
$ VBoxManage registerimage disk debian.vmdk
Création de la machine virtuelle
Création de la VM sans disque
Nous allons donc créer la VM pour qu'elle support les extensions VT-x et qu'elle soit limitée à 256Mo de RAM il ne s'agirait pas non plus que notes se sente trop à son aise.
$ VBoxManage createvm -name debianVM -register
$ VBoxManage modifyvm debianVM --ostype debian -memory 256M
$ VBoxManage modifyvm debianVM --vtxvpid on
Nous allons aussi déporter le port 22 de l'invité sur le port 2222 local afin de se simplifier la tâche pour le réseau (on laisse le réseau par défaut de virtualbox)
$ VBoxManage setextradata debianVM "VBoxInternal/Devices/pcnet/0/LUN#0/Config/ssh/GuestPort" 22
$ VBoxManage setextradata debianVM "VBoxInternal/Devices/pcnet/0/LUN#0/Config/ssh/HostPort" 2222
$ VBoxManage setextradata debianVM "VBoxInternal/Devices/pcnet/0/LUN#0/Config/ssh/Protocol" TCP
Ajout du disque à la nouvelle VM et de l'iso de l'installeur
Tout d'abord on liste les disques disponibles dans le pool pour récupérer son identifiant :
$ VBoxManage list hdds
UUID: b6db4102-90fd-4073-ae61-c1c57556bb85
Format: VMDK
Location: /home/bapt/debian.vmdk
Accessible: yes
Il suffit maintenant de le rajouter :
$ VBoxManage modifyvm debianVM -hda b6db4102-90fd-4073-ae61-c1c57556bb85
On enregistre l'iso dans le pool VirtualBox :
$ VBoxManage registerimage dvd /home/bapt/Desktop/debian-501-i386-netinst.iso
Et on l'ajoute de la même manière à la VM
$ VBoxManage list dvds
UUID: b3329255-221a-4bb6-b1f4-be2d4bdc0f2f
Path: /home/bapt/Download/debian-501-i386-netinst.iso
Accessible: yes
$ VBoxManage modifyvm debianVM -dvd b3329255-221a-4bb6-b1f4-be2d4bdc0f2f -boot1 dvd
Installation de l'invité
Pour l'installation de l'invité, on démarrera en mode sdl pour la suite ça ne sera plus nécessaire :
$ VBoxManage startvm debianVM --type sdl
Ou
$ VBoxSDL startvm debianVM
il ne vous reste plus qu'à faire votre installation debian normale à laquelle vous ajouterez votre client br0tchus notes et le configurerez.
afin que votre VM puisse accéder au disque de l'hôte sans se prendre la tête, VirtualBox prévoie un mécanisme bien sympathique :
$ VBoxManage sharedfolder add debianVM -name share -hostpath /home/bapt/sharedvm
Pour y accéder depuis votre debian, il faudra installer les guestutils
$ apt-get install virtualbox-ose-guest-modules virtualbox-ose-guest-utils
Puis dans le /etc/fstab de l'invité
share /home/bapt/sharedHost vboxsf uid=bapt,gid=bapt 0 0
Maintenant lorsque vous démarrerez votre VM vous le ferez de la manière suivante :
$ VBoxManage startvm debianVM --type headless
Ou
$ VBoxHeadless startvm debianVM
Et pour se connecter à la VM depuis l'hôte :
$ ssh -Y -p 2222 bapt@localhost
lancez notes ou votre application désirée.
Comme je suis un gentil lutin j'ai partagé tout ça de manière plus générique sur GCU
Reconstruire les paquets cassés
Voici un petit script ZSH pour rechercher les binaires systèmes qui ne trouvent pas les bibliothèques dont ils dépendent et les reconstruire en utilisant portmaster.
#!/usr/local/bin/zsh typeset -a torebuild rep=(/usr/local/bin/**/*(.)) rep+=(/usr/local/lib/**/*.so(.)) rep+=(/usr/local/sbin/**/*(.)) for bin ($rep) { file $bin | grep -q "ELF" && { ldd =$bin | grep -q "not found" && { torebuild+=$(pkg_info -qoW $bin) } } } portmaster -f ${(u)torebuild}
Convertir l'arbre CVS des ports en git
Voulant pouvoir jouer tranquillement avec les ports via git, je me suis dit que j'allais convertir les CVS des ports en git tout simplement.
Récupération du CVSROOT
Créer le fichier de config suivant pour csup
*default host=cvsup.free.org
*default base=/var/db
*default prefix=/usr/portsdev
*default release=cvs
*default delete use-rel-suffix
*default compress
ports-all
Puis récupérer le cvsroot :
$ csup cvsroot-supfile
Récupération et construction de parsecvs
Récupérer les sources
$ git clone git://anongit.freedesktop.org/~keithp/parsecvs
Contruire les lib git qui seront nécessaires, sans les installer.
$ make -C /usr/ports/devel/git
Modifier le Makefile de parsecvs pour qu'il ressemble à celui-ci
GCC_WARNINGS1=-Wall -Wpointer-arith -Wstrict-prototypes
GCC_WARNINGS2=-Wmissing-prototypes -Wmissing-declarations
GCC_WARNINGS3=-Wnested-externs -fno-strict-aliasing
GCC_WARNINGS=$(GCC_WARNINGS1) $(GCC_WARNINGS2) $(GCC_WARNINGS3)
GITPATH=/usr/ports/devel/git/work/git-1.6.4
CFLAGS=-O2 -g $(GCC_WARNINGS) -I$(GITPATH) -DSHA1_HEADER='<openssl/sha.h>' -I/usr/local/include
LIBS=-L$(GITPATH) -lgit $(GITPATH)/xdiff/lib.a -lssl -lcrypto -lz -liconv -L/usr/local/lib
YFLAGS=-d -l
LFLAGS=-l
OBJS=gram.o lex.o parsecvs.o cvsutil.o revdir.o \
revlist.o atom.o revcvs.o git.o gitutil.o rcs2git.o \
nodehash.o tags.o tree.o
parsecvs: $(OBJS)
cc $(CFLAGS) -o $@ $(OBJS) $(LIBS)
$(OBJS): cvs.h
lex.o: y.tab.h
lex.o: lex.c
y.tab.h: gram.c
clean:
rm -f $(OBJS) y.tab.h gram.c lex.c parsecvs
install:
cp parsecvs edit-change-log ${HOME}/bin
Construction et installation de parsecvs
$ gmake
$ cp parsecvs edit-change-log /usr/local/bin
Conversion du CVSROOT en git
$ cd /usr/portsdev/ports
Si vous utilisez zsh :
$ print -l **/*,v | parsecvs
Sinon
$ find . -name "*,v" -print | parsecvs
Attention c'est long, très long : 17h30 sur un Q6600 avec 4Go de RAM et un disque SATA 150 en zfs Le facteur principal est la vitesse du disque dur en effet la consommation de RAM et CPU est négligeable comparée à l'utilisation disque.
Une fois cette étape terminée vous disposez d'un répertoire git fonctionnel mais énorme : plus de 4Go
Repack du rep
$ git repack -a -f -d -l
Cette étape est très longue aussi et dépend de la vitesse de votre disque pour beaucoup. Ici ça a pris 28h50
Une fois cette étape finie vous voila avec un répertoire git de 400M ce qui est quand même beaucoup mieux.
Préparation pour les mises à jour
Alors comme cvsps foire prodigieusement souvent via git cvsimport, il faut le lancer de côté :
$ export CVS_RSH=ssh
$ export CVSROOT=anoncvs@anoncvs.fr.FreeBSD.org:/home/ncvs
$ cvsps -x --norc -u -A ports > /tmp/cvsps.out
Mise à jour de l'arbre git
$ git cvsimport -o master -P /tmp/cvsps.out ports
Vous voila avec un git à jour, pour continuer à mettre à jour, recommencer les deux dernières étapes.
En un seul coup pour zsh :
$ git cvsimport -o master -P <(cvsps -x --norc -u -A ports) ports
zcp un wrapper pour cp
L'autre jour sidh me demandait si je n'avais rien en zsh pour pouvoir suivre la progression d'un cp volumineux et je n'avais rien, mais j'ai trouvé l'idée intéressante. Un petit man cp plus tard, je me rend compte que le cp de FreeBSD il est beau et bien foutu, en lui envoyant un SIGINFO il nous dis ce qu'il fait et ou il en est. De là a wrapper tout dans un petit script zsh il n'y avait qu'un pas.
De plus zsh permet de créer un tty virtuel (zpty) dans lequel on peut exécuter des commandes et interagir, du coup, voici un petit script bien pratique :
#!/usr/local/bin/zsh setopt extendedglob zmodload zsh/zpty zpty copy "cp $@ 2>&1" ZPTYPID=${${=${(M)${(f)"$(ps -o pid,ppid,command)"}:#[[:space:]]#[[:digit:]]##[[:space:]][[:space:]]#$$*zsh*}}[1]} CPPID=${${=${(M)${(f)"$(ps -o pid,ppid,command)"}:#[[:space:]]#[[:digit:]]##[[:space:]][[:space:]]#${ZPTYPID}*cp*}}[1]} line="" while [ : ] do zpty -rt copy out if [[ $#out -gt 0 ]] then newline=${${=${out}}[0,-2]} percent=${${=${out}}[-1]} if [[ -z $line || "x$newline" != "x$line" ]] then [[ -n $line ]] && print "${line}: done" line=$newline print "${line}: ${(l: ::4:)percent}\c" else print "\r${line}: ${(l: ::4:)percent}\c" fi fi kill -SIGINFO $CPPID 2>/dev/null || break done [[ -n $line ]] && print "${line}: done" zpty -d copy
la sortie donne : # zcp toto.iso bla/ toto.iso -> bla/toto.iso: 48%
UPDATE: Apparemment ça ne fonctionne qu'avec zsh 4.3.10+


