Skip to content
Open
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
9 changes: 9 additions & 0 deletions includes/Hooks/CreateWikiHookRunner.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class CreateWikiHookRunner implements
CreateWikiReadPersistentModelHook,
CreateWikiRemoteWikiCommitHook,
CreateWikiRenameHook,
CreateWikiSetContainersAccessFailedHook,
CreateWikiStateClosedHook,
CreateWikiStateOpenHook,
CreateWikiStatePrivateHook,
Expand Down Expand Up @@ -110,6 +111,14 @@ public function onCreateWikiRename(
);
}

/** @inheritDoc */
public function onCreateWikiSetContainersAccessFailed( string $dir, string $zone ): bool {
return $this->hookContainer->run(
'CreateWikiSetContainersAccessFailed',
[ $dir, $zone ]
);
}

/** @inheritDoc */
public function onCreateWikiStateClosed( string $dbname ): void {
$this->hookContainer->run(
Expand Down
14 changes: 14 additions & 0 deletions includes/Hooks/CreateWikiSetContainersAccessFailedHook.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace Miraheze\CreateWiki\Hooks;

interface CreateWikiSetContainersAccessFailedHook {

/**
* @param string $dir The current storage directory.
* @param string $zone The current zone.
* @return bool Whether to retry the script again after running this hook.
* @codeCoverageIgnore Cannot be annotated as covered.
*/
public function onCreateWikiSetContainersAccessFailed( string $dir, string $zone ): bool;
}
68 changes: 54 additions & 14 deletions maintenance/SetContainersAccess.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,19 @@
use MediaWiki\MainConfigNames;
use MediaWiki\Maintenance\Maintenance;
use Miraheze\CreateWiki\ConfigNames;
use Miraheze\CreateWiki\Hooks\CreateWikiHookRunner;
use Miraheze\CreateWiki\Services\RemoteWikiFactory;
use StatusValue;
use Wikimedia\FileBackend\FileBackend;
use function print_r;

class SetContainersAccess extends Maintenance {

private CreateWikiHookRunner $hookRunner;
private RemoteWikiFactory $remoteWikiFactory;

private bool $isRetrying = false;
private bool $needsRetry = false;

public function __construct() {
parent::__construct();

Expand All @@ -24,12 +29,23 @@ public function __construct() {

private function initServices(): void {
$services = $this->getServiceContainer();
$this->hookRunner = $services->get( 'CreateWikiHookRunner' );
$this->remoteWikiFactory = $services->get( 'RemoteWikiFactory' );
}

public function execute(): void {
$this->initServices();
$this->processContainers();

if ( $this->needsRetry && !$this->isRetrying ) {
$this->isRetrying = true;
$this->needsRetry = false;

$this->processContainers();
}
}

private function processContainers(): void {
$repo = $this->getServiceContainer()->getRepoGroup()->getLocalRepo();
$backend = $repo->getBackend();

Expand All @@ -38,30 +54,33 @@ public function execute(): void {
);

$isPrivate = $remoteWiki->isPrivate();

foreach ( $this->getConfig()->get( ConfigNames::Containers ) as $zone => $status ) {
foreach ( $this->getConfig()->get( ConfigNames::Containers ) as $zone => $state ) {
$dir = $backend->getContainerStoragePath( $zone );
$private = $status === 'private';
$publicPrivate = $status === 'public-private';

$private = $state === 'private';
$publicPrivate = $state === 'public-private';

$secure = ( $private || ( $publicPrivate && $isPrivate ) )
? [ 'noAccess' => true, 'noListing' => true ] : [];

$this->prepareDirectory( $backend, $dir, $secure );
$this->prepareDirectory( $backend, $secure, $dir, $zone );
}
}

protected function prepareDirectory(
private function prepareDirectory(
FileBackend $backend,
array $secure,
string $dir,
array $secure
string $zone
): void {
// Create zone if it doesn't exist...
$this->output( "Making sure '$dir' exists..." );
$backend->clearCache( [ $dir ] );
$status = $backend->prepare( [ 'dir' => $dir ] + $secure );

if ( !$status->isOK() ) {
$this->output( 'failed...' );
$this->handleFailure( $status, $dir, $zone );
return;
}

// Make sure zone has the right ACLs...
Expand All @@ -75,11 +94,32 @@ protected function prepareDirectory(
$status->merge( $backend->publish( [ 'dir' => $dir, 'access' => true ] ) );
}

if ( $status->isOK() ) {
$this->output( "done.\n" );
} else {
$this->output( "failed.\n" );
print_r( $status->getMessages( 'error' ) );
if ( !$status->isOK() ) {
$this->handleFailure( $status, $dir, $zone );
return;
}

$this->output( "done.\n" );
}

private function handleFailure(
StatusValue $status,
string $dir,
string $zone
): void {
if ( $this->isRetrying ) {
$this->output( "retry failed.\n" );
$this->error( $status );
return;
}

$this->output( "failed.\n" );
$this->error( $status );

if ( $this->hookRunner->onCreateWikiSetContainersAccessFailed( $dir, $zone ) ) {
// If the hook returned true, we can try this script one time.
$this->output( "retrying.\n" );
$this->needsRetry = true;
}
}
}
Expand Down
Loading