commit 2d10ccdd4eb5f62bc23e66818cb7224d051e2209
Author: Moshe Weitzman <weitzman@tejasa.com>
Date:   Fri May 8 16:26:10 2015 -0400

    Tolerate a read-only settings.php during installation.

diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index 3ab64bf..aaafdbc 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -837,7 +837,7 @@ function drupal_installation_attempted() {
  * When this function is called during Drupal's initial installation process,
  * the name of the profile that's about to be installed is stored in the global
  * installation state. At all other times, the "install_profile" setting will be
- * available in settings.php.
+ * available in settings.php, or declared as a Distribution.
  *
  * @return string|null $profile
  *   The name of the installation profile or NULL if no installation profile is
@@ -857,13 +857,33 @@ function drupal_get_profile() {
     }
   }
   else {
-    // Fall back to NULL, if there is no 'install_profile' setting.
-    $profile = Settings::get('install_profile');
+    $profile = Settings::getInstallProfile();
   }
 
   return $profile;
 }
 
+/*
+ * Get the name of any discovered profile that is a distribution. If multiple
+ * profiles are distributions, then the first discovered profile will be
+ * selected. See https://www.drupal.org/node/2210443.
+ *
+ * @return string|null
+ *   The machine name of any discovered distribution.
+ */
+function drupal_get_distribution() {
+  $container = Drupal::getContainer();
+  $root = $container->get('app.root');
+  $listing = new ExtensionDiscovery($root);
+  $listing->setProfileDirectories(array());
+  foreach ($listing->scan('profile') as $profile) {
+    $info = \Drupal::service('info_parser')->parse($profile->getPathname());
+    if (!empty($info['distribution'])) {
+      return $profile->getName();
+    }
+  }
+}
+
 /**
  * Registers an additional namespace.
  *
diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index 554ad06..331af95 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -1205,12 +1205,9 @@ function _install_select_profile(&$install_state) {
       return $profile;
     }
   }
-  // Check for a distribution profile.
-  foreach ($install_state['profiles'] as $profile) {
-    $profile_info = install_profile_info($profile->getName());
-    if (!empty($profile_info['distribution'])) {
-      return $profile->getName();
-    }
+  // Check for a Distribution.
+  if ($distribution = drupal_get_distribution()) {
+    return $distribution->getName();
   }
 
   // Get all visible (not hidden) profiles.
@@ -2283,13 +2280,15 @@ function install_display_requirements($install_state, $requirements) {
 }
 
 /**
- * Installation task; ensures install profile is written to settings.php.
+ * Installation task; install profile is written to settings.php unless a
+ * distribution is present.
  *
  * @param array $install_state
  *   An array of information about the current installation state.
  */
 function install_write_profile($install_state) {
-  if (Settings::get('install_profile') !== $install_state['parameters']['profile']) {
+  $is_mismatch = Settings::getInstallProfile() !== $install_state['parameters']['profile'];
+  if ($is_mismatch) {
     // Remember the profile which was used.
     $settings['settings']['install_profile'] = (object) array(
       'value' => $install_state['parameters']['profile'],
diff --git a/core/lib/Drupal/Core/Config/ConfigInstaller.php b/core/lib/Drupal/Core/Config/ConfigInstaller.php
index 6c0bd7e..6e75052 100644
--- a/core/lib/Drupal/Core/Config/ConfigInstaller.php
+++ b/core/lib/Drupal/Core/Config/ConfigInstaller.php
@@ -631,7 +631,7 @@ protected function drupalGetPath($type, $name) {
   protected function drupalGetProfile() {
     // Settings is safe to use because settings.php is written before any module
     // is installed.
-    return Settings::get('install_profile');
+    return Settings::getInstallProfile();
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Config/ExtensionInstallStorage.php b/core/lib/Drupal/Core/Config/ExtensionInstallStorage.php
index f31976b..56689d4 100644
--- a/core/lib/Drupal/Core/Config/ExtensionInstallStorage.php
+++ b/core/lib/Drupal/Core/Config/ExtensionInstallStorage.php
@@ -83,7 +83,7 @@ protected function getAllFolders() {
       $this->folders = array();
       $this->folders += $this->getCoreNames();
 
-      $install_profile = Settings::get('install_profile');
+      $install_profile = Settings::getInstallProfile();
       $profile = drupal_get_profile();
       $extensions = $this->configStorage->read('core.extension');
       // @todo Remove this scan as part of https://www.drupal.org/node/2186491
diff --git a/core/lib/Drupal/Core/Site/Settings.php b/core/lib/Drupal/Core/Site/Settings.php
index 18f55ff..df2a975 100644
--- a/core/lib/Drupal/Core/Site/Settings.php
+++ b/core/lib/Drupal/Core/Site/Settings.php
@@ -150,6 +150,22 @@ public static function getHashSalt() {
   }
 
   /**
+   * Get the configured install profile, or fall back to the first Distribution
+   * that was declared. If neither is available, return NULL.
+   *
+   * @return string|null
+   *   The name of the active install profile or distribution.
+   */
+  public static function getInstallProfile() {
+    $install_profile = self::$instance->get('install_profile');
+    if (empty($install_profile)) {
+      $install_profile = drupal_get_distribution();
+    }
+
+    return $install_profile;
+  }
+
+  /**
    * Generates a prefix for APC user cache keys.
    *
    * A standardized prefix is useful to allow visual inspection of an APC user
diff --git a/core/modules/system/src/Tests/Installer/InstallerExistingSettingsNoProfileTest.php b/core/modules/system/src/Tests/Installer/InstallerExistingSettingsNoProfileTest.php
index 61dd5be..92c1430 100644
--- a/core/modules/system/src/Tests/Installer/InstallerExistingSettingsNoProfileTest.php
+++ b/core/modules/system/src/Tests/Installer/InstallerExistingSettingsNoProfileTest.php
@@ -73,7 +73,7 @@ protected function setUpSettings() {
   public function testInstaller() {
     $this->assertUrl('user/1');
     $this->assertResponse(200);
-    $this->assertEqual('testing', Settings::get('install_profile'));
+    $this->assertEqual('testing', Settings::getInstallProfile());
   }
 
 }
