Problem/Motivation

I noticed something strange today with configuration synchronisation. When we deploy configuration that contains both the enabling of a (contrib/core) module & the config from it it doesn’t seem to work. The module appears to get enabled, and the configuration gets imported, but in the end the module really isn’t enabled, although the status in the modules overview screen shows it is enabled. Uninstalling & re-enabling the module & re-importing the config fixes this, but it’s strange as it happened to me twice today.

Encountered on the following stack:
PHP: 7.3
Drupal Core: 8.8.3
Drush: 10.2.2
Drupal Console: 1.9.4

EDIT
The issue seems to only happen when you are not using the Drupal batch UI interactive batch runner.

config import via drush cim --> fail
config import via drupal console ci --> fail
config import via UI --> works

So this seems to be related to the way how batch imports handled.

Steps to reproduce

I encountered the issue twice today on 2 different sites for 2 different modules (jsonapi_extras / media_library), below are the 2 scenarios written out.

jsonapi_extras

  • locally enabled the module (drush en)
  • locally configured some overrides
  • locally exported the configuration (drush cex -y)
  • committed and merged on our test branch that triggers a build & deploy
  • on the server the configuration is imported (should enable & configure the module)
  • config import done & cache is cleared --> no errors
  • checked the json:api confiugration --> FAIL: No json:api extras tab
  • checked the module overview --> module is enabled --> not true...
  • on the server drush pm:uninstall the module
  • on the server drush en the module
  • on the server drush cim -y (lists all the changes again for the module)
  • now it works fine

media_library

  • locally enabled the module (drush en)
  • locally configured some fields to use the media widget
  • locally exported the configuration (drush cex -y)
  • committed and merged on our test branch that triggers a build & deploy
  • on the server the configuration is imported (should enable & configure the module)
  • config import done & cache is cleared --> no errors
  • checked the field configuration --> FAIL: The fields don't have the media library widget selected, nor is it available
  • checked the module overview --> module is enabled --> not true...
  • on the server drush pm:uninstall the module
  • on the server drush en the module
  • on the server drush cim -y (lists all the changes again for the module)
  • now it works fine

Proposed resolution

This occurs with Drush 10 since the config import commands incorrectly use the UpdateKernel. See https://github.com/drush-ops/drush/pull/4217 for more.
This also occurs with Drupal Console - see https://github.com/hechoendrupal/drupal-console/issues/4235

However, this issue also shows that drupal_flush_all_caches() has a problem when rebuilding the container if a new module has been added to core.extension:module configuration. The patch on this issue addresses this weakness.

Remaining tasks

User interface changes

N/A

API changes

N/A

Data model changes

N/A

Release notes snippet

None

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

BramDriesen created an issue. See original summary.

Pascal-’s picture

Ran into this several times as well, first noticed this in 8.8.2

BramDriesen’s picture

Priority: Major » Critical

Going to set this to critical as it looks like even just enabling a module doesn't work anymore.

BramDriesen’s picture

I have the feeling it might have something to do with this change that is listed in none of the release notes #3043455: Add an API for installing a fieldable entity type (or I'm really looking over it)

BramDriesen’s picture

I just came to an interesting conclusion:

config import via drush cim --> fail
config import via UI --> works

So is there anything specific to doing an import using the cli vs doing it in the UI ?

cilefen’s picture

If it turns out to only affect Drush, let the maintainers know: https://github.com/drush-ops/drush/issues

BramDriesen’s picture

FYI: I also reported this to the drush issue queue since it might be related to drush only, https://github.com/drush-ops/drush/issues/4350

jungle’s picture

Subscribing. Would be great if someone to have a check against Drupal Console which has similar commands to Drush.

BramDriesen’s picture

I'll test that tomorrow, I totally forgot to test this with Drupal Console.

BramDriesen’s picture

On Drupal Console I have the same issue, I'll update the description a bit to reflect this. The Drush maintainer said the following:

Drush is just calling core's config sync service so the bug is not likely in Drush. It might only manifest in Drush because Drupal's UI uses the interactive batch runner.

So since it's seems to happen on both Drush & Console I still feel it's a Drupal Core issue.

BramDriesen’s picture

Issue summary: View changes
alexpott’s picture

This issue needs to be updated with Drush and console versions so that we can try to reproduce the issue.

alexpott’s picture

I've tried to reproduce this on Drupal 8.9.x and Drush 9.8.0-dev and the jsonapi_extras module is been successfully installed and the overrides I've created are being imported.

alexpott’s picture

Out of interest is the site in question using core provided caches or a something different?

BramDriesen’s picture

Hi Alexpott,

Everything is on the latest version, meaning:
Drupal Core: 8.8.3
Drush: 10.2.2
Drupal Console: 1.9.4

To your question of caching, regular caching has been used, no other cache related modules.

BramDriesen’s picture

Issue summary: View changes
swentel’s picture

Does it fail manually, or is it only with the build script? Might seem a stupid question maybe, but you never know something is going wrong in the build script (some leak somewhere, just a guess for now).

BramDriesen’s picture

Fails in both cases actually, both manual drush commands as our ansible script that executes the commands on the server.

E.g. when manually doing the following it fails (repeatably):

  • drush pm:uninstall module
  • drush cr
  • drush cim -y
  • drush cr
swentel’s picture

And it also fails with just core and json api only? Sorry for too much questions, just trying to isolate :)

The reason I'm asking is because something else might be in the way, e.g. some other config module or so, maybe even custom code?

BramDriesen’s picture

I'll try to reproduce it on a clean up-to-date drupal installation this evening.

But the thing is I encountered it on 3 different websites :/ we do have the configuration translation & config ignore modules enabled

module:
  ...
  config: 0
  config_distro: 0
  config_filter: 0
  config_ignore: 0
  config_translation: 0
  ...

(from core.extension.yml)

BramDriesen’s picture

Another test I did was to only import the core.extension.yml file by copy pasting it into a partial directory:

drush cim --partial --source=../config/sync/partial/

Which also failed. So the complete scenario was like:
- drush pm:uninstall module
- drush cim --partial --source=../config/sync/partial/
- drush cr

While manually enabling the module works
- drush pm:uninstall module
- drush en module
- drush cr

swentel’s picture

I'm afraid that one of those additional config (or maybe a combination) modules will cause the fail.

BramDriesen’s picture

Nope, I was just able to reproduce it on a clean Drupal installation.

Here is the full & complete setup of what I did.

- composer create-project drupal-composer/drupal-project:8.x-dev config_issue --no-interaction
- Installed through the UI using the standard profile
- After installation I did a drush status with the following output

 Drupal version   : 8.8.3
 Site URI         : http://default
 DB driver        : mysql
 DB hostname      : database
 DB port          : 3306
 DB username      : drupal8
 DB name          : drupal8
 Database         : Connected
 Drupal bootstrap : Successful
 Default theme    : bartik
 Admin theme      : seven
 PHP binary       : /usr/local/bin/php
 PHP config       :
 PHP OS           : Linux
 Drush script     : /app/vendor/drush/drush/drush
 Drush version    : 10.2.2
 Drush temp       : /tmp
 Drush configs    : /app/vendor/drush/drush/drush.yml
                    /app/drush/drush.yml
 Install profile  : standard
 Drupal root      : /app/web
 Site path        : sites/default
 Files, Public    : sites/default/files
 Files, Temp      : /tmp

Okay good, next step:
- composer require drupal/jsonapi_extras
- lando drush en -y jsonapi_extras
- In the configuration I just created one override for the first item shown (block)
- drush cex -y
Now the magical part to prove that it's not working
- drush pm:uninstall jsonapi_extras
- drush cim -y
- drush cr

It doesn't work, the configuration is imported, but no jsonapi_extras tab anymore in the UI.

catch’s picture

#23 Doesn't entirely prove that configuration import is failing, it proves that the tab for jsonapi_extras isn't showing up after configuration import.

For example if drush cex doesn't show any changes, then the configuration import probably finished successfully.

Can you try things like going to /admin/config/services/jsonapi/extras directly?

alexpott’s picture

I can repeat the test but it only occurs for me on Drush 10 and not Drush 9. That's still not saying this is Drush's fault but there is something different in the way that D9 and D10 do things that's resulting in this bug.

On D10 the module is installed and there are no config changes to import but the route doesn't work and even doing a cache rebuild via the UI doesn't work. I considered that maybe this was something in APCu so I disabled that - didn't fix it either. V interesting.

alexpott’s picture

So one sign of the problem is that jsonapi_extras has not made it into the container.modules parameter. Which is why it's not in the router.

alexpott’s picture

Status: Active » Needs review
FileSize
784 bytes

So the patch attached allows drush cache-rebuild to fix the problem but it doesn't actually fix the problem on import.

BramDriesen’s picture

Status: Needs review » Reviewed & tested by the community

To #24

For example if drush cex doesn't show any changes, then the configuration import probably finished successfully.

That's probably correct, but if none of the module code is being executed, it doesn't really add any value :-D

#27 I tested it and it fixed the issue on my clean drupal installation test stack! I'll go ahead and also test this on my other sites.

alexpott’s picture

Status: Reviewed & tested by the community » Needs review
FileSize
871 bytes

