Conf de dev migration

Présentation (rapide) de l'environnement ddev8, qui va servir à Migrer vers drupal 8 (page de 2015 actualisée) , ici un site drupal 7 (env de prod, chez l'hébergeur : php 5, apache, mysql) vers drupal 8 (sous php 7, ngninx, mariadb) dans un env de dev.

On aura drush 9.4.0 et un drupal 8.6.x, dans un environnement de developpement. Pour l'utilisateur (sur le pc hote, où est installé ddev), un ddev describe montrera les interfaces de base : on peux surfer (depuis l'hote)

  • le drupal 8 est accessible via https://ddevd8.ddev.local
  • PhpMyAdmin est à http://ddevd8.ddev.local:8036
  • emails à http://ddevd8.ddev.local:8025

Quelques commandes fréquentes, pèle-mele de commandes ddev, composer et drush 9, sont en bas de cette page.
D'autres commandes ddev sont à ddev : commandes fréquentes (que fait ddev config sur les settings.php, détails sur la db). upgrade vers drupal 8 commente des exemples, et présente les divers modules de migration. Test de ddev a des liens vers la doc ddev, des notes d'un essai d'install et surtout des notes sur la configuration de ddev8

 

Env de dev "ddevd8"

L'hote (conf de ddev)

Mon poste est sous ubuntu 18.04.1 (sous Gnome3) (linux, Ubuntu "Bionic Beaver", la LTS en nov 2018), avec php 7.2... ddev est un docker "simplifié", avec des images et utilitaires de divers CMS (drupal 7, drupal 8 et d'autres).

Le serveur de dev est un docker "ddev" (installé dans dossier /.../ddev8), installé via curl composer (voir en bas de Test de ddev)
Vu de l'hote, Drush 9.4-dev-g849cea53 (pas d'alias dans /etc/drush/aliases.drushrc.php et rien de particulier dans  /home/userlinux/.composer/vendor/drush/drush/drush.yml.

Après le premier ddev config, le dossier pèse 220 Mo (voir l'arborescence des fichiers à Test de ddev).
Le drupal 8.6.3 n'étant pas installé (et sans ddev config), seul le lien phpMyAdmin fonctionne (ici http://ddup.ddev.local:8036), composer et drush.
Une fois installé (suite ddev config ; ddev start et installation via l'URL), il manque encore les modules pour migrer, pathauto....

  • Surveiller le poid de /home/userlinux/.ddev
    Le dossier ddev8 pèse quasi 3 Go, avec 4 snapshots dedans (cachés dans ddevd8/.ddev/db_snapshots), 50 Mo de fichiers de mon site de prod compris, 2 db.
    Avec un seul snapshot, 2 db sans les fichiers car upgrade non lancé : 577,4 Mo
  • Certificats en /home/userlinux/.ddev/certs

ddevd8

Une fois terminé, on a un environnement, nommé ddevd8, presque complet pour lancer une migration (de drupal v7 vers drupal v8), on a (après maj, le 3 nov 2018):

  • drush 9.4.0 (accessible depuis l'hote via les dossiers /.../ddev1/drupal/vendor/drush/drush),
  • drupal 8.6.2 (accessible de l'hote via le dossier ddev1/drupal/web),
    • phpmyadmin (logué non en root, mais en db/db seul),
    • conf test serveur d'emails "MailHog", drupal console, composer...
      • sur nginx/1.14.0 (ddev logs -f montre aussi toute la conf) et php 7.1.22,
      • avec MariaDB : serveur db et user/pw = db/db (le compte root est root/root) pour le drupal 8 (de destination).
      • 1024 M Ram (php.ini)

    Le drupal 8 (mono-site ie 1 seule db, un seul virtual host, ddev exec cat /etc/nginx/sites-enabled/nginx-site.conf ou mieux, ddev logs -f).

    En pratique... ou d'où lancer quelles commandes ?

    Si l'on vient d'installer ddev, il montre les liens pour administrer le drupal 8, sinon, faire: cd ddev8/drupal puis ddev start puis ddev describe
    La plupart des commandes sont lancées depuis le bash shell, après le prompt, en ddev8/drupal $

    De l'hote (vrai pc qui a le serveur docker, et qui a lancé le ddev start depuis le dossier ddev8/drupal$) on accède au site defaut via  https://ddevd8.ddev.local (un ddev describe montre comment accéder à phpmyadmin et au gestionnaire des emails MailHog).
    On lance (en ligne de commande, etre dans son projet, ici  sous le prompt ddev8/drupal$, là où est composer.json) depuis l'hote :

    • les "composer require" (dl de modules), les commandes ddev (ddev logs -f)...  mais
    • les commandes drush (donc de migrations) sont gérées par le drush v9.4 du containeur, donc après un ddev exec, par ex un:    ddev exec drush st

    De temps en temps, un message s'affiche pour mettre à jour ddev ou l'image utilisée (drupal, console, composer et drush).
    Attention aux commandes "composer", car souvent, elles modifient un fichier composer.json... et des fichiers "composer.json", il y en a dans beaucoup, beaucoup d'autres endroits :p

    Update du core drupal 8 (lire /ddev8/drupal/README.md): composer update drupal/core webflo/drupal-core-require-dev symfony/* --with-dependencies

     

    Configuration pour migrer

    Il est important d'installer le drupal 8, depuis l'url de l'hote, en fr, profil minimal (avec standard, il crée Articles et ses divers champs, ca va poser soucis) plus les modules drush et drupal 8 requis (les migrate-tools et autres).

    Coté drupal 7 (site à migrer), faire un export de la base (et des fichiers sous le dossier sites/files), qu'on importera sur le serveur "db". Il faut importer ce dru7.sql dans notre env de dev, dans une base séparée, en donnant les bons privilèges.
    Ici, l'env de dev du drupal 8 est une MariaDB, base db et deux users : db/db pour drupal et le user root/root (*).

    Débutants, ne pas confondre les users (notés user/pw, ou encore son nomuser est db et son pw est db). On ne parle pas ici des comptes utilisateurs dans le site drupal, mais des utilisateurs "coté infrastructure". Le serveur de base de donnée, MariaDB, a un user root/root - on ne trouve pas de suite cette info dans la doc ddev.
    La base nommée db et le user db ont été créés et configurés par ddev (et le drupal-composer), et c'est ce que connait drupal (cf le ddev/web/sites/defaut/settings.php). Le user db a des privilèges limités (que sur la base db), alors que root est admin de toutes le db.

    Car, avant de lancer la migration en ligne de commande via drush, il faut avant tout disposer sur le serveur :

      • d'une copie de la base du drupal 7 (que l'on va migrer).
      • un drupal 8 vierge (l'import va écraser le user ID 1, admin drupal 8, créé lors de l'installation du drupal 8 de destination) - le laisser vierge de contenu
      • Puis, prets à être installés (téléchargés, mais non activés ou installés), les modules de migrations (migrate, migrate_drupal et migrate_plus, migrate_upgrade ici en 8.x-3.0-rc5 et éventuellement migrate_file 1.1) et les modules voulus (cad, installés sur la v7 source).
        Faire un snapshot avant de commencer la migration (nommé ddevd8_avtmig) - il ne doit pas avoir de trace des exemples Beer et Wine.

      Note : Il est astucieux de faire un (après le prompt, qui ressemble à "user@host:chemin../ddev1/drupal$ "):   ddev snapshot -n ddevd8vierge
      Cela pourra etre utile pour recommencer depuis de début, après un ddev restore-snapshot ddevd8vierge
      Car, quand on lance le migrate-update, les .yml de configuration (qui mappent les champs v7 vers les champs v8) sont importés en base (les modifier par la suite ne change rien, car ils ont déja été importés - voir 2 solutions plus bas).

      Note 2 : en installant avec le profil minimal, le bundle article ne sera pas créé (doublons de champs lors de la migration). Par contre, il faudra activer les modules du core, généralement installés par le profil defaut (book, Configuration Manager, Custom Block,...).

       

        Principe d'une migration

          Suite à un (seul) ddev exec drush migrate-upgrade .. --configure-only on va importer les données d'un drupal 7, dans ce nouveau drupal 8 installé (en y effacant les données de type configuration éventuelles, donc autant le laisser vierge, surtout quand on débute), à l'aide de diverses commandes

          • ddev exec drush migrate-import upgrade_d7_nomID  (ou drush mim IDmig)
          • voir l'état de la migration avec ddev exec drush ms mais aussi l'UI (via l'url  en admin/structure/migrate/manage/migrate_drupal_7/migrations)

          Dans la pratique

          • le migrate-upgrade .. --configure-only  va créer plein de configurations de migration, nommées upgrade_d7_nomID. Leur nombre dépend des modules actifs dans le drupal 7 et 8 quand on a lancé la commande, qui retourne des lignes :
              Exporting d7_global_theme_settings as upgrade_d7_global_theme_settings
              Exporting d7_image_settings as upgrade_d7_image_settings
              Exporting d7_image_styles as upgrade_d7_image_styles
          • un drush ms retourne des lignes comme:
               Group                          Migration ID                           Status      Total   Imported   Unprocessed   Last Imported     
               Import from Drupal 7   upgrade_d7_user_role                   Idle        7       7              0                2018-11-01 05:59:21  
                (migrate_drupal_7) 
               Import from Drupal 7   upgrade_d7_comment_type          Idle        10      0            10
               Import from Drupal 7   upgrade_d7_field_instance            Idle        64      0            64 
          • les drush mim retournent des lignes, par ex:
             [error]  Missing filter plugin: filter_null.  
             [notice] Processed 4 items (4 created, 0 updated, 0 failed, 0 ignored) - done with 'upgrade_d7_filter_format'
             [notice] Processed 34 items (34 created, 0 updated, 0 failed, 0 ignored) - done with 'upgrade_d7_field'

            ddev exec drush migrate-import upgrade_d7_shortcut
             [error]  La migration upgrade_d7_shortcut n'a pas rempli les pré-requis. Missing migrations upgrade_d7_menu, upgrade_d7_shortcut_set, upgrade_d7_menu_links.
            ddev exec drush migrate-import upgrade_d7_shortcut --execute-dependencies

          Introduction et remarques importantes :

          • L'ordre des import est essenciel, car certains champs en référencent d'autres (citons les tables users et node-type, qui sont requises par bp d'autres données).
          • Si migrate voit qu'il manque des données, il crée des données temporaires (nommées stubs), pour les relier ensemble par la suite.
            Par ex, au moment où on importe le contenu de ses articles, des termes de taxonomie (référencés via un champs définit sur ce type de contenu donné, qu'on nomme souvent node_bundle), alors que les termes n'existent pas encore.
          • Les ID des nodes, termes... resteront les meme (site source et destination).
          • Par contre : les vues ne sont pas migrées, les vocabulaires récupérés sont aplatis (si Williams était sous Poire, on va bien récupérer ces 2 termes, mais ils auront le meme père : 0), on a des soucis entre les versions des modules (core ou contrib) v7 et v8... Bien des soucis pour migrer les traductions (module i18n)...
            Voir les bugs en cours de migrate-upgrade
          • Attention aux champs qui sont configurés differement selon les bundles.
            Par exemple, field_monimage qui utilise le widget media_browser dans article mais un widget file ou image dans book dans la migration upgrade_d7_field_formatter_settings (qui dépend aussi de upgrade_d7_view_modes)
          • Commencer par documenter le drupal 7, nottement sa volumétrie (cf ordre mes migration). Je me suis rendue compte, en testant et prenant ces notes, que j'allais devoir m'y prendre différement, j'y ai donc copié quelques requetes SQL basiques, pour savoir ce qu'on laisse tomber (récupérer ou non, copier à la mano) ou pas.
            • Bon nombre des mes fichiers (pdf, txt, jpg...) sont gérés via des entités Images media v7 et des types de fichiers qu'on gère via une URL admin/structure/file-types/manage/image/fields
              Or, ces dernières années, il y a eu de gros updates sur ces modules, et je n'ai pas toujours bien testé les modifications des confs.
              concerne les champs v7 field_file_image_alt_text, field_file_image_title_text et field_filetag
            • Vis à vis des commentaires, qui ont bp changés... J'en avais peu sur le drupal 7, idem pour les révisions. Je vais donc finallement laissser tomber ces aspects là.
            • les plugins ckeditor...

          En faisant ses premiers tests, on se rend compte qu'il faudrait modifier la structure du site d'origine  : optimisation de taxonomies ou de bundle, renommage et réimport de champs.... On peux tenter de le faire lors de la migration - et c'est là que ca se complique, surtout pour des modules comme media (et ses sous-modules) ou basés sur la taxonomie.
          C'est la raison pour laquelle j'ai opté pour ddev : ddev snapshot (ou ddev snapshot -n unnom) et ddev restore-snapshot sont efficaces et rapides.

          Liens dans cette page : Quelques commandes



           

            La conf pour migrer (données du drupal 7 existant vers drupal 8)

            Vérifier que sur le drupal 8 installé, il n'y a pas de données (ID de node), que tous les modules requis sont installés (modules du core drupal 8 et modules contribs à migrer).
            Citons du core : ckeditor, config, media, menu_link_content, responsive_image, views_ui mais aussi admin_toolbar_tools, ctools, metatag 1.7, pathauto, token 1.5, bartik 8.6.2, xmlsitemap 1.0-alpha3, schema_metatag ;
            migrate_upgrade 3.0-rc5  migrate_drupal_ui
            Ne pas avoir migrate_example_setup et migrate_example_advanced_setup

            Lancer la configuration de la migration

            Vérifier qu'il ne reste pas de résidu de l'exemple de migration ou de tout autre test, avant d'importer en base la préconfiguration de la migation (sinon, faire un ddev restore) :

            ddev exec drush migrate-upgrade --legacy-db-url=mysql://root:root@db/nom-base-v7 --legacy-db-prefix=prefixe-de-table --legacy-root=http://url.v7 --configure-only

            Gérer les migrations

            En gros : commencer par les users, conf systeme et les vocab (ie upgrade_d7_taxonomy_vocabulary). Puis :

            • Récupérer les résultats dans son tableur : ../ddev1/drupal$  ddev exec drush ms --group=migrate_drupal_7 --fields=id,total,imported,unprocessed,last_imported --format=csv > ../chemin/nom-fichier.csv
            • importer les termes via plusieurs "upgrade_d7_taxonomy_term_ID"
            • filtres de texte (drupal 7 a 3/4 messages filter_null manquant - seul "Plain text" ok) et oembed (cf Module media_oembed)
            • upgrade_d7_node_type (requis par bp d'autres, et comment_type) et ceux qui en dépendent directement : les divers upgrade_d7_node_bundle (soucis révisions et i18n)
            • Les champs : upgrade_d7_field puis d7_field_instance et leurs widgets
            • books : après upgrade_d7_node_bundle.

            On peux aussi jeter un coup d'oeil via l'interface web, avec l'url /admin/structure/migrate/manage/migrate_drupal_7/migrations

            Plus sur cette page, avec un site drupal 7 bilingue, concernant l'ordre de migration

            En route, ajouter sur les blocks breadcrumb, et les droits sur les données importées ....

            Quelques erreurs ou bugs rencontrés :

            • message filter_null manquant
              => /admin/config/content/formats/manage/full_html  et https://ddevd8.ddev.local/admin/config/content/formats/manage/filtered_html
              * Éditeur de texte:= ckeditor + conf barre à faire
              Activer les transferts d'images non coché + new items ici à étudier
              • Plain text ok (Éditeur de texte: aucun)
              •   oembed (Éditeur de texte: aucun) https://ddevd8.ddev.local/admin/config/content/formats/manage/oembed?destination=/admin/config/content/formats
                a le message "Le filtre filter_null est manquant"

             


            modifier les définitions des migrations

            Il y 2 façons de modifier les définitions des migrations qu'on avait déja importé via les fichiers au format YAML (lorsque l'on installe le module).

            méthode 1 : à la mano via Configuration Manager

            * exporter la def courante via admin/config/development/configuration/single/export  (module du core Configuration Manager)
            * éditer à la mano le fichier et le réimporter admin/config/development/configuration/single/import​

            méthode 2 : Drupal console

            drupal config:edit migrate_plus.migration.IDmig
            drush cr                    avant de relancer l'import
             
            Voir

             


            Avancé : migrate_manifest

            Un fichier manifest définit des ensembles de migrations. Pour lancer des groupes de facon reproductible.

            composer require 'drupal/migrate_manifest:^1.7'
            drush migrate:template:list # Drush 9

            doc à https://www.drupal.org/node/2350651 et https://www.drupal.org/docs/8/upgrade/upgrade-using-drush#manifest

             

            Ajout host virtuel pour avoir une autre base (multi site)

            Au vu des bugs sur la migration i18n et la volumétrie des données du drupal 7, je préfère récupérer sur le site principal les données FR, et avoir un autre site (meme fichiers php, mais autre db) avec les quelques pages bilingues (moins de 20).

            Ex de conf d'hotes virtuel ngninx à Installer drupal 8 et drush 8.1 sur un Pi - test 2

            https://stackoverflow.com/questions/49785023/how-can-i-create-and-load-a...

             


            Plus

            https://www.drupal.org/docs/8/upgrade/upgrade-using-drush
            drush migrate-upgrade --legacy-db-url=mysql://user:password@server/db --legacy-root=http://example.com --configure-only     
            avec 'user' 'password' info user de la db source (ici drupal 7), 'server' est le nom du serveur db source, 'db' est la base de donnée source et 'http://example.com' est la racine du site source un drupal 7).

            https://www.drupal.org/docs/8/upgrade/known-issues-when-upgrading-from-d...

             


            commandes ddev (etre en ddev1/drupal $)

            • en tp réel (CTRL+C pour sortir) et montre confs des services : ddev logs -f
              ddev logs -s db   montre log que le container db soit lancé ou non
            • ddev ssh (pour le container web) ou ddev ssh -s db (pour le container db)
            • backup
              • console drupal:  ddev ssh ; drupal database:dump ; drupal database:restore --file undump.sql
              • snapshots ddev en ddev1/drupal/.ddev/db_snapshots : ddev snapshot -n nombackup  et  ddev restore snapshot nombackup
            • ddev remove (lancé en ddev1/drupal $) est non destructif : efface les containeurs mais pas la db
              ddev remove --remove-data                 efface conteneurs et db

            drush 9

            ddev ssh drush sql:dump --result-file=../db-export.sql

            ddev exec drush cget system.site
            ddev exec drush state:get system.cron_last
            ddev exec drush queue:list
            ddev exec drush core-status --fields=*

            migration

            • ddev exec drush migrate-status     ou drush ms
              ou via l'url (si module UI activé) /admin/structure/migrate/manage/migrate_drupal_7/migrations
            • ddev exec drush migrate-import ID_migration     ou drush mim    plus:   drush mim --help
              Ou en 1 seul coup   ddev exec drush migrate-import --all ; mais en général, on commence par un test, ici on lance les tables dépendantes (node_type, user_role et user), puis celle demandée : ddev exec drush mim upgrade_d7_node_book --execute-dependencies
              ou par paquets de 10: mim nom_mig --limit=10
              ou plus précis (import du user qui a l'ID 5 dans la db source): mim beer_user --idlist=5
            • si bloqué en Import (drush ms montre Status tous en Idle, à part sur un en importing), reset statut avec    ddev exec drush mrs upgrade_d7_ID
            • annuler la migration avec un "drush mr"   ddev exec drush migrate-rollback upgrade_d7_ID

            ddev exec drush mr upgrade_d7_file
            ddev exec drush mim upgrade_d7_file

            ddev exec drush mim upgrade_d7_node_book --execute-dependencies

             

            basiques :

            ddev exec drush mim upgrade_d7_theme_settings,upgrade_d7_user_mail,upgrade_d7_image_styles
            ddev exec drush mim upgrade_search_page,upgrade_system_image,upgrade_system_logging,upgrade_system_rss,upgrade_system_site,upgrade_d7_contact_settings,upgrade_d7_user_role
            ddev exec drush mim upgrade_default_language,upgrade_user_picture_field,upgrade_user_picture_field_instance

            ddev exec drush migrate-import d6_upload_field,upgrade_d6_book_settings,upgrade_d7_global_theme_settings,upgrade_d7_language_types,upgrade_d7_search_settings
            ddev exec drush migrate-import upgrade_d7_system_file,upgrade_update_settings,upgrade_user_picture_entity_display,upgrade_user_picture_entity_form_display,upgrade_d7_shortcut_set_users

            1 erreur corrigée avec un
            drush sql-query "DELETE FROM key_value WHERE collection='system.schema' AND name='outside_in';"

             

            commandes composer (etre en ddev1/drupal $)

            composer require 'drupal/migrate_manifest:^1.7'

            composer require drupal/pathauto:^1.3   composer require 'drupal/ctools:^3.0’   composer require 'drupal/schema_metatag:^1.3'  
            composer require ‘drupal/entity_browser:^2.0’
            composer require drupal/permissions_by_term:^2.3

            admin_toolbar 1.24

            ddev exec drupal config:edit IDmig

            logo drush