18/04/2015

Weblog de Natacha >> Dissociation

Par : Natacha Kerensikova
Tags:
Tarée

J'ai rencontré récemment plusieurs évocations indépendantes du concept en psychologie appelé « dissociation ». Comme je ne le connaissais pas du tout, je suis allée faire une randonnée sur wikipédia en anglais, en passant par Dissociation puis Depersonalization et Derealization. Comment souvent, je suis déçue par les articles homologues sur wikipédia en français (Dissociation, Dépersonnalisation et Déréalisation).

De toute façon, cet billet ne va utiliser aucune de ces références. Certes, lorsque je tombe sur un concept comme ça, je cherche dans mon passé des expériences qui pourraient s'en rapprocher. Mais depuis que j'ai entendu parler de Karl Popper, je cherche surtout comment une expérience candidate pourrait ne pas coller à la définition. En me protégeant ainsi du Biais de confirmation, je tombe une fois de plus dans l'excès inverse : l'incapacité à conclure. J'arrive aussi facilement à tirer sur la définition pour y faire rentrer ce que je vais décrire, que pour que ça n'y rentre pas du tout.

Donc au lieu d'essayer de me raccrocher à des concepts que je ne maîtrise pas, qui ne s'appliquent peut-être même pas, je vais simplement décrire mon vécu avec des mots simples.

Mon vécu

Je l'ai déjà expliqué plusieurs fois à différents endroits, notamment dans mon billet la lecture et moi : quand je suis confrontée à une histoire, quelqu'en soit le support, j'ai tendance à essayer de me projeter dedans, généralement au travers de l'un des personnages.

À peu de choses près, plus je me projette profondément dans l'histoire, plus je suis satisfaite. En ce qui concerne les fictions, c'est pratiquement mon seul critère de jugement.

J'utilise depuis un bout de temps le verbe « projeter » pour décrire ce mécanisme mental, avant ça j'utilisais l'expression « rentrer dans l'histoire ». J'ai changé parce qu'en fait souvent, je me projette dans un personnage, pour vivre l'histoire au travers de lui. Il y a bien des histoires dans lesquelles je rentre objectivement, mais la plupart c'est en se projetant dans un personnage particulier, ou parfois plusieurs personnages.

C'est comme ça que je trouve qu'Evangelion est une série que j'aime beaucoup, qui fait 22.5 épisodes. Je ne vais pas divulgâcher parce que ceux qui connaissent savent (ou retrouvent facilement) ce qu'il se passe au milieu de l'épisode 23 et comprendront, et pour les autres ce serait déraisonnablement long et peu productif d'expliquer.

Bon, tout ça c'est très bien, et j'imagine que l'on ne manquerait pas de gens pour glorifier ce « voyage au pays de l'imaginaire », même si au fond ce n'est que du divertissement, quoique littéraire.

Bizarrement, personne ne parle du retour.

Il y a toujours un moment où il faut revenir dans la réalité : on arrive à la station de destination, on est première position de la queue, on est cherché en salle d'attente, etc.

La plupart du temps, ça ne pose pas de problème. Dans les histoires que j'aime beaucoup, c'est-à-dire celles dans lesquelles je me suis projetée profondément, il faut toujours un certain temps pour « atterrir ».

Plus je suis projetée profondément, plus je suis en manque de sommeil, et/ou moins j'ai le moral, plus ce temps est long. Parfois il peut même être très long, mais je préfère ne pas penser à ces fois.

C'est dans ces cas là que j'apprécie avoir un trajet habituel à suivre machinalement, pendant ce temps.

J'ai un peu de mal à trouver des mots pour décrire mon état à ces moments là, parce que le langage que j'ai appris ne couvre pas (ou très peu) ce champ. C'est exactement comme décrire une odeur.

Si je vivais dans une culture où l'utilisation des drogues récréatives était courante et faisable dans des conditions et un environnements sûrs, je pourrais peut-être le décrire par une analogie avec l'emprise de telle ou telle substance (par exemple, la kétamine). Comme je ferais pour décrire une odeur. Malheureusement, ce n'est pas le cas.

Ce sont ces expériences auxquelles les définitions de déréalisation m'ont fait penser (je n'ai jamais rien vécu se rapprochant de la dépersonnalisation), car je trouve effectivement qu'il manque quelque chose à ce que je perçois autour de moi, et ce manque est source d'une certaine confusion. Un quelque chose qui devrait appartenir à la réalité et qui n'appartient jamais à la fiction.

Ce serait un peu l'équivalent généralisé à tous les sens de ce que je ressentirais si je mangeais un steak qui a un goût de fromage, tout en ayant la consistance habituelle d'un steak, et après la surprise initiale passée. Cette espèce d'incrédulité, genre « y a un truc qui n'est pas comme il faut », une bouchée de plus pour vérifier que c'est bien le cas, les tentatives de décomposer l'expérience gustative pour arriver à la conclusion qui est ce que j'ai décrit comme étant la situation.

Mais d'un autre côté, je ne prends jamais conscience que les perceptions sensorielles décrivent toujours la réalité, et que ce vient d'ailleurs n'est pas la réalité. Donc dans ce sens là, ça ne colle pas du tout avec la plupart des définitions de la dissociation.

En fait tout le paragraphe précédent, c'est juste au niveau de la connaissance, de l'information et de son traitement. Je dirais même de façon plus générale, tout ce qui est froidement l'acquisition et le traitement de l'information fonctionne parfaitement, pendant la lecture ou après.

Par contre, le « quelque chose » qui manque à la réalité dans les moments que je décris ici, il existe sur le plan émotionnel. Je sais que la réalité est là, mais je m'en fous. Le monde est là, mais il ne provoque plus de réaction émotionnelle chez moi.

Je ne saurais pas trop dire si cette réaction émotionnelle est remplacée par autre chose, comme le goût dans l'analogie précédente, ou si elle est seulement absente (ce qui ne fonctionnerait pas dans l'analogie, parce que l'absence de perception n'existe pas vraiment, car cette absence est traitée comme une perception).

Est-ce un problème ?

Jusqu'à récemment, non.

J'ai toujours été comme ça, je l'ai accepté comme étant une partie normale de la vie. Ça n'a pas tellement de conséquences pratiques, et je peux m'organiser pour les éviter dans les rares cas où elles seraient gênantes. Par exemple en arrêtant de lire quand c'est le tour de la personne devant moi dans une queue, ou de la personne d'avant, suivant la vitesse de la queue.

Avoir lu qu'un problème psychologique existe, qui pourrait se rapprocher de cette situation, m'a fait réfléchir sur l'universalité de cette expérience : est-ce que ça arrive à tout le monde, ou à une grande partie de la population (parmi ceux qui lisent encore des livres…), ou est-ce qu'il n'y a que moi ?

Mais quand bien même ce serait anormal, tant que ça ne dérange personne, j'ai du mal à considérer ça comme une maladie à guérir ou un problème à résoudre.

Du moins, jusqu'à il y a quelques semaines.

C'était un samedi, et mon homme et moi allions à un évènement parisien, et toutes les conditions étaient réunies : le manque de sommeil, pas trop le moral, et Altered Carbon dans le métro. Une fois descendus du métro, le livre fraîchement refermé, il fallu déterminer comment aller de la station à l'évènement, et pour ce faire il a fallu que je sorte mon plan de Paris de mon sac à main.

