According to issue 2927814 we discussed another idea:

As site maintainer i want to open the drd ui and create a drush command 'profile' (Like in issue 2927799 (db dump profile)).
There i should be able to:
- create a name and machine name.
- input any drush command
- determine whether i want to see the output on drd (maybe like in #2932073)
-...

These created drush commands would serve as options for the new action 'Execute drush command'. The selected command would be executed on the remote parts and post-processed depending on the command settings.
The output (if checked) should be visible depending on setting.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

drupatz created an issue. See original summary.

drupatz’s picture

Issue summary: View changes
drupatz’s picture

Drush command profile is created:

-Label (textfield)
-Drush command (textarea)
- Additional confirmation step, if an input command contains '-y' to avoid accidental execution of drush commands on remote parts.
-Checkbox for retrieving output
- Currently does nothing, waits for #2932073 to have playground

Logic implemented for D8, D7, D6 (D7 and D6 not tested), drush and DC command.

jurgenhaas’s picture

Title: Action execute drush command with profile » Action to execute remote CLI command
Status: Active » Needs work

Thanks @drupatz this is a great starting point. A number of thoughts on how to make this generic:

  • Let's start with the wording: I got confused by the word profile here. From what it is now, it is a Drush command which is stored in a config entity, not a drush command profile. So we should remove "profile" completely, also from the code and the schemes.
  • This should be more generic and what we really need is an action to executed CLI commands. That means drush and console for now but could be more in the future. So, the action should be called drd_action_cli_command and one field in the config entity should be a select field for the CLI tool which is meant to be used. Currently that select field should allow the selection between Drush and Console.
  • The command field should only accept the arguments, not the full command - because if we accept the full command, then it's not a drush command action, then we're talking about scripts in general. THe arguments provided in this field should not contain details like -y or details about the domain, that should be added by the DRD code which knows all about that much better and won't make any typos.
  • Another field which is required should define the scope of the CLI command: domain, core, host or global. Just like any other DRD action, CLI commands can either be executed on domains, cores, hosts or globally on the DRD instance only.
  • If the 4 different scopes will be implemented, the selection process has to be context sensitive, depending on the scope which is defined in the config entity. It would be best to implement this as part of the drd.entities service where it should get the scope from the action which knows how to read the cli command config entites.
  • The implementation of the action will then get a list of domains or cores or hosts and it will have to check for each of those entities the CLI is defined in their associated host entity and call the remote site only if the required CLI has been defined and output some warning if not.
  • The implementation of the remote agent actions will then receive the CLI executable, the arguments defined in the CLI command config entity, the domain name, the Drupal root directory and anything else required and known by DRD such that the remote part does not have to apply any logic which is unnecessary. The remote site will then aggregate the pieces together in a way that the execution is save and will certainly be possible to work in unattended context, e.g. always add the -y argument.

Also, the patch contains settings from your IDE and the best approach would be to add the .idea directory to the global ignore list ion your host, that ensures that you never get into that problem in the future. And we don't want to add that into the project's ignore file because we would end up adding a lot of individual IDE directories to be ignored.

Last but not least, we may want to consider allowing extra and optional command line arguments when calling the drd action. If present, those arguments would be appended to the arguments from the CLI command config entity.

maxrab’s picture

If the 4 different scopes will be implemented, the selection process has to be context sensitive, depending on the scope which is defined in the config entity. It would be best to implement this as part of the drd.entities service where it should get the scope from the action which knows how to read the cli command config entites.

I understand the service part, but I am currently not sure where to get the information about the scope when I am inside the action. How do I get this information?

jurgenhaas’s picture

Each action has a type in its annotation which specifies the scope, e.g. for the cron action:

/**
 * Provides a 'Cron' action.
 *
 * @Action(
 *  id = "drd_action_cron",
 *  label = @Translation("Cron"),
 *  type = "drd_domain",
 * )
 */

This action has a scope for drd_domain which means that it can be executed on domains and will in the UI only show up in domain views.

For the CLI actions that are prepared in config entities, they need to create the actions as derivates and therefore define the type/scope on the fly depending on what is defined in the config entity.

maxrab’s picture

This patch was made according to comment #4 by @jurgenhaas and basically covers the first four points.

* All the existing code and logic was rewritten to provide more generic cli commands instead of only drush commands
* There now is a cli command config entity along with the needed fields like the type and the scope of the cli command
* There is already a cli command action, but this is currently only for the scope of a domain
* There are already additional classes and files defined and modified which have no use right now, but will be needed later, like the action logic in the src/agent directory

Next up would probably be to define the Derivates of the CLICommand Action, but before that I would welcome feedback on the current state.

Thanks in advance!

maxrab’s picture

Added the wrong files, these are the correct ones.

maxrab’s picture

maxrab’s picture

FileSize
23.7 KB
41.92 KB

Ok, Im sorry, these really are the correct ones.

jurgenhaas’s picture

Status: Needs work » Needs review

Sounds great, I'll have a look asap.

jurgenhaas’s picture

Status: Needs review » Needs work

Started review of this and have a couple of suggestions:

  • Sort alphabetically in drd.drush.inc and console.services.inc
  • What's the best name for the command? CLICommand for the entity is probably good but to execute the command we probably want to just use CLI? In that case the action could just be called cli too, that's then even shorter when used at the command line

However, I've tried the code and created my first CLI command successfully. Then I tried to execute that with drush and first didn't know what the ID of the action was. So maybe we need an option for drush cli that returns a list of available commands?

What I realised was that when I used an ID that doesn't exist, drush just finished silently. Maybe some sort of error message to tell that the given ID doesn't exist?

And then, when I used the correct ID I get the following error:

Fatal error: Cannot declare class Drupal\drd\Plugin\Action\CLICommand, because the name is already in use in /var/www/html/web/core/modules/user/src/Plugin/Action/CLICommand.php on line 18

include('/var/www/html/web/core/modules/user/src/Plugin/Action/CLICommand.php') /var/www/html/vendor/composer/ClassLoader.php:444

I'm a bit confused by that error because the namespace is different. But the error is consistent even after a cache rebuild. Can you please have a look what's going on? Maybe that's going away also when we rename the action from CLICommand to just CLI, but I'm not sure.

jurgenhaas’s picture

Status: Needs work » Closed (duplicate)