Problem/Motivation
When my module is enabled I need some content to be created, so I'm using hook_install() to create it. As content belongs to specific entities bundles I'm adding the required config entities in /config/install.
When installing the module in a running instance all works as expected.
However when module is installed through a configuration import process - either from Config UI or drush ci or config_installer profile - the whole import process while installing the module.
The error - in my case - is "Field field_myfieldname is unknown", which is a field on one of the bundles I create instances for in my hook_install().
I can't find any similar issue in the queue, and this makes me nervous because creating-content-on-module-install looks to me like a common scenario. That let me thinks the system may work as expected and the problem here is hook_install() shouldn't be used for creating content.
Proposed resolution
If this is a real bug, investigate and fix the problem. It may be related to #2451365: ConfigInstaller has the source storage injected by config importer and module installer but it is done incorrectly, although the IS doesn't mention this error as consequence.
If developers shouldn't rely on config/install/* to be available on hook_install(), then this issue should become a Documentation task and we can update the docs about config/install (Include default configuration in your Drupal 8 module & Co.) as well as hook_install() api.
Remaining tasks
- Confirming if this is a real issue or documentation should be updated
- Work on a patch
User interface changes
None.
API changes
None(?)
Data model changes
None.
Comment | File | Size | Author |
---|---|---|---|
#9 | interdiff_8-9.txt | 667 bytes | ranjith_kumar_k_u |
#9 | 2906107-9.patch | 5.02 KB | ranjith_kumar_k_u |
#8 | 2906107-7.patch | 5.03 KB | hchonov |
Issue fork drupal-2906107
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
gambryFrom
Drupal\Core\Config\ConfigInstaller::installDefaultConfig()
:It looks like during syncing only module own simple configuration is supposed to be imported?
This make sense as configuration should already be in the sync storage, but why is not already imported?
Comment #3
bircherThis is not really a bug in my opinion but rather a documentation issue.
The modules own configuration needs to be installed already when the module is installed since it could be settings etc that the module can expect to always exist. The rest of the default config will be synced along with the (potentially changed) modules configuration later in the config sync process. (Modules need to be installed first so that for example plugins are available that are then in the imported config).
We could also defer the default config installation until after the hook is fired (and install first only the simple config as while syncing) then module authors would never attempt to use the default config in the install hook as it would not work there and other solutions would be used.
Comment #4
gambryFrom IRC chat with bircher, just because there are good tips:
Comment #5
gambrySo changing the issue to target a documentation update.
The first piece of doc to be reviewd is https://www.drupal.org/docs/8/creating-custom-modules/include-default-co... . It's enough to mention to not rely on configuration existing from within module's
hook_install()
, but rather using ConfigImporterEvent::* (or whatever the current best solution is).Also mentioning on the hook_install() dockblock in module.api.php default config may not be available.
Comment #6
gambryClosing this in favour of #2901418: Add hook_post_config_import_NAME after config import. We can polish the documentation of hook_install(), hook_update_N(), https://www.drupal.org/docs/8/creating-custom-modules/include-default-co... , etc. in there.
Comment #7
gambryI've pasted the wrong link for the related issue. Updated now.
Comment #8
hchonovUnfortunatelly the linked issues have gotten in a different direction and there is still no solution for this issue, which is why I am reopening it.
@bircher has summurized that pretty good:
However I do not agree that modules are "abusing" the hook_install, which is documented as follows:
This documentation does not state that all of the module's dependent configuration will be present in hook_install, but it states that anything else will be made ready for the module. Why not the configuration it depends on then? I think that the config import should match the default module install behavior, otherwise any single module realying on that behavior already will be breaking a config import where that module is installed.
Of course we could also agree on the correct behavior to be that hook_install is called only after its simple configuration is installed and before its third-party provided configuration, but that would require the introduction of a new hook that is common for both cases of enabling a module -
A rewrite of any module out there that that leverages the behavior of a regular module install will be required if a new hook is introduced. On the other side I think it is much more easier to simply delay the hook_install invocation until we can ensure that all the configuration a module is dependent on is available. I cannot currently think of a reason why that would be something we would not want to do. I might be missing something though.
Further we've lost the ability to react on the event that module Z and X have been installed together - e.g. hook_modules_installed will be fired for each module individually during config import instead of together so we have two calls hook_modules_installed([Z]) and hook_modules_installed([X]) during config import versus one call hook_modules_installed([Z, X]) during normal module installation. However I am not sure if this is really a concern we should be thinking about.
For sure we have quite the inconsistency now and no matter which behavior is declared the correct one both approaches of enabling an extension should have the same behavior.
I am attaching a patch proposal showing how hook_install could be delayed to match the normal module installation behavior as much as possible.
Comment #9
ranjith_kumar_k_u CreditAttribution: ranjith_kumar_k_u at Zyxware Technologies commentedComment #13
semiaddict CreditAttribution: semiaddict commentedI just stumbled on this issue as I am also creating content in hook_install for a custom entity type which has bundles.
The bundles are being created by module configs, which also end up in config/sync.
If the module is installed via a sync, the bundles don't exist when hook_install is called.
I managed to work around this by creating missing bundles in hook_install before creating the entities, but this seems more like a hack.
During a sync, wouldn't it make more sense to:
This would insure that module configs have been imported before calling hook_install, and would likely result in having the production site mimic more closely what usually happens in development.
Comment #17
ressa CreditAttribution: ressa at Ardea commentedHere's a re-roll on Gitlab for 11.x based on @hchonov’s patch in #8.
Comment #18
Wim LeersRan into this too yesterday in https://www.drupal.org/project/automatic_updates. We had to resort to using
hook_modules_installed()
.Looks like some tests still need to have their expectations updated?
Comment #19
DamienMcKennaI think it'd be useful if Drupal core had an expanded deployment process built in that could be executed via update.php (or similar) rather than replying on Drush (see #2901418: Add hook_post_config_import_NAME after config import), which is only available when using Drush.