DCDL
Categories
Component ID
Component name
Component type
Maintenance status
Development status
Component security advisory coverage
Component created
Component changed
Component body
DCDL (Drupal Config Dump & Load) is a configuration management module written to support migrating configuration via drush for Drupal 6. It aims to be a small tool to handle a very specific problem space: snapshotting and loading configuration parts of a site without affecting the content.
DCDL works at a very low level, pulling the configuration directly from the database and writing directly back. It does not follow any code paths in the modules, but does read and write the configuration with guidance from the modules themselves.
While it tackles a similar class of problems, this is not a replacement for the Drupal 8 CM initiative or for Features or Strongarm or any other process. It is a tool I needed for client sites in Drupal 6, that I wrote because nothing else solved my problem. I'm willing to share with the community as a whole because it may solve the same problem for someone else.
Defining Content vs Configuration
Before you can create a Drupal configuration management tool, you have to define the line between configuration and content, because under Drupal 6 is that there is no defined way to tag data as configuration data. Most modules stick some configuration in the variables table, but not everything in variables is configuration. Modules also store configuration in other custom tables, too. Consequently, there is great debate about what is and what is not configuration, usually focusing on Taxonomy as the biggest gray area.
Since there is no way to externally deduce where all the configuration data lives, the best (possibly only) way to build comprehensive configuration export is to ask the modules themselves to provide their configuration data following some guidelines, listed below.
For DCDL, I use the following criteria to determine content vs configuration:
- Nodes & Users are content. (Generally, I get no arguments there.)
- Data that reference a NID or a UID are content.
- Data that can be created by end-users are content. (Comments, free-tagged Taxonomy)
- Data that can be created only in an admin page (i.e., anything URL path starting with admin) are configuration.
- EXCEPT for third-party account credentials such as the Acquia Connector site keys or Google Analytics Web Property IDs.
- Data created and used exclusively by module code are state information and are excluded from configuration.
How DCDL Works and How to Use It
As mentioned in the last section, DCDL exports two drush commands: dcdl-dump and dcdl-load.
Dumping
The dump command creates a configuration array $config for each module and writes it out as PHP code to sites/SITE/conf.d/MODULE.conf.php. It does so by going to each module and asking it to create the $config
array, which is then written out by DCDL.
Since the most common use cases are a number of entries in the variables table and / or some custom tables, DCDL provides an easy way to specify the variables and tables. HOOK_dcdl_config_variables() returns an array of the keys of entries in the variables tables that should be saved. HOOK_dcdl_config_tables() similarly returns the names of the tables that should be saved. If either of these two hooks are defined, then DCDL will automatically dump the named variables and the contents of the name tables.
If a module needs more control over the exported configuration, it can define HOOK_dcdl_dump(&$config) to add or alter the saved configuration. This hook is called after the variables and tables are dumped.
One of the hard parts of migrating configuration from system to system is the IDs may not always match. This is particularly hard with taxonomy, where free tagging vocabularies may add terms with TIDs on the live site that conflict with TIDs in the staging sites. To address this, DCDL converts anything it identifies as an ID to a UUID in the module.conf.php files and saves a mapping to the dcdl_id_map table in the site database. For convenience, the original value is also stored in the module.conf.php files, but not used by DCDL. DCDL identifies ID three ways:
1. Any fields identified as a primary key in the schema ($schema['primary key']
).
2. Any fields identified as a foreign key in the schema ($schema['foreign keys']
).
3. Any fields identified as a foreign key by HOOK_dcdl_config_tables() ('table' => array('foreign keys' => …
).
Loading
At a high level, the load command hands each module's $config array back to the module and expects the module to configure itself appropriately. The reality is a little more complicated to give the process some flexibility.
In a nutshell, the overall process is:
Phase I
Step 1: Disable modules marked to be disabled in dcdl-global.conf.
Step 2: Enable modules marked to be enabled in dcdl-global.conf.
Phase II
Step 1: Invoke HOOK_dcdl_pre_load()
Step 2: Invoke HOOK_dcdl_load($config) & HOOK_dcdl_load_after_MODULE()
Step 3: Invoke HOOK_dcdl_post_load()
Phase III: Flush caches
For the two default cases above, the core DCDL load will put anything in $config['variables'] in the variables table, and merge any tables defined in $config['tables']. When loading into the tables, files that have UUIDs are translated first to the local system. If the UUID is not mapped on the local system, it is considered a new entry.
After the default load processes $config['variables'] and $config['tables'], DCDL passes the entire $config array to the owning module's HOOK_dcdl_load($config). After the HOOK_dcdl_load() is called, all modules have an opportunity to react in HOOK_dcdl_load_after_MODULE().
After all modules have loaded their configuration, DCDL invokes HOOK_dcdl_post_load(). This is a good time to do some validation of the configuration, check for widowed or orphaned references.
After all modules have loaded their configurations, DCDL flushes all the caches.