PROJET AUTOBLOG


Planet-Libre

source: Planet-Libre

⇐ retour index

Frédéric Perrin : ZFS pour des mises à jour sereines

samedi 28 mars 2015 à 21:34

Table of Contents

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 portlistuniq
cut -d' ' -f1 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.

Gravatar de Frédéric Perrin
Original post of Frédéric Perrin.Votez pour ce billet sur Planet Libre.

Frédéric Perrin : Notes d'EuroBSDcon 2011

samedi 28 mars 2015 à 21:34

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 :

À 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.

Gravatar de Frédéric Perrin
Original post of Frédéric Perrin.Votez pour ce billet sur Planet Libre.

Frédéric Perrin : Écrire un fichier de complétion pour zsh

samedi 28 mars 2015 à 21:34

Table of Contents

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 , 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.

Gravatar de Frédéric Perrin
Original post of Frédéric Perrin.Votez pour ce billet sur Planet Libre.

Frédéric Perrin : ezjail : mettre à jour ses jails FreeBSD avec freebsd-update

samedi 28 mars 2015 à 21:34

Table of Contents

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.

Gravatar de Frédéric Perrin
Original post of Frédéric Perrin.Votez pour ce billet sur Planet Libre.

Frédéric Perrin : iftop, IPv6 et FreeBSD (et Linux aussi, d'ailleurs)

samedi 28 mars 2015 à 21:34

iftop(8) est un très bon outil pour mesurer l'activité réseau d'une machine. La dernière version stable (0.17), qui est dans tous les bons OS, remonte à février 2006. Récemment, Paul Warren a ajouté le support d'IPv6 (auparavant, seuls les flux en IPv4 étaient pris en compte). Il y a quelques difficultés pour compiler ceci sous FreeBSD ; j'ai une série de patches pour corriger cela, en attendant son intégration par Paul Warren. J'ai aussi un port pour FreeBSD.

Les deux premières choses à corriger sont deux Linuxeries, ajouter un #include oublié ainsi qu' un #define manquant.

La correction suivante est moins triviale. Pour faire la résolution inverse des adresses vues, iftop(8) utilise plusieurs threads, et plusieurs méthodes sont implémentées. Seule la méthode utilisant getnameinfo(3) fait de la résolution inverse en ip6. Cependant, le configure.in fournit refuse d'utiliser getnameinfo(3), avec une note disant que sur certains OS, cette fonction n'est pas thread-safe (NetBSD est donné en exemple).

On peut donc se plonger dans les macros d'autoconf pour utiliser getnameinfo(3) (vous avez le cœur bien accroché ?). Ou alors, on peut patcher resolver.c , au moins c'est du C, on sait où l'on s'aventure. Et oui, vous avez bien lu le code, le code initial essaie de deviner le type de l'adresse en lisant les premiers octets d'un struct in{4,5}_addr.

Pour les FreeBSD'iens, j'ai mis tout cela dans un port. Pour les autres, récupérez les patches liés plus haut (les GNU/Linuxiens se contenteront probablement de celui contre resolver.c). Attention, il y a un bug dans le Makefile fournit, il faut faire make iftop et non make all pour compiler.

Gravatar de Frédéric Perrin
Original post of Frédéric Perrin.Votez pour ce billet sur Planet Libre.