Schplurtzeries
Le wiki de schplurtz
Dokuwiki

24. June 2012 [temps d'exécution et mémoire ?] ztrulphcs

Dokuwiki chez free

DokuWiki fraichement déployé chez free donne l'illusion qu'il fonctionne bien. Et puis, au fur et à mesure qu'on s'en sert, on tombe sur plein de problèmes bizarres et étranges qui font renoncer et passer à un autre produit. NON, c'est pas la faute à DokuWiki, et OUI on peut facilement rendre DokuWiki compatible avec les spécificités de PHP chez free grâce à liberatator.

Liberatator rend DokuWiki freeproof en quelques minutes. Ceci est valable pour toutes les versions de DokuWiki, y compris les versions à venir…

Allez voir la page liberatator et le tuto vidéo

Voici les impacts des problèmes relevés dans cette page, les solutions trouvées pour réussir à faire fonctionner dokuwiki chez free. et d'autres trucs et astuces. Je le répète : Pour appliquer tous ces changements de manière automatique à toutes les versions de dokuwiki, même les versions futures, utiliser le script liberatator. Si vous voulez faire les modifications manuellement, lisez le reste de cette page.

Il est fréquemment fait référence à un fichier preload.php dans cette documentation. Vous en trouverez une copie ici même.

inc/preload.php

sessions

La solution consiste à créer un dossier sessions à la racine de votre espace web chez free.

Versions de php

Les versions de dokuwiki actuelles (2010-11-07 «anteater» et +) fonctionnent avec php 5.

solution

Créer à la racine de son site un fichier nommé .htaccess contenant cette ligne

php 1

Modules PHP manquant

Sans openssl, on ne peut pas utiliser le module plugin:securelogin, seulement à moitié gênant. Le gestionnaire de greffon ne peut pas télécharger les greffons depuis certains sites comme github qui sont en HTTPS. De toutes façons, free a bridé un peu plus PHP, qui ne peut plus rien télécharger du tout. Voir Absence de connexion vers l'extérieur plus bas dans la page.

Sans TLS, on est contraint d'utiliser seulement la fonction mail de PHP. pas très gênant en fait. Le module bureaucracy peut tout de même fonctionner presque normalement (sauf qu'il m'envoie des messages tout pourris à moitié en HTML mais sans y mettre les en-têtes nécessaires)

solution

Décider que c'est un faux problème. On peut toujours installer à la main les greffons dans le répertoire lib/plugins de DokuWiki. En tout cas ce n'est certainement pas vital, sinon :

  • pour le greffon plugin:securelogin, utiliser une bibliothèque SSL pure php (si cela existe) et l'incorporer au greffon plugin:securelogin.
  • pour le gestionnaire de greffon : le modifier vous même, faire parvenir la solution.

glob()

Si on regarde le type de glob() effectué dans dokuwiki, on se rend compte qu'il est très basique. par exemple pour la version «anteater» de fin 2010, voilà ce qu'il y à :

cd dokuwiki-2010-11-07
grep -r  'glob *(' *

inc/pageutils.php:    $files  = glob($dir.$name.'.*');
lib/images/fileicons/index.php:foreach (glob('*.png') as $img) {
lib/images/fileicons/index.php:foreach (glob('*.png') as $img) {
lib/plugins/config/settings/extra.class.php:      $authtypes = glob(DOKU_INC.'inc/auth/*.class.php');

et pour la version rc2011-05-08 “Rincewind RC2”, des trucs à peine plus compliqués

grumpf [3934] 10:56:15 (0) tmp $ grep -nr 'glob *(' dokuwiki-rc2011-05-08
dokuwiki-rc2011-05-08/inc/pageutils.php:318:    $files    = glob($basename.'.*', GLOB_MARK);
dokuwiki-rc2011-05-08/lib/images/fileicons/index.php:35:foreach (glob('*.png') as $img) {
dokuwiki-rc2011-05-08/lib/images/fileicons/index.php:43:foreach (glob('*.png') as $img) {
dokuwiki-rc2011-05-08/lib/plugins/config/settings/extra.class.php:48:      $authtypes = glob(DOKU_INC.'inc/auth/*.class.php');
grumpf [3935] 10:57:42 (0) tmp $ 

Vu le problème dans config/settings/extra.class.php, DokuWiki sera incapable d'utiliser d'autre mécanismes d'authentification que le mécanisme standard (habituellement, c'est pas franchement gênant)

Dans pageutils, par contre c'est dans une fonction appelée metaFiles. Il faut donc s'attendre à ce que certaines fonctionnalités (que je n'ai pas identifiées) soient défectueuses.

solution

On pourra donc se contenter de la fonction myglob() à la main assez simpliste. Il faut la mettre dans le fichier inc/preload.php chargé par dokuwiki avant tout autre chose. Au besoin, créer le fichier inc/preload.php s'il n'existe pas.

Après avoir installé le fichier preload.php avec la fonction myglob() montrée ci-dessus, il faut appliquer la transformation globmyglob à tous les fichiers du répertoire dokuwiki concernés.

rmdir()

Le fait que la fonction rmdir() ne fonctionne pas a trois (au moins) impacts sur dokuwiki :

  1. Le système de verrou basé sur la création – forcément atomique – de répertoires vides ne peux plus fonctionner normalement. On peut remplacer dans inc/io.php la création de répertoire par la création de fichier, et on contourne ainsi le problème. Mais le système de verrou est alors basé sur la création de fichiers et n'est plus atomique. Il est possible, en théorie, qu'un verrou ne soit pas respecté. Sur un wiki fermé avec un seul rédacteur, cela n'est pas gênant, dans tous les autres cas, il y a un problème potentiel. Cela dit, la probabilité pour que deux personnes réussissent à éditer le même document simultanément reste très faible. Le système de verrou basé sur des fichiers n'est pas sûr à 100% mais il s'en approche, et de toutes façons, le risque dépend aussi de l'activité du site…
  2. DokuWiki ne peut plus détruire une catégorie (un namespace) lorsqu'elle devient vide… ça c'est franchement plus gênant.
  3. dokuwiki ne peut pas détruire les dossiers temporaires créés lors de l'installation de nouveau greffons.
  4. DokuWiki ne peut pas enlever correctement un greffon dont on ne veut plus
  5. L'indexation du site ne fonctionne pas, ou mal
  6. certains greffons ne fonctionneront pas ou mal (par exemple plugin:cacherevisionseraser)

Les fichiers atteints

$ grep -r rmdir * | grep -v -e inc/geshi -e install.php -e inc/preload.php

bin/indexer.php:            @rmdir($lock);
bin/indexer.php:    @rmdir($lock);
inc/io.php:        if(@rmdir($dir)) {
inc/subscription.php:            @rmdir($lock);
inc/subscription.php:    return @rmdir($lockf);
lib/exe/indexer.php:            @rmdir($lock);
lib/exe/indexer.php:    @rmdir($lock);
lib/exe/xmlrpc.php:                    @rmdir($lock);
lib/exe/xmlrpc.php:            @rmdir($lock);
lib/plugins/plugin/classes/ap_manage.class.php:            return @rmdir($path);

Comme on ne peut pas faire fonctionner ce qui est dans bin1), on ne s'occupe même pas de bin/indexer.php

Contournements

Le plus simple consiste à remplacer tous les rmdir() par des myrmdir() dans tous les fichiers .php de DokuWiki en utilisant cette définition de myrmdir().

Sinon, on peut faire des trucs plus fins, ou bêtement plus compliqués, c'est comme on veut.

  1. Pour le fichier inc/io.php
    1. fonction io_lock
      remplacer mkdir(lockDir) par fopen($lockDir, 'x'). L'option “x” de fopen équivaut à open( … O_EXCL|O_CREAT); ça devrait faire l'affaire.
    2. fonction io_unlock
      remplacer rmdir($lodkDir) par if(is_file($lockDir)) @unlink($lockDir);
    3. fonction io_sweepNS
      qui enlève les répertoire des catégories vides. Remplacer rmdir par myrmdir. à définir dans preload.php et qui utilise la technique précédemment décrite:
  2. pour les fichiers inc/subscription.php,
    lib/exe/indexer.php,
    lib/exe/xmlrpc.php,
    il s'agit encore une fois de verrous. On fonctionne comme pour io.php : verrous basé sur un fichier; modification du code de ces fichiers.
  3. lib/plugins/plugin/classes/ap_manage.class.php
    on dirait bien un vrai rmdir, pas un verrou. Technique du rename vers répertoire poubelle grâce à la fonction myrmdir.

J'ai créé et détruit des catégories, installé et retiré des greffons, sans rencontrer aucun problème en utilisant les deux techniques. Le plus simple reste le remplacement systématique.

opendir()

opendir() échoue même avec l'opérateur @. La classe de gestion des greffons (entre autre) tente d'ouvrir des répertoires avec @opendir(….), et le script foire. Dans certaines situations, dokuwiki ne fonctionne carrément plus. L'interface de gestion de dokuwiki, entre autre et à tous les coups, ne fonctionne pas.

contournement

Le plus simple est de remplacer tous les appels à opendir par un appell à myopendir dans tous les fichiers .php.

Sinon, comme précédemment, on peut faire au coup par coup. mais c'est plus compliqué. PHP indique avec un beau message d'erreur le nom du fichier qui contient l'erreur et la ligne ou l'erreur s'est produite. Reste alors à modifier le fichier en question…

fonction usleep()

Cette fonction ne fonctionne absolument pas.Je ne m'en étais même pas rendu compte. Il y a quelques fichiers qui l'utilisent, mais le fait que ça ne fonctionne pas ne semble pas gêner.

fonction array_fill_keys()

Cette fonction est absente de PHP chez free. Voir php chez free pour les détails. Le greffon plugin:translation l'utilise, mais c'est l'un des rares. Cette fonction n'est pas utilisée par dokuwiki de base.

La solution est d'inscrire dans le fichier preload.php la version en pur PHP que je donne sur cette page.

Merci à Damien Gaignon d'avoir signalé le problème et testé la solution.

Absence de connexion vers l'extérieur

Symptôme :

  • Le gestionnaire de greffons ne peut pas télécharger les modules complémentaires depuis d'autre sites.
  • L'agrégateur interne de flux ATOM et RSS ne peut pas fonctionner : Les syntaxes du genre {{rss>http://slashdot.org/index.rss 5 author date 1h }} produisent ce message, pas le flux :
    Une erreur s'est produite en récupérant ce flux : http://slashdot.org/index.rss
  • Dokuwiki ne peut pas vérifier s'il existe une version plus récente de lui même.

Pas de connexion vers l'extérieur

Voir php chez free pour les explications semi techniques et les possibilités de déblocage d'URL externe.

Informations de debugage de dokuwiki lors du téléchargement d'un greffon

Contournement

Dès que vous êtes frappé par ce problème, il faut installer les greffons manuellement en les téléversant dans le dossier lib/plugins/nom-du-greffon.

Le gestionnaire de modules externes peut toujours supprimer les modules.

temps d'exécution et mémoire ?

D'autre problèmes surviennent sans qu'il soit possible de vraiment savoir… Est-ce que le temps d'exécution d'un script est dépassé, ou bien s'agit-il d'un dépassement de mémoire ?

Le greffon gallery par exemple ne parvient pas à afficher toutes les miniatures d'un gros namespace (365 images de 260 ko chacune env).

De même, en utilisant le même namespace que pour le greffon gallery, le greffon imageflow ne charge qu'une partie des images.

Dans les deux cas, les images sont valides.

1) pas de shell disponible pour lancer ça et `` ne fonctionne pas chez free