Problem/Motivation

Enable a custom migrate module, then uninstall it. Then re-enable it for the 2nd time. The re-enable fails. Because it looks like the uninstall doesn't clean-up after itself. Marking as major since this seems like a significant issue that should be resolved.

The following extensions will be enabled: custom_migrate
Do you really want to continue? (y/n): y
exception 'Drupal\Core\Entity\EntityStorageException' with message ''migration' entity with ID 'csv_file'    [error]
already exists.' in /home/lucas/websites/drupal/core/lib/Drupal/Core/Entity/EntityStorageBase.php:430
Stack trace:
#0 /home/lucas/websites/drupal/core/lib/Drupal/Core/Entity/EntityStorageBase.php(394):
Drupal\Core\Entity\EntityStorageBase->doPreSave(Object(Drupal\migrate\Entity\Migration))
#1 /home/lucas/websites/drupal/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php(264):
Drupal\Core\Entity\EntityStorageBase->save(Object(Drupal\migrate\Entity\Migration))
#2 /home/lucas/websites/drupal/core/lib/Drupal/Core/Entity/Entity.php(340):
Drupal\Core\Config\Entity\ConfigEntityStorage->save(Object(Drupal\migrate\Entity\Migration))
#3 /home/lucas/websites/drupal/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php(600):
Drupal\Core\Entity\Entity->save()
#4 /home/lucas/websites/drupal/core/lib/Drupal/Core/Config/ConfigInstaller.php(306):
Drupal\Core\Config\Entity\ConfigEntityBase->save()
#5 /home/lucas/websites/drupal/core/lib/Drupal/Core/Config/ConfigInstaller.php(130):
Drupal\Core\Config\ConfigInstaller->createConfiguration('', Array)
#6 /home/lucas/websites/drupal/core/lib/Drupal/Core/ProxyClass/Config/ConfigInstaller.php(79):
Drupal\Core\Config\ConfigInstaller->installDefaultConfig('module', 'custom_migrate')
#7 /home/lucas/websites/drupal/core/lib/Drupal/Core/Extension/ModuleInstaller.php(253):
Drupal\Core\ProxyClass\Config\ConfigInstaller->installDefaultConfig('module', 'custom_migrate')
#8 /home/lucas/websites/drupal/core/lib/Drupal/Core/ProxyClass/Extension/ModuleInstaller.php(87):
Drupal\Core\Extension\ModuleInstaller->install(Array, true)
#9 /home/lucas/drush/commands/core/drupal/environment.inc(130):
Drupal\Core\ProxyClass\Extension\ModuleInstaller->install(Array, true)
#10 /home/lucas/drush/commands/core/drupal/environment.inc(197): drush_module_install(Array)
#11 /home/lucas/drush/commands/pm/pm.drush.inc(1120): drush_module_enable(Array)
#12 [internal function]: drush_pm_enable('custom_migrate')
#13 /home/lucas/drush/includes/command.inc(359): call_user_func_array('drush_pm_enable', Array)
#14 /home/lucas/drush/includes/command.inc(210): _drush_invoke_hooks(Array, Array)
#15 [internal function]: drush_command('custom_migrate')
#16 /home/lucas/drush/includes/command.inc(178): call_user_func_array('drush_command', Array)
#17 /home/lucas/drush/lib/Drush/Boot/BaseBoot.php(62): drush_dispatch(Array)
#18 /home/lucas/drush/drush.php(70): Drush\Boot\BaseBoot->bootstrap_and_dispatch()
#19 /home/lucas/drush/drush.php(11): drush_main()
#20 {main}

See https://github.com/heddn/d8_custom_migrate for the migration this is sourced from.

Proposed resolution

Clean-up migrate config entries on uninstall.

Remaining tasks

User interface changes

API changes

Data model changes

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

heddn created an issue. See original summary.

heddn’s picture

Priority: Normal » Major
Issue summary: View changes
mikeryan’s picture

Priority: Major » Normal

I'm curious, if you uninstall the module through the UI, does it prompt you to uninstall the configuration objects?

Downgrading to normal - this doesn't impact migration functionality, it's just a PITA for developers.

heddn’s picture

Just tested using the web UI vs drush. Same error in the web UI.

MichaelB’s picture

Same problem here, any advice ?

#edit :
Looks like I found a solution, not sure it is the best one though.

I had to manually delete the configuration entity in a hook_uninstall using the config factory service as so :

\Drupal::service('config.factory')->getEditable('migrate.migration.myid')->delete();

heddn’s picture

re #5, there's also a command in drupal console that will let you delete config entries.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

selwynpolit’s picture

For those folks who want the details of the drupal console command to delete the config, it looks something like this:

