Skip to content

Resolving module:uninstall hanging without response #32955

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: 2.4-develop
Choose a base branch
from

Conversation

tschallacka
Copy link

@tschallacka tschallacka commented May 5, 2021

This fix is based on #3544

Basically, when Magento command bin/magento module:uninstall Module_Name is called it will hang indefinitely, even for half an hour. The only way to exit is to CTRL +C out of it.

I posted my research in this issue here: https://blog.tschallacka.de/2021/05/binmagento-moduleuninstall-never.html but it boils down that when auth.json is not found in the Magento root dir, composer will prompt for the access keys to repo.magento.com, but as the output is contained in a BufferedOutput that doesn't output to STDOUT this isn't visible.

My proposed fix, before initiating the uninstall via composer, check if auth.json exists in the root dir.
When auth.json is not found, an FileNotFoundException is thrown, adding a reference to https://devdocs.magento.com/guides/v2.4/install-gde/prereq/dev_install.html#authentication-file so they can resolve the issue.

For testing have a module that registers a custom attribute that you remove with an uninstaller, with a missing auth.json in the Magento root directory.

<?php namespace Test\Dummy\Setup;

use Magento\Catalog\Model\Product;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
use Magento\Framework\Setup\UninstallInterface;
use Symfony\Component\Console\Output\ConsoleOutput;

class Uninstall implements UninstallInterface
{
    protected $eavSetupFactory;
    protected $output;

    public function __construct(EavSetupFactory $eavSetupFactory, ConsoleOutput $output)
    {
        $this->eavSetupFactory = $eavSetupFactory;
        $this->output = $output;
    }

    /**
     * @inheritDoc
     */
    public function uninstall(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        $eavSetup = $this->eavSetupFactory->create();
        $this->output->writeln("Starting to remove the attributes for something.");
        $eavSetup->removeAttribute(Product::ENTITY, UpgradeData::SOME_ATTRIBUTE);
    }
}

Description (*)

Added a private method ModuleUninstaller::failOnMissingAuthJson().
This method tests whether auth.json exists in the Magento root dir. When it is not found it throws a meaningful error message with a reference to the developer documentation.

This method is called in ModuleUninstaller::uninstallCode()

Related Pull Requests

Fixed Issues (if relevant)

  1. Fixes bin/magento module:uninstall never completes #3544

Manual testing scenarios (*)

  1. Fresh install of magento
  2. install https://github.com/tschallacka/mage2-dummy-test
  3. run bin/magento module:enable Test_Dummy && bin/magento setup:upgrade && bin/magento module:disable Test_Dummy && bin/magento module:uninstall Test_Dummy
  4. Type yes twice to the questions
  5. Process will hang forever. After roughly 30-60 seconds, only when you type gibberish/hit enter a few times you'll get the output from an exception handler.

Questions or comments

Contribution checklist (*)

  • Pull request has a meaningful description of its purpose
  • All commits are accompanied by meaningful commit messages
  • All new or changed code is covered with unit/integration tests (if applicable)
  • README.md files for modified modules are updated and included in the pull request if any README.md predefined sections require an update
  • All automated tests passed successfully (all builds are green)

When auth.json is not found, an FileNotFoundException is thrown.
This is to fix issue magento#3544
This will prevent workarounds like described at https://blog.tschallacka.de/2021/05/binmagento-moduleuninstall-never.html
@m2-assistant
Copy link

m2-assistant bot commented May 5, 2021

Hi @tschallacka. Thank you for your contribution
Here are some useful tips how you can test your changes using Magento test environment.
Add the comment under your pull request to deploy test or vanilla Magento instance:

  • @magento give me test instance - deploy test instance based on PR changes
  • @magento give me 2.4-develop instance - deploy vanilla Magento instance

❗ Automated tests can be triggered manually with an appropriate comment:

  • @magento run all tests - run or re-run all required tests against the PR changes
  • @magento run <test-build(s)> - run or re-run specific test build(s)
    For example: @magento run Unit Tests

<test-build(s)> is a comma-separated list of build names. Allowed build names are:

  1. Database Compare
  2. Functional Tests CE
  3. Functional Tests EE,
  4. Functional Tests B2B
  5. Integration Tests
  6. Magento Health Index
  7. Sample Data Tests CE
  8. Sample Data Tests EE
  9. Sample Data Tests B2B
  10. Static Tests
  11. Unit Tests
  12. WebAPI Tests
  13. Semantic Version Checker

You can find more information about the builds here

ℹ️ Please run only needed test builds instead of all when developing. Please run all test builds before sending your PR for review.

For more details, please, review the Magento Contributor Guide documentation.

⚠️ According to the Magento Contribution requirements, all Pull Requests must go through the Community Contributions Triage process. Community Contributions Triage is a public meeting.

🕙 You can find the schedule on the Magento Community Calendar page.

📞 The triage of Pull Requests happens in the queue order. If you want to speed up the delivery of your contribution, please join the Community Contributions Triage session to discuss the appropriate ticket.

🎥 You can find the recording of the previous Community Contributions Triage on the Magento Youtube Channel

✏️ Feel free to post questions/proposals/feedback related to the Community Contributions Triage process to the corresponding Slack Channel

@tschallacka
Copy link
Author

@magento run all tests

@magento-automated-testing
Copy link

The requested builds are added to the queue. You should be able to see them here within a few minutes. Please re-request them if they don't show in a reasonable amount of time.

@tschallacka
Copy link
Author

I'm seeing a cross at the functional tests, yet I don't see any failing tests, only one yellow test that is wholly unrelated to this pr. Is that test broken?

Also, I signed the document, when wil the status update?

Comment on lines +103 to +110
private function failOnMissingAuthJson()
{
$auth_json_path = BP . DIRECTORY_SEPARATOR . 'auth.json';
if (!file_exists($auth_json_path)) {
$error_message = sprintf('auth.json at %s could not be found. Refer to https://devdocs.magento.com/guides/v2.4/install-gde/prereq/dev_install.html#authentication-file how to install this file.', $auth_json_path);
throw new FileNotFoundException($error_message);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure it's ok to make the auth.json mandatory? I don't think so, as we might set the credentials globally.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have set my auth.json globally, via ~/.composer/auth.json and that works fine when a manual ~ composer update or ~ composer remove xxx is run. But when this composer sub process is started up, via the ~ bin/magento module:uninstall it doesn't read from ~/.composer/auth.json for whatever reason, which then leads to the bug as is set out in the related issue as it prompts for the password behind the scenes. It only continues on when the data is present in the auth.json file.

I've made a dummy repo here of the plugin that demonstrates the issue. https://github.com/tschallacka/mage2-dummy-test

When there is an auth.json in the root it runs fine, as is highlighted in my blog post. If there is no auth.json in the root, it hangs and gives issues.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like the issue is related to incorrect composer usage, so it's not reading the global auth.json file. The correct fix should fix this inconsistent behavior.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd be amenable to make a more comprehensive test if you could point me to where the wrapped composer instance tries to read auth.json and when it fails, if you have a better suggested course of action, to prevent the hanging screen i'm open. Just an error message like in my plugin perhaps?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know exactly where that code located, but it looks like the composer remove logic is here:

public function remove(array $packages)
{
$composerApplication = $this->composerApplicationFactory->create();
return $composerApplication->runComposerCommand(
[
'command' => 'remove',
'packages' => $packages,
'--no-update-with-dependencies' => true,
]
);
}

Please set the breakpoint on this code and debug deeper.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like the issue is related to incorrect composer usage, so it's not reading the global auth.json file. The correct fix should fix this inconsistent behavior.

totally agree, that composer should read auth.json anywhere

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ihor-sviziev if you read my blog post at https://blog.tschallacka.de/2021/05/binmagento-moduleuninstall-never.html you can follow my tracking process how I traced the composer path related to the output. I never delved into the actual process of composer itself as it takes so many twists and turns that after 15 minutes of pressing step into I still wasn't at the auth.json search steps. I must admit I kinda gave up.

@m2-assistant
Copy link

m2-assistant bot commented May 6, 2021

Hi @tschallacka, thank you for your contribution!
Please, complete Contribution Survey, it will take less than a minute.
Your feedback will help us to improve contribution process.

@tschallacka
Copy link
Author

@magento run Functional Tests B2B

@magento-automated-testing
Copy link

The requested builds are added to the queue. You should be able to see them here within a few minutes. Please re-request them if they don't show in a reasonable amount of time.

@dharake
Copy link

dharake commented Sep 5, 2021

2.4.3 CE. Even with correct utilisation of auth.json the command bin/magento module:uninstall still hangs indefinitely at the code removal step.

@Green2Matter
Copy link

2.4.3-p1 CE and I'm hit by this bug. I have auth.json populated with access credentials. Any solution, workaround available?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component: Setup Priority: P3 May be fixed according to the position in the backlog. Progress: review Release Line: 2.4
Projects
Status: Review in Progress
Development

Successfully merging this pull request may close these issues.

bin/magento module:uninstall never completes
7 participants