Problem/Motivation

Currently, reports list configuration entities for which the version in an extension's config/install directory differs from that in the active storage.

This is a good start, but would have more value if we could say something about the source of the difference. If it's a change I or someone on my team made, chances are I might want to keep it. If no customization was done, chances are I'd be happy to just accept changes in bulk (e.g. all changes in a module), perhaps without individually reviewing them.

This is territory mapped out in potentially relevant ways by the D7 Features module. See the section on "Component states" in the API documentation.

So for each piece of extension-provide configuration, we might want to distinguish:

  • Config has been customized.
  • Default config provided by the extension has changed.
  • Default config provided by the extension has changed and config has been customized.

To make this distinction, it appears we would need to calculate and store some additional information about each extension-provided configuration object. That's well beyond the scope of this module. However, we could look at facilitating this ability in other modules.

On initial site install (see install_finished(), and on each configuration synchronization (through ConfigSnapshotSubscriber::onConfigImporterImport()), a snapshot is saved. But those snapshots represent the (potentially customized) current state of configuration, not the state provided at install time. So, at best, the snapshot system is a model on which a module might store and analyze install-time extension snapshots.

A similar distinction might be useful for missing configuration. Configuration might be missing (a) because it was never present, (b) because it's been deleted, (c) because it's been renamed. This, too, would require storing data on the origin of changes, e.g., responding to the ConfigEvents::RENAME event.

Proposed resolution

Define requirements to make reports customizable, perhaps through an alter call, or a hook that would add more operations.

Issue is postponed until this is specified.

Remaining tasks

User interface changes

API changes

Comments

jhodgdon’s picture

Status: Active » Closed (won't fix)

That is way beyond the scope of this module and not something I'm willing to add. This module is not going to be Features. Site owners or developers will need to make their own decisions on what the differences mean and whether they want to upgrade, and module developers will need to make their own decisions on whether config changes and additions are essential (in which case they'll need to make an update function that would update it) or not.

jhodgdon’s picture

By the way, I think that the tools in this module should hopefully be modular enough that another module that wants to be Features should be able to use for instance the ConfigDiffer class/service to help. And I'd be happy to add a hook to this module that would let other modules extend the list of operations available in the reports, and things like that, if that would help.

But I really think that storing the contents of config files is not a road I'd like to go down. That is a good use case for storing the config in files and using git diff. Making decisions about where differences came from is just not something the Config system is equipped for.

nedjo’s picture

Title: Distinguish customization from extension changes » Faciliatate customization of reports, e.g., distinguishing edits from extension changes
Issue summary: View changes

Sounds good, updating the ticket summary to reflect this.

jhodgdon’s picture

Issue summary: View changes
Status: Closed (won't fix) » Postponed (maintainer needs more info)

OK I'll open this back up as "needs more info". If you think of a hook that should be added, post here.

nedjo’s picture

I opened #2406059: Faciliatate customization of reports, e.g., distinguishing edits from extension changes to look at a possible approach to the question of how to distinguish configuration that can safely be reverted.

jhodgdon’s picture

Um. Are you talking about #2407609: Coordinate configuration development?? You linked in #5 to this issue here. Oops. ;}

nedjo’s picture

jhodgdon’s picture

I would recommend that people look at diffs to decide themselves if configuration can be reverted, rather than trying to "lock down" some config. It just seems like locking things would introduce complications in trying to maintain a site.

However, if someone did want to lock things down, I could envision that this module would have a hook something like hook_config_report_actions_alter(), which would ask modules "Here's the list of actions for each config item in this section of the report. Do you want to modify the actions?" and let them either add or remove the actions. That would allow the "lock down" module to say "don't allow revert", and the Foo Bar module to add its own action.

nedjo’s picture

Title: Faciliatate customization of reports, e.g., distinguishing edits from extension changes » Distinguish edits from extension changes
Issue summary: View changes
Status: Postponed (maintainer needs more info) » Active

Turns out we actually have most or all of what's needed in core.

On initial site install (see install_finished(), and on each configuration install (through ConfigSnapshotSubscriber::onConfigImporterImport()), a snapshot is saved.

So it looks like we have what's needed to introduce a new section in the config reports to show config that is unchanged since install.

jhodgdon’s picture

I'll take a look at that. Obviously, not something I was aware of. Thanks!

jhodgdon’s picture

Status: Active » Postponed (maintainer needs more info)

I took a look at the snapshot subscriber.

What it actually does is that each time config is imported, it clears out the previous snapshot in the "snapshot" config storage, and then saves a complete snapshot of all the current config.

I don't think this will acually help to figure out the reason that particular config has been updated. Consider this scenario:

a) On Monday, I install the Views module. Snapshot is created.

b) On Tuesday, I edit a View.

c) On Wednesday, I install the Foo module. New snapshot is created.

d) On Thursday I go to the config report from this module. It tells me this view differs from the version that is currently being provided by the Views module. However, the current config is the same as the latest snapshot. So, all I know is that it hasn't been edited since the last time a snapshot has been created. Which does not tell me the truth in this case, which is that the reason it's edited is that I edited it. In fact, it would lead me to the opposite conclusion.

