The storage API could really use comprehensive set of drush commands that allow for creating/removing/modifying containers, and placing them in the appropriate classes, as well as doing the syncing process in full, or in part.

For this purpose I've done up a patch to add at least some of these commands to the storage API.

The commands that it adds are:

  • storage-cron
  • storage-sync-files
  • storage-sync-migration
  • storage-list-containers
  • storage-list-classes
  • storage-list-container-classes
  • storage-create-container
  • storage-modify-container
  • storage-destroy-container
  • storage-container-class

Using the help command for storage-create-container or storage-modify-container lists all the expected values for each of the defined storage services.
These are primarily the commands we use, and as such are missing the appropriate create class, destroy class, etc.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Perignon’s picture

Assigned: Unassigned » Perignon

  • Perignon committed 0653066 on 7.x-1.x authored by rhys
    [#2348597] Creation of the first set of custom drush commands for...
Perignon’s picture

Committed to Dev

scottrigby’s picture

Status: Needs review » Needs work

@rhys & @Perignon

The storage-modify-container drush command has an incorrect callback. It also needs to pass the $container object. I'd re-roll the patch, but the earlier one was already committed (even though this issue status is Needs Review).

I also can't submit it properly for some reason, because of this warning (I see #2002236: Add S3 container: "The difference between the request time and the current time is too large" but the recommendation didn't fix it):

WD storage_s3: Amazon S3 error: The difference between the request time and the current time is too large. [error]

Here's a quick diff. Can someone take a stab at this who has a matching server time in their dev environment? I don't want to cross issues, but just can't test this to be sure everything works properly.

diff --git a/storage.drush.inc b/storage.drush.inc
index 7cd8084..5415f17 100644
--- a/storage.drush.inc
+++ b/storage.drush.inc
@@ -365,7 +365,7 @@ function drush_storage_create_container($service_id, $name) {
  * @param string $name
  *   The name the storage container is listed as.
  */
-function drush_storage_manage_container($service_id, $name) {
+function drush_storage_modify_container($service_id, $name) {
   // Ensure the settings and the service id and name are somewhat valid.
   if (($settings = _drush_storage_get_container($service_id, $name, FALSE)) === FALSE) {
     return;
@@ -388,7 +388,7 @@ function drush_storage_manage_container($service_id, $name) {
 
   // Call the submit function for this behaviour.
   module_load_include('inc', 'storage', 'container.admin');
-  drupal_form_submit('storage_container_edit_form', $form_values);
+  drupal_form_submit('storage_container_edit_form', $form_values, $container);
 }
 
 /**
Perignon’s picture

In regards to the server time, make sure you are using NTP and that should fix it.

Attached is a patch file for use. I don't have a dev environment setup with a bucket that I can use at the moment so I cannot test this.

jonhattan’s picture

Patch in #5 is fine.

I've found that `storage-create-container` command rely on the array returned by serviceSettingsDefault() to obtain the accepted options, but not all configuration settings have a default value, so they're missing in drush.
For example, in the case of S3, there's no way to configure `secret_access_key`.

How do you want to proceed? Add a key to serviceSettingsDefault() for each option or decouple drush from serviceSettingsDefault() and replicate all options within drush? I may write a patch in either direction you prefer.

Perignon’s picture

I honestly don't have much of a preference myself. I have not written any drush integrations to date so I am not really one to say one way or the other honestly.

scottrigby’s picture

@jonhattan & @Perignon: I have written a command that allows this, and lets me get on with what I need to do. Also this is simplified, and bypasses some of the existing container validation (because, even though my values were correct, that validation was not passing).

Here's what I added in case it's helpful. Let's decide on a direction first, then I'm happy to roll a patch as needed:

/**
 * Implements hook_drush_command().
 *
 * See @link https://www.drupal.org/node/2348597#comment-9398179 the d.o issue. @endlink
 *
 * @todo Remove this once the storage-modify-container drush command is fixed.
 */
function MYMODULE_drush_command() {
  $items = array();

  $items['storage-container-set-value'] = array(
    'description' => 'Set a storage container value.',
    'arguments' => array(
      'container_id' => 'A StorageContainerInterface ID.',
      'key' => 'A container settings key.',
      'value' => 'A container settings value',
    ),
    'drupal dependencies' => array('MYMODULE'),
    'aliases' => array('storage-csv'),
  );

  return $items;
}

/**
 * Implements hook_drush_help().
 */
function MYMODULE_drush_help($section) {
  switch ($section) {
    case 'drush:storage-container-set-value':
      return dt('Set a storage container value. This is especially helpful for setting storage container keys per environment.');
  }
}

/**
 * Implements drush_hook_COMMAND_validate().
 */
function drush_MYMODULE_storage_container_set_value_validate($container_id, $key, $value) {
  if ($container = storage_container_menu_load($container_id)) {
    // @todo Validate settings.
  }
  else {
    return drush_set_error(dt('A container with the ID @id does not exist.', array('@id' => $container_id)));
  }
}

/**
 * Sets a container value.
 *
 * This is a convenience For example:
 * @code
 * drush storage-csv 2 secret_access_key ABC123456
 * @endcode
 *
 * @param $container_id
 *   A StorageContainerInterface ID.
 * @param $key
 *   A container settings key.
 * @param $value
 *   A container settings value.
 *
 * @see storage_container_edit_form()
 */
function drush_MYMODULE_storage_container_set_value($container_id, $key, $value) {
  // Loads an instance of StorageContainerInterface or throws StorageException.
  $container = storage_container_menu_load($container_id);
  $container->settings = array($key => $value) + $container->settings;
  $container->update();
}
Perignon’s picture

Issue tags: +Storage API 7.x-1.7