Changeset 88450 in spip-zone


Ignore:
Timestamp:
Apr 4, 2015, 2:03:51 PM (4 years ago)
Author:
marcimat@…
Message:

Création d'une branche expérimentale afin de gérer différemment les migrations entre serveurs.

La configuration à réaliser pour migrer les données (sql, IMG) d'un serveur à l'autre est
actuellement assez complexe, et nécessite la création de clés ssh, la présence de certains
outils sur les serveurs, pas toujours évidents à mettre en place ; d'autant que c'est apache qui
exécute ici les commandes (et non pas l'utilisateur qui se connecte au site par ssh, comme c'est
le cas si on utilise php en ligne de commandes).

On cherche à simplifier tout cela dans cette branche en utilisant des transferts par HTTP,
comme le fait le plugin "Migration" d'ailleurs, mais d'une manière quelque peu différente.

Cela nécessite l'installation de notre plugin "Migrateur" sur les 2 sites, et de le configurer
d'un côté comme source ; de l'autre comme destination. La configuration du serveur source
crée automatiquement des clés, l'une pour l'authentification (qui se périme au bout de 12h), l'autre
qui sert à crypter les données transmises (cryptage aes qui utilise https://github.com/defuse/php-encryption).

La communication s'effectue en json, avec un message en 2 partie : 'key' est la clé d'authentification (en clair) et
'message' est le contenu du message crypté aes, qui contient l'action demandée au serveur ou sa réponse. Le message
décodé est par défaut un tableau [action: xxx, data: yyy] où xxx est une chaîne et yyy est une donnée libre.

Le cas d'une demande de récupérer un fichier est légèrement différent et créera une communication en stream où
chaque morceau est également transmis crypté de la même façon ; et décrypté de la même façon sur le
serveur destination. On utilise pour ça toujours la librairie php-encryption ainsi qu'un filtre sur
les stream php pour les encoder ou décoder à la volée. Lorsque le fichier est entièrement reçu,
on vérifie que le fichier est identique (sha256) à ce qui était attendu.

Avec ce dépot, les actions de création et téléchargement du dump sql semble fonctionner (en local du moins).
On s'appuie sur un appel à mysqldump si cette librairie est présente, sinon on utilise une librairie PHP équivalente
(https://github.com/ifsnop/mysqldump-php) pour créer le dump SQL.

Il reste à gérer une approximation d'un rsync du répertoire IMG pour que les fonctionnalités soient à peu près équivalentes
à ce qu'on avait avant. Je suppose que la première migration sera beaucoup plus longue par HTTP que par la commande rsync+ssh
équivalente. On n'a rien sans rien

Il manque donc encore quelques dépots et tests avant que ça puisse servir correctement.

Note: désolé de ce gros commit ; j'ai en partie utilisé GIT en local, mais pas assez tôt pour utiliser git-svn.
Bref, c'est un peu beaucoup d'un coup.

Location:
_plugins_/migrateur/dev-by-http
Files:
75 added
10 deleted
12 edited
5 copied

Legend:

Unmodified
Added
Removed
  • _plugins_/migrateur/dev-by-http/CHANGELOG.md

    r87375 r88450  
    11CHANGELOG
    22=========
     3
     4Version 3.0
     5-----------
     6
     7Suppression de tout ce qui concerne la connexion SSH et Rsync, trop compliqué à utiliser
     8en fonction des différentes permissions des serveurs ;
     9
     10Gestion d'une relation client / serveur sécurisée pour les transferts, par HTTP,
     11(un peu comme le plugin 'migration' d'ailleurs) qui prend bien plus de temps pour effectuer
     12certaines taches entre les serveurs, tel que la syncronisation de IMG/ par exemple,
     13mais qui simplifie grandement la mise en place de l'outil.
     14
     15
    316
    417
  • _plugins_/migrateur/dev-by-http/_doc/index.md

    r81044 r88450  
    1212- l'autre destination (par exemple une future version du site en construction).
    1313
    14 Avec ce plugin configuré présent sur le site de destination, il devient
    15 possible de mettre à jour le site destination à partir des données
    16 du site source.
    17 
    18 Par exemple, cloner le répertoire IMG, installer la base de données source
    19 sur le site destination (à condition que ce SPIP ait une version >= à celui
    20 source).
    21 
    22 Des actions spécifiques peuvent être appliquées, tel que migrer des tables SQL
     14Le plugin permet de définir des actions de migrations, par exemple pour :
     15- synchroniser le répertoire IMG du site source vers celui de destination,
     16- exporter et récupérer la base de données source,
     17- insérer cet export SQL dans le site destination (cela nécessite de se ré-authentifier
     18ensuite au SPIP de destination dont la BDD vient d'être écrasée !),
     19- activer des plugins,
     20- exécuter toute tâche de migration que vous avez définie, tel que migrer des tables SQL
    2321dans un nouveau format.
    2422
    2523
    26 ## Conditions
     24## Installation
    2725
    28 Cette migration nécessite d'avoir des droits de lecture sur le répertoire
    29 source du site SPIP, ainsi que de pouvoir se connecter à la base de données source.
     26Ce plugin doit être présent, actif et configuré sur les 2 sites.
    3027
    31 Évidemment, il faudra des droits d'écriture sur les répertoires du site de destination.
     28La configuration permet d'indiquer le statut du site (source ou destination),
     29ainsi que de créer différentes clés de sécurités (côté source) qui serviront
     30à l'authentification et au chiffrement des échanges avec le site destination.
     31
     32Ces clés doivent être renseignées sur le site de destination.
     33
     34L'une de ces clés est périssable (validité de 12h par défaut)
     35et doit donc être redéfinie régulièrement.
    3236
    3337
    34 ## Installation
     38
     39## Liste des actions
    3540
    3641Une fois ce plugin installé, il est nécessaire, de surcharger, dans un plugin
     
    3944 `squelettes/migrateur/config.php`
    4045
    41 Il faudra alors configurer ce fichier avec les données adéquates.
     46Il faudra alors configurer ce fichier avec les données adéquates,
     47en indiquant les différentes actions souhaitées.
    4248
    4349
     
    4854  et mots de passe) nécessaires pour les sites source et destination
    4955- d'autre part il faut indiquer la liste des étapes de migration à réaliser.
    50 
    51   Voir le chapitre consacré à ces étapes.
    52 
    53 ### Constantes de configuration
    54 
    55 La liste des constantes possibles est indiquée dans la 2è partie du fichier d'exemple
    56 (après la liste des étapes). Certaines sont obligatoires, d'autres sont optionnelles.
    57 
    58 #### Constantes du site source
    59 
    60 ##### Constantes obligatoires
    61 
    62 MIGRATEUR_SOURCE_DIR
    63 : Chemin absolu, complet depuis la racine du serveur jusqu'au répertoire racine du SPIP
    64 
    65 MIGRATEUR_SOURCE_SQL_USER
    66 : Nom d'utilisateur de la base de données (doit accéder en lecture à celle-ci)
    67 
    68 MIGRATEUR_SOURCE_SQL_PASS
    69 : Mot de passe de l'utilisateur
    70 
    71 MIGRATEUR_SOURCE_SQL_BDD
    72 : Nom de la base de données
    73 
    74 
    75 ##### Constantes optionnelles
    76 
    77 
    78 ### Constantes du site destination
    79 
    80 ##### Constantes obligatoires
    81 
    82 MIGRATEUR_DESTINATION_DIR
    83 : Chemin absolu, complet depuis la racine du serveur jusqu'au répertoire racine du SPIP
    84 
    85 MIGRATEUR_DESTINATION_SQL_USER
    86 : Nom d'utilisateur de la base de données (doit accéder en écriture à celle-ci)
    87 
    88 MIGRATEUR_DESTINATION_SQL_PASS
    89 : Mot de passe de l'utilisateur
    90 
    91 MIGRATEUR_DESTINATION_SQL_BDD
    92 : Nom de la base de données
    93 
    94 ##### Constantes optionnelles
    95 
    96 
    97 ### Autres constantes
    98 
    99 MIGRATEUR_NOM_EXPORT_SQL
    100 : Nom du fichier d'export (extension .sql) de la base de données source
    101  
    102 
    10356
    10457
     
    12275
    12376Il est conseillé d'avoir une clé d'étape préfixée pour mieux se repérer.
    124 Par exemple `mig_rsync_img` est préfixé de `mig_` donc, pour montrer
     77Par exemple `mig_sync_img` est préfixé de `mig_` donc, pour montrer
    12578que cette étape est définie dans le plugin migrateur directement
    12679(et non dans le répertoire squelettes ou dans un plugin dépendant de migrateur).
    12780
    12881Chaque étape, définie par sa clé appelle une fonction PHP spécifique
    129 définie dans le répertoire migrateur. Ainsi, la clé `mig_rsync_img`
    130 appelle la fonction `migrateur_mig_rsync_img` définie dans le fichier
    131  `migrateur/mig_rsync_img.php`, ceci par l'intermédiaire de la fonction
     82définie dans le répertoire `migrateur`. Ainsi, la clé `mig_sync_img`
     83appelle la fonction `migrateur_mig_sync_img` définie dans le fichier
     84 `migrateur/mig_sync_img.php`, ceci par l'intermédiaire de la fonction
    13285 SPIP `charger_fonction($cle, 'migrateur')`.
    13386
     
    13588 `MIGRATEUR_ETAPES` et sa fonction correspondante `migrateur_$cle` dans un fichier
    13689 `migrateur/$cle.php` (ce fichier peut être dans votre plugin ou dans votre répertoire
    137  squelettes, donc dans ce cas dans `squelettes/migrateur/$cle.php` (note : remplacer $cle
     90 squelettes, donc dans ce cas dans `squelettes/migrateur/$cle.php` (note : remplacer `$cle`
    13891 par le nom réel de votre clé !)
    13992
     
    154107### Étapes fournies avec le migrateur
    155108
    156 mig_test
     10900_rien
    157110: Ne fait rien !
    158111
    159 mig_rsync_img
     112mig_test
     113: Teste le bon dialogue entre le site destination et le site source
     114
     115mig_sync_img
    160116: Synchronise le répertoire IMG source avec le répertoire IMG destination.
    161117  Cela supprimera aussi sur le site de destination les fichiers de IMG éventuellement en trop.
    162118
    163 mig_exporter_bdd
    164 : Crée un export de la base de données source.
     119mig_bdd_source_make_dump
     120: Crée un export de la base de données source, sur le site source (dans tmp/dump).
    165121  Cela n'affecte pas la base de données de destination.
    166122
    167 mig_transferer_bdd
    168 : Copie le dernier export réalisé dans la base de données de destination.
     123mig_bdd_source_get_dump
     124: Télécharge le dernier export fait sur le site source, dans site destination (dans tmp/dump)
     125  Cela n'affecte pas la base de données de destination.
     126
     127mig_bdd_destination_put_dump
     128: Copie le dernier export réalisé dans la base de données de destination (dans tmp/dump).
    169129  Attention, une fois cela fait, vous n'aurez plus accès au migrateur
    170130  aussitôt. Vous devrez vous reconnecter, et peut être effectuer des mises
     
    173133
    174134  Si tout s'est bien passé, le plugin Migrateur (et tout autre plugin
    175   qui était actif dont le préfixe commence par `migrateur`) sera toujours actif.
     135  qui était actif dont le préfixe contient le terme `migrateur`) sera toujours actif.
    176136  Vous pourrez donc vous rendre facilement à la page exec=migrateur pour continuer.
    177137
    178   Une partie des plugin du site source ne seront peut être plus actifs,
    179   si, dans le site de destination, ils n'ont pas le même chemin depuis le
    180   répertoire `plugins/`. Il vous faudra, si vous le souhaitez, les réactiver.
    181   Pour cela, une fonction de migration peut s'en charger (le migrateur
     138  Une partie des plugins du site source ne seront peut être plus actifs.
     139  C'est le cas si, dans le site de destination, ils n'ont pas le même chemin depuis le
     140  répertoire `plugins/` que sur le site source. Il vous faudra, si vous le souhaitez,
     141  les réactiver. Pour cela, une fonction de migration peut s'en charger (le migrateur
    182142  dispose de quelques outils pour faciliter la tâche).
    183143
  • _plugins_/migrateur/dev-by-http/action/migrateur.php

    r81044 r88450  
    22
    33if (!defined("_ECRIRE_INC_VERSION")) return;
    4 
    5 
    6 include_spip('migrateur/config');
    7 include_spip('inc/migrateur');
    84
    95
     
    1814        $arg = $securiser_action();
    1915
     16        include_spip('migrateur/config');
     17        include_spip('inc/migrateur');
     18
    2019        $func = charger_fonction($arg, 'migrateur', true);
     20
     21        /* En cas de demande de flux continue des logs, préparer ce qu'il faut */
     22        $stream = (bool) _request('stream');
     23        if ($stream) {
     24                // forcer les logs à faire des echos
     25                migrateur_log("", "", true);
     26                // forcer l'absence de redirection ajax
     27                $GLOBALS['redirect'] = "";
     28
     29                header('Content-type: text/html; charset=utf-8');
     30                #header('Content-type: application/octet-stream;');
     31
     32                // Turn off output buffering
     33                ini_set('output_buffering', 'off');
     34                // Turn off PHP output compression
     35                ini_set('zlib.output_compression', false);
     36                // Implicitly flush the buffer(s)
     37                ini_set('implicit_flush', true);
     38                ob_implicit_flush(true);
     39                // Clear, and turn off output buffering
     40                while (ob_get_level() > 0) {
     41                        // Get the curent level
     42                        $level = ob_get_level();
     43                        // End the buffering
     44                        ob_end_clean();
     45                        // If the current level has not changed, abort
     46                        if (ob_get_level() == $level) break;
     47                }
     48
     49                // Disable apache output buffering/compression
     50                if (function_exists('apache_setenv')) {
     51                        apache_setenv('no-gzip', '1');
     52                        apache_setenv('dont-vary', '1');
     53                }
     54        }
    2155
    2256        if (function_exists($func)) {
     
    4074                if ($nb) {
    4175                        migrateur_log("-----| Étape n°$nb");
    42                         migrateur_log("     | " . $GLOBALS['MIGRATEUR_ETAPES'][$arg]);
     76                        migrateur_log("     | <em>" . $GLOBALS['MIGRATEUR_ETAPES'][$arg] . "</em>");
    4377                } else {
    4478                        migrateur_log("-----> " . $GLOBALS['MIGRATEUR_ETAPES'][$arg]);
     
    5185
    5286        } else {
    53                 die("La fonction $func n'existe pas !");
     87                die("La fonction <code>$arg</code> n'existe pas !\n");
    5488        }
    5589}
    5690
    5791
    58 
    59 
    60 ?>
  • _plugins_/migrateur/dev-by-http/class/Data.php

    r88075 r88450  
    44 * Classe pour stocker les paramètres de migration
    55 *
    6  * @package SPIP\Migrateur\Migrateur_DATA
     6 * @package SPIP\Migrateur\Data
    77**/
    8 
    9 if (!defined("_ECRIRE_INC_VERSION")) return;
    10 
     8namespace SPIP\Migrateur;
    119
    1210/**
     
    1412 *
    1513**/
    16 Class Migrateur_DATA {
     14Class Data {
    1715
    1816        /**
     
    2826        private $sql = null;
    2927
    30         /**
    31          * Chemin d'accès SSH
    32          * @var Migrateur_SSH|null
    33          */
    34         private $ssh = null;
    3528
    3629        /**
     
    4033        **/
    4134        public function __construct($props = array()) {
     35
     36                $this->dir = realpath(_DIR_RACINE);
     37
    4238                if (is_array($props)) {
    4339                        foreach($props as $prop => $val) {
     
    4743                        }
    4844                }
    49                 if (isset($props['ssh']) and isset($props['ssh']['server']) and $props['ssh']['server']) {
    50                         $this->ssh = new Migrateur_SSH($props['ssh']);
    51                         $this->ssh->setParent($this);
     45
     46                $this->sql = new Sql();
     47                $this->sql->setParent($this);
     48                if (!empty($props['sql'])) {
     49                        $this->sql->setInfos($pros['sql']);
     50                } else {
     51                        $this->sql->setInfosAuto();
    5252                }
    53                 if (isset($props['sql']) and $props['sql']) {
    54                         $this->sql = new Migrateur_SQL($props['sql']);
    55                         $this->sql->setParent($this);
    56                 }
     53
    5754        }
    5855
     
    6259        public function __get($prop) {
    6360                if (!property_exists($this, $prop)) {
    64                         throw new Exception("Paramètre " . $prop . " inconnu");
     61                        throw new \Exception("Paramètre " . $prop . " inconnu");
    6562                }
    6663                return $this->$prop;
     
    7168         * Retourne le code permettant d'exécuter une commande sur le serveur
    7269         *
    73          * Le code retourné dépend à la fois du fait si la connexion au serveur
    74          * est locale ou par SSH ; et du chemin vers la commande sur le serveur
    75          * (très souvent /usr/bin/$command, mais pas toujours)
    76          *
    7770         * @api
    7871         * @example
    7972         *     ```
    80          *     $source = migrateur_source();
    81          *     if ($cmd = $source->commande('rsync')) {
     73         *     $infos = migrateur_infos();
     74         *     if ($cmd = $infos->commande('rsync')) {
    8275         *         exec("$cmd ... ...")
    8376         *     }
     
    8982        **/
    9083        function commande($command) {
    91                 if ($this->ssh) {
    92                         return $this->ssh->obtenir_commande_serveur($command);
    93                 }
    9484                return $this->obtenir_commande_serveur($command);
    9585        }
     
    10090         * @example
    10191         *     ```
    102          *     $source = migrateur_source();
    103          *     $cmd = $source->obtenir_commande_serveur('rsync');
     92         *     $infos = migrateur_infos();
     93         *     $cmd = $infos->obtenir_commande_serveur('rsync');
    10494         *     if ($cmd)
    10595         *         exec("$cmd ... ... ");
  • _plugins_/migrateur/dev-by-http/class/Sql.php

    r88075 r88450  
    44 * Classe pour stocker les paramètres SQL
    55 *
    6  * @package SPIP\Migrateur\Migrateur_SQL
     6 * @package SPIP\Migrateur\Sql
    77**/
    8 
    9 if (!defined("_ECRIRE_INC_VERSION")) return;
    10 
    11 
     8namespace SPIP\Migrateur;
    129
    1310/**
    1411 * Stocker les données de connexion à un serveur via ssh
    1512**/
    16 class Migrateur_SQL {
     13class Sql{
     14
    1715        /**
    1816         * Utilisation de mysql ou mysqldump sans mot de passe
     
    2119        **/
    2220        private $login_path = '';
    23        
    24         #private $server = 'localhost';
     21
     22        private $server = 'localhost';
    2523        private $bdd = '';
    2624        private $user = '';
    2725        private $pass = '';
     26        private $prefixe = '';  // souvent 'spip' = prefixe des tables
     27        private $req = '';      // mysql | sqlite
    2828
    2929        /**
    3030         * Parent de cette instance de classe
    31          * @var Migrateur_DATA|null
     31         * @var Spip\Migrateur\Data|null
    3232        **/
    3333        private $parent = null;
     
    3939        **/
    4040        public function __construct($props = array()) {
    41                 if (is_array($props)) {
     41                $this->setInfos($props);
     42        }
     43
     44
     45        /**
     46         * Permet de passer un tableau de couples de données (cle => valeur)
     47        **/
     48        public function setInfos($props = array()) {
     49                if (is_array($props) and $props) {
    4250                        foreach($props as $prop => $val) {
    4351                                if (property_exists($this, $prop)) {
     
    4957
    5058        /**
     59         * Calcul automatiquement des identifiants de connexion à partir du fichier config/connect.php
     60        **/
     61        public function setInfosAuto() {
     62                if (!is_readable(_FILE_CONNECT)) {
     63                        $this->parent->log("Impossible de calculer les identifiants de connexion");
     64                        return false;
     65                }
     66                include_spip('inc/install');
     67                $data = analyse_fichier_connection(_FILE_CONNECT);
     68                if (!$data) {
     69                        $this->parent->log("Impossible de lire les identifiants de connexion");
     70                }
     71
     72                $this->serveur = array_shift($data);
     73                $this->user = array_shift($data);
     74                $this->pass = array_shift($data);
     75                $this->bdd = array_shift($data);
     76                $this->req = array_shift($data);
     77                $this->prefixe = array_shift($data);
     78        }
     79
     80
     81        /**
    5182         * Permet d'obtenir une propriété de la classe
    5283        **/
    5384        public function __get($prop) {
    5485                if (!property_exists($this, $prop)) {
    55                         throw new Exception("Paramètre " . $prop . " inconnu");
     86                        throw new \Exception("Paramètre " . $prop . " inconnu");
    5687                }
    5788                return $this->$prop;
     
    6192         * Définit un accès au parent
    6293         *
    63          * @param Migrateur_DATA $data
     94         * @param Spip\Migrateur\Data $data
    6495        **/
    65         public function setParent(Migrateur_DATA $data) {
     96        public function setParent(Data $data) {
    6697                $this->parent = $data;
    6798        }
  • _plugins_/migrateur/dev-by-http/inc/migrateur.php

    r85955 r88450  
    77**/
    88
     9use SPIP\Migrateur;
     10
     11
    912if (!defined("_ECRIRE_INC_VERSION")) return;
    1013
    1114include_spip('inc/migrateur_aide');
    12 include_spip('inc/Migrateur_SSH');
    13 include_spip('inc/Migrateur_SQL');
    14 include_spip('inc/Migrateur_DATA');
    15 
    1615
    1716
    1817/**
    19  * Retourne les données d'accès au serveur source
    20  *
    21  * Si elles sont là, on les retoune
     18 * Retourne certaines informations du site
    2219 *
    23  * @uses migrateur_data()
    24  * @return null|Migrateur_DATA
    25  *     Données de connexions si définies
     20 * @uses migrateur_infos()
     21 * @return null|Spip\Migrateur\Data
     22 *     Données de connexions si obtenues
    2623**/
    2724function migrateur_source() {
    28         return migrateur_data('source');
     25        return migrateur_infos();
    2926}
    3027
    3128
    3229/**
    33  * Retourne les données d'accès au serveur destination
    34  *
    35  * Si elles sont là, on les retoune
    36  *
    37  * @uses migrateur_data()
    38  * @return null|Migrateur
    39  *     Données de connexions si définies
     30 * Retourne certaines informations du site
     31 * 
     32 * @uses migrateur_infos()
     33 * @return null|Spip\Migrateur\Data
     34 *     Données de connexions si obtenues
    4035**/
    4136function migrateur_destination() {
    42         return migrateur_data('destination');
     37        return migrateur_infos();
    4338}
    4439
    4540
    4641/**
    47  * Retourne les données d'accès au serveur source ou destination
     42 * Retourne certaines informations sur le SPIP actuellement exécuté
    4843 *
    49  * Si elles sont là, on les retoune
     44 * Notamment les identifiants de connexion à la base de données,
     45 * ainsi que le chemin complet vers la racine du site.
    5046 *
    51  * @uses migrateur_data()
    52  * @param string $type
    53  *     Type de données désirées (source | destination)
    54  * @return null|Migrateur_DATA
     47 * @api
     48 * @return null|Spip\Migrateur\Data
    5549 *     Données de connexions si définies
    5650**/
    57 function migrateur_data($type) {
    58         static $migs = array();
     51function migrateur_infos() {
     52        return new Migrateur\Data();
     53}
    5954
    60         $type = strtoupper($type);
    61 
    62         if (isset($migs[$type])) {
    63                 return $migs[$type];
    64         }
    65 
    66         $props = array();
    67 
    68         foreach (array(
    69                 "MIGRATEUR_{$type}_DIR" => 'dir',
    70 
    71                 "MIGRATEUR_{$type}_SQL_USER"        => 'sql/user',
    72                 "MIGRATEUR_{$type}_SQL_PASS"        => 'sql/pass',
    73                 "MIGRATEUR_{$type}_SQL_BDD"         => 'sql/bdd',
    74                 "MIGRATEUR_{$type}_SQL_LOGIN_PATH"  => 'sql/login_path',
    75 
    76                 "MIGRATEUR_{$type}_SSH_SERVER"      => 'ssh/server',
    77                 "MIGRATEUR_{$type}_SSH_USER"        => 'ssh/user',
    78                 "MIGRATEUR_{$type}_SSH_PORT"        => 'ssh/port',
    79         ) as $const => $prop) {
    80                 if (defined($const) and constant($const)) {
    81                         // 'ssh/server' => group 'ssh' et clé 'server'
    82                         $keys = explode('/', $prop);
    83                         if (count($keys) > 1) {
    84                                 $group = array_shift($keys);
    85                                 $prop = array_shift($keys);
    86                                 if (!isset($props[$group])) {
    87                                         $props[$group] = array();
    88                                 }
    89                                 $props[$group][$prop] = constant($const);
    90                         } else {
    91                                 $props[$prop] = constant($const);
    92                         }
    93                 }
    94         }
    95 
    96         return $migs[$type] = new Migrateur_DATA($props);
    97 }
    9855
    9956
     
    10562 * @param string $msg Le message
    10663 * @param string $type Type de message
     64 * @param bool|null $set_stream
     65 *     Indique si la fonction doit effectuer des echos lorsqu'elle est appelée (défaut false).
     66 *     À définir avec `migrateur_log('', '', true);`
    10767**/
    108 function migrateur_log($msg, $type="") {
    109         static $done = false;
     68function migrateur_log($msg, $type="", $set_stream = null) {
     69        static $done   = false;
     70        static $stream = false;
     71
     72        if (!is_null($set_stream)) {
     73                $stream = (bool)$set_stream;
     74                return true;
     75        }
     76
    11077        $dir = _DIR_TMP . 'migrateur';
    11178        if (!$done) {
    11279                sous_repertoire(_DIR_TMP . 'migrateur');
     80                $done = true;
    11381        }
    11482
    115         if ($type) $message = '[' . $type . '] ' . $message;
     83        if ($type) {
     84                $message = '[' . $type . '] ' . $message;
     85        }
    11686
    117         file_put_contents($dir . "/migrateur.log", date("Y:m:d H:i:s") . " > " . $msg . "\n", FILE_APPEND);
     87        file_put_contents($dir . "/migrateur.log", date("Y:m:d H:i:s") . " | " . $msg . "\n", FILE_APPEND);
    11888        file_put_contents($dir . "/etape.log", $msg . "\n", FILE_APPEND);
    11989        spip_log($msg, 'migrateur');
     90
     91        if ($stream) {
     92                echo $msg . "\n";
     93                flush();
     94        }
    12095}
    12196
    12297
    12398
    124 /**
    125  * Retourne les données d'accès au serveur source s'il est par SSH
    126  *
    127  * Si le SPIP source se trouve sur un autre serveur que le SPIP de distination
    128  * (là où on execute le plugin migrateur), alors des données
    129  * de connexion SSH sont définies.
    130  *
    131  * Si elles sont là, on les retoune
    132  *
    133  * @deprecated Utiliser migrateur_source()->ssh
    134  *
    135  * @return null|Migrateur_SSH
    136  *     Données de connexion SSH si définies
    137 **/
    138 function migrateur_source_ssh() {
    139         $source = migrateur_source();
    140         return $source->ssh;
    141 }
    142 
    143 
    144 
    145 /**
    146  * Obtient le chemin d'un executable sur le serveur.
    147  *
    148  * @deprecated Utiliser migrateur_source()->obtenir_commande_serveur('rsync')
    149  * @example
    150  *     ```
    151  *     $cmd = migrateur_obtenir_commande_serveur('rsync');
    152  *     if ($cmd)
    153  *         exec("$cmd ... ... ");
    154  *     }
    155  *     ```
    156  * @param string $command
    157  *     Nom de la commande
    158  * @return string
    159  *     Chemin de la commande
    160 **/
    161 function migrateur_obtenir_commande_serveur($command) {
    162         $source = migrateur_source();
    163         return $source->obtenir_commande_serveur($command);
    164 }
    165 
  • _plugins_/migrateur/dev-by-http/inc/migrateur_aide.php

    r85955 r88450  
    319319        }
    320320}
     321
     322
     323/**
     324 * Retourne un Client de migrateur (pour demander des choses au Serveur).
     325 *
     326 * @return \SPIP\Migrateur\Client
     327**/
     328function migrateur_client() {
     329        include_spip('inc/config');
     330
     331        $client = new \SPIP\Migrateur\Client(
     332                lire_config('migrateur/auth_key'),
     333                lire_config('migrateur/aes_key'),
     334                lire_config('migrateur/url_source')
     335        );
     336        $client->setLogger(new \SPIP\Migrateur\Client\Log());
     337        return $client;
     338}
  • _plugins_/migrateur/dev-by-http/lang/migrateur_fr.php

    r84608 r88450  
    66$GLOBALS[$GLOBALS['idx_lang']] = array(
    77
    8     // P
    9     'migrateur_titre'            => 'Migrateur de site',
    108
    11     // C
    12     'conf_chemin'                => 'Chemin',
    13     'conf_destination'           => 'Destination',
    14     'conf_source'                => 'Source',
    15     'conf_sql_user'              => 'Utilisateur SQL',
    16     'conf_sql_bdd'               => 'Base de données',
    17     'conf_verification_visuelle' => "Vous n'avez pas encore utilisé le migrateur
    18                 sur ce site (ou vous venez de vider le cache).
    19                 Vérifiez bien la configuration des sites
    20                 source et destination avant de lancer une des étapes de migration.",
     9        // C
     10        'cle_authentification_perimee' => "Clé d'authentification non renseignée ou périmée.",
     11        'cle_valide_une_heure'       => "Clé d'authentification valide seulement @nb@ heure",
     12        'cle_valide_nb_heures'       => "Clé d'authentification valide encore @nb@ heures",
     13        'conf_aes_key'               => 'Clé AES',
     14        'conf_auth_key'              => "Clé d'authentification",
     15        'conf_chemin'                => 'Chemin',
     16        'conf_ce_site_est'           => 'Ce site est défini comme',
     17        'conf_configurer_migrateur'  => '[Configurer le migrateur->?exec=configurer_migrateur]',
     18        'conf_destination'           => 'Destination',
     19        'conf_non_configure'         => 'Non configuré',
     20        'conf_source'                => 'Source',
     21        'conf_sql_user'              => 'Utilisateur SQL',
     22        'conf_sql_bdd'               => 'Base de données',
     23        'conf_url_source'            => 'URL du site source',
     24        'conf_verification_visuelle' => "Vous n'avez pas encore configuré le migrateur
     25                sur ce site. Cette étape est indispensable pour le fonctionnement.",
     26
     27        // E
     28        'erreur_cle_authentification' => "Clé d'authentification périmée.",
     29        'etape_suivante' => 'Étape suivante',
     30        'explication_configuration_migrateur' => "Le migrateur doit être configuré comme étant source de données
     31                 (auquel cas des clés d'authentification et de cryptage seront générées) ou comme étant
     32                 le site de destination vers lequel on migre (dans ce cas, il faudra remplir les clés qui ont été
     33                 calculées par le migrateur du site source.",
     34
     35        // G
     36        'generer_cle_auth' => "Générer une nouvelle clé d'authentification",
     37        'generer_cles' => "Générer toutes les clés",
     38
     39        // M
     40        'migrateur_configurer'       => 'Configurer le migrateur',
     41        'migrateur_page'             => 'Page du migrateur',
     42        'migrateur_titre'            => 'Migrateur de site',
     43        'migrateur_titre_court'      => 'Migrateur',
     44
     45        // R
     46        'recommencer_etapes' => 'Recommencer les étapes ?',
    2147
    2248);
  • _plugins_/migrateur/dev-by-http/migrateur/99_autres_exemples.php

    r85955 r88450  
    220220**/
    221221function migrateur_exemple_supprimer_vignettes_logos() {
    222         $ori = MIGRATEUR_DESTINATION_DIR . 'IMG/';
    223         foreach (scandir($ori) as $filename) {
     222        if (!defined('_DIR_IMG')) {
     223                return false;
     224        }
     225        foreach (scandir(_DIR_IMG) as $filename) {
    224226                if (preg_match('/.*-[0-9]+x[0-9]+\.(jpg|gif|png)/i', $filename)) {
    225                         unlink($ori . $filename);
    226                 }
    227         }
    228 }
    229 
    230 
    231 
    232 
    233 /**
    234  * Test ssh uptime
    235  *
    236  * Tente de se connecter en ssh au serveur source et d'obtenir
    237  * l'uptime du serveur
    238 **/
    239 function migrateur_test_ssh_uptime() {
    240         $source = migrateur_source();
    241         if ($source->ssh) {
    242                 $cmd = $source->ssh->obtenir_commande_connexion();
    243                 if ($cmd) {
    244                         $run = "$cmd uptime 2>&1";
    245                         migrateur_log($run);
    246                         exec($run, $output, $err);
    247                         migrateur_log(implode("\n", $output));
    248                 } else {
    249                         migrateur_log("Pas de commande 'ssh' locale !");
    250                 }
    251         } else {
    252                 migrateur_log("Pas de serveur distant défini.");
    253         }
    254 }
     227                        unlink(_DIR_IMG . $filename);
     228                }
     229        }
     230}
     231
  • _plugins_/migrateur/dev-by-http/migrateur/config.php

    r85406 r88450  
    1515/*
    1616$GLOBALS['MIGRATEUR_ETAPES'] = array(
    17         'mig_rsync_img'       => 'Synchroniser le répertoire IMG',
    18         'mig_exporter_bdd'    => 'Exporter la base de données source',
    19         'mig_transferer_bdd'  => 'Transfert des données SQL sur la base de données destination',
     17        'mig_sync_img'                  => 'Synchroniser le répertoire IMG',
     18        'mig_bdd_source_make_dump'      => 'Crée un dump SQL de la base de données source (sur le site source dans tmp/dump)',
     19        'mig_bdd_source_get_dump'       => 'Copie le dernier dump SQL du site source (sur ce site dans tmp/dump)',
     20        'mig_bdd_destination_put_dump'  => 'Écrase la base de données actuelle par le dernier dump SQL présent dans tmp/dump)',
    2021
    2122        'supprimer_tables_inutiles' => 'Suppression des tables SQL inutiles',
     
    2425);
    2526*/
    26 
    27 // Configuration
    28 // =============
    29 
    30 // Origine
    31 // -------
    32 define('MIGRATEUR_SOURCE_DIR', '/sites/mon_domaine.fr/html/');
    33 
    34 // SQL source
    35 define('MIGRATEUR_SOURCE_SQL_USER', 'user_prod');
    36 define('MIGRATEUR_SOURCE_SQL_PASS', '*******');
    37 define('MIGRATEUR_SOURCE_SQL_BDD', 'db_prod');
    38 
    39 // Source via SSH (serveur source ailleurs que serveur dev, accès par clé SSH)
    40 # define('MIGRATEUR_SOURCE_SSH_SERVER', 'dev.domain.tld');
    41 # define('MIGRATEUR_SOURCE_SSH_USER',   'username_ssh');
    42 # define('MIGRATEUR_SOURCE_SSH_PORT',   22);
    43 
    44 
    45 
    46 // Destination
    47 // -----------
    48 define('MIGRATEUR_DESTINATION_DIR', '/sites/mon_domaine.fr/sd/dev/html/');
    49 
    50 // SQL destination
    51 define('MIGRATEUR_DESTINATION_SQL_USER', 'user_dev');
    52 define('MIGRATEUR_DESTINATION_SQL_PASS', '*******');
    53 define('MIGRATEUR_DESTINATION_SQL_BDD', 'db_dev');
    54 
    55 // Nom du fichier d'export SQL
    56 define('MIGRATEUR_NOM_EXPORT_SQL', 'export_source.sql');
    57 
  • _plugins_/migrateur/dev-by-http/migrateur/mig_bdd_destination_put_dump.php

    r88075 r88450  
    2626 * Transfert des données SQL sur la base de données destination
    2727**/
    28 function migrateur_mig_transferer_bdd() {
     28function migrateur_mig_bdd_destination_put_dump() {
    2929
    3030        // récupérer les plugins de migration
    3131        $migrateurs = migrateur_obtenir_plugins_actifs('migrateur');
     32
     33        // conserver la conf
     34        $conf = lire_config('migrateur');
    3235
    3336        // vider toutes les tables avant insertion
     
    4043        migrateur_ajouter_plugins_actifs($migrateurs);
    4144
     45        // restaurer la conf
     46        ecrire_config('migrateur', $conf);
     47
    4248        // On vide le cache
    4349        migrateur_vider_cache();
     
    4955        $ou = generer_url_ecrire('upgrade','reinstall=non', false, _DIR_RESTREINT_ABS);
    5056        redirige_par_entete(parametre_url(generer_url_public('login'),'url', $ou, '&'));
     57
    5158}
    5259
     
    9097
    9198        $dest = migrateur_destination();
    92         $sauvegarde = $dest->dir . 'tmp/dump/' . ($source_sql ? $source_sql : MIGRATEUR_NOM_EXPORT_SQL);
     99        $sauvegarde = $dest->dir . '/tmp/dump/' . ($source_sql ? $source_sql : 'migrateur.sql');
    93100
    94101        migrateur_log("Copie de la BDD par MySQL");
     102
    95103        //$mysql_cmd = "mysql --user={$dest->sql->user} --password={$dest->sql->pass} --default_character_set=utf8 {$dest->sql->bdd} < $sauvegarde";
    96104        $mysql_cmd = "mysql --user={$dest->sql->user} --password={$dest->sql->pass} {$dest->sql->bdd} < $sauvegarde";
  • _plugins_/migrateur/dev-by-http/migrateur/mig_bdd_destination_put_dump_interclassements.php

    r88075 r88450  
    44
    55// partage de fonctions
    6 include_spip('migrateur/mig_transferer_bdd');
     6include_spip('migrateur/migrateur_mig_bdd_destination_put_dump');
    77
    88/**
     
    1111 * @link http://zzz.rezo.net/Reparer-le-charset-d-une-base-SPIP.html
    1212**/
    13 function migrateur_mig_importer_bdd_interclassements() {
     13function migrateur_mig_bdd_destination_put_dump_interclassements() {
    1414
    1515        // vider toutes les tables avant insertion
  • _plugins_/migrateur/dev-by-http/migrateur_fonctions.php

    r81044 r88450  
    11<?php
     2
     3/**
     4 * Fonctions du migrateur
     5 *
     6 * @package SPIP\Migrateur\Fonctions
     7**/
     8
     9if (!defined("_ECRIRE_INC_VERSION")) return;
    210
    311
     
    3644        return $nb = 0;
    3745}
     46
     47/**
     48 * Vérifier la péremption d'une clé d'authentification
     49 *
     50 * Validité de 12h.
     51 *
     52 * @param string $cle
     53 *     Clé au format '{date}@{hash}'
     54 * @return false|int
     55 *     false si la clé est périmée ou non renseignée,
     56 *     nombre d'heures de validité restant sinon
     57**/
     58function migrateur_verifier_peremption_auth_key($key) {
     59        include_spip('migrateur_options');
     60        return SPIP\Migrateur\Serveur::verifier_peremption_auth_key($key);
     61}
  • _plugins_/migrateur/dev-by-http/paquet.xml

    r87825 r88450  
    22        prefix="migrateur"
    33        categorie="outil"
    4         version="2.6.2"
    5         etat="test"
     4        version="3.0.0"
     5        etat="dev"
    66        compatibilite="[3.0.5;3.1.*]"
    77        logo="prive/themes/spip/images/migrateur-64.png"
  • _plugins_/migrateur/dev-by-http/prive/squelettes/contenu/migrateur.html

    r81044 r88450  
     1[(#AUTORISER{webmestre}|sinon_interdire_acces)]
    12
    23<h1><:migrateur:migrateur_titre:></h1>
    34
    4 [(#SET{liste,[(#VAL**|migrateur_etapes)]})]
    5 
    65[(#REM)
    7         Si aucune étape de migration n'a encore été faite,
    8         Alors on affiche les informations de connexion
    9         pour vérifier visuellement les données (hors password).
     6        Si aucune configuration n'a été faite, on affiche un message
    107]
    11 [(#VAL|migrateur_derniere_etape|non)
     8[(#CONFIG{migrateur/type}|non)
    129        <div class='notice'>
    1310                <p><:migrateur:conf_verification_visuelle:></p>
    14                 <table class='spip'>
    15                         <thead>
    16                                 <tr>
    17                                         <th></th>
    18                                         <th><:migrateur:conf_source:></th>
    19                                         <th><:migrateur:conf_destination:></th>
    20                                 </tr>
    21                         </thead>
    22                         <tbody>
    23                                 <tr>
    24                                         <th><:migrateur:conf_chemin:></th>
    25                                         <td>#EVAL{MIGRATEUR_SOURCE_DIR}</td>
    26                                         <td>#EVAL{MIGRATEUR_DESTINATION_DIR}</td>
    27                                 </tr>
    28                                 <tr>
    29                                         <th><:migrateur:conf_sql_user:></th>
    30                                         <td>#EVAL{MIGRATEUR_SOURCE_SQL_USER}</td>
    31                                         <td>#EVAL{MIGRATEUR_DESTINATION_SQL_USER}</td>
    32                                 </tr>
    33                                 <tr>
    34                                         <th><:migrateur:conf_sql_bdd:></th>
    35                                         <td>#EVAL{MIGRATEUR_SOURCE_SQL_BDD}</td>
    36                                         <td>#EVAL{MIGRATEUR_DESTINATION_SQL_BDD}</td>
    37                                 </tr>
    38                         </tbody>
    39                 </table>
    4011        </div>
    4112]
    4213
    43 
    44 #SET{next,''}
    45 #SET{contenu,''}
    46 #SET{suivant,''}
    47 <BOUCLE_migration(POUR){tableau #GET{liste}}>
    48         [(#VAL|migrateur_derniere_etape|=={#COMPTEUR_BOUCLE}|oui)
    49                 [(#SET{next,[(#COMPTEUR_BOUCLE|plus{1})]})]
    50                 [(#SET{contenu,<div id='etape_effectuee'><strong>#COMPTEUR_BOUCLE</strong> #VALEUR</div>})]
    51         ]
    52         [(#GET{next}|et{#GET{next}|=={#COMPTEUR_BOUCLE}}|oui)
    53                 [(#SET{suivant,
    54                                 <div class='migration_next right'>
    55                                         <a href='[(#URL_ACTION_AUTEUR{migrateur,#CLE}
    56                                                 |parametre_url{redirect,[(#SELF
    57                                                         |parametre_url{nb,#GET{next}})]})]'>
    58                                                 [(#CHEMIN_IMAGE{migration_suivante.png}
    59                                                         |image_reduire{60}
    60                                                         |inserer_attribut{alt,#VALEUR}
    61                                                         |inserer_attribut{title,#VALEUR})]
    62                                         </a>
    63                                 </div>
    64                 })]
    65         ]
    66 </BOUCLE_migration>
    67 
    68 [(#GET{contenu}|oui)
    69         #BOITE_OUVRIR{Étape effectuée, simple}
    70                 #GET{suivant}
    71                 #GET{contenu}
    72         #BOITE_FERMER
     14[(#CONFIG{migrateur/type}|in_any{#LISTE{source,destination}}|oui)
     15        [(#INCLURE{fond=prive/squelettes/inclure/migrateur-[(#CONFIG{migrateur/type})], env})]
    7316]
    74 
    75 <div id='etapes_migration'>
    76         <h3>Étapes de migration</h3>
    77 <div class='liste'>
    78 <ul class='liste-items'>
    79 <BOUCLE_migration_liste(POUR){tableau #GET{liste}}>
    80         <li class='item[ (#VAL|migrateur_derniere_etape|=={#COMPTEUR_BOUCLE}|oui)on]'>
    81         <a href='[(#URL_ACTION_AUTEUR{migrateur,#CLE}
    82                 |parametre_url{redirect,[(#SELF
    83                         |parametre_url{nb,#COMPTEUR_BOUCLE})]})]'><strong>#COMPTEUR_BOUCLE</strong> #VALEUR</a>.</li>
    84 </BOUCLE_migration_liste>
    85 </ul>
    86 </div>
    87 </div>
    88 
    89 
    90 [(#EVAL{_DIR_TMP . '/migrateur/etape.log'}|file_exists|oui)
    91 [[(#VAL{Logs de la dernière étape exécutée}|boite_ouvrir{simple,'',logs})]
    92 <pre>
    93 (#EVAL{_DIR_TMP . '/migrateur/etape.log'}|file_get_contents)
    94 </pre>
    95 #BOITE_FERMER
    96 ]]
    97 
    98 <style type='text/css'>
    99 .migration_next.right {float:right; margin-top:-35px;}
    100 #etapes_migration a strong { font-size:1.2em; margin-right:1em; margin-left:.2em; }
    101 #etape_effectuee strong { font-size:1.2em; margin-right:1em; }
    102 
    103 #logs {margin-top:2em; overflow:visible;}
    104 
    105 
    106 .logo_navigation.loading img {
    107     -webkit-animation-iteration-count:infinite;
    108     -webkit-animation-timing-function:linear;
    109     -webkit-animation-name:rotation;
    110     -webkit-animation-duration:2s;
    111     -moz-animation-iteration-count:infinite;
    112     -moz-animation-timing-function:linear;
    113     -moz-animation-name:rotation;
    114     -moz-animation-duration:2s;
    115     animation-iteration-count:infinite;
    116     animation-timing-function:linear;
    117     animation-name:rotation;
    118     animation-duration:2s;
    119 }
    120 @-webkit-keyframes rotation {
    121 from { -webkit-transform:rotateY(0deg) }
    122 to { -webkit-transform:rotateY(360deg) }
    123 }
    124 @-moz-keyframes rotation {
    125 from { -moz-transform:rotate(0deg) }
    126 to { -moz-transform:rotate(360deg) }
    127 }
    128 @keyframes rotation {
    129 from { transform:rotate(0deg) }
    130 to { transform:rotate(360deg) }
    131 }
    132 </style>
    133 
    134 
    135 <script type='text/javascript'>
    136 ;(function($){
    137 $(document).ready(function() {
    138         $('#contenu a, #navigation a').click(function() {
    139                 $('#navigation .logo_navigation')
    140                         .attr('aria-busy','true')
    141                         .addClass('loading').css('opacity', 0.5);
    142         });
    143 });
    144 })(jQuery);
    145 </script>
  • _plugins_/migrateur/dev-by-http/prive/squelettes/navigation/migrateur.html

    r81044 r88450  
    44        <img src="[(#CHEMIN_IMAGE{migrateur-128.png})]" alt="Logo migrateur" />
    55</a>
    6 <h1><:migrateur:migrateur_titre:></h1>
     6<h1><:migrateur:migrateur_titre_court:></h1>
    77</div>
    88
    9 [(#SET{liste,[(#VAL**|migrateur_etapes)]})]
    109
    11 <BOUCLE_migration(POUR){tableau #GET{liste}}>
    12         [(#VAL|migrateur_derniere_etape|=={#COMPTEUR_BOUCLE}|oui)[(#SET{next,[(#COMPTEUR_BOUCLE|plus{1})]})]]
    13 </BOUCLE_migration>
     10[(#SET{key_ok,#CONFIG{migrateur/auth_key}|migrateur_verifier_peremption_auth_key})]
    1411
    15 <BOUCLE_migration_next(POUR){tableau #GET{liste}}>
    16 [(#GET{next}|oui|et{#GET{next}|=={#COMPTEUR_BOUCLE}}
    17 |ou{[(#GET{next}|non|et{#COMPTEUR_BOUCLE|=={1}})]})
    18 #BOITE_OUVRIR{Étape suivante,simple}
    19         <div id='next_migration'>
    20         <a href='[(#URL_ACTION_AUTEUR{migrateur,#CLE}
    21                 |parametre_url{redirect,[(#SELF
    22                         |parametre_url{nb,#COMPTEUR_BOUCLE})]})]'>
    23                 <strong>#COMPTEUR_BOUCLE</strong>
    24                 [(#CHEMIN_IMAGE{migration_suivante.png}|image_reduire{100}|inserer_attribut{alt,#VALEUR})]
    25                 <span>#VALEUR</span>
    26         </a>
    27         </div>
     12#BOITE_OUVRIR{'',simple}
     13<div id='goto_config_migrateur'>
     14<a href='[(#URL_ECRIRE{configurer_migrateur})]'>
     15        [(#CHEMIN_IMAGE{cfg-16.png}|balise_img)]
     16        <:migrateur:migrateur_configurer:>
     17</a>
     18</div>
    2819#BOITE_FERMER
     20
     21
     22[(#CONFIG{migrateur/type}|=={source}|oui)
     23        #BOITE_OUVRIR{'',simple}
     24        <:migrateur:conf_ce_site_est:><br /><strong><:migrateur:conf_source:></strong>
     25        #BOITE_FERMER
    2926]
    3027
    31 [(#COMPTEUR_BOUCLE|=={1}|et{#GET{next}}|et{#GET{next}|=={#TOTAL_BOUCLE|plus{1}}}|oui)
    32 #BOITE_OUVRIR{Recommencer les étapes ?,simple}
    33         <div id='next_migration'>
    34         <a href='[(#URL_ACTION_AUTEUR{migrateur,#CLE}
    35                 |parametre_url{redirect,[(#SELF
    36                         |parametre_url{nb,#COMPTEUR_BOUCLE})]})]'>
    37                 <strong>#COMPTEUR_BOUCLE</strong>
    38                 [(#CHEMIN_IMAGE{migration_recommencer.png}|image_reduire{100}|inserer_attribut{alt,#VALEUR})]
    39                 <span>#VALEUR</span>
    40         </a>
    41         </div>
    42 #BOITE_FERMER
     28[(#CONFIG{migrateur/type}|=={destination}|oui)
     29        #BOITE_OUVRIR{'',simple}
     30        <:migrateur:conf_ce_site_est:><br /><strong><:migrateur:conf_destination:></strong>
     31        #BOITE_FERMER
    4332]
    44 </BOUCLE_migration_next>
     33
     34
     35[(#CONFIG{migrateur/type}|non)
     36        #BOITE_OUVRIR{'',error}
     37        <:migrateur:conf_ce_site_est:><br /><strong><:migrateur:conf_non_configure:></strong>
     38        #BOITE_FERMER
     39]
     40
     41[(#CONFIG{migrateur/type}|in_any{#LISTE{source,destination}}|oui)
     42        [(#GET{key_ok}|oui)
     43                #BOITE_OUVRIR{'',success}
     44                [(#GET{key_ok}|singulier_ou_pluriel{migrateur:cle_valide_une_heure,migrateur:cle_valide_nb_heures}|_T)]
     45                #BOITE_FERMER
     46        ]
     47        [(#GET{key_ok}|non)
     48                #BOITE_OUVRIR{'',error}
     49                <:migrateur:cle_authentification_perimee:>
     50                #BOITE_FERMER
     51        ]
     52]
     53
     54[(#CONFIG{migrateur/type}|=={destination}|oui)
     55        #BOITE_OUVRIR{'',simple}
     56        [(#SELF|parametre_url{stream,''}|lien_ou_expose{Mode normal,#ENV{stream}|non})]
     57        | [(#SELF|parametre_url{stream,1}|lien_ou_expose{Mode stream,#ENV{stream}|oui})]
     58        #BOITE_FERMER
     59]
    4560
    4661<style type='text/css'>
    4762.logo_navigation {text-align:center;}
    48 #next_migration { text-align:center; }
    49 #next_migration a { vertical-align:middle;  padding:2px; border-radius:5px; display:inline-block; }
    50 #next_migration a:hover { text-decoration:none; background:#f3f3f3; }
    51 #next_migration a strong { font-size:3em; vertical-align: middle; }
    52 #next_migration a img { vertical-align:middle; }
    53 #next_migration a span { display:block; }
     63#goto_config_migrateur img { vertical-align:middle; }
    5464</style>
     65
     66
     67[(#REM)
     68        Afficher un lien vers l'étape suivante,
     69        uniquement si le site est configuré comme destination
     70]
     71[(#CONFIG{migrateur/type}|=={destination}|oui)
     72        [(#INCLURE{fond=prive/squelettes/inclure/migrateur-destination-colonne, env})]
     73]
Note: See TracChangeset for help on using the changeset viewer.