simplytest-8.x-4.x-dev/modules/simplytest_tugboat/src/Controller/SimplytestTugboatController.php

modules/simplytest_tugboat/src/Controller/SimplytestTugboatController.php
<?php

namespace Drupal\simplytest_tugboat\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Routing\TrustedRedirectResponse;
use Drupal\Core\Url;
use Drupal\simplytest_tugboat\InstanceManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;

/**
 * Returns responses for Simplytest tugboat routes.
 */
class SimplytestTugboatController extends ControllerBase {

  /**
   * The module settings.
   *
   * @var \Drupal\Core\Config\ImmutableConfig
   */
  protected $settings;

  /**
   * The instance manager service.
   *
   * @var \Drupal\simplytest_tugboat\InstanceManagerInterface
   */
  protected $instanceManager;

  /**
   * The file system service.
   *
   * @var \Drupal\Core\File\FileSystemInterface
   */
  protected $fileSystem;

  /**
   * The logger channel for this module.
   *
   * @var \Drupal\Core\Logger\LoggerChannelInterface
   */
  protected $logger;

  /**
   * The messenger service;
   *
   * @var \Drupal\Core\Messenger\MessengerInterface
   */
  protected $messenger;

  /**
   * The Tugboat Execute service.
   *
   * @var \Drupal\tugboat\TugboatExecute
   */
  protected $tugboatExecute;

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    $instance = new static();
    $instance->settings = $this->config('simplytest_tugboat.settings');
    $instance->instanceManager = $container->get('simplytest_tugboat.instance_manager');
    $instance->fileSystem = $container->get('file_system');
    $instance->logger = $this->getLogger('simplytest_tugboat');
    $instance->messenger = $container->get('messenger');
    $instance->tugboatExecute = $container->get('tugboat.execute');
    return $instance;
  }

  /**
   * Start and run the tugboat execution.
   *
   * @param string $instance_id
   *   The primary identifier for the instance.
   */
  public function provision($instance_id) {
    $state = $this->instanceManager->getStatusState($instance_id);

    if ($state['code'] !== InstanceManagerInterface::ENQUEUE) {
      return new Response();
    }

    $this->instanceManager->updateStatus($instance_id, InstanceManagerInterface::SPAWNED);

    // Let's run this in Tugboat.
    $tugboat_repo = $this->settings->get('tugboat_repository_id');

    $return_data = [];
    $error_string = '';

    $drupal_path = 'public://instance-log';
    $this->fileSystem->prepareDirectory($drupal_path, FileSystemInterface::CREATE_DIRECTORY);
    $result_path = "$drupal_path/$instance_id-result.txt";
    $output_path = "$drupal_path/$instance_id-output.txt";
    $error_path = "$drupal_path/$instance_id-error.txt";

    //$return_status = TRUE;

    $context = simplytest_tugboat_context_load($instance_id);
    $this->instanceManager->updateStatus($instance_id, InstanceManagerInterface::PREPARE);

    // Load the ID of the correct base preview ID.
    $base_preview_id = simplytest_tugboat_load_preview_id($context, TRUE);

    $this->logger->notice('message', 'Trying to load base preview ' . $base_preview_id);

    // Run the tugboat command.
    $command = "create preview $instance_id repo=$tugboat_repo preview=$instance_id base=$base_preview_id";
    $this->logger->notice($command);
    $return_status = $this->tugboatExecute->execute($command, $return_data, $error_string, NULL, $result_path, $output_path, $error_path);

    $this->logger->notice('Error: ' . $error_string);
    $this->logger->notice('Return data: ' . var_export($return_data, TRUE));

    if (!$return_status or empty($return_data['url'])) {
      $this->messenger->addMessage($this->t('An instance could not be created at this time! Please try again later.'));
      $this->instanceManager->updateStatus($instance_id, InstanceManagerInterface::FAILED);

      if ($error_string) {
        $this->logger->notice("Failed to create sandbox. Error from Tugboat: <pre>$error_string</pre>");
      }
      else {
        $this->logger->notice('Failed to create instance. No error data returned from Tugboat!');
      }
    }
    else {
      $url = $return_data['url'];
      $this->logger->notice('simplytest_tugboat', "Submitted Tugboat sandbox: $instance_id");
      // Set it to finished so it redirects.

      simplytest_tugboat_url_update($instance_id, $url);
      $this->instanceManager->updateStatus($instance_id, InstanceManagerInterface::FINISHED);
    }

    return new Response();
  }

  /**
   * Progress indicator page for a specific submission.
   *
   * @param string $instance_id
   *   The primary identifier for the instance.
   */
  public function progress($instance_id) {

    // Make sure this submission is available.
    $state = $this->instanceManager->getStatusState($instance_id);
    if ($state === FALSE) {
      $this->messenger->addError($this->t('The requested submission is not available.'));
      return $this->redirect('<front>');
    }

    // If the siterequest came by the meta no_js refresh.
    if (isset($_GET['no_js'])) {
      // If this submission is finished, HTTP redirect.
      if ($state['percent'] == '100') {
        $this->goto($instance_id);
        return new Response();
      }
    }

    // Check for an established URL, forward if exists.
    if ($state['percent'] == '100') {
      $url = $this->instanceManager->loadUrl($instance_id);

      // Redirect through a 'Refresh' meta tag if JavaScript is disabled.
      $meta_refresh = [
        '#prefix' => '<noscript>',
        '#suffix' => '</noscript>',
        '#tag' => 'meta',
        '#attributes' => [
          'http-equiv' => 'Refresh',
          'content' => '5; URL=' . $url,
        ],
      ];

      return [
        '#type' => 'container',
        'html_head' => [[$meta_refresh, 'simplytest_tugboat_status_meta_refresh']],
        'page-contents' => [
          '#type' => 'markup',
          '#markup' => '<p>Forwarding you to the Tugboat instance</p>',
        ],
      ];

    }
    else {

      $this->logger->notice('State: ' . var_export($state, TRUE));

      // Redirect through a 'Refresh' meta tag if JavaScript is disabled.
      $current_path = Url::fromRoute('<current>', [], ['query' => ['no_js' => NULL]])
        ->toString();
      $meta_refresh = [
        '#prefix' => '<noscript>',
        '#suffix' => '</noscript>',
        '#tag' => 'meta',
        '#attributes' => [
          'http-equiv' => 'Refresh',
          // Keep refreshing the current page, but mark each refresh with no_js.
          'content' => '5; URL=' . url(current_path(), ['query' => ['no_js' => NULL]]),
          'content' => '5; URL=' . ltrim($current_path, '/'),
        ],
      ];

      // Return a progress bar and attach own javascript.
      return [
        '#type' => 'container',
        '#attributes' => [
          'class' => ['simplytest-progress-bar'],
        ],
        '#attached' => [
          'html_head' => [[$meta_refresh, 'simplytest-progress-bar']],
          'js' => [
            [
              'data' => [
                'simplytest_tugboat' => [
                  'id' => $instance_id,
                ],
              ],
              'type' => 'setting',
            ],
          ],
        ],
        'progress-bar' => [
          '#theme' => 'progress_bar',
          '#percent' => $state['percent'],
          '#message' => $state['message'],
        ],
        'log' => [
          '#prefix' => '<div id="simplytest-log" class="log">',
          '#suffix' => '</div>',
          '#markup' => $state['log'],
          //'#children' => $this->t('number of items: ' . count($state['log'])),
          '#cache' => [
            'max-age' => 0,
          ],
        ],
      ];
    }
  }

  /**
   * Redirection page to final sandbox environment url.
   *
   * @param string $instance_id
   *   The primary identifier for the instance.
   */
  public function goto($instance_id) {
    // Check for an established URL, forward if exists.
    $tugboat_url = $this->instanceManager->loadUrl($instance_id);
    if (!empty($tugboat_url) and $tugboat_url !== '') {
      return new TrustedRedirectResponse($tugboat_url);
    }

    // Check state.
    $state = $this->instanceManager->getStatusState($instance_id);
    if ($state['code'] === FALSE) {
      $this->messenger->addError($this->t('The requested submission is not available.'));
      return $this->redirect('<front>');
    }
    switch ($state['code']) {
      case InstanceManagerInterface::ENQUEUE:
      case InstanceManagerInterface::SPAWNED:
      case InstanceManagerInterface::PREPARE:
      case InstanceManagerInterface::DOWNLOAD:
      case InstanceManagerInterface::PATCHING:
      case InstanceManagerInterface::INSTALLING:
      case InstanceManagerInterface::FINALIZE:
        return $this->redirect('simplytest_tugboat.progress', ['instance_id' => $instance_id]);
        break;

      case InstanceManagerInterface::FINISHED:
        // @todo Will we get the same result as at the start of this function?
        $tugboat_url = $this->instanceManager->loadUrl($instance_id);
        return new TrustedRedirectResponse($tugboat_url);
        break;

      default:
        $this->message->addError($state['message']);
        return $this->redirect('<front>');
    }
  }

  /**
   * Callback for remote services to update the status of an instance.
   *
   * @param string $instance_id
   *   The primary identifier for the instance.
   * @param int $status_code
   *   One of the constants from InstanceManagerInterface.
   */
  public function status($instance_id, $status_code) {
    $this->instanceManager->updateStatus($instance_id, $status_code);
    return new Response();
  }

  /**
   * New JSON output callback for current instance status.
   *
   * @param string $instance_id
   *   The primary identifier for the instance.
   */
  public function instanceState($instance_id) {
    $state = $this->instanceManager->getStatusState($instance_id);
    $state['do_provision'] = $state['code'] === InstanceManagerInterface::ENQUEUE;
    return new JsonResponse($state);
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc