Problem/Motivation

Imagine the following use-case:

You are installing media_entity_instagram and you have a second module, for example thunder_media, which contains media_entity.bundle.instagram.yml as optional config. media_entity.bundle.instagram.yml has a module dependency on media_entity_instagram.
So after the installation, media_entity.bundle.instagram.yml was imported successfully from ConfigInstaller::installOptionalConfig() during ModuleInstaller:install(). So far so good.

Now our thunder_media also contains several field and view/form-mode configs as optional config. These configs don't have a dependency on the module media_entity_instagram but on the config media_entity.bundle.instagram. installOptionalConfig() doesn't pick up the new resolvable dependencies recursively.

Proposed resolution

Let ConfigInstaller::installOptionalConfig() pick up direct and indirect optional configs.

Remaining tasks

User interface changes

API changes

Data model changes

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

chr.fritsch created an issue. See original summary.

chr.fritsch’s picture

Status: Active » Needs review
FileSize
647 bytes

Here is a patch.

chr.fritsch’s picture

Issue summary: View changes

Status: Needs review » Needs work

The last submitted patch, 2: 2930996-2.patch, failed testing. View results

chr.fritsch’s picture

It's not only appearing on optional config. If you have an optional configuration based on a config from config/install, it will also not be installed.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

alexpott’s picture

We need to do some issue archeology to work out why a test for this specific case was added to Drupal\Tests\config\Functional\ConfigOtherModuleTest

alexpott’s picture

Status: Needs work » Needs review
Issue tags: +Configuration system
FileSize
2.85 KB

So the ConfigInstaller used to do this until #2623940: ConfigInstaller tries to install optional config with missing dependencies - reading that issue points towards a better fix. But obviously we need to read it though and determine if we're now breaking something.

No interdiff cause new approach.

alexpott’s picture

@Berdir pointed out that #8 might cause deleted configuration to suddenly reappear. That would be a problem. We need to add a test for that. #2 might not suffered from this problem. Since we're limiting it only to things with direct dependencies on the new configuration that is created.

alexpott’s picture

Here's an approach that might satisfy both cases. We need more test coverage though.

The last submitted patch, 8: 2930996-8.patch, failed testing. View results

chr.fritsch’s picture

I tested the patch with the use-case I provided in the IS and it works fine.

mtodor’s picture

I have tested this additionally. It looks good.

Small nitpick from patch.

