Over the last few years Drush has matured significantly and has seen an incredible uptake in usage. It's become indispensable in the day to day workflow of innumerable Drupal users and has been accepted with open arms by contributed module developers who are finding new and wonderful functionality to expose via its clear command line interface.
What not many people realize is that beneath this simple command line API beats the heart of a far more flexible and powerful beast. Drush was written with re-use and scriptability in mind, with this entire concept deeply ingrained in its design, and this is a large part of what gives it its power and flexibility. This will be even more apparent in Drush 3.0.
Below is a rundown of some useful things you'll be able to do with Drush 3.0.
Remote procedure calling
Each Drush command can be called from within any other Drush command, spawning a new process and returning structured and meaningful information to the calling script. A more accurate terminology would be that Drush commands all operate on a somewhat RESTful API , which is similar to XMLRPC and other RPC mechanisms that you may already be familiar with. Because of how this feature is implemented in Drush it can not only call Drush commands locally, but it can also call Drush commands on a remote server via SSH.
Up until now this functionality has been hidden within the API and only systems such as Aegir really made use of it. For example, in the Aegir hosting system we re-use the
drush updatedb command when we do site migration and to run updates, and we have a single
drush provision-backup command we can simply call when we need to make a backup.
What about security on remote calls?
Remote Drush calls run over SSH and require you to have your key already added to the remote server's list of authorized keys. Therefore Drush isn't capable of doing anything that you don't have the necessary permissions to log in manually and do on the server itself. It just does what it does best - automate away some of the steps so you get your results quicker.
Magic is now being exposed to the user!
The big news in Drush 3.0 is that there is now a way to access the magic from the user interface, without needing to make use of the API. With Drush 2.x if you wanted to run the
drush status command on a specific site in a multi-site Drupal install, you had to cd into the relative site directory or specify the following command line options :
drush --root=/path/to/drupal --uri=dev.mysite.com status
While the above example will still work, you now have the option to do the following:
drush /path/to/drupal#dev.mysite.com status
You can also now do commands that weren't possible before, like:
drush firstname.lastname@example.org/path/to/drupal#mysite.com status
At first this might not seem like such an incredible improvement, but that's just because I haven't shown the most important new functionality that's been enabled.
Note: These examples are based on Drush HEAD and not any of the currently available releases.
If all the typing above still seems like far too much work for you, the real magic in Drush 3.0 is the introduction of site aliases.
Instead of having to type out all those specifications for each site or changing to a specific directory or even specifying endless command line options to run commands on your sites, you can simply create a configuration file that holds all this information for you!
~/.drush directory , I created the
dev.mysite.com.alias.drushrc.php file containing :
$aliases['dev.mysite.com'] = array ( 'root' => '/path/to/drupal', 'uri' => 'dev.mysite.com' );
Now wherever I am on my system I can simply run:
drush @dev.mysite.com status
Of course you aren't restricted to only using a URL for the alias name - you can choose '@dev' or '@mysite' or any name that makes sense to you.
If the site was on a remote server (say my shared hosting environment), I would simply create a record such as:
$aliases['mysite.com'] = array( 'root' => '/path/to/drupal', 'uri' => 'mysite.com', 'remote_host' => 'server.example.com', 'remote_user' => 'myuser', );
Now when I call
drush @mysite.com status it will actually connect to my server and call the Drush command there with the correct parameters, returning the information to me.
Can I only call the status command?
No, that wouldn't be very useful would it? All Drush commands work with this mechanism. You can use a Drush command to download an updated version of a module to your staging or live site with
drush dl, and run
drush updatedb on the site to do the upgrades, regardless of which server it is on.
You can use the
drush watchdog-show command to monitor your site for problems, and use the
drush cache-clear to clear your caches.
Another feature that's already most of the way there is the ability to run commands on multiple aliases with a single command. If you wanted to get the status of the previous examples, you could use:
drush @mysite.com,@dev.mysite.com status
There's even ongoing work to provide mechanisms to, say, run
drush updatedb on all the Drupal sites in a specific Drupal directory. But this functionality might not make the cut for Drush 3.0.
How do I generate alias records?
Alias records are easy to generate by hand in a text file. Alternatively, you can use the
drush site-alias command, which will print out the specified record for you, which you can then copy and paste into the required file.
What's missing is a command to manage these aliases and automatically manage the site alias files, so you could just go:
drush alias-add @aliasname /path/to/drupal#sitename.com or something similar.
The actual backend implementation of these configuration files still needs to be hidden from the user.
What other uses are there for Aliases?
Beyond specifying aliases as shortcuts to different Drupal installations across the internet, you can also specify aliases relative to the sites themselves. For instance in my local
/path/to/drupal/sites/dev.mysite.com, I can have a
staging.alias.drushrc.php file that contains the definition of an alias called '@staging'. Certain commands can make use of these "relative aliases" as arguments or options to dynamically load the configuration when necessary.
The basic example here is
drush @dev.mysite.com sql-sync @staging, which would take the contents of the database used by the local '@dev.mysite.com' alias and sync it to the database of the relative alias '@staging'. What's important here is that the relative alias can be stored in your version control system and shared between all members of your team, allowing you to build sophisticated development workflows.
What does this mean for the Aegir Hosting System
As has always been the case, Aegir and Drush have a very symbiotic relationship with innovations freely crossing over between the two. The timing of this new functionality is rather fortuitous as we are busy working on our new Aegir multi-server release. We will make full use of the alias functionality in the next release of Aegir, in as far as generating and managing aliases for each server, platform, and site that is managed by Aegir.
Instead of having to generate complex commands such as:
drush --root=/path/to/openatrium provision-install site.com --db_host=127.0.0.1 --db_port … [snip.. this gets crazy long]
We can just do:
drush @openatrium provision-install site.com --db_server=@dbserver1
This will allow us to significantly reduce the complexity of both the front and backend, and it will make it a lot easier to cleanly manage many of the use cases we have.