Le sac à main en question, c'est le Sherpani Esprit dont j'ai fait une critique il y a quelques mois, que j'utilise quotidiennement depuis.

Sept cents mètres après la station de métro, il a fallu ressortir le plan. J'étais encore dans cet état étrange, enveloppée d'un brouillard émotionnel. Et j'ai remarqué que mon sac était ouvert. Ce qui a causé une contrariété tellement forte qu'elle a percé ce brouillard.

Il m'était déjà arrivé plusieurs fois de porter ce sac à main à dos ouvert, généralement sur la quinzaine de mètres entre mon bureau et les toilettes, ce que j'ai toujours trouvé très contrariant à cause du risque que quelque chose tombe du sac, mais rien n'en était jamais tombé.

Or ce samedi là, ma trousse (contenant une variété de stylos et de clefs USB) a disparu.

Je ne saurai probablement jamais ce qui est vraiment arrivé. Ai-je oublié de fermer le sac ou a-t-il été ouvert dans mon dos ? La trousse est-elle tombée ou a-t-elle été volée ? Est-ce que mon air paumée / high m'a désignée comme cible ? Ai-je perçu une chute accidentelle de la trousse, sans y accorder d'importance à cause de cet état ? Est-ce que j'aurais raté une chute accidentelle de la trousse même sans être dans cet état ?

Les conséquences matérielles sont dérisoires : rien d'autre que la trousse ne manque à l'appelle, et presque tout est facilement remplaçable (il n'y a que la trousse elle-même que je n'ai pas encore pu remplacer par quelque chose d'au moins autant à mon goût).

En revanche, le bris de ma confiance envers mon sac à main est très grave (et probablement disproportionné). Même si j'aime encore beaucoup ce sac, il a fallu le remplacer à court terme, car l'angoisse de ne pas l'avoir fermée était rapidement devenue insupportable.

Avant cet incident, il m'était peut-être arrivé une demi-douzaine de fois de vérifier qu'il est bien fermé après l'avoir mis sur le dos. J'ai probablement dépassé la centaine de fois pendant la semaine qui a suivi l'incident.

Je suis encore en train d'évaluer les remplacements à ce sac à main et à cette trousse, je posterai ici mon avis quand je serai fixée.

Et vous, avez-vous déjà vécu des moments comme ceux-ci ? En avez-vous aussi subi des conséquences désagréables ?


31/03/2015

Weblog de Natacha >> Promesse

Par : Natacha Kerensikova
Tags:
Tarée

Je jure solennellement que lors ce 1er avril, je ne posterai pas sur Facebook de fausse photo de fiançailles, comme un abruti. Je ne colporterai pas non plus la fausse annonce de la mort d'une célébrité, parce que ça rend les gens tristes. Et je ne ferai même pas de farce, et si je vois quelqu'un préparer une blague, je lui dirai : « Hé, là tu fais vraiment le con. Arrête de faire le con. Arrête de faire le con. Sérieusement, arrête de faire le con. »

Et je suis très fan de John Oliver.

Au cas où l'intégration de la vidéo ci-dessus fonctionne mal, voici la vidéo originale sur Youtube


30/03/2015

Another Home Page Blog >> Moi aussi j'ai des lutins qui courent très vite dans les fils !

Par : Nils
Tags:

Résumé des épisodes précédents : NetBSD et PXE sont de grands copains. Démarrer ce type d'OS en PXE est faisable, pas trop difficile, documenté dans la langue de Shakespeare ou dans celle de Molière que ce soit pour un système fini (merci iMil) ou juste pour l'installation (autopromotion sans honte).

Mieux vaut tard que jamais, j'ai décidé de tenter ma chance et de configurer un système NetBSD sans disque, suite à la présence à ${HOME} d'une machine graphiquement réduite mais disposant d'une puissance de calcul non négligeable, jugez plutôt :

marvin# egrep '(name|MHz)' /proc/cpuinfo 
model name      : AMD Phenom(tm) 8450 Triple-Core Processor
cpu MHz         : 2100.35
model name      : AMD Phenom(tm) 8450 Triple-Core Processor
cpu MHz         : 2106.73
model name      : AMD Phenom(tm) 8450 Triple-Core Processor
cpu MHz         : 2304.94
marvin# grep MemTotal /proc/meminfo
MemTotal:   3931368 kB

Merci à Madame de me laisser l'utiliser !

Je pourrais utiliser une clé USB, débrancher les disques durs et en ajouter un de mon stock. Mais ce ne serait pas drôle. J'ai utilisé les liens ci-dessus pour démarrer le brave Marvin via NFS, je ne vais donc pas paraphraser ces articles, mais ajouter ici quelques détails, remarques, trucs et peut-être astuces glanés ici et là et qui m'ont aidé.

D'abord, mieux vaut tester dans une machine virtuelle. Parce qu'aller chercher la bécane au fond sous le bureau, ça va une fois. Du coup, il faut s'assurer quand même qu'elle démarre sur le réseau, voire via Wake On LAN pour les plus fainéants. Sinon, une clé USB ou un CD Etherboot devrait faire l'affaire.

Ensuite, repérer la marque de la carte réseau et surtout potentiellement le pilote qui sera utilisé par NetBSD sera pratique : en effet, il faudra créer un fichier ifconfig.xy0, où xy0 sera remplacé par le nom du pilote de la carte réseau, dans mon cas c'est nfe0. Comment trouver le nom du pilote ? Soit on démarre un noyau NetBSD (l'installeur par exemple, qui permet d'obtenir un shell et d'exécuter dmesg | grep -i eth), soit on connaît le modèle de carte réseau et on cherche dans les sources. En ce qui me me concerne, je suis allé cherché la chaîne "NVIDIA" dans le fichier de configuration du noyau.

Toujours dans la catégorie réseau, si vous faites des tests en machine virtuelle, vous risquez probablement de le faire depuis un ordinateur portable connecté en Wi-Fi. Mieux vaut réfléchir un instant à la qualité de son réseau sans fil, et envisager de faire les tests en filaire. Mon expérience personnelle (VM simple cœur, 2Go de ram) : en Wi-Fi, le système démarre en plus de 5 bonnes minutes, en filaire (gigabit Ethernet) cela met moins d'une minute. 5 FICHUES MINUTES QUOI !!! En prime, dès que vous allez vouloir écrire ne serait-ce qu'un méga-octet sur le système, cela va se traîner. J'ai senti ma douleur quand je me suis rendu compte que j'avais oublié de décompresser un set.

J'ai eu une surprise sur le fichier /dev/null, il peut être nécessaire de le recréer :

marvin# cd /dev/
marvin# rm null
marvin# ./MAKEDEV -u all

L'installeur de NetBSD crée automatiquement certains fichiers ou paramètres. Sauf qu'on ne l'a pas utilisé... Parmi les trucs qu'il peut être utile de faire manuellement, il y a ces lignes dans /etc/fstab :

procfs                                          /proc            procfs  rw,auto,linux
kernfs                                          /kern            kernfs  rw
ptyfs                                            /dev/pts       ptyfs    rw

