Our workflow is as follows:

1) get site working in dev environment
2) load site in production using drush sql-connect < backup.sql

With domain access enabled in settings.php, this does not work because drush sql-connect will fail on the site until a drupal database is loaded. Chicken/egg problem. We have to remove the domain access load from settings.php before continuing.

Comments

agentrickard’s picture

Category: bug » support

Try passing -uri or -l.

See https://drupal.org/node/1096956. I thought this was documented more generally, but probably needs clarification.

joelcollinsdc’s picture

Thanks, I definitely did pass -l, our entire environment is kind of complex and requires it to work. So this works normally? I'm not talking about normal drush commands, they work just great, its just the few commands that you can run with drush before the database is ever loaded, specifically something like drush sql-connect.

agentrickard’s picture

I don't know. I never use those commands ;-p.

I suspect I know _why_ this fails. Can you post a sample command that I can test with?

If you are debugging, look in _domain_bootstrap() inside domain.bootstrap.inc. I suspect the problem is that we are trying to leap ahead in the bootstrap phase. We've had problems with this before.

      // Make sure database is loaded.
      // The new update handler causes problems here, so we account for it.
      // Same with drush or other CLI resources. It turns out that the
      // drupal_is_cli() function is not consistent for php and drush scripts,
      // so instead, we check to see if the database driver has been loaded.
      // See http://drupal.org/node/1342740 for the latest background.
      $new_phase = FALSE;
      // If running from drush or update.php, we act differently.
      if (function_exists('drush_verify_cli') || function_exists('update_prepare_d7_bootstrap')) {
        $new_phase = TRUE;
      }
      drupal_bootstrap(DRUPAL_BOOTSTRAP_DATABASE, $new_phase);

What version of drush?

joelcollinsdc’s picture

StatusFileSize
new664 bytes

dev.

attached a rudimentary attempt at a patch. no idea if this is the right approach though.

agentrickard’s picture

Category: support » bug
Status: Active » Needs review

That looks like the kind of exception handling we've had to implement due to inconsistencies in how drush and other external scripts interact with Drupal.

The question is: does it break anything else?

agentrickard’s picture

Status: Needs review » Needs work

It does. It breaks drush domains and all regular drush functions.

agentrickard’s picture

Status: Needs work » Postponed (maintainer needs more info)

Actually, this appears to be working properly and is in fact a drush documentation bug.

See #1117460: drush sql-connect < database.sql displays credentials and doesn't import database?

Try drush sql-cli < file.sql

Using that command works fine for me on drush 5.

joelcollinsdc’s picture

I'm not sure i understand your response. Sql-cli and sql-connect are 2 different functions with different purposes. Both are supported. In that issue, yes, the user was trying to use the wrong command, or he shoudl have wrapped sql-connect in a subshell like $(drush sql-connect) < file.sql.

I can see if we can change our scripts to use cli instead of connect, but this doesn't seem to be the correct approach.

agentrickard’s picture

Neither command caused any problems for me. I was using DA 7.x.3.x-dev and Drush 5.0.

My response is based on item 2 in the original post, which will only return the database connection string, because it is an improperly documented drush command. The command tries to import data, but will fail due to the drush bug listed above.

I ran drush cli < import.sql just fine. And drush sql-connect returned the expected string.

In effect, I am saying "cannot reproduce", but I left it open in case I'm missing something.

joelcollinsdc’s picture

so drush sql-connect works for you when there is NO DATABASE yet? For example, go into your settings.php and change the DB password to something wrong, and try drush sql-connect. I can't see how this will work because domain will try to bootstrap to a higher level than drush is trying to.

agentrickard’s picture

Wait, NO DATABASE? You can't run that command if settings.php isn't configured, with or without DA. Your request makes no sense to me.

joelcollinsdc’s picture

There are many drush commands (drush, by itself, for instance) that do not require a working drupal site.

examples:
drush --version
drush sql-connect
drush dl (modulename)

All of these commands are broken if you are trying to run these on a site that has the domain settings.inc file added to settings.php because domain does not check to see what bootstrap level drush is trying to load. If drush is ONLY trying to bootstrap to DRUSH_BOOTSTRAP_DRUSH, domain should not try to bootstrap the database.

agentrickard’s picture

None of these are broken for me.

If you are adding the domain settings config line to settings.php BEFORE you install the site, then you are simply doing it wrong.

agentrickard’s picture