So... I fail to see how this helps.

jhodgdon’s picture

Actually, it's even worse: it looks to me as though these snapshots are only created during a Config Synch operation. So they may not even be made when you update a module.

nedjo’s picture

Title: Distinguish edits from extension changes » Faciliatate customization of reports, e.g., distinguishing edits from extension changes
Issue summary: View changes

Ouch. Sorry for the false trail there. Evidently a case of wishful thinking. I should have see that, if it's necessary to explicitly invoke snapshot creation in install_finished(), it can't be happening when extensions are first installed.

This issue seems to get at the heart of a key challenge in even the concept of reverting--it works against some key assumptions of D8 architecture and its orientation to the staging problem. For Configuration Revert, this D8 orientation means that a lot of tools that superficially look nicely fitted are instead by design inapplicable.

Related muse/rant in a blog post today.

jhodgdon’s picture

I think I should really rename this module, actually. To call it "revert" is not really right... It should probably be "Keep track of config updates" or something. Maybe I should also call the links "Update to source" instead of "Revert to source", just like the report is titled "Config Updates", because it's probably usually about updating to the latest version provided by a module rather than reverting your edits, although it could be used for both.

But in any case, I really do think that human judgment is always going to be needed in order to decide whether some particular config object that differs from the module-provided value is something you want to update/revert to or not.

nedjo’s picture

I really do think that human judgment is always going to be needed

This is really my point: that specific type of "human judgement" is a huge assumption and shouldn't be the baseline for what it takes to have a Drupal site.

Drupal admin UIs are designed to bypass the technical details of how specific configuration is structured and stored. In the staging workflow, site admins may, if they choose, review diffs between e.g., staging and production. But they don't need to. If they've themselves staged the configuration, they can trust that it's fine and accept it en masse.

Some site admin tasks, running from low expertise to high, might be:

  1. I can customize simple configuration, like the site name.
  2. I can update a module through the update UI and run updates.
  3. I can customize or build from scratch more complex configuration like content types and views.
  4. I can read exported configuration of many different types in its native form, analyze line by line diffs, and knowledgeably make decisions about what to keep.

It's important to acknowledge just how great the leap is between the last two skill levels. To state the obvious, examining line by line diffs of unlimited different configuration types assumes a very specialized and technical knowledge. For enterprise users staging configuration, it is indeed a valid assumption that you have in house or contracted expertise that can make sense of configuration diffs. But for every one of the million plus Drupal sites, when doing a common task like updating to a latest software release?

Again, the Configuration Revert use case begins with "You update a module, and it has either changed default config that it provides, or added new config items". Which of these skill levels should we assume? We look to be at level two: we're updating a module.

So, by all means, we should be providing a UI for the limited set of advanced admins who can navigate diffs. But, it seems to me, not as the required workflow. Rather, we need - in core or in contrib - a workflow and a UI that's accessible to the site admin that the builk of the admin UI is aimed at.

A tall task? Absolutely.

jhodgdon’s picture

I do not think that this is going to be possible. Have you looked at the report, even just after doing an install with the Standard install profile? Even before you start configuring the site, there are a lot of config items that have been updated by the profile or the install-time settings. Sorting this out programmatically is not something I think is even possible. There are too many reasons it could be changed (module did something at install time, user edited it, module put out a new version, a different module changed it when it was installed, a module changed it when it uninstalled, etc.), and software is never going to be able to sort it out. At least, I don't think so.

Which is why I decided that the only real feasible thing was to at least provide a tool so that a knowledgeable user could figure out what was going on and do something about it. Yes, a user would have to be "advanced" in order to use it, but without this module that user doesn't have any way to manage this situation.

jhodgdon’s picture

Version: » 8.x-1.x-dev
nedjo’s picture

Issue summary: View changes
nedjo’s picture

I've started to sketch in a module to see if it's feasible to apply safe bulk updates: Configuration Synchronizer. It's very conceptual and completely untested at this point. It depends on Configuration Update Manager, which it's been a pleasure to build on. The nicely separated services and their public methods have made for very compact code, and I learned a lot by studying config_update's coding approaches. So thanks!

jhodgdon’s picture

I think you meant to add the comment above to your "do bulk" feature request issue, not here? Or were you just saying "thanks for making your classes usable"? :) If so, you're welcome!

nedjo’s picture

I think you meant to add the comment above to your "do bulk" feature request issue

Well, it's potentially relevant here as well, but I didn't note why. Configuration Synchronizer takes a snapshot of configuration as installed and uses that to determine "safe" updates. If and when that's actually working, it could be used as a basis to alter the Configuration Update Manager reports.

jhodgdon’s picture

OK, keep me posted.

jhodgdon’s picture

Component: Code » Reports module
Pasqualle’s picture

Status: Postponed (maintainer needs more info) » Closed (won't fix)

After may years, still won't fix.