Split off from http://drupal.org/node/628996#comment-2678160. I'm new to the drush queue, so excuse me if I'm naive on some of this.
I was surprised to learn that drush has some great new functionality for searching site folders and running commands on several sites at once. There have been countless unofficial bash scripts, etc. to do this in the past, so it's exciting to finally have something built-in. The problem is that currently, it's just some internal functionality that's not in the command list or docs. I'd like to have this function like a regular command, even though the functionality is already implemented around aliases.
This patch uses mostly existing functionality, but lets you do:
carlos8f@solrac:~/projects/d6$ drush multisite updatedb
You are about to execute 'updatedb' on all of the following targets:
/home/carlos8f/projects/d6#default
/home/carlos8f/projects/d6#dev.d6
Continue? (y/n):
Which I think is nicer than the way it currently stands:
carlos8f@solrac:~/projects/d6$ drush /home/carlos8f/projects/d6#all updatedb
This is done with a special alias, and it autodetects the Drupal root to use (and still works with -r or --root), so you don't have to worry about full paths. I've also written a dummy command to provide documentation and help text. The --site-list option is listed here and can be used in conjunction with "drush multisite" to specify specific sites to run on.
I merged this with #727058: Site aliases should not be cached in the options context, and when that patch goes in I will re-roll without it. Another issue is #733244: Aliases should be named '@alias' instead of 'alias', which might change the behavior here. Ideally the "multisite" alias would seem like a normal command to the user, and thus wouldn't have a "@" before it.
| Comment | File | Size | Author |
|---|---|---|---|
| #18 | limit-sites-alias-search-scope.patch | 7.22 KB | greg.1.anderson |
| #14 | drush-sites-alias-2.patch | 10.05 KB | greg.1.anderson |
| #12 | drush-sites-alias.patch | 2.46 KB | greg.1.anderson |
| drush-multisite.patch | 30.28 KB | carlos8f |
Comments
Comment #1
moshe weitzman commentedok, we'll discuss after #727058: Site aliases should not be cached in the options context. As mentioned elsewhere, I have issues with the word multisite here.
Comment #2
greg.1.anderson commentedIt is also very important to consider the impact of #733256: Aliases should be loaded from a central location rather than drushrc.php, which adds new ways that aliases can be grouped together. The concept of an
@allalias is clear enough to those who only have one Drupal root, but it becomes a little less clear when there are multiple roots. This is why the current code stopped at /path/to/drupal#all, which though inconvenient to type is at least unambiguous. Perhaps part of what is needed is a way to specify "all" in terms of some alias that defines only a root folder. Addressing all of the aliases in a particular alias file that defines a group of related aliases (e.g. inside servername.aliases.drushrc.php) would also be useful.This will require more discussion on syntax and such.
Comment #3
moshe weitzman commentedI think we might want to add help topics which are not real commands. There we would discuss site aliases. That helps the docs portion of this request without adding a pseudo-command
Comment #4
greg.1.anderson commentedThis can, at least, be un-postponed now.
How about an @all alias that means "all sites in a certain Drupal root"? For example
-r /path/to/root @all,@drupalrootalias/@all,/path/to/root/@all?This is similar in concept to #all, but could be implemented similar to @self.
Comment #5
greg.1.anderson commentedComment #6
carlos8f commented@all sounds good, especially if the full path need not be specified, i.e.
drush @all command(with optional -r argument). The main issue I had with #all is having to specify the full root path in a way that doesn't respect the -r arg or the normal root autodetect. Calling it @all rather than multisite makes sense.Comment #7
moshe weitzman commentedhmm. nice, but needs less confusing name. i can't think of one in 10 secs. will ponder.
Comment #8
greg.1.anderson commentedNo problem; not critical for 3.0.
Comment #9
greg.1.anderson commented@sites?
drush @sites updatedrush -r /root @sites updatedrush /root/@sites updatedrush @root-alias/@sites updateComment #10
moshe weitzman commentedi like @sites. it matches the 'sites' dir which is the path you take from their 'shared drupal root'.
Comment #11
timidri commentedJust some thoughts about 'inferring' sites on which to execute the drush command. If you cd to a site dir and do a drush command there, drush automatically infers that you want to execute the command on that site, and does not require an argument for that. In (IMHO) analogous way, when using a '@sites', '@multi' or '@multisite' modifier, (here meaning 'multisite' in the original Drupal sense), drush can infer that all sites of this specific docroot are meant. If you mean something else than that, then you should be required to use aliases or whatever other means to specify the exact list of sites on which to operate. So, in other words, drush should assume the 'closest' meaning first and not require the user to always specify the docroot when it is obvious.
Comment #12
greg.1.anderson commentedHere's a patch that should do the trick. Of the forms shown in #9, all work except for "/root/@sites", since "/root" is not a valid site specification all by itself.
Comment #13
moshe weitzman commentedcode looks fine. i did not test but i doubt others will without a commit so go ahead.
Comment #14
greg.1.anderson commentedThe patch in #12 didn't actually work for aliases in the form
@root-alias/@sites, so what I actually committed is attached here, which does support that form.With this patch, it would be possible to make aliases @d5, @d6 and @d7 for your various document roots; then
@d6/@siteswould be an alias for every d6 site in the @d6 sites folder.Comment #15
moshe weitzman commentedOops - we introduced a critical bug here.
The new call shown at http://drupalcode.org/viewvc/drupal/contributions/modules/drush/includes... eventually leads to
$files = drush_scan_directory($base_path, '/settings\.php/', array('.', '..', 'CVS', 'all'));. This line appears to traverse down the whole codebase, including file files directory. Thats no good.@greg - any chance you can take a look and commit a quick fix?
Comment #16
greg.1.anderson commentedSure. You're right, that is too aggressive. The intention was to allow $base_path to be either a drupal root, or perhaps a folder above the drupal root so that you could get all sites available anywhere in a number of different drupal root directories.
For a quick fix, I could make it scan just $base_path/sites/*/settings.php. For the second use case... hm, I wouldn't want to find just _any_ 'sites' directory, as someone might have a copy of 'sites' in the 'files' directory. I'd have to find real drupal roots and then look at sites/*/settings.php inside each.
Comment #17
moshe weitzman commentedAs long as we don't dive into a modules/themes/files/libraries (new in D7) directory, then I am OK.
Comment #18
greg.1.anderson commentedThis patch renames the parameter $recurse in drush_scan_directory to $recurse_max_depth. Its default value is still TRUE, and the behavior of this function is unchanged when TRUE is passed. When a positive non-zero integer is passed in, it has the effect of limiting the traversal depth of the directory scan.
This new behavior of drush_scan_directory is used to search for 'bootstrap.inc' files inside a specified root directory when building a relative @sites alias. The default maximum search depth for drupal root folders is 1, so if you are searching for @drupal/@sites and the "@drupal" alias is /srv/www/drupal, then only drupal roots immediately inside the 'drupal' folder will be found. This depth can be increased via the --search-depth option.
Note that the search for a drupal root is skipped if the path provided in the alias points to a drupal root ('includes/bootstrap.inc' exists).
When a drupal root is found, drupal sites are searched for, but only the 'sites' folder is checked. Inside the 'sites' folder, the traversal only goes one level deep. This avoids false positives should someone have a settings.php file inside a 'files' folder inside their site folder.
Comment #19
moshe weitzman commentedcommitted.
at this point, i'm afraid to edit the sitealias code for fear of breaking something. its gotten pretty dense. i'd love to see some unit tests here. i think it could just be a drush command that builds out test drupal directory structures (single sites, multi-site) and compares if the aliases return the right number of sites. similarly, we could run a command on several of them at once and compare expected output. at this point, we should just abandon hopes of finding a separate unit test library and just use drush. my .03
Comment #21
David_Rothstein commentedEven only scanning the top level of the sites directory, this can still be extremely slow if you have a large multisite installation. I've created an issue with a possible patch here: #801060: Drush 3.0 is extremely slow on a large multisite installation