Problem/Motivation

install_profile_info() keeps a static cache, but that cache does not vary per the passed in langcode. Thus, if a call such as install_profile_info('standard', 'en), will pollute the return value of a later call to install_profile_info('standard', 'de).

This in fact happens in core with the call to _install_select_profile() (which in turn calls install_profile_info() from _install_begin_request(). No language code is passed at this point (so the default en is used), which pollutes a later call to install_profile_info() where the language code is passed.

This causes locale and language module to not be installed, which breaks (as in fatal error) the later call to entity_load('configurable_language', ...).

Strangely, I don't see any of the relevant code as having been changed since March 2014 but I'm almost 100% certain that drush si --locale=de worked in Amsterdam (September 2014), so I don't know what caused this.

Proposed resolution

Vary the static cache by the passed-in language code.

Remaining tasks

User interface changes

None.

API changes

None.

Beta phase evaluation

-->

Reference: https://www.drupal.org/core/beta-changes
Issue category Bug because drush si is broken (as in it fatals) for anything other than English installations
Issue priority Major because 80% of the internet is non-English speaking. (If this were did not affect "just" Drush it would be critical.)
Unfrozen changes Not unfrozen
Prioritized changes Prioritized because it is a bug
Disruption No disruption (not even for installation profiles/distributions/...)

Comments

tstoeckler’s picture

Issue summary: View changes
Status: Active » Needs review
StatusFileSize
new854 bytes

Here we go.

tstoeckler’s picture

Issue summary: View changes
Patrick Storey’s picture

StatusFileSize
new111.6 KB

I was not able to recreate this problem. Drush si worked for me with the --locale=de designation.

I used MAMP PRO 3.2.1, Drush 7.0-dev, and Drupal 8.0.0-beta9

I made a new directory and then from the terminal I:

  1. $ drush dl drupal-8 --select --all
  2. [ select the drupal-8.0.0-beta9 version ]
  3. $ cd drupal-8.0.0-beta9/
  4. $ drush si standard --locale=de --db-url=mysql://[db_user]:[db_pass]@localhost/[db_name] --site-name=[site_name] --account-name=[user_name] --account-pass=[user_pass] --account-mail=[user_mail]
  5. It will ask you if you want to create the settings.php file and CREATE the database. I selected “y”
  6. Once it finished doing that, I pointed my MAMP Pro to the Drupal root, and everything was set up. The site is not fully translated as you can see in the picture but it looks like a success.

I took that screenshot after I started to translate the site back to English as I can not currently read German. :-)

Patrick Storey’s picture

Issue tags: +Novice

I'm adding the novice tag because this task has clear steps to completion and won't take long to complete.

Please see if the steps I wrote work for your machine.

michaellenahan’s picture

Status: Needs review » Reviewed & tested by the community
StatusFileSize
new3.35 KB
new2.54 KB
new96.18 KB

The patch works for me.

On Ubuntu 14.04 I was able to recreate the problem with the latest drupal-8.0.x (b31bbb084ab0d5e5a9ce0985db1dccaf39242bf9)
https://www.drupal.org/files/issues/2474537-installation-fails.txt

After patching the installation succeeds.
https://www.drupal.org/files/issues/2474537-installation-succeeds.txt

Here's a screenshot.
https://www.drupal.org/files/issues/2474537-screenshot.png

Setting to RTBC.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs tests

The fix looks good. I think we should be able to kernel test this just by calling the function with different language after including install.inc

Noe_’s picture

StatusFileSize
new1.08 KB

Added a test, to see if the code #1 actually works.

Noe_’s picture

StatusFileSize
new808 bytes
new854 bytes

Whoops, forgot to remove the ini_set.

And I uploaded the working patch from tstoeckler.
They are separate so you can see that the test fails first, and then after applying the patch it works.

cilefen’s picture

Status: Needs work » Needs review
Issue tags: -Needs tests

The last submitted patch, 7: 2474537-7.patch, failed testing.

The last submitted patch, 8: 2474537-8.patch, failed testing.

cilefen’s picture

Status: Needs review » Needs work