Status: Postponed (maintainer needs more info) » Needs work

I just pounded on this for a half hour, and it looks like an unsolvable drush issue to me.

The fact is that there is no way to accurately tell if a database connection will work -- unless there is a magic Drupal function or method that I am missing.

Your patch simply *breaks* drush commands if a database _is_ present. I tried a variety of methods to check to see if the database connection was loaded, but, in the end, drush simply won't allow it.

agentrickard’s picture

/me points to the install documentation: https://drupal.org/node/477372

If you can find a working solution, I'll commit it.

joelcollinsdc’s picture

Ok, I wanted to document my steps, I think there is a disconnect here...

1) Download drupal core and domain
2) add my patch to domain
3) configure settings.php with a valid database but which is currently empty
4) run $(drush sql-connect) < dump.sql (this works with my patch)
5) run regular drush commands (i tried cc, status, etc, they seem to work). Can you give me an example of a drush command that is not working for you? Mind you I never enabled domain in my steps here, maybe thats the issue?

Also I noticed that you can't install drupal when domain is being included in settings.php. I feel that this is a symptom of the same issue. Dmain should check fi you have a valid database somehow before proceeding. I"m not sure what the 'correct' way of doing this is, I think that making it drush-specific code isn't probably the correct way because people have other ways of drying to run drupal (lke going to install.php). I realize that your instructions give users a different order of operations but like I said in our enterprise environment following your instructions forces us to break our automation scripts and do things manually.

agentrickard’s picture

You MUST install Drupal before editing settings.php. This is documented because there is no consistent way to work around it, AFAIK. This problem is because drupal_bootstrap() doesn't actually give useful information on fail.

For your automated scripts, you may just have to wrap the DA include line in some IF logic specific to your build. Or you might use try/catch, which might be best practice.

With your patch, install the module and then try "drush domains". I get a load error . I get the same error with "drush vl" for Views module.

The drush command 'domains' could not be found.  Run `drush cache-clear drush` to clear the commandfile cache[error]
if you have installed new extensions.
Drush was not able to start (bootstrap) the Drupal database.                                                 [error]
Hint: This error often occurs when Drush is trying to bootstrap a site that has not been installed or does
not have a configured database.

Without your patch, this works fine.

joelcollinsdc’s picture

StatusFileSize
new661 bytes

coming through loud and clear now, I didn't try one of those commands. Seems that the drush_verify_boostrap function actually forces the bootstrap to that level, unlike what the name of the function seems to indicate. My apologies.

Like I said, our workflow does not support modifying settings.php only after loading a database, our order of operations is

get site working in dev, commit everything
pull site into higher environment
load database (using drush)

It would be frustrating if we have to modify this workflow only for sites that leverage domain, so I hope you find this patch reasonable. Thanks!

agentrickard’s picture

Status: Needs work » Needs review

That looks promising.

agentrickard’s picture

Status: Needs review » Needs work

Here's the one remaining problem I have:

With this patch, drush skips the domain bootstrap process entirely if the site is already installed. This is a regression, because there are times when you want to target a drush command at a specific domain.

E.g.:

drush domains
WD domain: Domain access failed to load during phase: bootstrap include. Please check your settings.php file [error] and site configuration.

If we can fix that, we're all set.

joelcollinsdc’s picture

I'm having trouble figuring out how to solve this.

The problem seems to come from a confusing order of operations. Drush has bootstrap levels 0-6 (drush, root, site, configuration, database, full, login). During drush's configuration bootstrap phase is when the settings.php is loaded; however if domain in included in settings.php it will try to call drupal_boostrap(DRUPAL_DATABASE). This means drupal is bootstrapping the database during drush's configuration phase, instead of its database phase. This is why drush_has_boostrapped doesn't work...because its still loading configuration.

If domain truly must be loaded during drush's configuration phase, I can't currently find a way in drush to see what phase drush is attempting to bootstrap to. I suppose I could look up the command being executed and look up the required boostrap for that command. Seems horribly complicated however.

agentrickard’s picture

That is consistent with my findings.

The difference is that drupal_boostrap() allows this type of "jumping" behavior.

In your case, I think the best thing to do is wrap that include line in a conditional, then we can document that and move on.

Since you are editing settings.php before installing Drupal anyway, this shouldn't bother the workflow much.

joelcollinsdc’s picture