$ drupal config:delete migrate_plus.migration.recipe_photo

Hope this saves you a little time.
Selwyn

mikeryan’s picture

Title: EntityStorageException' with message ''migration' entity with ID 'foo' already exists » Examples should uninstall configuration
Project: Drupal core » Migrate Plus
Version: 8.1.x-dev » 8.x-2.x-dev
Component: migration system » Examples

Moving to migrate_plus - migration configuration entities are no longer a core thing.

This isn't migrate-specific behavior, it's how configuration works in Drupal 8 (see, for example, http://drupal.stackexchange.com/questions/173684/how-to-remove-mymodule-...). The premise is that all configuration "belongs" to the system rather than the module, therefore configuration created by a module is not automatically uninstalled - it stays active in the system. For example, if a module provides a view which does not depend on any code in the module, uninstalling that module leaves the view - it's up to the system administrator (who may have customized the view and be depending on it) to decide whether to delete it.

So, a custom migration module (which in most cases would want its configuration entities removed on uninstall) is responsible for seeing that it's done (see the response on StackExchange). Right now the examples in migrate_plus don't do that, so they cannot be uninstalled and reinstalled - they should uninstall their configuration, not just so they can be reinstalled, but to demonstrate this for other migration module authors (this is a *very* frequently asked question).

pguillard’s picture

Status: Active » Needs review
FileSize
588 bytes

I guess doing that in an uninstall will save even more time to developers.

pguillard’s picture

I guess my former patch was removing too much configuration. This is a new one.

heddn’s picture

Status: Needs review » Needs work
+++ b/migrate_example_advanced/migrate_example_advanced.install
@@ -48,3 +48,19 @@ function migrate_example_advanced_install() {
+  $config= \Drupal::service('config.factory')->getEditable('migrate.migration.wine_role_json')->delete();

Assigning to a variable isn't necessary.

gl2748’s picture

Agree with @mikeryan #9. and Per: https://www.drupal.org/node/2629516
Here we use:

dependencies:
  enforced:
    module:
      - migrate_example
pguillard’s picture

Status: Needs work » Needs review

  • mikeryan committed 9da1ae7 on 8.x-2.x authored by gl2748
    Issue #2574903 by gl2748: Examples should uninstall configuration
    
mikeryan’s picture

Status: Needs review » Fixed

Committed (with a reroll and some comment rewriting), thanks!

Status: Fixed » Closed (fixed)

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

bob.hinrichs’s picture

Drupal 8.7.3
Migrate Example Version: 8.x-4.2

Uninstalling will delete some of the configurations for the examples. But upon uninstalling the modules, and exporting your configuration, all of these configurations contain migrate_example configurations:
I have tables in the database hanging around such as: `user__field_migrate_example_favbeers`, `user__field_migrate_example_gender`and looking at user accounts, I still see field_migrate_example_gender.

Has the module changed to add more configuration, such that the changes made for cleanup are now out of date?

comment.type.migrate_example_advanced_comment.yml
core.entity_form_display.comment.migrate_example_advanced_comment.default.yml (4 matches)
core.entity_form_display.taxonomy_term.migrate_example_wine_varieties.default.yml (4 matches)
core.entity_form_display.user.user.default.yml (4 matches)
core.entity_view_display.comment.migrate_example_advanced_comment.default.yml (4 matches)
core.entity_view_display.taxonomy_term.migrate_example_wine_varieties.default.yml (4 matches)
core.entity_view_display.user.user.compact.yml (2 matches)
core.entity_view_display.user.user.default.yml (2 matches)
core.extension.yml (2 matches)
field.field.comment.migrate_example_advanced_comment.comment_body.yml (3 matches)
field.field.taxonomy_term.migrate_example_wine_varieties.field_variety_attributes.yml (3 matches)
field.field.user.user.field_migrate_example_favbeers.yml (3 matches)
field.field.user.user.field_migrate_example_gender.yml (3 matches)
field.storage.user.field_migrate_example_favbeers.yml (2 matches)
field.storage.user.field_migrate_example_gender.yml (2 matches)
rest.resource.migrate_example_advanced_position.yml (3 matches)
rest.resource.migrate_example_advanced_variety_items.yml (3 matches)
rest.resource.migrate_example_advanced_variety_list.yml (3 matches)
rest.resource.migrate_example_advanced_variety_multiple.yml (3 matches)
taxonomy.vocabulary.migrate_example_beer_styles.yml
taxonomy.vocabulary.migrate_example_wine_best_with.yml
taxonomy.vocabulary.migrate_example_wine_regions.yml
taxonomy.vocabulary.migrate_example_wine_varieties.yml