+++ b/core/modules/config/tests/src/Functional/ConfigOtherModuleTest.php
@@ -64,10 +64,9 @@ public function testInstallOtherModuleFirst() {
+    $this->assertTrue(entity_load('config_test', 'other_module_test_optional_entity_unmet', TRUE), 'The optional configuration config_test.dynamic.other_module_test_optional_entity_unmet whose dependencies are met is not created.');

Assertion message should be adjusted.

I'm not sure are following cases covered in some of the tests, but they should be:

  1. Import single configuration => optional configuration should not be imported
  2. Import full site configuration, where module that triggers import of optional configuration is enabled => optional configuration should not be imported

Since I have fiddled a bit with tests to try single import, I have provided a patch here with mentioned changes. If it's of some use. I'm not sure if that test should be part of the optional configuration test or in import/export tests.

mtodor’s picture

My uploads are strange in the last comment (#13) - here are correct ones.

The last submitted patch, 13: 2930996_13.patch, failed testing. View results

alexpott’s picture

Single import and full site import explicit don't look in a module's optional configuration so that's okay. What we do need to test is that deleted configuration is not suddenly reimported because of this.

alexpott’s picture

I've basically reverted #14 since this doesn't add meaningful test coverage. The single import export form doesn't ever touch optional configuration or install anything other than the config object you provide it.

I've have however extended the test coverage to ensure that you can delete a configuration entity provided by a module and then install a module and ensure it does not magically come back again. New optional configuration is only installed if it could not possibly have existed before. I.e. the module being installed has to be in the dependency chain.

chr.fritsch’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: -Needs tests

This looks all good to me. Now we also have more test coverage.

And since my patch from #2 was completely reverted, I think I am allowed to mark this RTBC.

chr.fritsch’s picture

Status: Reviewed & tested by the community » Needs work

Sorry, have to kick it back. I tested this patch with Thunder and I found a case where not all possible installable configs get imported.

The corresponding PR in Thunder is https://github.com/BurdaMagazinOrg/thunder-distribution/pull/542

We have to analyze what the exact problem there is and then provide a test for this patch.

alexpott’s picture

Thanks for testing @chr.fritsch nice find. First I'm going to expand the testing to have dependencies of dependencies as looking at https://github.com/BurdaMagazinOrg/thunder-distribution/pull/542 that's the problem.

alexpott’s picture

Status: Needs work » Needs review
FileSize
848 bytes
3.91 KB

Thanks thunder tests! So what's happening here is that we need the full configuration graph in order to determine proper dependencies.

Status: Needs review » Needs work

The last submitted patch, 21: 2930996-21.patch, failed testing. View results

alexpott’s picture

Version: 8.5.x-dev » 8.6.x-dev
alexpott’s picture

Here's a 8.5.x patch for Thunder testing.

alexpott’s picture

Status: Needs work » Needs review
FileSize
5.31 KB
7.43 KB

Here's a test for why we need the full dependency graph and a fix for ViewsKernelTestBase tests. This is needed because of the way it installs configuration out of order and so when we do $this->installConfig(['system']); we end up installing some optional views because they depend on system. This populates views data and the overrides from each test didn't take affect. Fun.

Berdir’s picture

Status: Needs review » Needs work
  1. +++ b/core/modules/config/tests/src/Functional/ConfigOtherModuleTest.php
    @@ -62,12 +62,24 @@ public function testInstallOtherModuleFirst() {
         $this->assertNull(entity_load('config_test', 'other_module_test_optional_entity_unmet', TRUE), 'The optional configuration config_test.dynamic.other_module_test_optional_entity_unmet whose dependencies are not met is not created.');
         $this->installModule('config_test_language');
    +    $this->assertNull(entity_load('config_test', 'other_module_test_optional_entity_unmet2', TRUE), 'The optional configuration config_test.dynamic.other_module_test_optional_entity_unmet2 whose dependencies are not met is not created.');
    

    I thought we had actually replaced all entity_load() calls, but apparently #2723593: Properly deprecate entity_load() and friends never got in.

    Should we at least avoid it in the new calls and use ConfigTest::load()?

  2. +++ b/core/modules/config/tests/src/Functional/ConfigOtherModuleTest.php
    @@ -62,12 +62,24 @@ public function testInstallOtherModuleFirst() {
    +    // The following configuration entity's are now met even though it has no
    +    // direct dependency on the module and it's dependency is not provided by
    +    // the being installed. The dependency already exists in configuration.
    +    $this->assertTrue(entity_load('config_test', 'other_module_test_optional_entity_unmet2', TRUE), 'The optional configuration config_test.dynamic.other_module_test_optional_entity_unmet2 whose dependencies are met is now created.');
    

    word missing? the ... module? ... being installed?

On the plus side, I successfully tested this with two different complex distributions and only had a single problem in a kernel test that was caused by an incorrectly named config file, created #2972003: Verify that the file name matches the ID when installing configuration.

alexpott’s picture

1. Can we file a follow-up for that? We have to reset the cache every time we load just to be sure we're using up-to-date info.
2. Fixed.

alexpott’s picture

Status: Needs work » Needs review
Berdir’s picture

Status: Needs review » Reviewed & tested by the community

1. Fine, lets reroll the other issue when this is in. It will conflict anyway. That said, config entities do currently not use the static cache by default, they have to opt-in, and only role is doing that currently. So that cache reset isn't doing anything at the moment, unless we'd opt-in to static caching.

The last submitted patch, 24: 2930996-8.5.x-24.patch, failed testing. View results

Status: Reviewed & tested by the community » Needs work

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

Mixologic’s picture

Status: Needs work » Reviewed & tested by the community

Testbot Snafu.

catch’s picture

Status: Reviewed & tested by the community » Needs work
  1. +++ b/core/lib/Drupal/Core/Config/ConfigInstaller.php
    @@ -204,16 +203,19 @@ public function installOptionalConfig(StorageInterface $storage = NULL, $depende
    +      // on the thing being installed.
    

    Can we be more specific than thing?

  2. +++ b/core/modules/config/tests/src/Functional/ConfigOtherModuleTest.php
    @@ -62,12 +62,25 @@ public function testInstallOtherModuleFirst() {
    +
    +    // The following configuration entity's are now met even though it has no
    +    // direct dependency on the module.
    

    Should this be configuration entity's dependencies?

alexpott’s picture

Status: Needs work » Reviewed & tested by the community
FileSize
3.18 KB
7.78 KB

@catch thanks for the review.

Re #1. Turned the sentence around so we didn't have to work out what thing is - it is an extension - either a module or a theme.
Re #2. Yep you're right. I tried to add more detail to help people / myself when I look at this in the future.

As all of the fixes are comments / test assertion text only setting back to rtbc.

  • catch committed fb05cb4 on 8.6.x
    Issue #2930996 by alexpott, mtodor, chr.fritsch, Berdir: Config...
catch’s picture

Status: Reviewed & tested by the community » Fixed
Issue tags: +8.6.0 release notes

This is theoretically just a bug fix, but in practice it could mean unexpected new configuration showing up in profiles and sites under development which feels behaviour-change-ish, so leaving in 8.6.x only for now. Would think about backporting but would we need a change notice for that? (Genuinely not sure).

jhedstrom’s picture

Note that this caused a change in kernel tests where if one specified a module's config to be installed, any optional config for other enabled modules would be installed. This is demonstrated in the Message Digest module's recent fixes: #2981675: Tests are failing on 8.6. The workaround seems fine in that case, but perhaps a change notice is needed? It obviously didn't impact any core tests though.

alexpott’s picture

@jhedstrom thanks for the report of the issue. Do you feel a CR would have helped you track down the fix? If so it'd be great to add one. I'm not sure of what to write that would be like a change record and inform the people that need to know.

As an aside I feel that KernelTestBase and the way it ignores configuration and module dependencies on configuration install is not really that great.

jhedstrom’s picture

Do you feel a CR would have helped you track down the fix?

Honestly, probably not. I wouldn't have known what to search for until I found this issue I think.

As an aside I feel that KernelTestBase and the way it ignores configuration and module dependencies on configuration install is not really that great.

It's a bit of a mixed bag. It's great to not have to install every single dependency if the tested code doesn't need it, but it does lead to other issues. I think this new approach of installing installable config makes sense, without tipping too far the other way to requiring every dependency to be installed for all kernel tests.

Status: Fixed » Closed (fixed)

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

xjm’s picture

Title: Config installer doens't install possible installable config » Config installer doesn't install possible installable config
xjm’s picture

Status: Closed (fixed) » Needs work
Issue tags: +Needs change record

This issue is missing a change record. Can we add one that can be linked in the 8.6.0 release notes? Thanks!

catch’s picture

Status: Needs work » Fixed

Added a change record.

Amber Himes Matz’s picture

Thanks for the change record. The CR says "This should not require any action from module authors or site administrators." But as @catch pointed out in #36, "in practice it could mean unexpected new configuration showing up in profiles and sites under development".

Under what circumstances would new configuration show up? And what if someone wanted to trigger this? I assume the only way to trigger a recursive installation of config would be to uninstall and re-install the module? Is that correct? (Asking for documentation and tutorial updating's sake.)

Status: Fixed » Closed (fixed)

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