1

So I'm trying to upgrade our system from using Drush 6 to Drush 8, as that is the currently supported version of Drush that supports Drupal 7. I have managed to get drush working, however it does not recognize any of our environments as a Drupal environment.

If I run drush cc all I get back:

No Drupal site found, only 'drush' cache was cleared.

If I run any other Drush command (from my sites directory) I get back:

Command 'command' needs a higher bootstrap level to run.

Running drush status returns no DB information at all.

Now there seems to be quite a few questions out there like this, and lots of recommended solutions, but nothing is pertinent to my environment. I'm using IIS on a Windows Server machine, with SQL Server (not MySQL), so none of the solutions are applicable. I'm wondering if anyone has any ideas for solving this within my current environment?


Keeping in mind, all of these environments worked fine with no issue prior to upgrading to Drush 8 (using Drush 6).

Output of drush -v status:

Loading outputformat engine.                                 [notice]
 PHP configuration      :  "C:\Program Files (x86)\PHP\5.6.26\php.ini"
 PHP OS                 :  WINNT
 Drush script           :  location/of/drush
 Drush version          :  8.1.13
 Drush temp directory   :  temp/location
 Drush configuration    :
 Drush alias files      :
Command dispatch complete                                    [notice]

settings.php file database settings:

$databases['default']['default'] = array(
  'database' => 'databasename',
  'username' => 'username',
  'password' => 'password',
  'host' => 'hostName',
  'driver' => 'sqlsrv',
);

Executing drush sql-connect command returns:

Unable to load class Drush\Sql\Sql.

Unable to find matching SQL Class.

Drush cannot find your database connection details.

I should also mention that drush site-install works fine, it's just running Drush inside a newly created area that doesn't work.


To clarify, I am using a multi-tenant install, so I have multiple tenants such as sites/tenant, sites/tenant2, sites/tenant3, etc.

For example I am running drush from the sites/tenant directory and Drush doesn't recognise my Drupal installation. Traditionally, before updating, I could run drush from inside any of those and everything would work.

  • @kenorb edited my original post to include that – Arak Tai'Roth Sep 26 '17 at 19:19
  • @kenorb Pasted database settings into original post. Yes, I can confirm the existence of all those files. The link doesn't really apply. Everything worked fine within Windows Server, IIS, and SQL Server before I upgraded Drush from version 6 to version 8. I'm using the sqlsrv module for my connection. – Arak Tai'Roth Sep 26 '17 at 20:27
  • @kenorb Yes I can confirm that the command exists globally and can be run from anywhere via the command line. – Arak Tai'Roth Sep 26 '17 at 21:31
  • @kenorb I get the following error running that. Unable to load class Drush\Sql\Sql. And 'Unable to find matching SQL Class. Drush cannot find your database connection details.'. I should also mention that drush site-install works fine, it's just running Drush inside a newly created area that doesn't work. – Arak Tai'Roth Sep 26 '17 at 22:32
0

You should perform the following checks:

  • For SQL Server, review README file of SQL Server driver for Drupal 7 to confirm the right requirements and installation steps. See also: Can I use MS SQL with Drupal.

  • Make sure that your database client (such as sqlcmd) command exists globally (from the command-line). Otherwise make sure its path is added into your PATH system variable. See: Sqlsqlsrv.php.

  • Clear Drush internal caches and try again:

    drush cc drush
    
  • If you're using a multisite environment, make sure to specify the right Drupal site to use, e.g.

    drush --uri=http://site1.example.com status
    

    or:

    drush -l http://site2.example.com status
    

    Note: By default Drush uses sites/default unless you will run the command in specific sites/ folder.

    Note: To define URI of the Drupal site, set $base_url in your settings file per given site (or drushrc.php).

  • Run drush status (add -d for debugging output) to check whether Drupal root, Database name and Database driver has been detected correctly. If not, run the command again, but in the same folder where is your settings.php file and verify that Drupal Settings File has been recognized. Verify it has the right read permissions

  • Check the output of drush sql-connect command whether it returns the right command and there are no errors.

    If there is no matching SQL Class, this suggests drush can't detect the db driver from your settings file. So confirm the following command returns the current site path (folder containing settings.php):

    drush ev "echo drush_site_path();"
    

    If it's empty, make sure you're running drush command in the right folder and your settings.php exists.

  • Check whether Drupal bootstrap object is properly loaded by:

    drush ev "print_r(drush_get_bootstrap_object());"
    

    If so, check whether your settings file is readable:

    drush ev 'echo file_get_contents(drush_get_bootstrap_object()->conf_path()."/settings.php");
    

    Otherwise if your bootstrap object is EmptyBoot, please review how Drush defines Drupal root as valid (candidates are: DrupalBoot6, DrupalBoot7, DrupalBoot8), for Drupal 7 the logic is as below:

    function valid_root($path) {
      if (!empty($path) && is_dir($path) && file_exists($path . '/index.php')) {
        // Drupal 7 root.
        // We check for the presence of 'modules/field/field.module' to differentiate this from a D6 site
        $candidate = 'includes/common.inc';
        if (file_exists($path . '/' . $candidate) && file_exists($path . '/misc/drupal.js') && file_exists($path . '/modules/field/field.module')) {
          return $candidate;
        }
      }
    }
    

    So make sure that you've the following files present: includes/common.inc, misc/drupal.js and modules/field/field.module in your Drupal root (where $path is your Drupal root, but it can be specified manually by --root=path/to/drupal). Also make sure the files are readable by the user (in case of symlinks, they're pointing to the right files; right permissions in case of network share or Linux file system). Otherwise edit Drupal boot class file (e.g. DrupalBoot7.php, part of Drush) and try to debug the above valid_root() method by checking which condition exactly fails and why.

    Example Drush command to verify whether index.php exists:

    drush ev '$path = drush_get_context("DRUSH_SELECTED_DRUPAL_ROOT"); var_dump(file_exists($path . "/index.php"));'
    
  • Finally check whether SQL class can be loaded by:

    drush ev 'var_dump(drush_sql_get_class());'
    
  • You may consider re-testing in different PHP versions, e.g.

