unable to make non-provision tasks
Yorirou - October 1, 2009 - 13:39
| Project: | Hosting |
| Version: | 6.x-0.4-alpha1 |
| Component: | Code |
| Category: | feature request |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | needs work |
Description
hi
I would like to develop tasks for the features module. The problem lies in task.hosting.inc:62
$output = drush_backend_invoke("provision " . $task->task_type, $data, $mode, TRUE, $drush_path, $hostname, $username);
This function call should not hardcode the "provision" string.

#1
#2
This is a major blocker for things like DNS or #541754: abstract away vhost engine that need custom tasks. It would also make it possible to call any drush command (cache clear, etc) much more easily.
I think we will need to have feedback from Adrian on this one beforehand.
#3
I like this idea, it'll increase Aegir's power tenfold. A couple other specific uses for this:
1) Be able to execute my Login reset drush command now that it's not in provision #567094: Password reset link
2) Work with *other* APIs such as SliceHost and Linode APIs : this leads in to hooking into their own DNS APIs as well as actually provisioning servers from scratch and *then* attaching roles to them like 'web server', 'db server' etc, which is something I want to do.
#4
Not only that, but all the drush tasks: cache clear, dl, etc...
I think the cleaner fix would be to remove the "provision" prefix from the provision module, simply.
#5
following
#6
jep, interested also
#7
Here is a patch, I think it solves the problem.
#8
this is close to the solution, but it can be done without re-indexing the array.
the only line that really matters in this is :
<?php$output = drush_backend_invoke("provision " . $task->task_type, $data, $mode, TRUE, $drush_path, $hostname, $username);
?>
all that needs to be done is to default $task->command to "provision " . $task->task_type in the _validate hook where the object is constructed, and then use $task->command for the backend_invoke.
at any point the task being processed can change $task->command to whatever it wants.
#9
I choose the array reindexing, because of a possible collision. Put case that I want to integrate my module with the hostmaster, and my module also has an install task.
#10
here's what i have against providing a 1:1 user interface / mapping for mainline drush commands.
Tasks in hosting should be in their own namespace because it becomes reeeaaalllly easy to provide a shitty user interface if you try and expose all the functionality of a command line tool in a user interface.
You end up with user interfaces like this : http://www.jensroesner.de/wgetgui/wgetgui_simple.png
so i will never allow tasks in the front end to become the full drush command, hence my objection against the 'provsion $task' index in the array. The user interface WILL have only have one set of tasks that it can do on a given object. There will not be a provision install, install and some other install task that can be created on a site.
#11
Here are my objections to calling the mainline drush commands directly from the user interface.
Single point of entry
The decision to use the provision commands which map to the tasks on the front end is because it gives the front end a single point of communication. Each task that is performed turns into exactly one command sent to the backend.
Even the simplest tasks end up requiring multiple drush commands to actually make something happen. an example being drush dl.
you need to download the modules and enable them afterwards.
Pollution of front end with back end logic.
if we have the front end pushing multiple drush commands, we start having to implement back end logic in the front end. So instead of just calling out to the backend, we have multiple commands we need to call and we need to manage that logic in the front end.
Provision commands are atomic.
Provision commands are written so that they fail and roll back atomically. Either the entire command fails or none of it does. This is an extension of the above problem. If we have the front end calling drush commands directly (and assuming there is almost always multiple commands that need to be called) , we need to manage the rollback inside hosting, not provision.
Simplicity for multi-server situations.
This gets even more complex when we get to the point of multi-server communication, because now we end up having to manage multiple ssh pipes to the remote installation of provision AND all that logic to manage that stuff now gets left up to the front end interface module. This has worked so far, but might need to change in the 0.4 release, I want to avoid it if at all possible tho.
Provision commands follow a contract with the UI.
The provision commands act as an abstraction layer to the functionality of drush. It means that any command that we want to call in the backend will behave exactly the same way, and we are mostly even protected from changes unless the functionality changes.
Additional 'magic' that happens in provision commands.
Provision commands have some subtle differences to normal drush commands, in that they handle a lot of the server level things in the back end for you.
A good example of which being that they automatically handle pickling of data into the drushrc.php on closure, set up sensible defaults for most of the components.
If you were to use standard drush commands, you would need to extend them to accomplish this needed functionality anyway. The stuff that needs to happen for provision back end commands is also not guaranteed to stay the same, so you will have to update all your code with each new release of provision, whereas you are protected from internal api changes when using the provision commands.
Bootstrapping is important
provision commands bootstrap to a much lower level than most drush commands, and this allows the same command to work either in the platform or site scope, depending on the parameters passed to it. This will get even more complex when we add an additional level for servers (ie: server:verify, platform:verify and site:verify would need completely different code on the front end to work properly)
Provision commands provide a layer of abstraction
With the provision commands, we are guaranteed of being able to generate a very very simple command in the front end, without any knowledge of how that translates to real drush commands in the backend. It means it is much simpler to maintain.
provision needs extra stuff to happen
Even if you used the mainline drush commands, there's additional stuff that often needs to happen on provision commands.
take for example if you wrote a command for drush dl. Not only will you need to download the code, you would have to enable the modules and you would then have to rebuild the package database (and have it synched up to the front end and cached to the hard drive).
You will need to write additional code around almost any drush command to make it work anyway, by having the provision command wrapper you have a clear, easy to maintain place to do that all.
And lastly, this is the grand total of code that you guys are objecting to writing (for the absolutely simplest case, which is not really that common)
<?php
function mymodule_drush_command() {
return array('provision mycommand' => array('bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_ROOT, 'description' => 'Example command'));
}
function drush_mymodule_mycommand($url) {
drush_invoke('command', array("param1", "param2"));
}
?>
If the issue people have is the proliferation of commands in drush help, that can be easily solved by collapsing all the commands in the help down to a single entry, like the way git help works.
#12
I rewrote the patch.
#13
Just wanted to say I read and digested #11 and really appreciate the underlying experience exposed by that post. Thanks adrian.