Status: Needs work » Closed (won't fix)

you mean wrap the INCLUDE in a conditional? goddamnit why didn't I think of that earlier. that solves my problem, thank you sir.

agentrickard’s picture

Yeah, wrap it in

if (!function_exists('drush_verify_cli')) {
 ... INCLUDE CODE ...
}

I keep trying to find another way, but there doesn't seem to be one. Ideally, you would remove that conditional once the site is built.

gabriel.achille’s picture

I know this topic is a bit old now but:
@joelcollinsdc: how did you manage to get that working: patch DA... or custom include in settings.php ?
I'm having the same problem but I'm confused

les lim’s picture

@gabriel.achille: replace your existing "include" line in settings.php with this:

if (!function_exists('drush_verify_cli')) {
  include DRUPAL_ROOT . '/sites/all/modules/domain/settings.inc';
}

... adjusting the path if necessary to reflect where domain module is.

gabriel.achille’s picture

ok thank you.

However when I tested it I still had the error message "WD domain: Domain access failed to load during phase: bootstrap include. Please check your settings.php file and site configuration. [error]" when doing a drush cc all... Apart from that it is working fine.

I tested another code in my settings.php file: If the calling context is a drush command, it checks if the table "system" exists:

/* ... */
if (function_exists('drush_shell_exec')) {
  $connect_string = _drush_sql_connect(_drush_sql_get_db_spec());
  drush_shell_exec('$connect_string -e "SELECT 1 FROM system" ');
  $output = drush_shell_exec_output();
  if ($output[0] == 1) {
    include DRUPAL_ROOT . '/sites/all/modules/domain/settings.inc';
  }
}
else {
  include DRUPAL_ROOT . '/sites/all/modules/domain/settings.inc';
}

Tested on mysql only and it is less elegant...

sam152’s picture

Issue summary: View changes
Status: Closed (won't fix) » Needs work

Can confirm this is a problem. Wouldn't it be best to move all of this logic into the core of domain access so that there aren't extra steps and code required for users to put into the settings file? It would then be properly tracked as a feature and not just a random recommendation made in the issue queue?

P.S Great to see the progress on the D8 version of the module coming along. Thanks for the work!

agentrickard’s picture

D7 forces us to use the settings file in many cases. If you can find a workaround within the code here, please do:

domain.bootstrap.inc

karol haltenberger’s picture

A small update on gabrielle's code.

/* ... */
    drush_shell_exec('$connect_string -e "SELECT 1 FROM system" ');
/* ... */
/* ... */
    drush_shell_exec($connect_string . ' -e "SELECT 1 FROM system" ');
/* ... */
greg.1.anderson’s picture

Version: 7.x-3.3 » 7.x-3.x-dev
Status: Needs work » Needs review

I want to be able to use Drush to run site-install on a site that uses Domain access. This is an important use case if, for example, you want to be able to install a site using domain access from within a CI script. It is more convenient to be able to be able to set up settings.php in advance, rather than install the site first and then edit settings.php. It is also useful during the development workflow if you are able to `drush sql-drop` and then install again without having to modify files.

Swallowing errors from `domain_bootstrap();` does the trick nicely.

agentrickard’s picture

Again, given the Drupal bootstrap call stack, we have to load into settings.php. We don't have a choice.

I just account for that in my build scripts. e.g.:

# add setup to settings.php
chmod 775 sites/default/settings.php
echo >> sites/default/settings.php
echo "\$cookie_domain = '.example.com';" >> sites/default/settings.php
echo >> sites/default/settings.php
echo "include DRUPAL_ROOT . '/sites/all/modules/domain/settings.inc';" >> sites/default/settings.php;
chmod 664 sites/default/settings.php
greg.1.anderson’s picture

StatusFileSize
new300 bytes

The inconvenience with #32 is, on its own, `drush site-install` will fail if you ever run `drush sql-drop`. You have to remove `domain/setting.inc` before you do this, and then put it back.

It is way more convenient to just catch the errors from `domain_bootstrap();`; that way, you can keep the include of `domain/settings.inc` in your settings file, and re-install your site as needed. I have a working patch, and tried to attach it to #31, but for some reason it didn't get uploaded. I'll just attach it to this comment... (sorry about the filename/comment number mis-match).

See also: https://github.com/drush-ops/drush/pull/1442#issuecomment-126503886

agentrickard’s picture

Status: Needs review » Fixed

Committed.

fcdd3d4..aa82b25 7.x-3.x -> 7.x-3.x

Status: Fixed » Closed (fixed)

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