@Noe_ Nice work on this. We need the full patch please, with the test and the core code changes.

  1. +++ b/core/modules/system/src/Tests/Installer/InstallerLanguageTest.php
    @@ -40,4 +40,16 @@ function testInstallerTranslationFiles() {
    +  /**
    +   *
    +   */
    

    We need a function comment.

  2. +++ b/core/modules/system/src/Tests/Installer/InstallerLanguageTest.php
    @@ -40,4 +40,16 @@ function testInstallerTranslationFiles() {
    +    $infoEn = install_profile_info('standard', 'en');
    +    $infoNl = install_profile_info('standard', 'nl');
    

    We usually do not use camel-case for local variables.

  3. +++ b/core/modules/system/src/Tests/Installer/InstallerLanguageTest.php
    @@ -40,4 +40,16 @@ function testInstallerTranslationFiles() {
    +    $this->assertFalse(in_array('locale', $infoEn['dependencies']), 'testing English');
    

    The assert comment should be something like 'Locale is not set in the dependencies key.' Also something more appropriate should be in the dutch line.

Noe_’s picture

StatusFileSize
new910 bytes
new854 bytes

Changed the test according to #12

cilefen’s picture

@Noe_ Great work! Could you please create the combined patch with the changes to install.inc and the test? It should be named 2474537-15.patch (if 15 is the next comment number). With it, post a patch with only the test. Name it 2474537-15-tests.patch. Before you post the comment, set the issue status to "Needs review" which signals the humans to check your work and the testbots to execute the automated tests.

Noe_’s picture

Status: Needs work » Needs review
StatusFileSize
new1.72 KB
new910 bytes

And hereby the full patch, and a separate with only the tests.
Note that the full patch also contains the test.

Status: Needs review » Needs work

The last submitted patch, 15: 2474537-15-only-test.patch, failed testing.

Noe_’s picture

Status: Needs work » Needs review

This is actually a brilliant example of the old codebase failing, and the patch passing.

Because the -only-test.patch is just the test, which fails.
And the install-profile-info.patch is the patch including the test, and this one passes.

So I setting it back to needs review.

The last submitted patch, 13: 2474537-13.patch, failed testing.

cilefen’s picture

Status: Needs review » Needs work

@Noe_ Nice work. We are almost finished.

  1. +++ b/core/modules/system/src/Tests/Installer/InstallerLanguageTest.php
    @@ -40,4 +40,16 @@ function testInstallerTranslationFiles() {
    +  /**
    +   * Tests for proper caching in non-English languages.
    +   */
    

    I would try "Tests profile info caching in non-English languages.", if it fits.

  2. +++ b/core/modules/system/src/Tests/Installer/InstallerLanguageTest.php
    @@ -40,4 +40,16 @@ function testInstallerTranslationFiles() {
    +    require_once('core/includes/install.inc');
    

    There should not be parenthesis in this statement.

  3. +++ b/core/modules/system/src/Tests/Installer/InstallerLanguageTest.php
    @@ -40,4 +40,16 @@ function testInstallerTranslationFiles() {
    +    $this->assertFalse(in_array('locale', $info_en['dependencies']), 'Locale is not set in English language');
    +    $this->assertTrue(in_array('locale', $info_nl['dependencies']), 'Locale is set when installing in Dutch');
    

    The assert messages should end with periods. Also, the messages should match. "Locale is not set when installing in English." "Locale is set when installing in Dutch."

Once those are done, this will be RTBC for me.

Noe_’s picture

Status: Needs work » Needs review
StatusFileSize
new911 bytes
new911 bytes

There you go.

Status: Needs review » Needs work

The last submitted patch, 20: 2474537-20-only-test.patch, failed testing.

The last submitted patch, 20: 2474537-20-install-profile-info.patch, failed testing.

cilefen’s picture

@Noe_ It looks as though both patch files were the same - the test only. We need the combined patch.

+++ b/core/modules/system/src/Tests/Installer/InstallerLanguageTest.php
@@ -40,4 +40,16 @@ function testInstallerTranslationFiles() {
+    $this->assertFalse(in_array('locale', $info_en['dependencies']), 'Locale is not set in English language.');
+    $this->assertTrue(in_array('locale', $info_nl['dependencies']), 'Locale is set when installing in Dutch.');

Let's go with "Locale is not set when installing in English."

Noe_’s picture

Status: Needs work » Needs review
StatusFileSize
new911 bytes
new1.72 KB

whoops.

The last submitted patch, 24: 2474537-24-only-test.patch, failed testing.

cilefen’s picture

Status: Needs review » Needs work

@Noe_ Great! Could you post the single, combined patch (no need for the test-only patch any more) with 1 and 3 from comment #19 fixed?

cilefen’s picture

cilefen’s picture

The way the caching bug works, it matters whether you specify the install profile to drush.

drush -y si standard --locale=de works

drush -y si --locale=de throws an exception

Patrick Storey’s picture

Issue tags: -Novice

Removing the Novice tag as the task I assigned it to (testing this with the standard profile designation) has been completed by Cilefen in IRC for the latest patch in comment #24.

Noe_’s picture

Status: Needs work » Needs review
StatusFileSize
new1.73 KB

Cilefen, I have made the next patch to include #1 and #3 from #12

Status: Needs review » Needs work

The last submitted patch, 30: 2474537-30.patch, failed testing.

Status: Needs work » Needs review

Noe_ queued 30: 2474537-30.patch for re-testing.

Status: Needs review » Needs work

The last submitted patch, 30: 2474537-30.patch, failed testing.

cilefen’s picture

@Noe_ When a something like this happens, it is usually because a recent commit has changed HEAD in a way that affects the issue. Looking at the recent core commits, I noticed #1081266: Avoid re-scanning module directory when a filename or a module is missing could be the commit that is affecting this.

Status: Needs work » Needs review

Noe_ queued 30: 2474537-30.patch for re-testing.

Noe_’s picture

cilefen: I think you are quite right.
Because someone added this line of code:
trigger_error(SafeMarkup::format('The following @type is missing from the file system: @name', array('@type' => $type, '@name' => $name)), E_USER_WARNING);
And I get this message when I run the test:
"The following module is missing from the file system: standard"

After a bit of searching in bootstrap.inc I found this:

  // Profiles are converted into modules in system_rebuild_module_data().
  // @todo Remove false-exposure of profiles as modules.
  $original_type = $type;
  if ($type == 'profile') {
    $type = 'module';
  }

at line 223.
So it should be known since someone added a @todo, but I think this is why the test fails now.

Any thought about how to proceed?

Status: Needs review » Needs work

The last submitted patch, 30: 2474537-30.patch, failed testing.

cilefen’s picture

@Noe_ You have to prime the filename cache now.

From ModuleHandlerTest::testModuleList():

  // Prime the drupal_get_filename() static cache with the location of the
    // testing profile as it is not the currently active profile and we don't
    // yet have any cached way to retrieve its location.
    // @todo Remove as part of https://www.drupal.org/node/2186491
    drupal_get_filename('profile', 'testing', 'core/profiles/testing/testing.info.yml');
    // Build a list of modules, sorted alphabetically.
    $profile_info = install_profile_info('testing', 'en');

We should use the testing profile for the assert if possible. I would use exactly the same comment in this test.

Noe_’s picture

StatusFileSize
new2.1 KB

Fixed the problems we were having because of #1081266
The solution was #38.

Noe_’s picture

Status: Needs work » Needs review

Forgot to set the Status to "Needs review"

cilefen’s picture

Status: Needs review » Reviewed & tested by the community

@Noe_ Nice work!

I have tested the patch manually. The test identifies the only difference when install_profile_info() is called and uses the same cache priming and comment used in other tests in core.

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed 99aa2d6 and pushed to 8.0.x. Thanks!

Thanks for adding the beta evaluation to the issue summary.

  • alexpott committed 99aa2d6 on 8.0.x
    Issue #2474537 by Noe_, tstoeckler, michaellenahan, cilefen: Installing...
gábor hojtsy’s picture

Issue tags: -sprint, -language-base +anguage-base

Yay, thanks!

gábor hojtsy’s picture

Issue tags: -anguage-base +language-base

Status: Fixed » Closed (fixed)

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

oneliner’s picture

I can see this happening in the web install for Drupal 9.0.7

ubuntu 18.04 lts
php 7.3 fpm as fcgi
Apache 2.4.46

Selecting english lets installation continue, all other languages give redirect error

- other working drupal installs on server: yes(Drupal 8)
- obtained codebase via composer command
composer create-project drupal/recommended-project