Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Blocks: #111715: Convert node/content types into configuration
Problem
- Data loss due to
config_install_default_config()
overwriting preexisting configuration.
Details
- Scope and scenario:
- Module A provides configuration for module B.
- The user customizes the configuration.
- Module A gets uninstalled, leaving its configuration for module B intact (or in a disabled state).
- Module A gets re-installed.
- The existing configuration is overwritten with module A's default configuration.
- Example:
- Poll module provides node.type.poll for Node module.
- node.type.poll is customized.
- Poll module gets uninstalled.
- Poll module gets re-installed.
- node.type.poll is overwritten with Poll module's default node.type.poll configuration.
Proposed solution
- Change
config_install_default_config()
to not overwrite existing configuration.
Related issues
Comment | File | Size | Author |
---|---|---|---|
#40 | 1889620-install-overwrites-config-40.patch | 7.79 KB | vijaycs85 |
#39 | 1889620-install-overwrites-config-39.patch | 11.25 KB | vijaycs85 |
#39 | 1889620-diff-35-39.txt | 6.27 KB | vijaycs85 |
#35 | 1889620-install-overwrites-config-35.patch | 17.05 KB | vijaycs85 |
#35 | 1889620-diff-34-35.txt | 925 bytes | vijaycs85 |
Comments
Comment #1
tim.plunkettWith #1887654: Creating a config entity with an existing machine name shouldn't work, ConfigEntities would throw an exception. In what other case would there be conflicting config? (Not saying there isn't one, I just can't think of it)
Comment #2
sunTDD: Here's full test coverage.
Comment #3
gddIt actually seems perfectly natural to me that this get overwritten. Uninstalling a module is *supposed* to destroy all the data that it provides and this is consistent with D7 behavior (I'm pretty sure.)
I know that over in #1776830: [META-1] Installation and uninstallation of configuration provided by a module that belongs to another module's API we have been hashing out this issue, but this is the one part of it that I'm still not a fan of because it feels really unintuitive and I think its the one part that remains unresolved (both xjm and I have spoken out about this.) So I'd like to postpone this until that is sorted out.
Comment #5
sun@heyrocker:
The problem is: Existing persistence tests for node types in HEAD disagree. (See the last test assertion. That's why this is blocking #111715: Convert node/content types into configuration)
Essentially, the node type + node data should be retained as-is, if the module that created the node type is disabled or uninstalled.
Comment #6
sunNode types (+ nodes) are actually a rather poor example.
Text formats are a much better example. Whatever you do, text formats never cease to exist. (Text formats cannot be deleted.)
Comment #7
gddHuh I had no idea that was expected behavior. You're right that Text Formats are a better example too. Given that, we should get this done, and if we want to have a greater discussion about the expectations behind config and uninstalled modules, it should continue in the other issue.
Comment #8
catchThe node type persistence test is due to the comment body deletion upgrade path bug that was live for 6 months after Drupal 7 release. That's only a workaround for disabled modules making no sense and I think we can change the assumption if we want as long as it's consistent.
So it comes down to:
1. When you uninstall a module, should configuration and content belong to that module be deleted (ideally it should but it ought to warn about deleting content and/or force you to delete it manually first).
2. Should there be a way to decouple configuration + content from a module if you want to - i.e. a module installs a node type and you want to keep the node type (because it has content in it) but get rid of the module otherwise.
Comment #9
sunFor now, I'd prefer to move forward with the existing expectations - especially due to the case of text formats.
This was supposed to be a one line fix, but the new manifest file handling (which still needs follow-up work) made it a bit more complex.
For now, I helped myself out with a new parameter for
config_sync_get_changes()
that allows to force-ignore manifest files.Comment #10
xjmI added one test for this scenario in #1887654: Creating a config entity with an existing machine name shouldn't work; I assumed it had the same cause.
Comment #11
tim.plunkettThe blocker I hit specifically in #1887654-22: Creating a config entity with an existing machine name shouldn't work sounds like it makes this issue a duplicate.
Comment #12
sun#1887654: Creating a config entity with an existing machine name shouldn't work does not conflict with this issue - they complement each other.
The specific case of #22 over there (PHP text format being re-installed + overwritten upon re-installation of PHP module) is exactly the case that this patch here fixes, and which shouldn't be touched over there.
I think #9 is ready, and comes with full test coverage (with expected failure in #2).
Comment #13
sunCan we move forward with the patch in #9?
That would allow me to continue work on #111715: Convert node/content types into configuration
Comment #14
sunFeedback, anyone? Or RTBC?
Comment #15
tim.plunkett#1887654: Creating a config entity with an existing machine name shouldn't work does indeed cover this issue, but it is not and will not be ready very soon, and this is a well scoped issue.
I'm fine with this going in first.
What is the reason for this change? It's not clear to me.
Note to reviewers, this is just indented under
if ($require_manifest) {
nowThis else should have a comment
These hunks were rejected, will need a reroll
Comment #16
gddThis is a reroll. Some larger changes happened to config.inc and DrupalUnitTestBase since this patch was posted but I think this is right. No interdiff as I merged HEAD too.
This change is now irrelevant as all that code was removed as part of #1889752: Remove unnecessary manifest creation in config_install_default_config().
I'd actually like more comments in general around the $require_manifest parameter, in particular what situations there are where you might want to set this as FALSE.
Comment #18
vijaycs85Adding test module from #9.
Comment #20
vijaycs85#18: 1889620-install-overwrites-config-18.patch queued for re-testing.
Comment #21
sunThanks!
This is a critical issue. Given that others have re-rolled this patch without raising major concerns against the actual change or disagreeing with them, I think it is safe to say that this is RTBC.
Comment #22
xjm@heyrocker asks for more feedback in #16, and RTBCing your own patch--. I'll look at this with my coffee. :)
Comment #23
alexpottI think the variable here should be $use_manifest as this is more explicit... we are not requiring a manifest we are using them. I don't think this is bikeshed-y since it is about meaning...
Hmmm... not sure about this function in light of #1891516: Remove $install parameter from DrupalUnitTestBase::enableModules(), encourage individual schema tables where we are removing the $install paramater from the equivalent
enableModules()
function. I thinkdisableModules()
should just manage the module list and leave disable / uninstall up to the test itself.Tricky.
Especially calling it with $uninstall = TRUE as once #1891516: Remove $install parameter from DrupalUnitTestBase::enableModules(), encourage individual schema tables it will be the test's responsibility to create all the database tables declared by a module's schema hook.
Comment #24
alexpottOne possible use-case for setting
$require_manifest/$use_manifest
to FALSE would be #1515312: Add snapshots of last loaded config for tracking whether config has changed where we need to be able to compare the snapshot and active storages.Comment #25
vijaycs85Updating patch with review comments in #23.
Comment #26
alexpotthmm.... the changes in #25 for DrupalUnitTestBase don't really address the issues raised in #23. @sun what do you think we should do?
Comment #27
sunLet's remove the DUTB changes here and move the new test method into a new ConfigInstallWebTest class.
We can optimize it and potentially convert it back to a DUTB test later on, when time permits.
Comment #28
alexpott#27 sounds like a great idea.
Comment #29
vijaycs85Just moving uninstallModules to ConfigInstallTest class.
Comment #30
vijaycs85Moving disableModules changes from DUTB to new class and updating docblock for $use_manifest change.
Comment #31
alexpottI think that this is very nearly ready to go... I think we need to add to the test.
Before we uninstall the integration module we should disable and then enable it again and then test that both the simple config and config entity have the non default values.
Comment #32
vijaycs85Updating test case as specified in #31
Comment #33
sunLet's move this test method into a new ConfigInstallWebTest that extends WebTestBase (instead of DUTB).
That inherently means that we can remove the test helper methods and use the regular module_enable(), module_disable(), and module_uninstall() instead.
All changes to this file should be reverted.
Comment #34
vijaycs85As per #33:
1. Renamed ConfigInstallTest to ConfigInstallWebTest and extends WebTestBase.
2. Removed helpers for install/uninstall/disable.
3. I this, it is valid fix (trailing space) in DrupalUnitTestBase.php
Comment #35
vijaycs85Reverting all changes from DUTB. Space got its own issue #1919134: Remove space from comment in DrupalUnitTestBase.php
Comment #36
alexpottThis patch is totally ready to fly but it contains exactly the same change to config_sync_get_changes as #1515312: Add snapshots of last loaded config for tracking whether config has changed and that issue is rtbc so I think should postpone on that issue and then reroll...
Comment #37
sunLet's keep the existing test method and ConfigInstallTest as-is, so that the new (and slow) web/integration test only contains tests that actually need the full environment.
Comment #38
sunAlso, you've clearly taken this over by now :)
Comment #39
vijaycs85Updating changes for #37.
Comment #40
vijaycs85As advised by @alexpott on IRC, Removing changes from config_sync_get_changes() as #1515312: Add snapshots of last loaded config for tracking whether config has changed made it to core.
Comment #41
alexpottThis looks great!
Comment #42
sunThanks! This also looks great to me now.
Comment #43
catchHad to think about this a few times but I can't really find any objections to the patch, so committed/pushed to 8.x. In the back of my head there's a nagging feeling this will be brought up again when someone expects it to do the opposite but I guess it's a case of deciding in this case.
Comment #44.0
(not verified) CreditAttribution: commentedUpdated issue summary.