Il n'est pas obligatoire de monter /proc avec l'option linux, c'est juste un confort personnel. Ne pas oublier de créer les répertoires /proc/ et /kern/ avant.

Autre paramètre, celui de la date et de l'heure : par défaut, le système est en heure UTC, moi je veux l'heure de Paris. Pour cela, j'ai modifié le lien symbolique /etc/localtime :

marvin# readlink -f /etc/localtime
/usr/share/zoneinfo/Europe/Paris

Cela n'exclut pas le paramétrage NTP.

J'ai choisi de ne configurer qu'un seul partage NFS, car je n'envisage pas dans l'immédiat d'utiliser ce partage pour d'autres machines. Du coup, je n'ai initialement pas paramétré de swap, mais j'ai ajouté un fichier après coup, en utilisant la documentation officielle. Cela donne :

marvin# dd if=/dev/zero bs=1024k count=1024 of=/swapfile
marvin# chmod 600 /swapfile
marvin# swapctl -a -p 1 /swapfile
marvin# echo "/swapfile none    swap    sw,priority=1 0 0" >> /etc/fstab

Si comme moi vous avez déjà un serveur PXE en place, avec un fichier boot.cfg utilisé par pxeboot_ia32.bin, vous n'avez pas envie de mettre tous les noyaux, d'installation ou non, dans une longue liste. Il est possible de créer un deuxième fichier, qu'on donne à manger à pxeboot en lieu et place de boot.cfg. On le paramètre au niveau du serveur DHCP, par exemple pour ISC DHCP j'ai mis en place la configuration suivante :

host marvin {
        hardware ethernet 01:23:45:67:89:ab;
        fixed-address 192.168.1.13;
        option host-name "marvin";
        option root-path "/chemin/vers/diskless/nbmarvin";
        if filename = "boot.cfg" {
                filename "tftp:nbmarvin.boot.cfg";
        }   
}

On remarque donc que si pxeboot veut récupérer boot.cfg depuis la machine marvin, alors on lui servira nbmarvin.boot.cfg.

J'ai aussi remarqué que le clavier est en qwerty par défaut. Comme je n'ai pas relié de clavier ou d'écran à cette machine, et que j'ai configuré un accès SSH dès que possible, je n'ai pas changé ce paramètre. Toutefois, pour les pressés, vous pouvez utiliser la documentation officielle pour changer l'agencement du clavier.

Et sinon, pas de bol, la carte Wi-Fi PCI n'est pas reconnue :

vendor 0x1814 product 0x3060 (miscellaneous network) at pci1 dev 7 function 0 not configured

Bref, quelques notes en vrac qui, je l'espère, pourront s'avérer utile à l'occasion. Maintenant, il me reste à utiliser cette puissance de calcul à ma disposition (quelqu'un a dit bulk build pkgsrc ?).


28/03/2015

% tar -jx < *.bz >> Tunnels IPv6 pour la maison

Tags:

J'ai voulu avoir de l'IPv6 à la maison. Mon opérateur Internet ne fournit que de l'IPv4, il faut donc tunneller d'une façon ou d'une autre. J'ai une Kimsufi à disposition, avec un accès IPv6 natif, j'ai donc voulu l'utiliser comme point de sortie.

Bien sûr, une solution est d'utiliser un fournisseur de tunnel comme HE ou SixXS, mais où est l'intérêt de ne pas faire les choses soi-même ?

1 Creusage de tunnels

Beaucoup de technologies qui permettent de faire des tunnels IPv6 à travers un réseau IPv4 :

Nom Type Usage
6in4 Routeur - Routeur Un lien IPv6 (typiquement entre routeurs) explicitement configuré entre les deux extrémités
GRE Routeur - Routeur Une technique d'encapsulation générique Cisco (depuis normalisée) avec quelques fonctionnalités en plus
6to4 Routeur - Internet Un lien IPv6, les adresses sont dans 2002::⁄32 et on inclut dans l'adresse IPv6 l'adresse IPv4 (publique !) du routeur. Il y a besoin de relais sur l'Internet (pour le sens Internet -> Routeur)
ISATAP Hôte - Hôte Deux hôtes (éventuellement routeurs pour leurs réseaux respectifs) qui peuvent se parler en IPv4, avec quelques options d'autoconfiguration. Prévu pour un réseau local.
6over4 Hôte - Hôte Comme ISATAP, mais les hôtes doivent se parler en IPv4 multicast (typiquement, ils sont sur le même LAN). Pas intéressant par rapport à ISATAP, mais historiquement le premier.
Teredo Hôte - Internet Un hôte (éventuellement derrière un NAT) qui accède à l'Internetv6
IPsec Routeur - Routeur Initialement prévu pour créer un tunnel sécurisé entre deux réseaux