Debugging

Assuming drush status doesn't return the right details, here are the suggested steps to debug drush (shell commands).

  1. Install and enable PHP xdebug extension. Verify by php71 -i | grep xdebug.

    Consider these xdebug ini settings: xdebug.ini for better visibility.

  2. On empty folder, install clean Drupal, e.g.

    drush -y qd --no-server --core=drupal-8
    cd quick-drupal-*/drupal*
    
  3. Verify Drupal root, Settings File and Database are present in drush status.

  4. Generate trace file for the working bootstrap process:

    drush ev "xdebug_start_trace(); print_r(_core_site_status_table()); echo xdebug_get_tracefile_name(); xdebug_stop_trace();"
    

    If xdebug is enabled for different PHP version, specify with DRUSH_PHP=/path/to/php.

    If successful, trace output file should be printed at the end, so take a note of it.

  5. Generate another trace file for the same command above, but in the location which doesn't work.

  6. Now compare these two trace files (working with non-working) using some diff tool (Meld, DiffMerge, opendiff, etc.) and check the differences. For better format, remove first 40 columns from these files (e.g. ex +'%norm 40dl' -scwq file.xt).

If you believe you found a Drush bug, please report it with details at GitHub issue page.

  • drush_site_path returns the correct path to the site folder. However drush_get_bootstrap_object just returns Drush\Boot\EmptyBoot Object, which I believe is likely where my problem lies. Looking up that specific issue gives me lots of issues with Drupal 8 which I'm not using, I'm using Drupal 7 with PHP 5.6. – Arak Tai'Roth Sep 27 '17 at 20:40
  • @ArakTai'Roth If you've got EmptyBoot, that means valid_root() method in DrupalBoot7 class failed to detect your Drupal root. Check the details in the updated answer to review what could be the case as you could be missing one of the files. – kenorb Sep 27 '17 at 20:55
  • 1
    So, I went into that function you gave me (thanks by the way) and did some debugging. Apparently $path is being set to C:/longListOfDirectories/sites/tenant where tenant is my sites folder. The files exist in my Drupal install, but not at that location, they exist at two levels above that, just above /sites. That's likely my issue, how would I go about permanently changing what directory Drush references? By the way, this is a multi-tenant install, which might be part of the issue. – Arak Tai'Roth Sep 27 '17 at 21:16
  • @ArakTai'Roth Then you need to run drush in sites/tenant, or use -l or --uri parameter, e.g. drush -l http://tenant.example.com status. I've updated the answer. – kenorb Sep 27 '17 at 21:28
  • 1
    I am running from the sites/tenant directory. I have multiple tenants sites/tenant2, sites/tenant3 etc.... Traditionally, before updating, I could run drush from inside any of those and everything would work. But as I said above, it appears that in the function valid_root, $path is set to the tenant directory, not the directory of my Drupal install which is just above sites, it's looking two levels too deep for the files and thus not finding them and thus returning an EmptyObject. – Arak Tai'Roth Sep 27 '17 at 22:03
0

This patch worked for me, https://github.com/drush-ops/drush/pull/3000.

For reference this is the fix, within Drush, in includes/environment.inc, add this line:

$path = str_replace('/', DIRECTORY_SEPARATOR, $path);

Just before:

$path = explode(DIRECTORY_SEPARATOR, $path);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.