Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add maint mode commands #5383

Merged
merged 2 commits into from
Feb 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions docs/cron.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
Running Drupal cron tasks from Drush
====================================

Drupal cron tasks are often set up to be run via a wget call to cron.php; this same task can also be accomplished via the [cron command](commands/core_cron.md), which circumvents the need to provide a web server interface to cron.
Drupal cron tasks are often set up to be run via a wget/curl call to cron.php; this same task can also be accomplished via the [cron command](commands/core_cron.md), which circumvents the need to provide a web server interface to cron.

Quick start
----------

If you just want to get started quickly, here is a crontab entry that will run cron once every hour at ten minutes after the hour:

10 * * * * cd [DOCROOT] && /usr/bin/env PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin COLUMNS=72 ../vendor/bin/drush --uri=your.drupalsite.org --quiet cron
10 * * * * cd [DOCROOT] && /usr/bin/env PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin COLUMNS=72 ../vendor/bin/drush --uri=your.drupalsite.org --quiet maint:status && /vendor/bin/drush --uri=your.drupalsite.org --quiet cron

You should set up crontab to run your cron tasks as the same user that runs the web server; for example, if you run your web server as the user www-data:

Expand Down Expand Up @@ -47,3 +47,7 @@ Specifying the Drupal site to run

There are many ways to tell Drush which Drupal site to select for the active command, and any may be used here. The example uses `cd [DOCROOT]`, but you could also use the --root and --uri flags.

Avoiding Maintenance mode
---------------------------------

The call to maint:status checks to see if the site is in maintenance mode. If yes, cron will not run and the command returns a failure. It is not safe to run cron while the site is in maintenance. See https://drupal.slack.com/archives/C45SW3FLM/p1675287662331809.
2 changes: 2 additions & 0 deletions src/Drupal/Commands/core/DrupalCommands.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ public function __construct(CronInterface $cron, ModuleHandlerInterface $moduleH
*
* @command core:cron
* @aliases cron,core-cron
* @usage drush maint:status && drush core:cron
* Run cron unless maintenance mode is enabled
* @topics docs:cron
*/
public function cron(): void
Expand Down
82 changes: 82 additions & 0 deletions src/Drupal/Commands/core/MaintCommands.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<?php

namespace Drush\Drupal\Commands\core;

use Consolidation\AnnotatedCommand\CommandResult;
use Consolidation\AnnotatedCommand\Input\StdinAwareInterface;
use Consolidation\AnnotatedCommand\Input\StdinAwareTrait;
use Drupal\Core\State\StateInterface;
use Drush\Commands\DrushCommands;

class MaintCommands extends DrushCommands
{
const KEY = 'system.maintenance_mode';

protected $state;

public function __construct(StateInterface $state)
{
$this->state = $state;
}

public function getState(): StateInterface
{
return $this->state;
}

/**
* Get maintenance mode. Returns 1 if enabled, 0 if not.
*
* Consider using maint:status instead when chaining commands.
*
* @command maint:get
*
* @usage drush maint:get
* Print value of maintenance mode in Drupal
* @aliases mget
* @version 11.5
*/
public function get(): string
{
$value = $this->getState()->get(self::KEY);
return $value ? '1' : '0';
}

/**
* Set maintenance mode.
*
* @command maint:set
*
* @param mixed $value The value to assign to the state key.
* @usage drush maint:set 1
* Put site into Maintenance mode.
* @usage drush maint:set 0
* Remove site from Maintenance mode.
* @aliases mset
* @version 11.5
*/
public function set(string $value): void
{
$this->getState()->set(self::KEY, (bool) $value);
}


/**
* Fail if maintenance mode is enabled.
*
* This commands fails with exit code of 3 when maintenance mode is on. This special
* exit code distinguishes from a failure to complete.
*
* @command maint:status
*
* @usage drush maint:status && drush cron
* Only run cron when Drupal is not in maintenance mode.
* @aliases mstatus
* @version 11.5
*/
public function status(): int
{
$value = $this->getState()->get(self::KEY);
return $value ? self::EXIT_FAILURE_WITH_CLARITY : self::EXIT_SUCCESS;
}
}
5 changes: 5 additions & 0 deletions src/Drupal/Commands/core/drush.services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ services:
arguments: ['@language_manager', '@config.factory', '@module_handler', '@state']
tags:
- { name: drush.command }
maint.commands:
class: \Drush\Drupal\Commands\core\MaintCommands
arguments: [ '@state' ]
tags:
- { name: drush.command }
messenger.commands:
class: \Drush\Drupal\Commands\core\MessengerCommands
arguments: ['@messenger']
Expand Down
23 changes: 23 additions & 0 deletions tests/integration/MaintTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace Unish;

/**
* Tests Maintenance commands
*
* @group commands
*/
class MaintenanceTest extends UnishIntegrationTestCase
{
public function testMaint()
{
$this->drush('maint:set', [1]);
$this->drush('maint:get');
$this->assertOutputEquals('1');
$this->drush('maint:status', [], [], self::EXIT_ERROR_WITH_CLARITY);
$this->drush('maint:set', [0]);
$this->drush('maint:get');
$this->assertOutputEquals('0');
$this->drush('maint:status', [], [], self::EXIT_SUCCESS);
}
}