Ok I know what has broken this in Drush. For some reason they've decide to use the UpdateKernel for running config import. Core does not do this and have no idea why they've chosen to do this. Here's one possible fix for Drush - just don't use the update kernel. Config updates are not database updates they are not meant to use that kernel. An alternative approach would be to force flush all the caches after config import. Note that core does not do this because it is not necessary because it uses the regular kernel.

The last submitted patch, 27: 3119373-27.patch, failed testing. View results

BramDriesen’s picture

Status: Needs review » Needs work

#30 :)

alexpott’s picture

@BramDriesen that's a patch for Drush that fixes the issue. It'll never pass on core :) and Drush works via github. The issue that has caused this problem is https://github.com/drush-ops/drush/pull/4217

BramDriesen’s picture

The patch of #27 is for Drupal core and failed the tests in #30 :-) the patch of #29 for drush and obviously won't apply to Drupal Core no ;-)

BramDriesen’s picture

Since it also failed with Drupal Console, I can only assume it would also be wrongly implemented there? Although Drush is the most popular option, I'll also open an issue in their issue queue tomorrow.

Back to this issue, I assume it would be okay to make the change of #27 and commit it to core once the tests are passing.

alexpott’s picture

Here's a fix for #27. I think this change makes sense as it means that the module list is coming from a single source of truth and that's the extension.list.module service.

alexpott’s picture

The last submitted patch, 36: 3119373-test-only.patch, failed testing. View results

BramDriesen’s picture

Status: Needs review » Reviewed & tested by the community

The patch works fine! Thanks a lot @alexpott !

FYI: I created a similar issue in the Drupal Console issue queue so they can also have a look at it.

alexpott’s picture

Title: Configuration synchronisation that both enables & configures a module fails » Configuration synchronisation that both enables & configures a module fails and drupal_flush_all_caches()
Issue summary: View changes

Updated the issue summary to reflect the solution and where the real problem is. This patch is a mitigation the real fix has to be in Drush 10 and Drupal Console.

BramDriesen’s picture

Yes :-) sounds good to me. Should the patch also be included in 8.9.x and 9.x ?

alexpott’s picture

Issue summary: View changes
catch’s picture

Status: Reviewed & tested by the community » Needs work

Test failures in 36, against 8.9.x and 9.0.x are real - couple of different ones.

alexpott’s picture

Ah yeah we'll need a different patch for 9.0.x because path_alias is not always installed there.

alexpott’s picture

I don't think the test failure against 8.9.x is real - that's from Tuesday and one of HEAD fails that day but the 9.x one is real. Here's new patches. the 8.x patch is the same as #36.

tim.plunkett’s picture

Status: Needs review » Reviewed & tested by the community

The fix looks good, tests look good for their respective versions.

+++ b/core/includes/common.inc
@@ -550,12 +550,15 @@ function drupal_flush_all_caches() {
   foreach ($module_data as $name => $extension) {

Not visible in the patch, but for reference, that variable comes from above:

$module_data = \Drupal::service('extension.list.module')->reset()->getList();
BramDriesen’s picture

RTBC For me as well :-)

  • catch committed 3304901 on 9.0.x
    Issue #3119373 by alexpott, BramDriesen: Configuration synchronisation...

  • catch committed 9b45f72 on 8.9.x
    Issue #3119373 by alexpott, BramDriesen: Configuration synchronisation...

  • catch committed 9fe181a on 8.8.x
    Issue #3119373 by alexpott, BramDriesen: Configuration synchronisation...
catch’s picture

Status: Reviewed & tested by the community » Fixed

Committed/pushed to 9.0.x, 8.9.x, and 8.8.x, thanks!

BramDriesen’s picture

Thanks all!

thhafner’s picture

Thanks to everyone for the quick turn around on this issue. It was a major pain-point for our team recently. Very appreciated!

Status: Fixed » Closed (fixed)

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

ressa’s picture

I just encountered this importing configuration into an existing Drupal 9.2.6 site, which enabled a module and its configuration. I got this error after running drush config:import:

The configuration cannot be imported because it failed validation for the following reasons:
Unable to install the field_defaults module since it does not exist.

#3247659: Can't import configuration

If I cleared cache in advance, the import went through smoothly:

drush cache:rebuild
drush config:import
[...]
[notice] Finalizing configuration synchronization.
[success] The configuration was imported successfully.
Lando          : 3.4.2
PHP            : 7.3.31
Drupal version : 9.2.6
DB driver      : pgsql
Drush version  : 10.6.0
BramDriesen’s picture

@ressa Maybe open a new issue and link back to this one? :-)

ressa’s picture