Quand on a un point de sortie, la technique idéale est 6in4, ou éventuellement IPsec en mode authentification (le chiffrement est peu intéressant, puisque couvrant uniquement la partie du trafic de la maison au point de sortie, et uniquement pour l'IPv6…).

2 Plan du réseau

Le serveur / point de sortie utilise lui-même des adresses IPv6. Le réseau côté maison a besoin d'au moins deux préfixes, pour le Wifi et pour le filaire. Or, OVH ne fournit aux kimsufi qu'un seul /64… Il va donc falloir découper en plusieurs morceaux. J'ai choisi /80, attribué comme suit :

tunnel-ip6.png

Figure 1: Schéma réseau

Où :

  • 2001:db8:a:b::/64 est le préfixe attribué au point de sortie ;
  • le premier /80 est attribué aux différents services qui tournent sur la machine ;
  • les /80 suivants pour la maison ;
  • en vert le tunnel entre le routeur Wifi à la maison et le point de sortie ;

J'ai utilisé des adresses ULA pour les extrémités du tunnels, mais en fait il n'y en a pas vraiment besoin : une fois qu'on a commencé à découper notre /64, autant aller jusqu'au bout. Ça permet juste de bien reconnaître les adresses dans les fichiers de configuration et dans les tcpdump.

3 Problèmes

Il y a deux problèmes avec cette façon de faire. Le premier est évident : on utilise des préfixes qui font plus que /64. Cela nous fait essentiellement perdre les mécanismes d'auto-configuration sur les réseaux de la maison.

Le deuxième est un peu plus subtile. Le /64 fournit par OVH n'est pas vraiment routé jusqu'à nous. Si c'était le cas, tous les paquets à destination du /64 seraient livrés à 2001:db8:a:b::1 (par exemple), et notre routage interne avec les /80 lui serait transparent. À la place, le dernier routeur s'attend à être directement connecté à ce /64, et à pouvoir faire directement un NS et recevoir une réponse pour chaque adresse. Il va donc falloir mettre en place sur l'interface externe un proxy NDP, qui fera croire au routeur que toutes les adresses sont directement connectées.

4 Implémentation

4.1 Routage sur le point de sortie

On va configurer les adresses que l'on utilise sur la machine comme des /128 (ou éventuellement comme des /80, enfin bref), créer le tunnel, et ajouter les routes statiques vers la maison.

Quelques lignes dans rc.conf :

            ifconfig_nfe0=
            "inet 203.0.113.197/24"

            defaultrouter=
            "203.0.113.254"

            ifconfig_nfe0_ipv6=
            "inet6 auto_linklocal"

            # 
            entree statique pour le routeur :

            # 
            http://travaux.ovh.net/?do=details&id=6819

            #
            rtsold_enable="YES"

            ipv6_defaultrouter=
            "fe80::5:73ff:fea0:0%nfe0"

            ifconfig_nfe0_alias0=
            "inet6 2001:db8:a:b::1/128"

            ifconfig_nfe0_alias1=
            "inet6 2001:db8:a:b::22/128"

            ifconfig_nfe0_alias2=
            "inet6 2001:db8:a:b::25/128"

            ifconfig_nfe0_alias3=
            "inet6 2001:db8:a:b::80/128"


            # 
            tunnel vers la maison

            gif_interfaces=
            "gif0"

            gifconfig_gif0=
            "203.0.113.197 198.51.100.56"

            ifconfig_gif0=
            "mtu 1480"

            ifconfig_gif0_ipv6=
            "inet6 -auto_linklocal"

            ifconfig_gif0_alias0=
            "fd93:1:2:3::1/127"


            ipv6_gateway_enable=
            "YES"

            ipv6_static_routes=
            "home_wifi home_wired"

            ipv6_route_home_wifi=
            "2001:db8:a:b:1:: -prefixlen 80 fd93:1:2:3::"

            ipv6_route_home_wired=
            "2001:db8:a:b:2:: -prefixlen 80 fd93:1:2:3::"

          

Si pf(4) tourne, on ajoutera :

            table <
            home_nets>  
            const 
            persist {
             2001:db8:a:b:1::/80 2001:db8:a:b:2::/80 }

            extif = 
            "nfe0"

            tunif = 
            "gif0"

            # Tunnel 6in4 vers maison

            pass 
            on $
            extif 
            proto ipv6

            pass 
            from <
            home_nets> 
            to 
            any

            pass 
            from 
            any 
            to <
            home_nets>


            # Éventuellement des règles plus restrictives pour contrôler ce qui

            # arrive à la maison

          

4.2 Configuration du routeur wifi

Le routeur est un Cisco 877W qui fait tourner 15.1(3)T4. En 12.2, j'ai vu que parfois, le routeur décide de ne pas répondre aux NS, ce qui est un peu gênant. On utilise DHCPv6 pour distribuer les adresses. L'interface Wi-Fi ne peut pas être configurée en IPv6, mais on peut la placer dans un bridge qui, lui, peut être configuré avec IPv6.

ipv6 unicast-routing
ipv6 cef
!
interface Dot11Radio0
 description wireless
 bridge-group 1
 ssid Coloc
!
interface BVI 1
 description bridge pour wireless
 ipv6 mtu 1480
 ipv6 address 2001:DB8:A:B:1::1/80
 ipv6 nd autoconfig default-route
 ipv6 nd managed-config-flag
 ipv6 dhcp server HOME_WLANv6
!
interface Vlan20
 description vlan wired
 ipv6 mtu 1480
 ipv6 address 2001:DB8:A:B:2::1/80
 ipv6 nd managed-config-flag
 ipv6 dhcp server HOME_WIREDv6
!
interface range FastEthernet 0 - 2
 switchport mode access
 switchport access vlan 20
 description wired (vlan 20)
 spanning-tree portfast
!
interface Vlan10
 description vlan internet
 ip address dhcp
!
interface FastEthernet3
 description internet (vlan 10)
 switchport access vlan 10
!
interface Tunnel0
 description tunnel vers serveur
 no ip address
 ipv6 address FD93:1:2:3::/127
 tunnel source Vlan10
 tunnel destination 203.0.113.197
 tunnel mode ipv6ip
!
ipv6 dhcp pool HOME_WIREDv6
 address prefix 2001:DB8:A:B:2::/80
 dns-server 2001:DB8:A:B::53
!
ipv6 dhcp pool HOME_WLANv6
 address prefix 2001:DB8:A:B:1::/80
 dns-server 2001:DB8:A:B::53
!
ipv6 route ::/0 FD93:1:2:3::1/127

Les interfaces Fa 0 - 2, utilisées pour le LAN filaire, sont mises en portfast. Sans le portfast, il faut ≈45 secondes à STP pour accepter que je n'ai pas créé de boucle en branchant mon portable. NetworkManager envoie n RS avec un timeout de t secondes pour la réponse RA. Avec n = 3, t = 1 seconde (RFC2461), NetworkManager a le temps d'abandonner plusieurs fois… Donc on passe en portfast.

4.3 Proxy NDP

Comme mentionné plus haut, l'un des soucis est que le routeur devant la KS s'attend à voir le /64 complètement à plat. Il faut donc un proxy NDP qui réponde à la place des machines qui sont à la maison.

Ça fait environ 300 lignes pour un programme qui écoute avec libpcap les NS sur l'interface externe et qui envoie les NA correspondants. Le code est dans un dépôt git (ou interface gitweb). Avec le réseau montré plus haut, j'appelle ndp6 avec les options :

ndp6 -i nfe0 -p 2001:db8:a:b:1::/80 -p 2001:db8:a:b:2::/80

Les gens qui utilisent Linux sur le point de sortie seront intéressés par ndppd. Parmi les linuxeries, il y a la lecture de /proc/net/ipv6_route pour mettre à jour les réseaux proxifiés, l'utilisation d'une socket AF_PACKET pour écouter les paquets qui ne nous sont pas destinés.

5 Soucis rencontrés

5.1 Clients DHCP

Avec ISC dhclient, lorsqu'une adresse est configurée par DHCPv6, elle est installée avec un préfixe en /64. C'est un bug dans le client DHCP (les annonces DHCP ne contiennent qu'une adresse, pas d'informations sur le lien local). La RFC 5942, section 5 explique le problème, disant que c'est ce qui arrive quand « the IPv6 subnet model is not understood by the implementers of several popular host operating systems ».

Le bug Debian #684009 contient un patch pour ISC dhclient (apparemment remonté upstream). De son côté, Network Manager ne fait ples confiance aux préfixes annoncé par les clients DHCPv6.

Le client WIDE dhcp6c a le bon comportement (à condition de lui dire de demander une adresse…), je n'ai pas testé son intégration avec Network Manager.

Le Windows 7 du boulot semble avoir le bon comportement.

5.2 Bizarrerie sur le DHCP côte WAN

Les serveurs DHCP de chez Virgin Media se comportent bizarrement. En particulier, après une coupure de courant, le routeur ne reçoit pas d'adresse jusqu'à ce que le modem câble se fasse rebooter. Pas quelque chose que je peux corriger de mon côté…


28/03/2015

% tar -jx < *.bz >> ZFS pour des mises à jour sereines

Tags:

Avec FreeBSD 9.0 qui est sorti il y a presque six mois, il est grand temps de se mettre à jour. On ne peut pas à la fois prétendre au status de cyborg, et utiliser autre chose que la dernière version de son OS préféré !

Dans un épisode précédent on avait installé son serveur avec ZFS, justement pour pouvoir faire des mises à jour avec une solution de repli si les choses tournent mal. On a deux solutions : faire un snapshot puis mettre à jour, avec la possibilité de faire un rollback plus tard ; ou alors installer dans un nouveau volume et pointer le bootloader sur le nouvel environnement. J'ai exploré la deuxième option. Cette deuxième option permet de ne pas tout perdre s'il faut revenir en arrière. On verra dans la suite si cela devait se révéler utile…

1 Préparation

Histoire d'avoir les ports déjà construits, on installe poudriere, la configuration se résume à pointer sur un FTP proche de chez nous. Ensuite on prépare un environnement pour 9.0 :

poudriere jail  -c -v 9.0-RELEASE -a amd64 -j poudre90
poudriere ports -c

On récupère la liste des ports installés, et tant qu'on y est on récupère aussi leur configuration pour que poudriere reconstruise les ports avec les bonnes options.

(pkg_version -o; jexecall pkg_version -o) >portlist
sort <portlist| uniq >portlistuniq
cut -d' ' -f1 <portlistuniq >portlist
cp -r /srv/jails/*/var/db/ports/* /usr/local/etc/poudriere.d/options
poudriere bulk -f portlist

2 Le système de base

Pendant que poudriere mouline, on installe FreeBSD 9.0 sur un système de fichiers à part.

zfs create zroot/slash90
zfs set mountpoint=/slash90 zroot/slash90
zfs create zroot/slash90/usr

cd /slash90
fetch http://ftp.fr.freebsd.org/pub/FreeBSD/releases/amd64/amd64/9.0-RELEASE/{base,kernel,src}.txz
tar -xpf base.txz
tar -xpf kernel.txz
tar -xpf src.txz

Pour les fichiers de configuration, on va copier la configuration depuis notre environnement actuel vers l'installation toute fraîche, puis lancer un coup de mergemaster(8) :

cd /slash90/etc
cp -a /etc/ .
chroot /slash90
mergaster -FUvi

On profite également d'être dans un chroot dans /slash90 pour installer les ports qu'on vient de construire.

La configuration réseau a un peu changé. Une configuration avec plusieurs addresses dans chaque famille ressemble à :

          ifconfig_nfe0=
          "inet 203.0.113.13/24"

          defaultrouter=
          "203.0.113.254"

          ifconfig_nfe0_ipv6=
          "inet6 2001:db8:1:8248::1/64 accept_rtadv"

          rtsold_enable=
          "YES" 
          # 
          ou ipv6_defaultrouter="fe80::f00:baa%nfe0"


          ifconfig_nfe0_alias0=
          "inet  198.51.100.43/32"

          ifconfig_nfe0_alias1=
          "inet6 2001:db8:1:8248::25"

          ifconfig_nfe0_alias2=
          "inet6 2001:db8:1:8248::53"

        

ipv6_network_interfaces n'est plus nécessaire.

On copie également /usr/local/etc dans /slash90.

3 Bascule vers 9.0

Pour basculer d'un environnement vers l'autre, il suffit 1 de faire :

zfs set canmount=noauto zroot/slash82
zfs set canmount=noauto zroot/slash82/usr

vi /slash90/boot/loader.conf
# Ajouter : zfs_load="YES"
# et : vfs.root.mountfrom="zfs:zroot/slash90"
zfs unmount zroot/slash90
zfs unmount zroot/slash90/usr
zfs set mountpoint=/ zroot/slash90
zfs set mountpoint=/usr zroot/slash90/usr
zpool set bootfs=zroot/slash90 zroot

Dans mon cas, l'environnement actuel est installé dans zroot/slash82, avec /usr qui est dans zroot/slash82/usr. Si la racine du système est directement à la racine du pool ZFS, il y aura quelques subtilités, si on passe zroot en noauto il faudra penser à modifier les autres points de montage par exemple. De plus, chez moi /var est dans zroot/var, monté automatiquement par ZFS, donc il n'y a pas besoin de le déplacer.

Au premier essai, ma kimsufi n'a pas démarré. Un peu d'investigation via le le mode rescue-pro d'OVH (un simple netboot avec les disques accessibles) ne donne rien. Un zpool import -o altroot=/mnt plus tard, on refait la bascule dans l'autre sens (en utilisant zroot/slash82), et on retrouve une machine qui boote.

Le lendemain, je retente l'opération, cette fois en vKVM (une machine virtuelle qui démarre sur le disque dur du serveur), et là… le démarrage se passe correctement. Je ne sais pas pourquoi au premier essai, les choses se sont bloquées au boot.

Après un peu d'exploration, on voit qu'il y a certaines choses qui ont été « perdues » :

  • ce qui est dans /root (un script de sauvegarde, par exemple) ;
  • ce qui est dans /usr/local. J'ai pensé aux ports et à leur configuration, mais j'ai laissé de côté le RTM d'OVH, les dossiers de données de poudriere… ;
  • /home (qui ne contenait guère que ~fred/.ssh/authorized_keys d'intéressant).

Il suffit de monter zroot/slash82 (qui est actuellement en canmount=noauto) pour avoir accès à ses données et les réinstaller.

4 Les jails

On pourrait tout à fait adopter la même procédure : installer dans un système de fichiers à part, y compris les ports, rapatrier les configurations, et pointer ezjail vers la nouvelle installation. La mise à jour en place semble plus simple, et tellement moins risquée que pour la machine hôte…

ezjail-admin update -s 8.2-RELEASE -U

Attention, freebsd-update essaie de mettre à jour le noyau, il faut le relancer à la main une deuxième fois.

Malheureusement, il faut lancer à la main mergemaster pour chacune des jails (et tant qu'on y pense, mettre à jour le gabarit d'ezjail).

Pour les ports, grâce à la préparation faite plus haut, on a déjà des packages binaires à jour pour nos jails, et il suffit de lancer un jexecall portmaster -a pour tout mettre à jour.

5 Conclusion

Le passage à 9.0 n'a pas été aussi facile qu'attendu. En particulier, je ne sais pas pourquoi le premier démarrage n'a pas réussi du premier coup, et si c'est dû à l'utilisation de ZFS ou pas. De plus, la méthode que j'ai suivie n'était pas idéale —je suppose qu'en ayant de vraies procédures de backup-restore, je n'aurais pas oublié RTM ou les scripts qui traînent dans /root. D'un autre côté, le paramètre bootfs plus jouer un peu avec les points de montage permet de basculer facilement d'une installation à l'autre ; c'était une promesse de ZFS, et cette promesse est tenue. Au premier essai, c'est ce qui m'a permis de revenir sur une configuration fonctionnelle.

Je regrette de ne pas avoir adopté poudriere plus tôt.

Footnotes:

1

Il serait certainement possible de laisser /usr hériter de zroot/slashXX, et ainsi il n'y aurait qu'un seul point de montage à déplacer.


28/03/2015

% tar -jx < *.bz >> Notes d'EuroBSDcon 2011

Tags:

EuroBSDcon 2011 s'est déroulé au début de ce mois d'octobre. Je viens de finir de mettre en forme mes notes sur les conférences que j'ai suivies.

On y retrouvera en particulier :

  • sendmail, history and design, présenté par Eric Allman, dans lequel l'auteur présente l'histoire du MTA qui est encore aujourd'hui le plus utilisé sur Internet, les éléments de design qui ont permis à sendmail de survivre pendant 30 ans, et les élèments malgré lesquels sendmail a survécu pendant 30 ans ;
  • Minix 3, ou comment construire un OS fiable, par Herbert Bos : en utilisant des principes systématiques de réduction des privilèges, de séparation des composants, et en acceptant que les composants peuvent crasher mais sont pour la plupart redémarrables ;
  • status d'IPv6 dans FreeBSD de Bjoern Zeeb, comment FreeBSD a vécu le World IPv6 Day cette année, les leçons du noyau AF_INET6-only, et ce qui doit arriver dans le futur proche dans un FreeBSD près de chez vous ;
  • portage d'OpenBSD vers UltraSPARC T1 et T2 de Mark Kettenis, une session très technique (au cours de laquelle je ne prétendrais pas avoir tout compris), qui décrit dans une première partie les atouts de cette plateforme, et comment OpenBSD est capable de tourner sur cette architecture ;
  • NPF, un nouveau pf pour NetBSD 6.0 de Zoltan Arnold Nagy, qui explique pourquoi un nouveau pare-feu est nécessaire et comment NPF a été construit ;
  • High Availability STorage in FreeBSD de Pawel Jakub Dawidek, du RAID1 over network, modes de synchronisation, démonstration, performance ;
  • testing automatique de NetBSD de Martin Husemann, les composants logiciels mis en œuvre, les bindings dans différents languages, les bugs découverts grâce au testing systématique.

À noter également les slides de quelques développeurs OpenBSD :

Malheureusement les slides de Claudio Jeker sur MPLS ne sont pas en ligne.

Michael Dexter a parlé de virtualisation dans le monde BSD ( plus de documents). Son exposé avait deux grands axes : une classification des techniques de virtualisation existante, et surtout une présentation de BHyVe, un hyperviseur de type 2 (à la Xen) pour FreeBSD.


28/03/2015

% tar -jx < *.bz >> Écrire un fichier de complétion pour zsh

Tags:

zsh est très connu pour son système de complétion très poussé. Malheureusement, zsh n'est pas équipé pour gérer les conventions d'appel de tous les outils qu'on peut trouver sur nos babasses. On peut donc être amené à écrire soi-même une méthode de complétion. Ces notes ont été prises à l'occasion de l'écriture d'un fichier de complétion pour ezjail, et les exemples viennent de là.

1 Parfois, il n'y a presque rien à faire…

Il y a quelques cas où on n'a presque rien à faire pour bénéficier de la complétion sur un nouvel outil. Par exemple, si un outil utilise les conventions GNU, zsh peut parser la sortie de --help pour obtenir la liste des options existantes. Il suffit pour cela d'ajouter quelque chose comme :

compdef _gnu_generic foo

dans un fichier lu par zsh ( .zshrc conviendra), et de relancer son shell pour pouvoir compléter les options de foo. On a même le droit à la documentation des options.

Un autre cas où l'on n'a presque rien à faire est lorsqu'on peut réutiliser une complétion existante. Si un outil attend comme argument uniquement des noms d'hôtes, on utilisera :

compdef _hosts foo

Maintenant, en tapant foo <TAB>, zsh proposera des complétions basées sur les noms d'hôtes, trouvés par `getent hosts` ou qui sont dans l'une des bases ssh_known_hosts entre autres.

Dans l'exemple au-dessus, _hosts est le nom d'une fonction zsh, dont la définition est (sur mon système) dans /usr/local/share/zsh/4.3.11/functions/Completion/Unix.

La documentation de zsh donne un autre exemple assez courant : le cas d'une commande qui accepte tous les fichiers qui ont une certaine extension.

compdef '_files -g "*.h"' foo

Ici, _files est encore une fonction, définie au même endroit que _hosts (et bon courage à celui qui voudra se plonger dans le code de cette fonction…). La documentation de cette fonction est visible dans le manuel de zsh, au nœud «  Completion Functions > Utility Functions  ».

2 …parfois c'est plus compliqué

Lorsqu'on a des besoins plus poussés, au hasard pour un outil tel qu'ezjail, on va devoir coder sa propre complétion. Une complétion n'est en soi qu'une fonction zsh qui est appelée par le shell lorsque l'utilisateur appuie sur TAB (ou C-d pour afficher les complétions).

Les fonctions de complétions sont installées par défaut dans /usr/local/share/zsh/site-functions/ (l'emplacement exact peut dépendre de votre OS). Par convention, le fichier dans lequel vous allez écrire votre fonction de complétion a le même nom que la commande concerné, avec un _ ajouté au début.

Lors du développement d'un fichier de complétion, il sera peut-être plus pratique de pouvoir éditer le fichier sans être root. Dans ce cas, il suffit de choisir un dossier local, par exemple ~/zsh. On placera le fichier de complétion dedans, et on l'ajoute au tableau $fpath (bien sûr, à placer avant l'appel à compinit) :

fpath=(~/zsh $fpath)

Notons que zsh refusera de charger des fonctions (donc des définitions de complétion) si le fichier appartient à un utilisateur autre que root ou l'utilisateur courant, ou s'il est modifiable par un autre utilisateur.

Le fichier de complétion commence avec un tag spécial sur la première ligne :

#compdef ezjail-admin

C'est un commentaire, qui indique à zsh que le fichier contient une complétion, et bien sûr quelle commande est concernée.

Ensuite, on définit une fonction de complétion, et on l'appelle :

          _ezjail () {
    
          # 
          code de complétion
}

_ezjail 
          "$@"

        

2.1 Informations fournies par le shell aux fonctions de complétions

Notre code, ici la fonction _ezjail, sera appelée avec quelques informations sur la ligne de commande qui a déjà été saisie par l'utilisateur.

Les informations qui sont accessibles depuis le code de complétion seront les suivantes :

Variable Description
$words Les mots déjà entrés par l'utilisateur
$CURRENT L'index, dans $words, du mot que l'utilisateur essaie de compléter (c'est $#words sauf si l'utilisateur est revenu en arrière)
$curcontext Une chaîne de caractères, décrivant le contexte courant

Le contexte courant est utilisé en interne à zsh pour savoir comment interpréter les demandes de complétions. Depuis le code de complétion, on passera aussi $curcontext à zstyle pour récupérer les styles de complétion voulus par l'utilisateur. Comme je n'utilise pas zstyle, je ne me suis pas beaucoup avancé dans cette direction.

Si vous avez sous les yeux le fichier de complétion d'ezjail, vous verrez que la fonction principale, _ezjail, fait un petit tour de passe-passe sur ces variables pour sauter sur la fonction correspondant à la sous-commande déjà entrée. La plupart des outils pourront certainement se passer d'une telle manipulation.

2.2 Renvoyer les candidats à la complétion

Pour renvoyer à zsh les complétions elles-mêmes, on va utiliser l'une des fonctions de complétion. La fonction _arguments sera notre outil principal, en particulier pour les outils qui ont des options standards.

2.2.1 Exemple typique

Si l'on prend comme exemple la complétion (un peu réorganisée) pour ezjail-admin create:

              _ezjail_cmd_create () {
    _arguments -s : 
              \
        
              "-i[file-based jail]" 
              \
        
              "-x[jail exists, only update the config]" 
              \
        
              "-a[restore from archive]:archive:_files" 
              \
        
              "-c[image type]:imagetype:(bde eli zfs)" 
              \
        
              "-C[image parameters]:imageparams:" 
              \
        
              "-s[size of the jail]:jailsize:" 
              \
        
              ":jail name:" 
              \
        
              ":comma-separated IP addresses:"
}

            

Le -s donné à _arguments permet de dire que pour cette commande, les options courtes peuvent être combinées, i.e. -ix est équivalent à -i -x. Le texte entre crochets est affiché à côté de la complétion, sauf si l'utilisateur a désactivé cela.

Dans l'exemple au-dessus, -i et -x sont des options qui n'attendent pas d'arguments. Les autres options attendent des arguments : on les distingue parce qu'une description de l'argument et une méthode pour compléter cet argument sont données, avec des : pour séparer les champs. Dans le cas de -a, l'argument sera complété par la fonction _files, qui propose des noms de fichiers comme choix. Dans le cas de -c, la completion se fait sur un petit nombre de choix possibles, qui sont donnés entre parenthèses. Pour -C, on indique qu'on attend un mot donné par l'utilisateur, mais le shell n'aidera pas à le compléter.

Enfin, la commande prend encore deux arguments, mais on ne sait pas offrir d'aide pour les compléter (il n'y a rien avant le premier :).

2.2.2 Options mutuellement exclusives

Il peut y avoir des cas où des options sont mutuellement exclusives. C'est le cas pour ezjail-admin archive : ou bien l'on archive toutes les jails avec -A, ou alors on donne une liste de jails.

              _ezjail_cmd_archive () {
    _arguments -s : 
              \
        
              "-a[archive name]:archive name:" 
              \
        
              "-d[destination directory]:destination dir:_files -/" 
              \
        
              "-f[archive the jail even if it is running]" 
              \
        - archiveall 
              \
            
              "-A[archive all jails]" 
              \
        - somejails 
              \
            
              "*:jail:_ezjail_stopped_jails"
}

            

On sépare les groupes d'options qui s'excluent avec un tag (je ne sais pas si le nom est réutilisé pour être montré à l'utilisateur dans certaines circonstances). Les options qui peuvent toujours être utilisées sont données en premier. Remarquez au passage l'astérisque pour la dernière ligne : cela permet d'indiquer qu'on peut avoir des répétitions.

2.2.3 _values: plus simple

Lorsqu'on a juste une liste de mots à proposer, surtout si cette liste est générée dynamiquement, les arguments pour _arguments ne sont pas faciles à manipuler. Dans ce cas, _values, qui permet de simplement donner la liste des mots candidats à la complétion, est plus facile à manipuler. En prenant comme exemple _ezjail, dans le cas où on propose les sous-commandes, on a :

              _ezjail () {
    
              local cmd
    
              if (( CURRENT > 2)); 
              then
        
              # 
              déjà un mot complet sur la ligne; sauter à la fonction
        
              # 
              spécifique à cette sous-commande.
    
              else
        
              # 
              on complète la sous-commande
        _values :                                                
              \
            
              "archive[create a backup of one or several jails]"   
              \
            
              "config[manage specific jails]"                      
              \
            
              "console[attach your console to a running jail]"     
              \
            
              "create[installs a new jail inside ezjail\'s scope]" 
              \
            
              "cryptostart[start the encrypted jails]"             
              \
            
              "delete[removes a jail from ezjail\'s config]"       
              \
            
              "install[create the basejail from binary packages]"  
              \
            
              "list[list all jails]"                               
              \
            
              "restart[restart a running jail]"                    
              \
            
              "restore[create new ezjails from archived versions]" 
              \
            
              "start[start a jail]"                                
              \
            
              "stop[stop a running jail]"                          
              \
            
              "update[create or update the basejail from source]"
    
              fi
}

            

2.2.4 compadd: pour construire les complétions au fur et à mesure

compadd est le builtin utilisé par _arguments, _values et les autres fonctions pour ajouter les candidats à la complétion. Il y a certains cas où il est plus facile d'ajouter un à un les candidats. C'est le cas pour lister les jails : une première version utilisait quelque chose de la forme :

              _ezjail_running_jails () {
    _values : 
              `_ezjail_list_jails running`
}


              _ezjail_list_jails () {
    
              local 
              jailcfgs=
              "/usr/local/etc/ezjail"
    
              local 
              state=$
              1
    
              local j
    ( 
              cd $
              jailcfgs && 
              echo * ) | 
              while 
              read j; 
              do
        
              case $
              state
               in
        running) [[ -f /var/run/jail_${
              j}.id ]] && 
              echo $
              j ;;
        stopped) [[ -f /var/run/jail_${
              j}.id ]] || 
              echo $
              j ;;
        *)       
              echo $
              j ;;
        
              esac
    
              done
}

            

Le problème est que lorsque la sortie de _ezjail_list_jails est vide, _values remonte un message d'erreur parce qu'on ne lui a donné aucun argument. Pour corriger cela, une première solution pourrait être de capturer la sortie de _ezjail_list_jails dans une variable, tester si cette variable est vide ou non, et agir en conséquence. La deuxième solution, qui est celle que j'ai retenu, est de faire ajouter à _ezjail_list_jails les complétions elles-mêmes. Il faut encore gérer à part le cas où il n'y a pas de candidats à la complétion, en revoyant 1 dans ce cas ; mais c'est plus facile à gérer. Au passage, la première version ne renvoyait pas 1 en l'absence de candidates… L'implémentation ressemble à ceci :

              _ezjail_running_jails () {
    _ezjail_list_jails running
}


              _ezjail_list_jails () {
    
              local 
              jailcfgs=
              "/usr/local/etc/ezjail"
    
              local 
              state=$
              1
    
              local 
              ret=1
    
              local j
    
              for j
               in $
              jailcfgs/*(:t) ; 
              do
        
              case $
              state
               in
        running) [[ -f /var/run/jail_${
              j}.id ]] && compadd $
              j && 
              ret=0 ;;
        stopped) [[ -f /var/run/jail_${
              j}.id ]] || compadd $
              j && 
              ret=0 ;;
        *)       compadd $
              j && 
              ret=0 ;;
        
              esac
    
              done
    
              return $
              ret
}

            

compadd, en tant que brique de base, permet bien plus que de simplement ajouter un candidat. Encore une fois, allez voir la documentation pour tous les détails.

2.3 Style

Le code de complétion est lancé à chaque fois que l'utilisateur tapotte sa touche TAB ou C-d. Le code doit donc être raisonnablement rapide.

Par ailleurs, le code de complétion s'exécute dans le shell courant de l'utilisateur. En particulier :

  • le code n'a pas le droit de faire un exit ;
  • il ne peut pas afficher de chose sur std{out,err} sans faire une horrible mixture entre le prompt, les propositions de complétion et ce qui est affiché ;
  • il faut penser à retourner 1 si on n'a pas de candidats à la complétion ;
  • toutes les variables utilisées doivent être déclarées avec local, pour éviter d'écraser ou de polluer les variables du shell courant de l'utilisateur ;
  • on écrit du code pour zsh, on a toute latitude pour écrire du code qui n'est pas POSIX.

Il y a également completion-style-guide, qui est chez moi dans /usr/local/share/doc/zsh ( copie en ligne), qui donne des conseils. J'ai découvert ce fichier un peu tard, et la complétion pour ezjail ne suit pas toujours à la lettre les conseils donnés.

Bien sûr, lorsqu'on a quelque chose qui marche, on le propose au projet en question, ou alors directement sur la liste zsh-workers@, pour en faire profiter les petits copains.

3 À voir

A User's Guide to the Z-Shell, Peter Stephenson, Chapter 6: Completion, old and new. Il y a en particulier un tutorial bien fait.

The Z Shell Manual, 20. Completion System, et en particulier 20.6 Utility Functions. Vous en avez certainement une version accessible en local avec info zsh (ou C-h i m zsh depuis emacs). Le manuel est assez aride, je ne l'ai utilisé que comme référence.

zsh completion support for ezjail , de votre serviteur.


28/03/2015

% tar -jx < *.bz >> Déménagement

Tags:

Déménagement…

23c23
< TIMEZONE="Europe/Paris"
---
> TIMEZONE="Europe/Brussels"

28/03/2015

% tar -jx < *.bz >> emacs dans Tron

Tags:

L'info fait le tour des blogs sur emacs: emacs est utilisé dans Tron 2.0. Plus précisément, eshell est utilisé pour tuer la vidéo que Sam Flynn utilise pour se moquer du conseil d'administration. jtnimoy, derrière les effets spéciaux du film, donne tous les détails.

emacs était déjà visible dans The Social Network, où Big Brother Zuckerberg dit qu'il est « temps de sortir emacs pour modifier un script Perl ».

emacs est une star, vi ne peut vraiment pas en dire autant…


28/03/2015

% tar -jx < *.bz >> ezjail : mettre à jour ses jails FreeBSD avec freebsd-update

Tags:

ezjail (sur la documentation duquel votre serviteur a pas mal travaillé ces derniers temps) est un outil d'administration des jails pour FreeBSD. Dirk Engling a ajouté il y a peu la possibilité de mettre à jour le système de base des jails en utilisant FreeBSD Update (c'est dans le CVS, pas encore dans la dernière version d'ezjail). Il est donc possible de passer son serveur FreeBSD avec ses jails d'une version à l'autre sans avoir à compiler quoi que ce soit.

1 Les jails de FreeBSD

Quelques petits rappels pour les malheureux Linuxiens qui ne connaîtraient pas les jails de FreeBSD. Les jails de FreeBSD sont parfois comparées à des chroot sur stéroïdes ; maintenant que Linux a des choses telles qu'OpenVZ ou LXC, il faudrait plutôt utiliser cela comme comparaison.

Les jails pour FreeBSD ont été introduites dans FreeBSD 4.0 (mars 2000) par Poul-Henning Kamp (le développeur derrière UFS2 et pas mal de code tournant autour du stockage disque, l'auteur du malloc(3) de FreeBSD, du cache Varnish, et l'inventeur de l'expression bikeshedding ). Une jail est définie par :

  • un dossier racine ;
  • un nom d'hôte ;
  • optionnellement une ou plusieurs adresses IP ;
  • une commande, qui est typiquement /etc/rc pour lancer un FreeBSD complet.

Depuis l'intérieur de la jail, il est impossible de sortir du dossier racine, contrairement à un chroot(2). Les processus tournant à l'intérieur de la jail ne peuvent utiliser que les adresses IP attribuées par l'administrateur pour se connecter ou accepter des connexions externes.

Le dossier attribué à une jail peut être tout petit (une dizaine de fichiers, comme le décrit Bapt dans ses NANO Jails), ou contenir un système FreeBSD complet (voire un système CentOS, en utilisant la couche d'émulation de Linux).

Pour des jails contenant un système FreeBSD complet, on voit qu'il peut rapidement y avoir quelques difficultés d'administration :

  • une approche naïve conduirait à avoir autant d'installations de FreeBSD que de jails, ce qui est gourmand en espace disque (et en consommation mémoire, les bibliothèques dynamiques ne pouvant pas être partagées) ;
  • lorsqu'une mise à jour est publiée, il faut réaliser autant de mises à jour que de jails ;
  • même si créer une jail est facile et se fait en environ 6 lignes, cela pourrait être encore plus simple.

ezjail propose une solution à tout cela, et notamment aux deux premiers points en utilisant mount_nullfs(4) (l'équivalent du mount -o bind de Linux) pour fournir à toutes les jails une unique installation de FreeBSD en lecture seule ; cette installation est appelée la basejail. ezjail a un certain nombre d'autres fonctionnalités, que je ne déveloperai pas ici.

2 Mise à jour du système de base

2.1 Pour l'hôte

Depuis l'introduction de FreeBSD Update, il est possible de mettre à jour son OS diabolique, y compris d'une version à l'autre. La procédure est décrite à chaque fois dans l'annonce de sortie, mais se résume à :

  • télécharger les nouveaux fichiers et merger les fichiers de configuration (c'est l'étape demandant un peu d'intervention manuelle) avec freebsd-update -r 8.2-RELEASE ;
  • installer le nouveau noyau avec freebsd-update install, et rebooter sur le nouveau noyau ;
  • installer les nouveaux fichiers du « monde », avec un deuxième passage de freebsd-update install ;
  • s'il s'agit d'un changement de branche (par exemple 7.4 -> 8.2), recompiler les ports contre les nouvelles bibliothèques.

2.2 Pour les jails

Comme nous l'avons dit au début, ezjail dans sa version CVS permet de mettre à jour la basejail à partir de FreeBSD Update. Le port ezjail n'a pas encore été mis à jour. J'ai un port local d'ezjail, qui installe directement à partir du CVS.

Une fois la version CVS d'ezjail installée, la mise à jour se fait tout simplement :

# ezjail-admin update -s 8.1-RELEASE -U

On notera qu'il est nécessaire de donner la version actuelle de la basejail : FreeBSD Update utilise en temps normal uname -r pour connaître la version actuelle de la machine, ce qui n'est bien sûr pas possible dans une jail, puisque uname va renvoyer la version du noyau de l'hôte, et non de l'espace utilisateur de la basejail.

Un problème : freebsd-update(8) détecte les composants installés à partir de deux choses : la ligne Components dans /etc/freebsd-update.conf, et ce qui est réellement sur le disque. Cependant, le noyau est géré un petit peu à part, et est ajouté aux composants à mettre à jour si Components liste kernel et si la nouvelle version vient avec un nouveau noyau, même si le noyau n'est pas installé sur la cible. Bien sûr, vouloir mettre à jour le noyau dans une jail ne va pas donner grand'chose… Ma solution a été de supprimer kernel des composants potentiellement installés. À terme, il faudra probablement qu'ezjail lance freebsd-update avec un fichier de configuration à lui.

2.3 Et pour les ports ?

ezjail a depuis longtemps la possibilité, avec update -p, de mettre à jour l'arbre des ports ; mais pour mettre à jour les ports eux-mêmes, rien de spécial n'est prévu. La technique habituelle, lorsqu'on a beaucoup de machines, est de consacrer une jail à la compilation de ports, et d'utiliser pkg_create -b pour créer des packages qu'on distribue ensuite aux autres jails.