Problem/Motivation
Content dependencies are also soft dependencies. This missing that if they are missing then the configuration should not remove them if resaved. This means that if the content does not exist during configuration import and the config entity is created the content dependency should not be removed. For example, Block content blocks lose their dependencies when exported after being imported before the block content entity existed.
If I have a module that provides some block placements and default content for the block entities themselves, the block placements are imported first and then the block content. This is allowed because of the fallback plugin for blocks. If you immediately attempt to re-export the block placements, the dependencies will be lost.
Proposed resolution
Don't clear out content dependencies when recalculating configuration dependencies.
Remaining tasks
Discuss approach, review patch, add tests.
User interface changes
None
API changes
tba
Data model changes
tba
Comment | File | Size | Author |
---|---|---|---|
#21 | 2597854-2-21.patch | 7.74 KB | alexpott |
#21 | 19-21-interdiff.txt | 1.77 KB | alexpott |
#19 | 2597854-2-19.patch | 7.26 KB | alexpott |
#19 | 13-19-interdiff.txt | 7.26 KB | alexpott |
#13 | 2597854-13.patch | 3.78 KB | benjy |
Comments
Comment #2
larowlan+1 from me assuming that this doesn't prevent importing (but I think all content entity dependencies are soft, so we're good)
Comment #4
benjy CreditAttribution: benjy at PreviousNext commentedFailures all look like config schema, will wait for some input from @alexpott before changing any tests.
Comment #5
alexpottSomething about this feels wrong. Can @benjy can you post such a module so I can see what's going on.
Comment #6
benjy CreditAttribution: benjy at PreviousNext commentedSee the attached module, simplified to the bare minimum of what is needed to reproduce this.
SHA1 25cc8257d0432cef8a79b7ddb6e66917f1307e58 test-content.tar.gz
Steps to reproduce
Comment #7
alexpottSo here is a better fix - i think. I think given the fact that all content dependencies in configuration are soft we can't remove them on recalculation as the whole point is that don't have to be met.
Comment #10
benjy CreditAttribution: benjy at PreviousNext commentedHere's a test for the issue. The solution in #7 only partly works, the dependency on the block_content module is still dropped, as shown by this test.
Comment #13
benjy CreditAttribution: benjy at PreviousNext commentedNow creating the block which was missing from the test.
#7 still doesn't fix the issue though because config.storage->read() doesn't trigger the re-calculation of the dependencies.
Comment #15
alexpottThis is a major bug - dependencies shouldn't go missing like this.
Comment #16
alexpottThis looks weird
Comment #17
roynilanjan CreditAttribution: roynilanjan commentedIs it possible to import block_content to import? This is found that after full import the block content unable to import in the db, the import block is missing/showing broken in the original region see http://drupal.stackexchange.com/questions/146037/block-error-on-cmi
Comment #18
alexpottUpdated issue summary
Comment #19
alexpottWhilst trying to explain some of the test fails @tstoeckler and I discovered #2625216: LocaleConfigManager::getTranslatableDefaultConfig() reads config from uninstalled modules
Comment #20
dawehnerIn that case fixing
\Drupal\views\Plugin\views\BrokenHandlerTrait
would be neat.The comment is now missing some information
Is that valid? I would be totally happy about that.
Comment #21
alexpottThanks @dawehner. I think 1 should be addressed in a followup since it will require tests of its own.
Comment #22
benjy CreditAttribution: benjy at PreviousNext commentedThis looks good to me, great to have this fixed.
Comment #23
alexpottHmmm... I think there might be a problem with the approach. If you create an entity reference field to content and then change the default value I don't think the dependency to the initial node will be removed :( testing this theory...
Comment #24
alexpottUnfortunately... #23 is right...
Comment #25
alexpottSo one option would be to only preserve during a configuration sync. However this would mean that any post update that saved all config entities to fix something would risk losing these dependencies too. So going back to first principles - is it right for configuration to have dependencies listed for things that are not there? I don't think so. It is okay for configuration to be broken is something is missing. (By broken I mean report to the user that something is missing).
So is this a bug? As long as the missing content dependency event is fired with the correct information and the system has the chance to create the content then everything is working as expected. Also if there is missing content dependencies after an import the user should be informed so they know stuff is broken.
Comment #26
benjy CreditAttribution: benjy at PreviousNext commentedYeah, +1 to this. Because this wasn't obvious, this is why the original issue described the problem as dropping off when re-exporting, because that was the first time I actually noticed.
Documenting what we discussed in IRC, processMissingContent() is currently too late to figure out which dependencies are removed, we need to calculate which dependencies are removed during sync so that processMissingContent() can send the correct information in the
MissingContentEvent
event.Whereabouts exactly does the dependency currently get dropped off? Somewhere within $config->save()?
Comment #27
alexpottSo testing the ConfigImporter reveals that importing a block through the config importer does indeed fire the
ConfigEvents::IMPORT_MISSING_CONTENT
event missing the correct missing content - and the dependencies are not removed during sync because of the following code:So actually everything is behaving as expected for config sync. The question is more complicated in terms of install profiles but I think the answer there is to use a config sync based installer instead of our current installer (see the config_installer project). A further question is what do we do for module installation where the config depends on missing content - this is the test added by the current patch. Also given that content_block placements can not exist at all when the content block is missing should the content block module listen and stub if the content is missing - and should be apply this generally?
Comment #28
alexpottHere's what I think we should do:
Comment #29
alexpottAlso I just tested importing and re-exporting a block with a missing content dependency and is it maintained.
Comment #30
catch#28 works for me.
Comment #31
larowlan28.2 will break one of the primary uses of default_content module
Pretty sure agov and Berdir's/md-systems' profile are using it that way.
Comment #32
BerdirYes, I don't think that is an option, how are modules supposed to create that content then. There's nothing that runs before config import AFAIK and content might depend on other config. So the config import must happen first (think custom block type > custom block > plugin > block placement) and then modules can create content, e.g. with default_content or hook_install or whatever they want.
That definitely seems like an API change if we'd change that now?
Comment #33
alexpott@Berdir thinking custom block type > custom block > plugin > block placement during a module install - in HEAD we have a problem. The block placement will be saved during the module install and this will recalculate the dependencies and at that point the content does not exist - so the plugin does not exist - so the block is not saved correctly.
Comment #34
BerdirI don't think BlockContentBlock even adds a dependency in the first place? It's the *plugin* that depends on the content entity, not the config entity, because it's a derivative (which I still think is bad architecture, but that's a different topic).
But that's kind of OK, we have that covered. You'd simply get that fallback plugin as long as the content entity doesn't exist.
So that example isn't actually really related, but there could be others that do involve config dependencies like that.
IIRC #2407853: TaxonomyIndexTid Views plugin stores selected terms with the ID instead of UUID is also related to this, that's a patch I need for our install profile.
Comment #36
xjm@alexpott, @catch, and I agreed that this is a major bug because of the lost dependencies.
Comment #42
xjmComment #48
smustgrave CreditAttribution: smustgrave at Mobomo commentedBased on the conversation looks like more work is neede.d