While writing an upgrade path test for #1846172: Replace the actions API, I ran into a bit of a problem.
system_update_8046() calls config_install_default_config('module', 'node');, which prematurely installs the new config I'm trying to update to.

Also, when doing config entity upgrades, we had to use config() directly, and not use entity_create().
But config_install_default_config() still invokes the storage controllers importCreate(), which is still calls EntityStorageControllerInterface::create() and EntityStorageControllerInterface::save()!

It is called by:
user_update_8011()
system_update_8046()

Files: 
CommentFileSizeAuthor
#17 config-1998204-17.patch4.57 KBtim.plunkett
PASSED: [[SimpleTest]]: [MySQL] 57,221 pass(es). View
#17 interdiff.txt1.83 KBtim.plunkett
#14 config-1998204-14.patch2.93 KBtim.plunkett
PASSED: [[SimpleTest]]: [MySQL] 57,149 pass(es). View
#11 config-1998204-11.patch2.66 KBtim.plunkett
PASSED: [[SimpleTest]]: [MySQL] 58,015 pass(es). View
#6 config-1998204-6.patch1.14 KBtim.plunkett
PASSED: [[SimpleTest]]: [MySQL] 58,326 pass(es). View

Comments

catch’s picture

Priority: Major » Critical
dcam’s picture

http://drupal.org/node/1427826 contains instructions for updating the issue summary with the summary template.

tim.plunkett’s picture

The direction #2001310: Disallow firing hooks during update is headed will solve this problem for us. But because that is only a sideaffect, we shouldn't close this until we're sure that goes in in a way that obsoletes this issue.

Berdir’s picture

The latest patch in there removes the last call to it in the upgrade path and makes sure that we can't add new ones, as that would trigger hook_entity_info(), which in turn would throw an exception.

So I *think* we're good here but let's wait until that issue is in.

tim.plunkett’s picture

We still will want a helper function for the approach taken in system_update_8046().

Something like

function config_install_single_config($type, $name, $config_name){}

config_install_single_config('module', 'node', 'views.view.frontpage');
tim.plunkett’s picture

FileSize
1.14 KB
PASSED: [[SimpleTest]]: [MySQL] 58,326 pass(es). View

I had no idea we had this function.

chx’s picture

Wow. I didn't know either and I should know these things.

Should we replace some / most / all of http://drupalcode.org/project/drupal.git/blob/9d73599020c282ed79294dcb41... with this function you found?

tim.plunkett’s picture

update_7_to_8_install_default_config() was added in #1712250: Convert theme settings to configuration system, of all places.

The code in UpdateModuleHandler::enable() is a bit different, it loops through all files in /config and writes them.
This is just for picking individual files. I think they can be separate.

I do think we should rename this to update_install_default_config().

Honestly it'd be really cool if somehow config_install_default_config() was controlled by ModuleHandler somehow, so it could be swapped out for this function... Not sure if that's reasonable/possible.

----

My only concern is this scenario:
Assume that we're on 8.0-rc1, and we're supporting head2head upgrade path.

We add a new config file, called history.bananas.yml to core/modules/history/config/history.bananas.yml
In history_update_8666() we call $success = update_7_to_8_install_default_config('module', 'history.bananas');
And then based on $success, we do something important.
This is committed, and is subsequently in 8.0-rc2.

If you run 8.0-rc1..8.0-rc2 updates, $success will be TRUE.
If you run 7.x..8.0-rc2 updates, $success will be FALSE.

Because node_update_8012() already ran module_enable(array('history'));, which would have blanket-installed all of history's config, including history.bananas.yml.

chx’s picture

I believe you read update_7_to_8_install_default_config wrong. It returns FALSE in this case only:

 $file = new FileStorage(drupal_get_path($type, $name) . '/config');
  if (!$file->exists($config_name)) {
    return FALSE;

It will only return FALSE if the core/modules/history/config/history.bananas.yml file does not exist. If it exists, it will blindly install it again and return TRUE.

catch’s picture

My only concern is this scenario:
Assume that we're on 8.0-rc1, and we're supporting head2head upgrade path.

We add a new config file, called history.bananas.yml to core/modules/history/config/history.bananas.yml
In history_update_8666() we call $success = update_7_to_8_install_default_config('module', 'history.bananas');

Even if the return value is the same, this still introduces two different code paths, it's a similar problem to installing a module with a schema, then updating the schema later, for that we added hook_schema_0().

tim.plunkett’s picture

Status: Active » Needs review
Issue tags: -Needs issue summary update
FileSize
2.66 KB
PASSED: [[SimpleTest]]: [MySQL] 58,015 pass(es). View

Let's just do it then.

catch’s picture

Issue tags: +D8 upgrade path
catch’s picture

We add a new config file, called history.bananas.yml to core/modules/history/config/history.bananas.yml
In history_update_8666() we call $success = update_7_to_8_install_default_config('module', 'history.bananas');
And then based on $success, we do something important.
This is committed, and is subsequently in 8.0-rc2.

If you run 8.0-rc1..8.0-rc2 updates, $success will be TRUE.
If you run 7.x..8.0-rc2 updates, $success will be FALSE.

Because node_update_8012() already ran module_enable(array('history'));, which would have blanket-installed all of history's config, including history.bananas.yml.

What if we enforce specifying the install of individual config files in updates. When a new file is added, a new update handler gets added for that file. That way regardless of when the update is run the configuration gets installed in the same order.

tim.plunkett’s picture

FileSize
2.93 KB
PASSED: [[SimpleTest]]: [MySQL] 57,149 pass(es). View

Two of the four times this is called, its installing a specific file. The other times, its in a foreach loop.

I don't think my concerns were actually valid.

dawehner’s picture

Status: Needs review » Reviewed & tested by the community

It seems to be that there should be an issue which uses this functionality for system_update_8046 and therefore need the new parameter.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/includes/update.incundefined
@@ -1462,16 +1462,21 @@ function update_variables_to_config($config_name, array $variable_map) {
+ * @param string $name
+ *   (optional) The owner of the config. Defaults to NULL, in which case the
+ *   name will be derived from the $config_name.
  *
  * @return boolean
  *   True on success, false if config file does not exist.
  */
-function update_7_to_8_install_default_config($type, $config_name) {
+function update_install_default_config($type, $config_name, $name = NULL) {
   // Build the new configuration object.
   $config = Drupal::config($config_name);
 
   // Extract the extension namespace/owner from the configuration object name.
-  $name = strtok($config_name, '.');
+  if (!$name) {
+    $name = strtok($config_name, '.');
+  }

This new functionality is not used in this patch... either we should remove it or convert system_update_8046() to use it.

tim.plunkett’s picture

Status: Needs work » Needs review
FileSize
1.83 KB
4.57 KB
PASSED: [[SimpleTest]]: [MySQL] 57,221 pass(es). View

Fine by me!

Status: Needs review » Needs work
Issue tags: -D8 upgrade path, -Configuration system, -VDC, -Configurables

The last submitted patch, config-1998204-17.patch, failed testing.

alexpott’s picture

Status: Needs work » Needs review
Issue tags: +D8 upgrade path, +Configuration system, +VDC, +Configurables

#17: config-1998204-17.patch queued for re-testing.

jibran’s picture

Status: Needs review » Reviewed & tested by the community

Back to RTBC.

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed 50ae478 and pushed to 8.x. Thanks!

Automatically closed -- issue fixed for 2 weeks with no activity.

Anonymous’s picture

Issue summary: View changes

Updated issue summary.