I wanted to experiment with the D6->D7 upgrade path to see how well the CCK data updates are working, so I was looking around for some real sites to upgrade. Like many of you, I maintain a bunch of 'friends and family' sites in addition to my 'day' job. Usually those sites are the last ones upgraded, but it occurred to me that they would be good fodder for doing some testing of the site upgrade process. I've been upgrading them, rolling back, and re-upgrading them over and over and I found a number of tips and tricks I thought I would share.
Clean House First
You know how when you move you always are amazed at the amount of junk you forgot you had lying around? Your site probably has some junk in it, especially if it is a few years old. These sites date back to Drupal 4.7 and include the results of a lot of early experimentation where I was installing and then removing lots of modules just to see what they would do. All that cruft is still in my databases. Time to clean it out.
First thing to check is whether there are any modules I never used, or previously disabled but never uninstalled. Disabling unused modules gets them off the list of things I need to worry about. Taking the extra step of uninstalling them will often clean a bunch of cruft out -- database tables and variables that they used that I no longer need.
But that won't necessarily find all the extra tables, especially if I installed a module and then removed it without uninstalling it, or used some modules that didn't properly clean up after themselves. I downloaded and installed the Schema module to help me find database tables that I no longer use. It provides a handy report that compares the schema of my installed modules with the ones actually in my database, to find things like those Aggregator tables that I don't need any more.
Any place I'm using Features in D6 that define content types, I need to do one more thing before I upgrade. I need to go into the node_types table and find any content types that have the module name of 'features' and change it back to 'node'. Without this step, when I disable the Features module all those content types will be dropped and will no longer be available in D7. Once everything is ported to D7 I will have to re-create the D7 feature from scratch, there currently is no upgrade path for the Feature itself, but my data will be fine.
Fields are in core in D7, so I won't need CCK's Text and Number modules, or modules like File Field and Image Field. I don't want to actually uninstall any of them though. If I uninstall them my fields will be marked inactive and my data deleted, and I need that data for the field upgrade.
Identify Changed Module Needs
Next I need to think about the modules I used in D6 that I won't need any more in D7, and new ones I will need that I didn't use before. One example there is the Admin Menu module. D7 has a nice built-in Toolbar module that I'm going to use. So I want to disable and totally uninstall the Admin Menu in D6 before I do my upgrade, so that it will clean all the Admin Menu items out of the menu tables. I used Modal Framework in D6, but won't need it in D7 with the built-in Overlay module, so I'll uninstall it, too. I won't need jQuery UI or jQuery Update now that jQuery UI is in core, so I can get rid of them.
I have numerous modules enabled in D6 that define CCK fields that I won't need in D7. I will still need the D7 version of CCK for the Content Migrate module which will upgrade my field data from the CCK format to the format now used by core. In D7 I will also need:
- Field Group (for what used to be the CCK Field Group module)
- References (for what used to be Nodereference and Userreference)
- Field Collection (for the Multigroup feature in CCK 6.3)
In D7 I could rely on the core file and image handling and not add any contrib modules, but I plan to use the new Media module and its relatives. That whole collection of modules can provide image galleries, image plugins for WYSIWYG editors, and a lot of other nice features. So I have a list of modules that I used in D6 that I won't need any more and another list of modules I will use in D7:
Out With the D6 Media Modules:
In With the D7 Media Modules:
I will also need a couple other modules that weren't required in D6:
- Entity (required by Field Collection and Media modules)
- CTools (required by the D7 version of Views)
Do the Upgrade
Now I'm ready to perform the upgrade. I use the Backup and Migrate module to easily create a backup of my D6 database before I start. I have to create an empty database for the D7 version of the site and a folder on my directory where I can put the new site. I won't re-use the old location and old database, I want to leave them pristine so I can go back and re-use them if necessary. And I'm doing this NOT on production but locally so I can be sure everything works before I do anything to my live site.
There are several ways to actually do the upgrade. I can do it manually, or I can use Drush to make it much easier. I'll describe both approaches.
For the manual upgrade I have to download and unzip a copy of Drupal 7 into my new site folder. Then I need to copy the D6 version of the settings.php file into the new directory. The only thing I need to change is the name of the database, if I'm using a different one for the D7 version. Other than that I don't make any other changes, the upgrade process will alter it as necessary for D7.
The easiest, best way to to the upgrade is to start with just the core code, no contrib modules. So navigate to the D7 folder and run update.php on only core. The official upgrade instructions say to disable all contrib modules before you upgrade, which can take a while, especially if you have lots of module dependencies that prevent you from disabling a module until all its dependencies are disabled. Running update.php without any contrib modules in the modules folder will basically accomplish the same goal -- which is to keep any contrib module updates from running until I'm ready for them.
Then I have to find, download, and unzip D7 versions of all my contrib modules into my sites/all/modules folder. That means looking each one up to find the right D7 version of the code. This step is really time-consuming. Part of the reason for cleaning house first is to avoid doing this for modules I don't even need.
Once I have added all the contrib modules I have to go back to my modules page to make sure they are enabled, then return to update.php to allow the contrib modules to do any updates that are needed.
Upgrade with Drush Site-Update
There are actually two ways to use Drush for the upgrade. I'll want to be sure to be using Drush version 4 or higher for best results. I prepare an empty database for the D7 version of my site, as above, and decide where I want to place the new files in my directory. I don't need to create the directory, Drush will do that.
I need one more thing to give Drush enough information to know what to do, I need to create a Drush alias file for the new site. If I already am using Drush aliases, I can add an alias to my current aliases. If I wasn't already using aliases, I would create a new file called 'aliases.drushrc.php', add it to the folder where my Drush code lives, and put something like the following text into it (I can give the sites whatever aliases I want, they don't have to be 'old' and 'new'):
$aliases['old'] = array( // The alias I want to use for the old site. 'uri' => 'www.oldsite.com', // The url of the old site. 'root' => '/var/www/drupal6', // The physical file location of the Drupal root for the old site. 'db-url' => 'mysqli://username:password@localhost/oldsite', // The db_url string for the old site's database. ); $aliases['new'] = array( // The alias I want to use for the new site. 'uri' => 'www.newsite.com', // The url of the new site. 'root' => '/var/www/drupal7', // The physical file location of the Drupal root for the new site. 'db-url' => 'mysqli://username:password@localhost/newsite', // The db_url string for the new site's database. );
Then I just type the following into a command line and watch it go:
drush @old site-upgrade @new
If I want more information about what it is doing I can append '--verbose --debug' to the command.
This will create the new site directory, copy the old database to the new database, add the core files to the new site location, run update.php on the core files, add the contrib modules, and run update.php on them.
Upgrade With a Drush Make File
Using Drush Site-Upgrade is pretty slick, but it does not do everything. It does not find a specific version of module code for my contrib modules if I need something that is not standard or not yet marked as supported. And it does not add the new modules I will need in D7 that did not exist in D6. And in some cases it adds modules to D7 that I won't actually want to use.
A more fine-grained approach is to create a Drush Make file for my upgrade that contains the exact modules and versions that I want in D7 and let me grab them all at once. It will also do things like add external files needed by some of the new modules, like the mediaelement library required by the Media Element module.
The easy way to do this is to go to the old site and type the following:
drush make-generate mymakefile.txt
This will create a Drush Make file for my old site. Then I can edit it to change the core version to D7 and fix the versions of each of the contrib modules to the version I want to use in my D7 site. I can also remove modules I no longer need and add new ones that are required.
Then I create an empty directory for my new site, place the make file in it and type:
drush make mymakefile.txt
That will populate my site with all the new code. I copy the settings.php file from the D6 site to the D7 site, copy the D6 database to the D7 database, navigate to update.php, and run update.php to update the database. As noted earlier, I may want to add an extra step of moving the contrib modules out of the sites/all/modules folder while I run update.php on only core, then move them back and run it again with the contrib modules in there.
I can then go to admin/modules and enable any new modules I need plus several modules that won't be turned on by default in an upgrade:
- Contextual Links
Many things were updated automatically but if I was using CCK in D6 I won't see any fields in D7. I have to update my field data as a separate step. I install the Content Migrate module (in the D7 version of CCK), then navigate to admin/structure/content_migrate.
There I will see three sections: a list of all the fields that are available to migrate, fields that cannot yet be migrated (because I don't have the right modules installed and available yet), and fields that have already been migrated.
After I migrate the fields to move the D6 field data to D7, I can go to the content types pages to confirm that the fields are there and structured correctly. I can roll the migration back if it doesn't work right and try it again later until I have the results I need.
I hope these tips are helpful. The upgrade process is never totally painless, but hopefully these ideas will make it a little smoother.