Follow-up of original issue in config_sync module. As this module has plugins for normalization and config_sync depends on it, it is reasonable to have default hash added within this module and its plugins.

Comments

a.dmitriiev created an issue. See original summary.

a.dmitriiev’s picture

Status: Active » Needs review
StatusFileSize
new1.17 KB

Patch with new plugin.

a.dmitriiev’s picture

StatusFileSize
new1.27 KB

Updated patch with proper interface

nedjo’s picture

Thanks, this looks like a good start.

A config hash should be generated only for configuration that is provided by an extension, and, likely, only when the configuration is being prepped for writing as opposed to comparison.

So we may need some new methods in ConfigNormalizerBase parallel to existing ones. By calling both new methods, we ensure we're applying the normalization only as needed. Here are some quick and untested suggestions.

A new method ::isProvideModeContext() parallel to ::isDefaultModeContext():

  protected function isProvideModeContext(array $context) {
    return !empty($context['normalization_mode']) && ($context['normalization_mode'] === NormalizedReadOnlyStorageInterface::NORMALIZATION_MODE_PROVIDE);
  }

And a new method ::isProviderStorageContext() parallel to ::isActiveStorageContext(). Here, I guess, we test for the service ID of the Configuration Provider storage:

  protected function isProviderStorageContext(array $context) {
    if (
      !empty($context['reference_storage_service']) &&
      !empty($context['reference_storage_service']->_serviceId) &&
      ($context['reference_storage_service']->_serviceId === 'config_provider.storage')
    ) {
      return TRUE;
    }

    return FALSE;
  }

Or, maybe better, we introduce a helper method:

  protected function isStorageServiceContext(array $context, $service_id) {
    if (
      !empty($context['reference_storage_service']) &&
      !empty($context['reference_storage_service']->_serviceId) &&
      ($context['reference_storage_service']->_serviceId === $service_id)
    ) {
      return TRUE;
    }

    return FALSE;
  }

and use that for both the new method and the existing one:

  protected function isStorageProviderContext(array $context) {
    return $this->isStorageServiceContext($context, 'config_provider.storage');
  }
nedjo’s picture

Hmm. The approach I've suggested might not be right. Because config from Configuration Provider may already have been altered. For example, the module Config Actions Provider applies alters via Config Actions. We need to ensure we're generating the hash for the config in its pristine state as read from the config/install or config/optional directory. So, possibly, we should be doing this in Configuration Provider instead? As a new method in ConfigProviderBase that we call in both ConfigProviderInstall and ConfigProviderOptional?

a.dmitriiev’s picture

Maybe there is no need in new method, I searched for a way to modify the config and found this method addConfigToCreate in ConfigProviderInterface. Now in both ConfigProviderInstall and ConfigProviderOptional it is empty and not doing anything, perhaps it is the place where we can modify $config_to_create and add the necessary properties?

nedjo’s picture

Project: Configuration Normalizer » Configuration Provider

I haven't had a chance yet to look again at this, will update when I do. Meantime, moving to Configuration Provider issue queue.

a.dmitriiev’s picture

Title: Default config hash is not generated for imported configuration (config_normalizer) » Default config hash is not generated for imported configuration (config_provider)
a.dmitriiev’s picture

Status: Needs review » Needs work
a.dmitriiev’s picture

Status: Needs work » Needs review
StatusFileSize
new4.7 KB

Here is the patch

a.dmitriiev’s picture

Status: Needs review » Needs work

Patch is not working, need to debug more.

nedjo’s picture

Thanks for working on this!

::addConfigToCreate() is invoked at extension install time. Core already covers that case for adding a config hash to config from config/install and config/optional.

Where we need to work in this issue is ::addInstallableConfig(), which is what's called to provide config to config_sync.

a.dmitriiev’s picture

StatusFileSize
new3.11 KB

Thanks, @nedjo.

Here is the new patch.

a.dmitriiev’s picture

Status: Needs work » Needs review
nedjo’s picture

Looks good!

I haven't tested but please feel free to apply once you're confident it's working.

One note:

+++ b/src/Plugin/ConfigProviderBase.php
@@ -292,4 +293,24 @@ abstract class ConfigProviderBase extends PluginBase implements ConfigProviderIn
+    if (empty($data['uuid']) && empty($data['_core']['default_config_hash'])) {

I believe in some cases a uuid is valid on extension-provided config, so perhaps we should be testing only for the second value.

a.dmitriiev’s picture

I found this issue https://www.drupal.org/project/drupal/issues/2628004 . While testing my patch, I saw that couple of even core modules also had no default_config_hash property, although they have the configs in config/install folder. That is why config_synchronizer updated them too and added missing property.

But maybe we also need to perform the checks like here is the patch https://www.drupal.org/files/issues/2628004-9.patch ? Checks on whether the config is config entity and whether there are any language overrides? Of course we are not updating all the configuration in the world, so maybe only language overrides is relevant here.

What do you think?

Updated patch without uuid check is attached.

nedjo’s picture

While testing my patch, I saw that couple of even core modules also had no default_config_hash property, although they have the configs in config/install folder.

Yes. the default_config_hash is generated by core when extension-provided config is installed, so it should not be present in the config/install folder files.

But maybe we also need to perform the checks like here is the patch

Hmm, good question. It's presumably true that we have a situation similar to that noted in #2628004: Create an upgrade path to determine if default_config_hash should be added (2625258): on existing sites running our module there may be config we installed that lacks a hash. I'd say:

  • Let's test to see whether we get the config hash when we run configuration update after applying this patch. That is: does the hash show up as importable? When we run an import, does our previously-installed config end up with the hash? If so, I suppose we're good.
  • If that doesn't work, let's open a new follow-up issue, so we can fix this one right away.
a.dmitriiev’s picture

With the patch in #16 config_sync import adds the default_config_hash property indeed and also to previously imported by config_sync configs from config/install and config/optional folders. So I am committing the fix. Let's fix other issues if they appear.

Thanks, @nedjo.

  • a.dmitriiev committed 59649ec on 8.x-2.x
    Issue #3143065 by a.dmitriiev: Default config hash is not generated for...
a.dmitriiev’s picture

Status: Needs review » Fixed

Status: Fixed » Closed (fixed)

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