You are here

function drush_hosting_task in Hosting 7.4

Same name and namespace in other branches
  1. 6.2 task.hosting.inc \drush_hosting_task()
  2. 7.3 task.hosting.inc \drush_hosting_task()

Drush hosting task command.

This is the main way that the frontend communicates with the backend. Tasks correspond to backend drush commands, and the results and log of the command are attached to the task for reference.

See also

drush_hosting_task_validate()

hook_hosting_TASK_OBJECT_context_options()

File

./task.hosting.inc, line 221
Drush include for the Hosting module's hosting task command.

Code

function drush_hosting_task() {
  $task =& drush_get_context('HOSTING_TASK');
  $output = array();
  $mode = drush_get_option('debug', FALSE) ? 'GET' : 'POST';

  // Make sure argument order is correct.
  ksort($task->args);

  // If this task type needs it, run provision-save to create the named context.
  if (!empty($task->task_info['provision_save'])) {

    // Invoke hook_hosting_TASK_OBJECT_context_options()
    // We copy module_invoke_all() here because it doesn't pass by
    // reference and it breaks under PHP 5.3
    $hook = 'hosting_' . $task->ref->type . '_context_options';
    foreach (module_implements($hook) as $module) {
      $function = $module . '_' . $hook;
      call_user_func_array($function, array(
        &$task,
      ));
    }

    // Launch a provision-save for the platform before running it for the site.
    if ($task->ref->type == 'site') {

      // Create a verify task to use as a mock so we can load provision-save options and trigger post_hosting_verify hooks.
      $platform_task = _drush_hosting_task_create_platform_task($task);
      $platform_node = $platform_task->ref;

      // drush_hosting_task_provision_save($platform_node->hosting_name, $platform_task->context_options, t('Saving codebase metadata...'));
      // Save Platform Alias file.
      drush_invoke_process('@none', 'provision-save', array(
        '@' . $platform_node->hosting_name,
      ), $platform_task->context_options, array(
        'method' => $mode,
        'integrate' => TRUE,
      ));

      // Run platform verify task if this is a site install. Provision MUST run platform verify before provision-install.
      // @TODO: Modernize installation of sites.
      if ($task->task_type == 'install' && empty($task->ref->platform_verified)) {
        $output = provision_backend_invoke("@{$platform_node->hosting_name}", "provision-verify", $task->args, $task->options);
        hosting_platform_post_hosting_verify_task($platform_task, $output);
      }
    }

    // Save Current Context Alias file.
    drush_invoke_process('@none', 'provision-save', array(
      '@' . $task->ref->hosting_name,
    ), $task->context_options, array(
      'method' => $mode,
      'integrate' => TRUE,
    ));
  }
  if ($task->ref->type == 'site' && $task->ref->site_status == HOSTING_SITE_DELETED || $task->ref->type == 'platform' && $task->ref->platform_status == HOSTING_PLATFORM_DELETED) {

    // We're performing a task on a site that has been deleted...
    // d() will not be returning a site object.
    $alias = '@none';
  }
  else {
    $alias = $task->ref->hosting_name;
  }
  if (!isset($task->task_command)) {
    $task->task_command = 'provision-' . $task->task_type;
  }

  // Tell provision this is being run by drush hosting-task
  $task->options['runner'] = 'hosting_task';

  // Run the actual command. Adding alias here to work around Drush API.
  foreach ($task->options as $name => $value) {
    $options[] = "--{$name}={$value}";
  }
  $args = implode(' ', $task->args);
  $opts = implode(' ', $options);
  $command = "drush @{$alias} {$task->task_command} {$args} {$opts}";
  drush_log(dt("Running command: {$command}"), 'p_log');
  $output = provision_backend_invoke($alias, $task->task_command, $task->args, $task->options, $mode);

  // Pass the drush output back to the HOOK_post_hosting_TASK_task() and
  // HOOK_hosting_TASK_task_rollback() hooks, as the $data argument.
  drush_set_context('HOSTING_DRUSH_OUTPUT', $output);

  // On delete error, throw a warning.
  if ($task->task_type === 'delete') {
    if (drush_get_error()) {
      drush_log(dt('Command "provision-delete" failed. Not running "@@alias provision-save --delete".', [
        '@alias' => $task->ref->hosting_name,
      ]), 'warning');
      drush_clear_error();
    }
    else {

      // If no error, run 'provision-save --delete'
      drush_invoke_process('@none', 'provision-save', array(
        '@' . $task->ref->hosting_name,
      ), array(
        'delete' => TRUE,
      ), array(
        'method' => $mode,
        'integrate' => TRUE,
      ));
    }
  }

  // New revision is created at the beginning of function.
  $task->revision = FALSE;
  $task->delta = microtime(TRUE) - $task->executed;
  node_save($task);

  // @TODO: END OF PROVISION 3 CODE

  /** @TODO: BEGINNING OF MODERNIZATION HACKS:
    $task = &drush_get_context('HOSTING_TASK');
    $output = array();
    $mode = drush_get_option('debug', FALSE) ? 'GET' : 'POST';

    // Make sure argument order is correct.
    ksort($task->args);

    // If this task type needs it, run provision-save to create the named context.
    if (!empty($task->task_info['provision_save'])) {

      // Launch a provison-save for the platform before running it for the site.
      if ($task->ref->type == 'site') {

        // Create a verify task
        $platform_node = node_load($task->ref->platform);

        $platform_task = clone($task);
        $platform_task->nid = null;
        $platform_task->vid = null;
        $platform_task->title = "Verify: " . $platform_node->hosting_name;
        $platform_task->task_type = 'verify';
        $platform_task->ref = $platform_node;
        $platform_task->rid = $platform_node->nid;
        $platform_task->context_options = array();

        // Save platform
        $hook = 'hosting_platform_context_options';
        foreach (module_implements($hook) as $module) {
          $function = $module . '_' . $hook;
          call_user_func_array($function, array(&$platform_task));
        }
        $platform_task->context_options['context_type'] = 'platform';

        drush_hosting_task_provision_save($platform_node->hosting_name, $platform_task->context_options, t('Saving codebase metadata...'));

        // Run platform verify task if this is a site or platform verify.
        if ($task->task_type == 'verify' || $task->task_type == 'install') {
  //        hosting_process(array(
  //          "drush",
  //          "@{$platform_task->ref->hosting_name}",
  //          "provision-verify",
  //        ), null, t('Preparing codebase...'));
          $output = provision_backend_invoke("@{$platform_task->ref->hosting_name}", "provision-verify", $mode);
        }
      }


      // Prepare context options and run provision-save.
      // Invoke hook_hosting_TASK_OBJECT_context_options()
      // We copy module_invoke_all() here because it doesn't pass by
      // reference and it breaks under PHP 5.3
      $hook = 'hosting_' . $task->ref->type . '_context_options';
      foreach (module_implements($hook) as $module) {
        $function = $module . '_' . $hook;
        call_user_func_array($function, array(&$task));
      }

      drush_hosting_task_provision_save($task->ref->hosting_name, $task->context_options, t('Saving metadata...'));

      /** @TODO: uncomment when pro4 cli is ready.
      // Save services to the context
      // Servers have services, platforms and sites have service subscriptions.
      if (is_array($task->ref->services)) {
        foreach ($task->ref->services as $service_type => $service_class) {
          $command = array(
            variable_get('provision_bin_command', '/usr/share/devshop/provision/bin/provision'),
            "@{$task->ref->hosting_name}",
            "-n",
            "--ansi",
            'service',
            'add',
            $service_type,
            "--service_type={$service_class->type}"
          );

          foreach ($service_class->provisionProperties() as $name => $value) {
            $value = escapeshellarg($value);
            $command[] = "--{$name}={$value}";
          }
          hosting_process($command, null, t('Saving service metadata...'));
        }
      }
      elseif (is_array($task->ref->servers)) {
        foreach ($task->ref->servers as $service_type => $server_node) {
          $command = array(
            variable_get('provision_bin_command', '/usr/share/devshop/provision/bin/provision'),
            "@{$task->ref->hosting_name}",
            "-n",
            "--ansi",
            "service",
            "add",
            $service_type,
            $server_node->hosting_name,
          );

          // @TODO: Provision4 support for properties.
  //        foreach ($subscription->properties as $name => $value) {
  //          $value = escapeshellarg($value);
  //          $command[] = "--{$name}={$value}";
  //        }
          hosting_process($command, null, t('Assigning servers...'));
        }
      }
    }

    if (($task->ref->type == 'site' && $task->ref->site_status == HOSTING_SITE_DELETED)
      || ($task->ref->type == 'platform' && $task->ref->platform_status == HOSTING_PLATFORM_DELETED)) {

      // We're performing a task on a site that has been deleted...
      // d() will not be returning a site object.
      $alias = '@none';
    }
    else {
      $alias = $task->ref->hosting_name;
    }

    if (empty($task->task_command)) {
      $task->task_command = 'provision-' . $task->task_type;
    }

    // Run the actual command. Adding alias here to work around Drush API.
  // @TODO: Convert from Legacy
    $output = provision_backend_invoke($alias, $task->task_command, $task->args, $task->options, $mode);

    /**
    // Build the task command.
    // @TODO: Create a function for this?
    $command = array(
      variable_get('provision_bin_command', '/usr/share/devshop/provision/bin/provision'),
      "@{$task->ref->hosting_name}",
      "-n",
      "--ansi",
      $task->task_command
    );

    // Build command as an array for compatibility.
    $command = array(
      "drush",
      "@{$task->ref->hosting_name}",
      $task->task_command,
    );

    // Append each argument.
    foreach ($task->args as $argument) {
      if (!empty($argument)) {
        $command[] = escapeshellarg($argument);
      }
    }

    // Append each option.
    foreach ($task->options as $name => $value) {
      if (!empty($value)) {
        // If $value is just TRUEish, don't show value in the command line
        if ((string) $value == "1") {
          $command[] = "--{$name}";
        }
        else {
          $value = escapeshellarg($value);
          $command[] = "--{$name}={$value}";
        }
      }
    }

    // Append --strict option because... hosting tasks often pass arbitrary options.
    $command[] = '--strict=0';
    hosting_process($command, null, t('Running Task...'));

    // Pass the drush output back to the HOOK_post_hosting_TASK_task() and
    // HOOK_hosting_TASK_task_rollback() hooks, as the $data argument.
    drush_set_context('HOSTING_DRUSH_OUTPUT', $output);

    // On successful delete, remove the named context.
    if ($task->task_type == 'delete' && !drush_get_error()) {

      // Use the task_arg if there is one, hosting_name as a backup. $node->ref->hosting_name may be missing.
      $context_to_delete = $task->task_args['hosting_context']?:
        ($task->ref->hosting_name?: FALSE);

      // Run the "provision-save --delete" command on $context_to_delete.
      if ($context_to_delete) {
        drush_log(dt("Deleting back-end context file for !context.", array(
          '!context' => $context_to_delete,
        )), 'notice');

        /* Reverting modernization for now
        // Build command as an array for compatibility.
        $command = array(
          "drush",
          "provision-save",
          "@{$task->ref->hosting_name}",
          "--delete"
        );
        hosting_process($command, null, t('Deleting metadata...'));
        drush_invoke_process('@none', 'provision-save', array('@' . $task->ref->hosting_name), array('delete' => TRUE), array('method' => $mode, 'integrate' => TRUE));
      }
      // If no context name was found, throw a warning.
      else {
        drush_log(dt('No "hosting_name" property was found on the !type node (!url). Unable to delete back-end context file.', array(
          '!type' => $task->ref->type,
          '!url' => url("node/$task->rid", array('absolute' => TRUE)),
        )), 'warning');
      }
    }

    // New revision is created at the beginning of function.
    $task->revision = FALSE;
    $task->delta = microtime(TRUE) - $task->executed;
    node_save($task);
    // @TODO: END OF MODERNIZATION HACKS
     */
}